diff options
Diffstat (limited to 'media/libstagefright/matroska/MatroskaExtractor.cpp')
-rw-r--r-- | media/libstagefright/matroska/MatroskaExtractor.cpp | 93 |
1 files changed, 60 insertions, 33 deletions
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index d260d0f..6ec9263 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -193,7 +193,7 @@ MatroskaSource::~MatroskaSource() { clearPendingFrames(); } -status_t MatroskaSource::start(MetaData *params) { +status_t MatroskaSource::start(MetaData * /* params */) { mBlockIter.reset(); return OK; @@ -313,7 +313,7 @@ void BlockIterator::seek( *actualFrameTimeUs = -1ll; - const int64_t seekTimeNs = seekTimeUs * 1000ll; + const int64_t seekTimeNs = seekTimeUs * 1000ll - mExtractor->mSeekPreRollNs; mkvparser::Segment* const pSegment = mExtractor->mSegment; @@ -410,7 +410,7 @@ void BlockIterator::seek( // Accept the first key frame *actualFrameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL; ALOGV("Requested seek point: %lld actual: %lld", - seekTimeUs, actualFrameTimeUs); + seekTimeUs, *actualFrameTimeUs); break; } } @@ -628,7 +628,8 @@ MatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) mReader(new DataSourceReader(mDataSource)), mSegment(NULL), mExtractedThumbnails(false), - mIsWebm(false) { + mIsWebm(false), + mSeekPreRollNs(0) { off64_t size; mIsLiveStreaming = (mDataSource->flags() @@ -716,41 +717,61 @@ bool MatroskaExtractor::isLiveStreaming() const { return mIsLiveStreaming; } +static int bytesForSize(size_t size) { + // use at most 28 bits (4 times 7) + CHECK(size <= 0xfffffff); + + if (size > 0x1fffff) { + return 4; + } else if (size > 0x3fff) { + return 3; + } else if (size > 0x7f) { + return 2; + } + return 1; +} + +static void storeSize(uint8_t *data, size_t &idx, size_t size) { + int numBytes = bytesForSize(size); + idx += numBytes; + + data += idx; + size_t next = 0; + while (numBytes--) { + *--data = (size & 0x7f) | next; + size >>= 7; + next = 0x80; + } +} + static void addESDSFromCodecPrivate( const sp<MetaData> &meta, bool isAudio, const void *priv, size_t privSize) { - static const uint8_t kStaticESDS[] = { - 0x03, 22, - 0x00, 0x00, // ES_ID - 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag - - 0x04, 17, - 0x40, // ObjectTypeIndication - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - - 0x05, - // CodecSpecificInfo (with size prefix) follows - }; - // Make sure all sizes can be coded in a single byte. - CHECK(privSize + 22 - 2 < 128); - size_t esdsSize = sizeof(kStaticESDS) + privSize + 1; + int privSizeBytesRequired = bytesForSize(privSize); + int esdsSize2 = 14 + privSizeBytesRequired + privSize; + int esdsSize2BytesRequired = bytesForSize(esdsSize2); + int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2; + int esdsSize1BytesRequired = bytesForSize(esdsSize1); + size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1; uint8_t *esds = new uint8_t[esdsSize]; - memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); - uint8_t *ptr = esds + sizeof(kStaticESDS); - *ptr++ = privSize; - memcpy(ptr, priv, privSize); - // Increment by codecPrivateSize less 2 bytes that are accounted for - // already in lengths of 22/17 - esds[1] += privSize - 2; - esds[6] += privSize - 2; - - // Set ObjectTypeIndication. - esds[7] = isAudio ? 0x40 // Audio ISO/IEC 14496-3 - : 0x20; // Visual ISO/IEC 14496-2 + size_t idx = 0; + esds[idx++] = 0x03; + storeSize(esds, idx, esdsSize1); + esds[idx++] = 0x00; // ES_ID + esds[idx++] = 0x00; // ES_ID + esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag + esds[idx++] = 0x04; + storeSize(esds, idx, esdsSize2); + esds[idx++] = isAudio ? 0x40 // Audio ISO/IEC 14496-3 + : 0x20; // Visual ISO/IEC 14496-2 + for (int i = 0; i < 12; i++) { + esds[idx++] = 0x00; + } + esds[idx++] = 0x05; + storeSize(esds, idx, privSize); + memcpy(esds + idx, priv, privSize); meta->setData(kKeyESDS, 0, esds, esdsSize); @@ -899,6 +920,12 @@ void MatroskaExtractor::addTracks() { err = addVorbisCodecInfo( meta, codecPrivate, codecPrivateSize); + } else if (!strcmp("A_OPUS", codecID)) { + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_OPUS); + meta->setData(kKeyOpusHeader, 0, codecPrivate, codecPrivateSize); + meta->setInt64(kKeyOpusCodecDelay, track->GetCodecDelay()); + meta->setInt64(kKeyOpusSeekPreRoll, track->GetSeekPreRoll()); + mSeekPreRollNs = track->GetSeekPreRoll(); } else if (!strcmp("A_MPEG/L3", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); } else { |