MPEG4Extractor: read codecDelay from opus header

Instead of hard coding codecDelay, read it from opus header.
Also allow for variable sized opusheader to support multiple channels

Bug:129712302
Test: atest android.media.cts.DecoderTest
Change-Id: I5e134f688125d275163dfa496acd8133354b5617
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index e1bfb62..348ea49 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -45,6 +45,7 @@
 #include <media/stagefright/foundation/ColorUtils.h>
 #include <media/stagefright/foundation/avc_utils.h>
 #include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/foundation/OpusHeader.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaDataBase.h>
@@ -1735,15 +1736,21 @@
             AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
 
             if (chunk_type == FOURCC("Opus")) {
-                uint8_t opusInfo[19];
+                uint8_t opusInfo[AOPUS_OPUSHEAD_MAXSIZE];
                 data_offset += sizeof(buffer);
+                size_t opusInfoSize = chunk_data_size - sizeof(buffer);
+
+                if (opusInfoSize < AOPUS_OPUSHEAD_MINSIZE ||
+                    opusInfoSize > AOPUS_OPUSHEAD_MAXSIZE) {
+                    return ERROR_MALFORMED;
+                }
                 // Read Opus Header
                 if (mDataSource->readAt(
-                        data_offset, opusInfo, sizeof(opusInfo)) < (ssize_t)sizeof(opusInfo)) {
+                        data_offset, opusInfo, opusInfoSize) < opusInfoSize) {
                     return ERROR_IO;
                 }
 
-                // OpusHeader must start with this magic sequence
+                // OpusHeader must start with this magic sequence, overwrite first 8 bytes
                 // http://wiki.xiph.org/OggOpus#ID_Header
                 strncpy((char *)opusInfo, "OpusHead", 8);
 
@@ -1760,17 +1767,18 @@
                 memcpy(&opusInfo[opusOffset + 2], &sample_rate, sizeof(sample_rate));
                 memcpy(&opusInfo[opusOffset + 6], &out_gain, sizeof(out_gain));
 
-                int64_t codecDelay = 6500000;
-                int64_t seekPreRollNs = 80000000;  // Fixed 80 msec
+                static const int64_t kSeekPreRollNs = 80000000;  // Fixed 80 msec
+                static const int32_t kOpusSampleRate = 48000;
+                int64_t codecDelay = pre_skip * 1000000000ll / kOpusSampleRate;
 
                 AMediaFormat_setBuffer(mLastTrack->meta,
                             AMEDIAFORMAT_KEY_CSD_0, opusInfo, sizeof(opusInfo));
                 AMediaFormat_setBuffer(mLastTrack->meta,
                         AMEDIAFORMAT_KEY_CSD_1, &codecDelay, sizeof(codecDelay));
                 AMediaFormat_setBuffer(mLastTrack->meta,
-                        AMEDIAFORMAT_KEY_CSD_2, &seekPreRollNs, sizeof(seekPreRollNs));
+                        AMEDIAFORMAT_KEY_CSD_2, &kSeekPreRollNs, sizeof(kSeekPreRollNs));
 
-                data_offset += sizeof(opusInfo);
+                data_offset += opusInfoSize;
                 *offset = data_offset;
                 CHECK_EQ(*offset, stop_offset);
             }