Loading apex/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ apex { "libmkvextractor", "libmp3extractor", "libmp4extractor", "liboggextractor", "libwavextractor", ], key: "com.android.media.key", Loading include/media/MediaExtractorPluginHelper.h +8 −8 Original line number Diff line number Diff line Loading @@ -183,32 +183,32 @@ public: mBuffer = buf; } ~MediaBufferHelperV3() {} virtual ~MediaBufferHelperV3() {} void release() { virtual void release() { mBuffer->release(mBuffer->handle); } void* data() { virtual void* data() { return mBuffer->data(mBuffer->handle); } size_t size() { virtual size_t size() { return mBuffer->size(mBuffer->handle); } size_t range_offset() { virtual size_t range_offset() { return mBuffer->range_offset(mBuffer->handle); } size_t range_length() { virtual size_t range_length() { return mBuffer->range_length(mBuffer->handle); } void set_range(size_t offset, size_t length) { virtual void set_range(size_t offset, size_t length) { mBuffer->set_range(mBuffer->handle, offset, length); } AMediaFormat *meta_data() { virtual AMediaFormat *meta_data() { return mBuffer->meta_data(mBuffer->handle); } }; Loading media/extractors/ogg/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ cc_library_shared { shared_libs: [ "liblog", "libmediaextractor", "libmediandk", ], Loading media/extractors/ogg/OggExtractor.cpp +123 −50 Original line number Diff line number Diff line Loading @@ -28,11 +28,8 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/base64.h> #include <media/stagefright/foundation/ByteUtils.h> #include <media/stagefright/MediaBufferBase.h> #include <media/stagefright/MediaBufferGroup.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaDataBase.h> #include <media/stagefright/MetaDataUtils.h> #include <system/audio.h> #include <utils/String8.h> Loading @@ -48,7 +45,7 @@ extern "C" { namespace android { struct OggSource : public MediaTrackHelperV2 { struct OggSource : public MediaTrackHelperV3 { explicit OggSource(OggExtractor *extractor); virtual media_status_t getFormat(AMediaFormat *); Loading @@ -57,7 +54,7 @@ struct OggSource : public MediaTrackHelperV2 { virtual media_status_t stop(); virtual media_status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL); protected: virtual ~OggSource(); Loading Loading @@ -85,7 +82,7 @@ struct MyOggExtractor { status_t seekToTime(int64_t timeUs); status_t seekToOffset(off64_t offset); virtual media_status_t readNextPacket(MediaBufferBase **buffer) = 0; virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) = 0; status_t init(); Loading @@ -93,6 +90,9 @@ struct MyOggExtractor { return AMediaFormat_copy(meta, mFileMeta); } void setBufferGroup(MediaBufferGroupHelperV3 *group) { mBufferGroup = group; } protected: struct Page { uint64_t mGranulePosition; Loading @@ -110,6 +110,7 @@ protected: int64_t mTimeUs; }; MediaBufferGroupHelperV3 *mBufferGroup; DataSourceHelper *mSource; off64_t mOffset; Page mCurrentPage; Loading Loading @@ -148,7 +149,7 @@ protected: // 1 - bitstream identification header // 3 - comment header // 5 - codec setup header (Vorbis only) virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type) = 0; virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) = 0; // Read the next ogg packet from the underlying data source; optionally // calculate the timestamp for the output packet whilst pretending Loading @@ -156,9 +157,9 @@ protected: // // *buffer is NULL'ed out immediately upon entry, and if successful a new buffer is allocated; // clients are responsible for releasing the original buffer. media_status_t _readNextPacket(MediaBufferBase **buffer, bool calcVorbisTimestamp); media_status_t _readNextPacket(MediaBufferHelperV3 **buffer, bool calcVorbisTimestamp); int32_t getPacketBlockSize(MediaBufferBase *buffer); int32_t getPacketBlockSize(MediaBufferHelperV3 *buffer); void parseFileMetaData(); Loading @@ -182,7 +183,7 @@ struct MyVorbisExtractor : public MyOggExtractor { virtual uint64_t approxBitrate() const; virtual media_status_t readNextPacket(MediaBufferBase **buffer) { virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) { return _readNextPacket(buffer, /* calcVorbisTimestamp = */ true); } Loading @@ -194,7 +195,7 @@ protected: return granulePos * 1000000ll / mVi.rate; } virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type); virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type); }; struct MyOpusExtractor : public MyOggExtractor { Loading @@ -212,16 +213,16 @@ struct MyOpusExtractor : public MyOggExtractor { return 0; } virtual media_status_t readNextPacket(MediaBufferBase **buffer); virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer); protected: virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const; virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type); virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type); private: media_status_t verifyOpusHeader(MediaBufferBase *buffer); media_status_t verifyOpusComments(MediaBufferBase *buffer); uint32_t getNumSamplesInPacket(MediaBufferBase *buffer) const; media_status_t verifyOpusHeader(MediaBufferHelperV3 *buffer); media_status_t verifyOpusComments(MediaBufferHelperV3 *buffer); uint32_t getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const; uint8_t mChannelCount; uint16_t mCodecDelay; Loading Loading @@ -249,7 +250,9 @@ media_status_t OggSource::start() { if (mStarted) { return AMEDIA_ERROR_INVALID_OPERATION; } // initialize buffer group with a single small buffer, but a generous upper limit mBufferGroup->init(1 /* number of buffers */, 128 /* size */, 64 /* max number of buffers */); mExtractor->mImpl->setBufferGroup(mBufferGroup); mStarted = true; return AMEDIA_OK; Loading @@ -262,7 +265,7 @@ media_status_t OggSource::stop() { } media_status_t OggSource::read( MediaBufferBase **out, const ReadOptions *options) { MediaBufferHelperV3 **out, const ReadOptions *options) { *out = NULL; int64_t seekTimeUs; Loading @@ -274,26 +277,27 @@ media_status_t OggSource::read( } } MediaBufferBase *packet; MediaBufferHelperV3 *packet; media_status_t err = mExtractor->mImpl->readNextPacket(&packet); if (err != AMEDIA_OK) { return err; } AMediaFormat *meta = packet->meta_data(); #if 0 int64_t timeUs; if (packet->meta_data().findInt64(kKeyTime, &timeUs)) { if (AMediaFormat_findInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeStampUs)) { ALOGI("found time = %lld us", timeUs); } else { ALOGI("NO time"); } #endif packet->meta_data().setInt32(kKeyIsSyncFrame, 1); AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1); *out = packet; ALOGV("returning buffer %p", packet); return AMEDIA_OK; } Loading @@ -304,7 +308,8 @@ MyOggExtractor::MyOggExtractor( const char *mimeType, size_t numHeaders, int64_t seekPreRollUs) : mSource(source), : mBufferGroup(NULL), mSource(source), mOffset(0), mCurGranulePosition(0), mPrevGranulePosition(0), Loading Loading @@ -573,13 +578,13 @@ ssize_t MyOggExtractor::readPage(off64_t offset, Page *page) { return sizeof(header) + page->mNumSegments + totalSize; } media_status_t MyOpusExtractor::readNextPacket(MediaBufferBase **out) { media_status_t MyOpusExtractor::readNextPacket(MediaBufferHelperV3 **out) { if (mOffset <= mFirstDataOffset && mStartGranulePosition < 0) { // The first sample might not start at time 0; find out where by subtracting // the number of samples on the first page from the granule position // (position of last complete sample) of the first page. This happens // the first time before we attempt to read a packet from the first page. MediaBufferBase *mBuf; MediaBufferHelperV3 *mBuf; uint32_t numSamples = 0; uint64_t curGranulePosition = 0; while (true) { Loading Loading @@ -617,24 +622,25 @@ media_status_t MyOpusExtractor::readNextPacket(MediaBufferBase **out) { int32_t currentPageSamples; // Calculate timestamps by accumulating durations starting from the first sample of a page; // We assume that we only seek to page boundaries. if ((*out)->meta_data().findInt32(kKeyValidSamples, ¤tPageSamples)) { AMediaFormat *meta = (*out)->meta_data(); if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, ¤tPageSamples)) { // first packet in page if (mOffset == mFirstDataOffset) { currentPageSamples -= mStartGranulePosition; (*out)->meta_data().setInt32(kKeyValidSamples, currentPageSamples); AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, currentPageSamples); } mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples; } int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition); (*out)->meta_data().setInt64(kKeyTime, timeUs); AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs); uint32_t frames = getNumSamplesInPacket(*out); mCurGranulePosition += frames; return AMEDIA_OK; } uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferBase *buffer) const { uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const { if (buffer == NULL || buffer->range_length() < 1) { return 0; } Loading Loading @@ -680,10 +686,66 @@ uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferBase *buffer) const { return numSamples; } media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisTimestamp) { /* * basic mediabuffer implementation used during initial parsing of the * header packets, which happens before we have a buffer group */ class StandAloneMediaBuffer : public MediaBufferHelperV3 { private: void *mData; size_t mSize; size_t mOffset; size_t mLength; AMediaFormat *mFormat; public: StandAloneMediaBuffer(size_t size) : MediaBufferHelperV3(NULL) { mSize = size; mData = malloc(mSize); mOffset = 0; mLength = mSize; mFormat = AMediaFormat_new(); ALOGV("created standalone media buffer %p of size %zu", this, mSize); } ~StandAloneMediaBuffer() override { free(mData); AMediaFormat_delete(mFormat); ALOGV("deleted standalone media buffer %p of size %zu", this, mSize); } void release() override { delete this; } void* data() override { return mData; } size_t size() override { return mSize; } size_t range_offset() override { return mOffset; } size_t range_length() override { return mLength; } void set_range(size_t offset, size_t length) override { mOffset = offset; mLength = length; } AMediaFormat *meta_data() override { return mFormat; } }; media_status_t MyOggExtractor::_readNextPacket(MediaBufferHelperV3 **out, bool calcVorbisTimestamp) { *out = NULL; MediaBufferBase *buffer = NULL; MediaBufferHelperV3 *buffer = NULL; int64_t timeUs = -1; for (;;) { Loading Loading @@ -719,7 +781,13 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV ALOGE("b/36592202"); return AMEDIA_ERROR_MALFORMED; } MediaBufferBase *tmp = MediaBufferBase::Create(fullSize); MediaBufferHelperV3 *tmp; if (mBufferGroup) { mBufferGroup->acquire_buffer(&tmp, false, fullSize); ALOGV("acquired buffer %p from group", tmp); } else { tmp = new StandAloneMediaBuffer(fullSize); } if (tmp == NULL) { if (buffer != NULL) { buffer->release(); Loading @@ -727,6 +795,7 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV ALOGE("b/36592202"); return AMEDIA_ERROR_MALFORMED; } AMediaFormat_clear(tmp->meta_data()); if (buffer != NULL) { memcpy(tmp->data(), buffer->data(), buffer->range_length()); tmp->set_range(0, buffer->range_length()); Loading Loading @@ -756,8 +825,9 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV // We've just read the entire packet. if (mFirstPacketInPage) { buffer->meta_data().setInt32( kKeyValidSamples, mCurrentPageSamples); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt32( meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples); mFirstPacketInPage = false; } Loading @@ -778,7 +848,8 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV mCurrentPage.mPrevPacketPos += actualBlockSize / 2; mCurrentPage.mPrevPacketSize = curBlockSize; } buffer->meta_data().setInt64(kKeyTime, timeUs); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs); } *out = buffer; Loading Loading @@ -824,11 +895,13 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV // is already complete. if (timeUs >= 0) { buffer->meta_data().setInt64(kKeyTime, timeUs); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs); } buffer->meta_data().setInt32( kKeyValidSamples, mCurrentPageSamples); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt32( meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples); mFirstPacketInPage = false; *out = buffer; Loading @@ -843,7 +916,7 @@ status_t MyOggExtractor::init() { AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType); media_status_t err; MediaBufferBase *packet; MediaBufferHelperV3 *packet; for (size_t i = 0; i < mNumHeaders; ++i) { // ignore timestamp for configuration packets if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) { Loading Loading @@ -920,7 +993,7 @@ void MyOggExtractor::buildTableOfContents() { } } int32_t MyOggExtractor::getPacketBlockSize(MediaBufferBase *buffer) { int32_t MyOggExtractor::getPacketBlockSize(MediaBufferHelperV3 *buffer) { const uint8_t *data = (const uint8_t *)buffer->data() + buffer->range_offset(); Loading Loading @@ -960,7 +1033,7 @@ int64_t MyOpusExtractor::getTimeUsOfGranule(uint64_t granulePos) const { return pcmSamplePosition * 1000000ll / kOpusSampleRate; } media_status_t MyOpusExtractor::verifyHeader(MediaBufferBase *buffer, uint8_t type) { media_status_t MyOpusExtractor::verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) { switch (type) { // there are actually no header types defined in the Opus spec; we choose 1 and 3 to mean // header and comments such that we can share code with MyVorbisExtractor. Loading @@ -973,7 +1046,7 @@ media_status_t MyOpusExtractor::verifyHeader(MediaBufferBase *buffer, uint8_t ty } } media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) { media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferHelperV3 *buffer) { const size_t kOpusHeaderSize = 19; const uint8_t *data = (const uint8_t *)buffer->data() + buffer->range_offset(); Loading Loading @@ -1001,7 +1074,7 @@ media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) { return AMEDIA_OK; } media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) { media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferHelperV3 *buffer) { // add artificial framing bit so we can reuse _vorbis_unpack_comment int32_t commentSize = buffer->range_length() + 1; auto tmp = heapbuffer<uint8_t>(commentSize); Loading Loading @@ -1094,7 +1167,7 @@ media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) { } media_status_t MyVorbisExtractor::verifyHeader( MediaBufferBase *buffer, uint8_t type) { MediaBufferHelperV3 *buffer, uint8_t type) { const uint8_t *data = (const uint8_t *)buffer->data() + buffer->range_offset(); Loading Loading @@ -1262,7 +1335,7 @@ size_t OggExtractor::countTracks() { return mInitCheck != OK ? 0 : 1; } MediaTrackHelperV2 *OggExtractor::getTrack(size_t index) { MediaTrackHelperV3 *OggExtractor::getTrack(size_t index) { if (index >= 1) { return NULL; } Loading @@ -1284,13 +1357,13 @@ media_status_t OggExtractor::getMetaData(AMediaFormat *meta) { return mImpl->getFileMetaData(meta); } static CMediaExtractorV2* CreateExtractor( static CMediaExtractorV3* CreateExtractor( CDataSource *source, void *) { return wrapV2(new OggExtractor(new DataSourceHelper(source))); return wrapV3(new OggExtractor(new DataSourceHelper(source))); } static CreatorFuncV2 Sniff( static CreatorFuncV3 Sniff( CDataSource *source, float *confidence, void **, Loading @@ -1311,11 +1384,11 @@ extern "C" { __attribute__ ((visibility ("default"))) ExtractorDef GETEXTRACTORDEF() { return { EXTRACTORDEF_VERSION_CURRENT, EXTRACTORDEF_VERSION_CURRENT + 1, UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"), 1, // version "Ogg Extractor", { .v2 = Sniff } { .v3 = Sniff } }; } Loading media/extractors/ogg/OggExtractor.h +2 −2 Original line number Diff line number Diff line Loading @@ -31,11 +31,11 @@ class String8; struct MyOggExtractor; struct OggSource; struct OggExtractor : public MediaExtractorPluginHelperV2 { struct OggExtractor : public MediaExtractorPluginHelperV3 { explicit OggExtractor(DataSourceHelper *source); virtual size_t countTracks(); virtual MediaTrackHelperV2 *getTrack(size_t index); virtual MediaTrackHelperV3 *getTrack(size_t index); virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags); virtual media_status_t getMetaData(AMediaFormat *meta); Loading Loading
apex/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ apex { "libmkvextractor", "libmp3extractor", "libmp4extractor", "liboggextractor", "libwavextractor", ], key: "com.android.media.key", Loading
include/media/MediaExtractorPluginHelper.h +8 −8 Original line number Diff line number Diff line Loading @@ -183,32 +183,32 @@ public: mBuffer = buf; } ~MediaBufferHelperV3() {} virtual ~MediaBufferHelperV3() {} void release() { virtual void release() { mBuffer->release(mBuffer->handle); } void* data() { virtual void* data() { return mBuffer->data(mBuffer->handle); } size_t size() { virtual size_t size() { return mBuffer->size(mBuffer->handle); } size_t range_offset() { virtual size_t range_offset() { return mBuffer->range_offset(mBuffer->handle); } size_t range_length() { virtual size_t range_length() { return mBuffer->range_length(mBuffer->handle); } void set_range(size_t offset, size_t length) { virtual void set_range(size_t offset, size_t length) { mBuffer->set_range(mBuffer->handle, offset, length); } AMediaFormat *meta_data() { virtual AMediaFormat *meta_data() { return mBuffer->meta_data(mBuffer->handle); } }; Loading
media/extractors/ogg/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ cc_library_shared { shared_libs: [ "liblog", "libmediaextractor", "libmediandk", ], Loading
media/extractors/ogg/OggExtractor.cpp +123 −50 Original line number Diff line number Diff line Loading @@ -28,11 +28,8 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/base64.h> #include <media/stagefright/foundation/ByteUtils.h> #include <media/stagefright/MediaBufferBase.h> #include <media/stagefright/MediaBufferGroup.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaDataBase.h> #include <media/stagefright/MetaDataUtils.h> #include <system/audio.h> #include <utils/String8.h> Loading @@ -48,7 +45,7 @@ extern "C" { namespace android { struct OggSource : public MediaTrackHelperV2 { struct OggSource : public MediaTrackHelperV3 { explicit OggSource(OggExtractor *extractor); virtual media_status_t getFormat(AMediaFormat *); Loading @@ -57,7 +54,7 @@ struct OggSource : public MediaTrackHelperV2 { virtual media_status_t stop(); virtual media_status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL); protected: virtual ~OggSource(); Loading Loading @@ -85,7 +82,7 @@ struct MyOggExtractor { status_t seekToTime(int64_t timeUs); status_t seekToOffset(off64_t offset); virtual media_status_t readNextPacket(MediaBufferBase **buffer) = 0; virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) = 0; status_t init(); Loading @@ -93,6 +90,9 @@ struct MyOggExtractor { return AMediaFormat_copy(meta, mFileMeta); } void setBufferGroup(MediaBufferGroupHelperV3 *group) { mBufferGroup = group; } protected: struct Page { uint64_t mGranulePosition; Loading @@ -110,6 +110,7 @@ protected: int64_t mTimeUs; }; MediaBufferGroupHelperV3 *mBufferGroup; DataSourceHelper *mSource; off64_t mOffset; Page mCurrentPage; Loading Loading @@ -148,7 +149,7 @@ protected: // 1 - bitstream identification header // 3 - comment header // 5 - codec setup header (Vorbis only) virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type) = 0; virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) = 0; // Read the next ogg packet from the underlying data source; optionally // calculate the timestamp for the output packet whilst pretending Loading @@ -156,9 +157,9 @@ protected: // // *buffer is NULL'ed out immediately upon entry, and if successful a new buffer is allocated; // clients are responsible for releasing the original buffer. media_status_t _readNextPacket(MediaBufferBase **buffer, bool calcVorbisTimestamp); media_status_t _readNextPacket(MediaBufferHelperV3 **buffer, bool calcVorbisTimestamp); int32_t getPacketBlockSize(MediaBufferBase *buffer); int32_t getPacketBlockSize(MediaBufferHelperV3 *buffer); void parseFileMetaData(); Loading @@ -182,7 +183,7 @@ struct MyVorbisExtractor : public MyOggExtractor { virtual uint64_t approxBitrate() const; virtual media_status_t readNextPacket(MediaBufferBase **buffer) { virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) { return _readNextPacket(buffer, /* calcVorbisTimestamp = */ true); } Loading @@ -194,7 +195,7 @@ protected: return granulePos * 1000000ll / mVi.rate; } virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type); virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type); }; struct MyOpusExtractor : public MyOggExtractor { Loading @@ -212,16 +213,16 @@ struct MyOpusExtractor : public MyOggExtractor { return 0; } virtual media_status_t readNextPacket(MediaBufferBase **buffer); virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer); protected: virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const; virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type); virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type); private: media_status_t verifyOpusHeader(MediaBufferBase *buffer); media_status_t verifyOpusComments(MediaBufferBase *buffer); uint32_t getNumSamplesInPacket(MediaBufferBase *buffer) const; media_status_t verifyOpusHeader(MediaBufferHelperV3 *buffer); media_status_t verifyOpusComments(MediaBufferHelperV3 *buffer); uint32_t getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const; uint8_t mChannelCount; uint16_t mCodecDelay; Loading Loading @@ -249,7 +250,9 @@ media_status_t OggSource::start() { if (mStarted) { return AMEDIA_ERROR_INVALID_OPERATION; } // initialize buffer group with a single small buffer, but a generous upper limit mBufferGroup->init(1 /* number of buffers */, 128 /* size */, 64 /* max number of buffers */); mExtractor->mImpl->setBufferGroup(mBufferGroup); mStarted = true; return AMEDIA_OK; Loading @@ -262,7 +265,7 @@ media_status_t OggSource::stop() { } media_status_t OggSource::read( MediaBufferBase **out, const ReadOptions *options) { MediaBufferHelperV3 **out, const ReadOptions *options) { *out = NULL; int64_t seekTimeUs; Loading @@ -274,26 +277,27 @@ media_status_t OggSource::read( } } MediaBufferBase *packet; MediaBufferHelperV3 *packet; media_status_t err = mExtractor->mImpl->readNextPacket(&packet); if (err != AMEDIA_OK) { return err; } AMediaFormat *meta = packet->meta_data(); #if 0 int64_t timeUs; if (packet->meta_data().findInt64(kKeyTime, &timeUs)) { if (AMediaFormat_findInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeStampUs)) { ALOGI("found time = %lld us", timeUs); } else { ALOGI("NO time"); } #endif packet->meta_data().setInt32(kKeyIsSyncFrame, 1); AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1); *out = packet; ALOGV("returning buffer %p", packet); return AMEDIA_OK; } Loading @@ -304,7 +308,8 @@ MyOggExtractor::MyOggExtractor( const char *mimeType, size_t numHeaders, int64_t seekPreRollUs) : mSource(source), : mBufferGroup(NULL), mSource(source), mOffset(0), mCurGranulePosition(0), mPrevGranulePosition(0), Loading Loading @@ -573,13 +578,13 @@ ssize_t MyOggExtractor::readPage(off64_t offset, Page *page) { return sizeof(header) + page->mNumSegments + totalSize; } media_status_t MyOpusExtractor::readNextPacket(MediaBufferBase **out) { media_status_t MyOpusExtractor::readNextPacket(MediaBufferHelperV3 **out) { if (mOffset <= mFirstDataOffset && mStartGranulePosition < 0) { // The first sample might not start at time 0; find out where by subtracting // the number of samples on the first page from the granule position // (position of last complete sample) of the first page. This happens // the first time before we attempt to read a packet from the first page. MediaBufferBase *mBuf; MediaBufferHelperV3 *mBuf; uint32_t numSamples = 0; uint64_t curGranulePosition = 0; while (true) { Loading Loading @@ -617,24 +622,25 @@ media_status_t MyOpusExtractor::readNextPacket(MediaBufferBase **out) { int32_t currentPageSamples; // Calculate timestamps by accumulating durations starting from the first sample of a page; // We assume that we only seek to page boundaries. if ((*out)->meta_data().findInt32(kKeyValidSamples, ¤tPageSamples)) { AMediaFormat *meta = (*out)->meta_data(); if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, ¤tPageSamples)) { // first packet in page if (mOffset == mFirstDataOffset) { currentPageSamples -= mStartGranulePosition; (*out)->meta_data().setInt32(kKeyValidSamples, currentPageSamples); AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, currentPageSamples); } mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples; } int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition); (*out)->meta_data().setInt64(kKeyTime, timeUs); AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs); uint32_t frames = getNumSamplesInPacket(*out); mCurGranulePosition += frames; return AMEDIA_OK; } uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferBase *buffer) const { uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const { if (buffer == NULL || buffer->range_length() < 1) { return 0; } Loading Loading @@ -680,10 +686,66 @@ uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferBase *buffer) const { return numSamples; } media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisTimestamp) { /* * basic mediabuffer implementation used during initial parsing of the * header packets, which happens before we have a buffer group */ class StandAloneMediaBuffer : public MediaBufferHelperV3 { private: void *mData; size_t mSize; size_t mOffset; size_t mLength; AMediaFormat *mFormat; public: StandAloneMediaBuffer(size_t size) : MediaBufferHelperV3(NULL) { mSize = size; mData = malloc(mSize); mOffset = 0; mLength = mSize; mFormat = AMediaFormat_new(); ALOGV("created standalone media buffer %p of size %zu", this, mSize); } ~StandAloneMediaBuffer() override { free(mData); AMediaFormat_delete(mFormat); ALOGV("deleted standalone media buffer %p of size %zu", this, mSize); } void release() override { delete this; } void* data() override { return mData; } size_t size() override { return mSize; } size_t range_offset() override { return mOffset; } size_t range_length() override { return mLength; } void set_range(size_t offset, size_t length) override { mOffset = offset; mLength = length; } AMediaFormat *meta_data() override { return mFormat; } }; media_status_t MyOggExtractor::_readNextPacket(MediaBufferHelperV3 **out, bool calcVorbisTimestamp) { *out = NULL; MediaBufferBase *buffer = NULL; MediaBufferHelperV3 *buffer = NULL; int64_t timeUs = -1; for (;;) { Loading Loading @@ -719,7 +781,13 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV ALOGE("b/36592202"); return AMEDIA_ERROR_MALFORMED; } MediaBufferBase *tmp = MediaBufferBase::Create(fullSize); MediaBufferHelperV3 *tmp; if (mBufferGroup) { mBufferGroup->acquire_buffer(&tmp, false, fullSize); ALOGV("acquired buffer %p from group", tmp); } else { tmp = new StandAloneMediaBuffer(fullSize); } if (tmp == NULL) { if (buffer != NULL) { buffer->release(); Loading @@ -727,6 +795,7 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV ALOGE("b/36592202"); return AMEDIA_ERROR_MALFORMED; } AMediaFormat_clear(tmp->meta_data()); if (buffer != NULL) { memcpy(tmp->data(), buffer->data(), buffer->range_length()); tmp->set_range(0, buffer->range_length()); Loading Loading @@ -756,8 +825,9 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV // We've just read the entire packet. if (mFirstPacketInPage) { buffer->meta_data().setInt32( kKeyValidSamples, mCurrentPageSamples); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt32( meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples); mFirstPacketInPage = false; } Loading @@ -778,7 +848,8 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV mCurrentPage.mPrevPacketPos += actualBlockSize / 2; mCurrentPage.mPrevPacketSize = curBlockSize; } buffer->meta_data().setInt64(kKeyTime, timeUs); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs); } *out = buffer; Loading Loading @@ -824,11 +895,13 @@ media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcV // is already complete. if (timeUs >= 0) { buffer->meta_data().setInt64(kKeyTime, timeUs); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs); } buffer->meta_data().setInt32( kKeyValidSamples, mCurrentPageSamples); AMediaFormat *meta = buffer->meta_data(); AMediaFormat_setInt32( meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples); mFirstPacketInPage = false; *out = buffer; Loading @@ -843,7 +916,7 @@ status_t MyOggExtractor::init() { AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType); media_status_t err; MediaBufferBase *packet; MediaBufferHelperV3 *packet; for (size_t i = 0; i < mNumHeaders; ++i) { // ignore timestamp for configuration packets if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) { Loading Loading @@ -920,7 +993,7 @@ void MyOggExtractor::buildTableOfContents() { } } int32_t MyOggExtractor::getPacketBlockSize(MediaBufferBase *buffer) { int32_t MyOggExtractor::getPacketBlockSize(MediaBufferHelperV3 *buffer) { const uint8_t *data = (const uint8_t *)buffer->data() + buffer->range_offset(); Loading Loading @@ -960,7 +1033,7 @@ int64_t MyOpusExtractor::getTimeUsOfGranule(uint64_t granulePos) const { return pcmSamplePosition * 1000000ll / kOpusSampleRate; } media_status_t MyOpusExtractor::verifyHeader(MediaBufferBase *buffer, uint8_t type) { media_status_t MyOpusExtractor::verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) { switch (type) { // there are actually no header types defined in the Opus spec; we choose 1 and 3 to mean // header and comments such that we can share code with MyVorbisExtractor. Loading @@ -973,7 +1046,7 @@ media_status_t MyOpusExtractor::verifyHeader(MediaBufferBase *buffer, uint8_t ty } } media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) { media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferHelperV3 *buffer) { const size_t kOpusHeaderSize = 19; const uint8_t *data = (const uint8_t *)buffer->data() + buffer->range_offset(); Loading Loading @@ -1001,7 +1074,7 @@ media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) { return AMEDIA_OK; } media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) { media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferHelperV3 *buffer) { // add artificial framing bit so we can reuse _vorbis_unpack_comment int32_t commentSize = buffer->range_length() + 1; auto tmp = heapbuffer<uint8_t>(commentSize); Loading Loading @@ -1094,7 +1167,7 @@ media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) { } media_status_t MyVorbisExtractor::verifyHeader( MediaBufferBase *buffer, uint8_t type) { MediaBufferHelperV3 *buffer, uint8_t type) { const uint8_t *data = (const uint8_t *)buffer->data() + buffer->range_offset(); Loading Loading @@ -1262,7 +1335,7 @@ size_t OggExtractor::countTracks() { return mInitCheck != OK ? 0 : 1; } MediaTrackHelperV2 *OggExtractor::getTrack(size_t index) { MediaTrackHelperV3 *OggExtractor::getTrack(size_t index) { if (index >= 1) { return NULL; } Loading @@ -1284,13 +1357,13 @@ media_status_t OggExtractor::getMetaData(AMediaFormat *meta) { return mImpl->getFileMetaData(meta); } static CMediaExtractorV2* CreateExtractor( static CMediaExtractorV3* CreateExtractor( CDataSource *source, void *) { return wrapV2(new OggExtractor(new DataSourceHelper(source))); return wrapV3(new OggExtractor(new DataSourceHelper(source))); } static CreatorFuncV2 Sniff( static CreatorFuncV3 Sniff( CDataSource *source, float *confidence, void **, Loading @@ -1311,11 +1384,11 @@ extern "C" { __attribute__ ((visibility ("default"))) ExtractorDef GETEXTRACTORDEF() { return { EXTRACTORDEF_VERSION_CURRENT, EXTRACTORDEF_VERSION_CURRENT + 1, UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"), 1, // version "Ogg Extractor", { .v2 = Sniff } { .v3 = Sniff } }; } Loading
media/extractors/ogg/OggExtractor.h +2 −2 Original line number Diff line number Diff line Loading @@ -31,11 +31,11 @@ class String8; struct MyOggExtractor; struct OggSource; struct OggExtractor : public MediaExtractorPluginHelperV2 { struct OggExtractor : public MediaExtractorPluginHelperV3 { explicit OggExtractor(DataSourceHelper *source); virtual size_t countTracks(); virtual MediaTrackHelperV2 *getTrack(size_t index); virtual MediaTrackHelperV3 *getTrack(size_t index); virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags); virtual media_status_t getMetaData(AMediaFormat *meta); Loading