diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp index 9e40a0fc26d382cb577c0a0f5fcaf2c795bd267c..0ecc16ccb537e8d431a75caf4919da22ff887ebc 100644 --- a/cmds/stagefright/SineSource.cpp +++ b/cmds/stagefright/SineSource.cpp @@ -89,7 +89,7 @@ status_t SineSource::read( x += k; } - buffer->meta_data()->setInt64( + buffer->meta_data().setInt64( kKeyTime, ((int64_t)mPhase * 1000000) / mSampleRate); mPhase += numFramesPerBuffer; diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp index b7a5066c044e547750be924f4481cc480c345273..a63b9b9984b7d50584ecbf5f8e1219b52ee81199 100644 --- a/cmds/stagefright/recordvideo.cpp +++ b/cmds/stagefright/recordvideo.cpp @@ -114,8 +114,8 @@ public: x = x >= 0xa0 ? 0x60 : x + 1; #endif (*buffer)->set_range(0, mSize); - (*buffer)->meta_data()->clear(); - (*buffer)->meta_data()->setInt64( + (*buffer)->meta_data().clear(); + (*buffer)->meta_data().setInt64( kKeyTime, (mNumFramesOutput * 1000000) / mFrameRate); ++mNumFramesOutput; diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index 5fa830461f7db2f6b913ee5989f710503da4a47c..936733d3f364b8eeb084160dcbd9734a3b567da9 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -253,7 +253,7 @@ static void playSource(sp &source) { shouldSeek = true; } else { int64_t timestampUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, ×tampUs)); bool failed = false; @@ -492,12 +492,12 @@ status_t DetectSyncSource::read( if (mStreamType == AVC) { bool isIDR = isIDRFrame(*buffer); - (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, isIDR); + (*buffer)->meta_data().setInt32(kKeyIsSyncFrame, isIDR); if (isIDR) { mSawFirstIDRFrame = true; } } else { - (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true); + (*buffer)->meta_data().setInt32(kKeyIsSyncFrame, true); } if (mStreamType != AVC || mSawFirstIDRFrame) { @@ -591,7 +591,7 @@ static void performSeekTest(const sp &source) { if (err == OK) { int64_t timeUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs)); printf("%" PRId64 "\t%" PRId64 "\t%" PRId64 "\n", seekTimeUs, timeUs, seekTimeUs - timeUs); diff --git a/include/media/MediaSourceBase.h b/include/media/MediaSourceBase.h deleted file mode 120000 index fe227b1a97cc60411329eb410e2434e344159dcc..0000000000000000000000000000000000000000 --- a/include/media/MediaSourceBase.h +++ /dev/null @@ -1 +0,0 @@ -../../media/libmediaextractor/include/media/MediaSourceBase.h \ No newline at end of file diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h new file mode 120000 index 0000000000000000000000000000000000000000..5a63287add2d0ab643bb97ba8f31c8b2d35dad57 --- /dev/null +++ b/include/media/MediaTrack.h @@ -0,0 +1 @@ +../../media/libmediaextractor/include/media/MediaTrack.h \ No newline at end of file diff --git a/include/media/VorbisComment.h b/include/media/VorbisComment.h new file mode 120000 index 0000000000000000000000000000000000000000..adaa4898cdf1d222a3e36f14b0ba707efb9c29ff --- /dev/null +++ b/include/media/VorbisComment.h @@ -0,0 +1 @@ +../../media/libmediaextractor/include/media/VorbisComment.h \ No newline at end of file diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp index f6c8664f11705e61f21ae2ea0d738ec73fb7ff72..bbc1ff8bd47d6986b7885e6beace106da73ab360 100644 --- a/media/extractors/aac/AACExtractor.cpp +++ b/media/extractors/aac/AACExtractor.cpp @@ -20,7 +20,7 @@ #include "AACExtractor.h" #include -#include +#include #include #include #include @@ -33,17 +33,18 @@ namespace android { -class AACSource : public MediaSourceBase { +class AACSource : public MediaTrack { public: - AACSource(DataSourceBase *source, - const sp &meta, - const Vector &offset_vector, - int64_t frame_duration_us); + AACSource( + DataSourceBase *source, + MetaDataBase &meta, + const Vector &offset_vector, + int64_t frame_duration_us); - virtual status_t start(MetaData *params = NULL); + virtual status_t start(MetaDataBase *params = NULL); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase&); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); @@ -54,7 +55,7 @@ protected: private: static const size_t kMaxFrameSize; DataSourceBase *mDataSource; - sp mMeta; + MetaDataBase mMeta; off64_t mOffset; int64_t mCurrentTimeUs; @@ -132,19 +133,10 @@ static size_t getAdtsFrameLength(DataSourceBase *source, off64_t offset, size_t* } AACExtractor::AACExtractor( - DataSourceBase *source, const sp &_meta) + DataSourceBase *source, off64_t offset) : mDataSource(source), mInitCheck(NO_INIT), mFrameDurationUs(0) { - sp meta = _meta; - - if (meta == NULL) { - ALOGE("no metadata specified"); - return; - } - - int64_t offset; - CHECK(meta->findInt64("offset", &offset)); uint8_t profile, sf_index, channel, header[2]; if (mDataSource->readAt(offset + 2, &header, 2) < 2) { @@ -159,7 +151,7 @@ AACExtractor::AACExtractor( } channel = (header[0] & 0x1) << 2 | (header[1] >> 6); - mMeta = MakeAACCodecSpecificData(profile, sf_index, channel); + MakeAACCodecSpecificData(mMeta, profile, sf_index, channel); off64_t streamSize, numFrames = 0; size_t frameSize = 0; @@ -182,7 +174,7 @@ AACExtractor::AACExtractor( // Round up and get the duration mFrameDurationUs = (1024 * 1000000ll + (sr - 1)) / sr; duration = numFrames * mFrameDurationUs; - mMeta->setInt64(kKeyDuration, duration); + mMeta.setInt64(kKeyDuration, duration); } mInitCheck = OK; @@ -191,23 +183,20 @@ AACExtractor::AACExtractor( AACExtractor::~AACExtractor() { } -sp AACExtractor::getMetaData() { - sp meta = new MetaData; - - if (mInitCheck != OK) { - return meta; +status_t AACExtractor::getMetaData(MetaDataBase &meta) { + meta.clear(); + if (mInitCheck == OK) { + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC_ADTS); } - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC_ADTS); - - return meta; + return OK; } size_t AACExtractor::countTracks() { return mInitCheck == OK ? 1 : 0; } -MediaSourceBase *AACExtractor::getTrack(size_t index) { +MediaTrack *AACExtractor::getTrack(size_t index) { if (mInitCheck != OK || index != 0) { return NULL; } @@ -215,12 +204,13 @@ MediaSourceBase *AACExtractor::getTrack(size_t index) { return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs); } -sp AACExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) { +status_t AACExtractor::getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t /* flags */) { if (mInitCheck != OK || index != 0) { - return NULL; + return UNKNOWN_ERROR; } - return mMeta; + meta = mMeta; + return OK; } //////////////////////////////////////////////////////////////////////////////// @@ -229,7 +219,8 @@ sp AACExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) const size_t AACSource::kMaxFrameSize = 8192; AACSource::AACSource( - DataSourceBase *source, const sp &meta, + DataSourceBase *source, + MetaDataBase &meta, const Vector &offset_vector, int64_t frame_duration_us) : mDataSource(source), @@ -248,7 +239,7 @@ AACSource::~AACSource() { } } -status_t AACSource::start(MetaData * /* params */) { +status_t AACSource::start(MetaDataBase * /* params */) { CHECK(!mStarted); if (mOffsetVector.empty()) { @@ -275,8 +266,9 @@ status_t AACSource::stop() { return OK; } -sp AACSource::getFormat() { - return mMeta; +status_t AACSource::getFormat(MetaDataBase &meta) { + meta = mMeta; + return OK; } status_t AACSource::read( @@ -319,8 +311,8 @@ status_t AACSource::read( } buffer->set_range(0, frameSizeWithoutHeader); - buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); - buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + buffer->meta_data().setInt64(kKeyTime, mCurrentTimeUs); + buffer->meta_data().setInt32(kKeyIsSyncFrame, 1); mOffset += frameSize; mCurrentTimeUs += mFrameDurationUs; @@ -334,14 +326,8 @@ status_t AACSource::read( static MediaExtractor* CreateExtractor( DataSourceBase *source, void *meta) { - sp metaData = static_cast(meta); - return new AACExtractor(source, metaData); -} - -static void FreeMeta(void *meta) { - if (meta != nullptr) { - static_cast(meta)->decStrong(nullptr); - } + off64_t offset = *static_cast(meta); + return new AACExtractor(source, offset); } static MediaExtractor::CreatorFunc Sniff( @@ -386,12 +372,9 @@ static MediaExtractor::CreatorFunc Sniff( if ((header[0] == 0xff) && ((header[1] & 0xf6) == 0xf0)) { *confidence = 0.2; - AMessage *msg = new AMessage; - msg->setInt64("offset", pos); - *meta = msg; - *freeMeta = &FreeMeta; - // ref count will be decreased in FreeMeta. - msg->incStrong(nullptr); + off64_t *offPtr = (off64_t*) malloc(sizeof(off64_t)); + *meta = offPtr; + *freeMeta = ::free; return CreateExtractor; } diff --git a/media/extractors/aac/AACExtractor.h b/media/extractors/aac/AACExtractor.h index e99699c13d124f3642da747fc8800dad522e88ac..9dadbed2ec1ad0f9aa4264a3de3aed7fe1b370a9 100644 --- a/media/extractors/aac/AACExtractor.h +++ b/media/extractors/aac/AACExtractor.h @@ -19,6 +19,7 @@ #define AAC_EXTRACTOR_H_ #include +#include #include @@ -29,13 +30,13 @@ class String8; class AACExtractor : public MediaExtractor { public: - AACExtractor(DataSourceBase *source, const sp &meta); + AACExtractor(DataSourceBase *source, off64_t offset); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual const char * name() { return "AACExtractor"; } protected: @@ -43,7 +44,7 @@ protected: private: DataSourceBase *mDataSource; - sp mMeta; + MetaDataBase mMeta; status_t mInitCheck; Vector mOffsetVector; @@ -54,8 +55,7 @@ private: }; bool SniffAAC( - DataSourceBase *source, String8 *mimeType, float *confidence, - sp *); + DataSourceBase *source, String8 *mimeType, float *confidence, off64_t *offset); } // namespace android diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp index 59d9ef123a708d978f5702634f19758032f19178..f56d5ef656eeac67a04d0da35bf7bfbca0a156a9 100644 --- a/media/extractors/amr/AMRExtractor.cpp +++ b/media/extractors/amr/AMRExtractor.cpp @@ -21,7 +21,7 @@ #include "AMRExtractor.h" #include -#include +#include #include #include #include @@ -31,18 +31,19 @@ namespace android { -class AMRSource : public MediaSourceBase { +class AMRSource : public MediaTrack { public: - AMRSource(DataSourceBase *source, - const sp &meta, - bool isWide, - const off64_t *offset_table, - size_t offset_table_length); - - virtual status_t start(MetaData *params = NULL); + AMRSource( + DataSourceBase *source, + MetaDataBase &meta, + bool isWide, + const off64_t *offset_table, + size_t offset_table_length); + + virtual status_t start(MetaDataBase *params = NULL); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); @@ -52,7 +53,7 @@ protected: private: DataSourceBase *mDataSource; - sp mMeta; + MetaDataBase mMeta; bool mIsWide; off64_t mOffset; @@ -116,25 +117,48 @@ static status_t getFrameSizeByOffset(DataSourceBase *source, return OK; } +static bool SniffAMR( + DataSourceBase *source, bool *isWide, float *confidence) { + char header[9]; + + if (source->readAt(0, header, sizeof(header)) != sizeof(header)) { + return false; + } + + if (!memcmp(header, "#!AMR\n", 6)) { + if (isWide != nullptr) { + *isWide = false; + } + *confidence = 0.5; + + return true; + } else if (!memcmp(header, "#!AMR-WB\n", 9)) { + if (isWide != nullptr) { + *isWide = true; + } + *confidence = 0.5; + + return true; + } + + return false; +} + AMRExtractor::AMRExtractor(DataSourceBase *source) : mDataSource(source), mInitCheck(NO_INIT), mOffsetTableLength(0) { - String8 mimeType; float confidence; - if (!SniffAMR(mDataSource, &mimeType, &confidence)) { + if (!SniffAMR(mDataSource, &mIsWide, &confidence)) { return; } - mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB); - - mMeta = new MetaData; - mMeta->setCString( + mMeta.setCString( kKeyMIMEType, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AMR_NB); - mMeta->setInt32(kKeyChannelCount, 1); - mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000); + mMeta.setInt32(kKeyChannelCount, 1); + mMeta.setInt32(kKeySampleRate, mIsWide ? 16000 : 8000); off64_t offset = mIsWide ? 9 : 6; off64_t streamSize; @@ -161,7 +185,7 @@ AMRExtractor::AMRExtractor(DataSourceBase *source) numFrames ++; } - mMeta->setInt64(kKeyDuration, duration); + mMeta.setInt64(kKeyDuration, duration); } mInitCheck = OK; @@ -170,23 +194,21 @@ AMRExtractor::AMRExtractor(DataSourceBase *source) AMRExtractor::~AMRExtractor() { } -sp AMRExtractor::getMetaData() { - sp meta = new MetaData; +status_t AMRExtractor::getMetaData(MetaDataBase &meta) { + meta.clear(); - if (mInitCheck != OK) { - return meta; + if (mInitCheck == OK) { + meta.setCString(kKeyMIMEType, mIsWide ? "audio/amr-wb" : "audio/amr"); } - meta->setCString(kKeyMIMEType, mIsWide ? "audio/amr-wb" : "audio/amr"); - - return meta; + return OK; } size_t AMRExtractor::countTracks() { return mInitCheck == OK ? 1 : 0; } -MediaSourceBase *AMRExtractor::getTrack(size_t index) { +MediaTrack *AMRExtractor::getTrack(size_t index) { if (mInitCheck != OK || index != 0) { return NULL; } @@ -195,18 +217,19 @@ MediaSourceBase *AMRExtractor::getTrack(size_t index) { mOffsetTable, mOffsetTableLength); } -sp AMRExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) { +status_t AMRExtractor::getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t /* flags */) { if (mInitCheck != OK || index != 0) { - return NULL; + return UNKNOWN_ERROR; } - return mMeta; + meta = mMeta; + return OK; } //////////////////////////////////////////////////////////////////////////////// AMRSource::AMRSource( - DataSourceBase *source, const sp &meta, + DataSourceBase *source, MetaDataBase &meta, bool isWide, const off64_t *offset_table, size_t offset_table_length) : mDataSource(source), mMeta(meta), @@ -227,7 +250,7 @@ AMRSource::~AMRSource() { } } -status_t AMRSource::start(MetaData * /* params */) { +status_t AMRSource::start(MetaDataBase * /* params */) { CHECK(!mStarted); mOffset = mIsWide ? 9 : 6; @@ -249,8 +272,9 @@ status_t AMRSource::stop() { return OK; } -sp AMRSource::getFormat() { - return mMeta; +status_t AMRSource::getFormat(MetaDataBase &meta) { + meta = mMeta; + return OK; } status_t AMRSource::read( @@ -325,8 +349,8 @@ status_t AMRSource::read( } buffer->set_range(0, frameSize); - buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); - buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + buffer->meta_data().setInt64(kKeyTime, mCurrentTimeUs); + buffer->meta_data().setInt32(kKeyIsSyncFrame, 1); mOffset += frameSize; mCurrentTimeUs += 20000; // Each frame is 20ms @@ -338,33 +362,6 @@ status_t AMRSource::read( //////////////////////////////////////////////////////////////////////////////// -bool SniffAMR( - DataSourceBase *source, String8 *mimeType, float *confidence) { - char header[9]; - - if (source->readAt(0, header, sizeof(header)) != sizeof(header)) { - return false; - } - - if (!memcmp(header, "#!AMR\n", 6)) { - if (mimeType != nullptr) { - *mimeType = MEDIA_MIMETYPE_AUDIO_AMR_NB; - } - *confidence = 0.5; - - return true; - } else if (!memcmp(header, "#!AMR-WB\n", 9)) { - if (mimeType != nullptr) { - *mimeType = MEDIA_MIMETYPE_AUDIO_AMR_WB; - } - *confidence = 0.5; - - return true; - } - - return false; -} - extern "C" { // This is the only symbol that needs to be exported __attribute__ ((visibility ("default"))) diff --git a/media/extractors/amr/AMRExtractor.h b/media/extractors/amr/AMRExtractor.h index b8b44eab0ef92c90df89253a8847b68c13e9e03e..c90b32510e4f153a48146be810204404a7fda149 100644 --- a/media/extractors/amr/AMRExtractor.h +++ b/media/extractors/amr/AMRExtractor.h @@ -20,6 +20,7 @@ #include #include +#include namespace android { @@ -32,10 +33,10 @@ public: explicit AMRExtractor(DataSourceBase *source); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual const char * name() { return "AMRExtractor"; } protected: @@ -43,7 +44,7 @@ protected: private: DataSourceBase *mDataSource; - sp mMeta; + MetaDataBase mMeta; status_t mInitCheck; bool mIsWide; @@ -54,9 +55,6 @@ private: AMRExtractor &operator=(const AMRExtractor &); }; -bool SniffAMR( - DataSourceBase *source, String8 *mimeType, float *confidence); - } // namespace android #endif // AMR_EXTRACTOR_H_ diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp index e5bbe3183c282eaefed7d56da4ce5d6c65281f36..bd8a00c8c910a140714287f91edc52283621048a 100644 --- a/media/extractors/amr/Android.bp +++ b/media/extractors/amr/Android.bp @@ -10,7 +10,6 @@ cc_library_shared { "liblog", "libmediaextractor", "libstagefright_foundation", - "libutils", ], name: "libamrextractor", diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp index 84ba6d3dc9e9ae33f46644c3ee04a1e67faa4dc7..0160ca46e5daeb44ae32ebf758bd20285b46d32e 100644 --- a/media/extractors/flac/Android.bp +++ b/media/extractors/flac/Android.bp @@ -11,7 +11,6 @@ cc_library_shared { "liblog", "libmediaextractor", "libstagefright_foundation", - "libutils", ], static_libs: [ diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp index 2c5e43e866ac3f64817af5f1dad4f1bcf5d668b4..e3da259e8b09a809003fdba9afb8909697fc8cfc 100644 --- a/media/extractors/flac/FLACExtractor.cpp +++ b/media/extractors/flac/FLACExtractor.cpp @@ -23,11 +23,11 @@ #include "FLAC/stream_decoder.h" #include -#include +#include +#include #include #include #include -#include #include #include #include @@ -35,142 +35,18 @@ namespace android { -// also exists in OggExtractor, candidate for moving to utility/support library? -static void extractAlbumArt( - const sp &fileMeta, const void *data, size_t size) { - ALOGV("extractAlbumArt from '%s'", (const char *)data); - - sp flacBuffer = decodeBase64(AString((const char *)data, size)); - if (flacBuffer == NULL) { - ALOGE("malformed base64 encoded data."); - return; - } - - size_t flacSize = flacBuffer->size(); - uint8_t *flac = flacBuffer->data(); - ALOGV("got flac of size %zu", flacSize); - - uint32_t picType; - uint32_t typeLen; - uint32_t descLen; - uint32_t dataLen; - char type[128]; - - if (flacSize < 8) { - return; - } - - picType = U32_AT(flac); - - if (picType != 3) { - // This is not a front cover. - return; - } - - typeLen = U32_AT(&flac[4]); - if (typeLen > sizeof(type) - 1) { - return; - } - - // we've already checked above that flacSize >= 8 - if (flacSize - 8 < typeLen) { - return; - } - - memcpy(type, &flac[8], typeLen); - type[typeLen] = '\0'; - - ALOGV("picType = %d, type = '%s'", picType, type); - - if (!strcmp(type, "-->")) { - // This is not inline cover art, but an external url instead. - return; - } - - if (flacSize < 32 || flacSize - 32 < typeLen) { - return; - } - - descLen = U32_AT(&flac[8 + typeLen]); - if (flacSize - 32 - typeLen < descLen) { - return; - } - - dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]); - - // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0 - if (flacSize - 32 - typeLen - descLen < dataLen) { - return; - } - - ALOGV("got image data, %zu trailing bytes", - flacSize - 32 - typeLen - descLen - dataLen); - - fileMeta->setData( - kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen); - - fileMeta->setCString(kKeyAlbumArtMIME, type); -} - -// also exists in OggExtractor, candidate for moving to utility/support library? -static void parseVorbisComment( - const sp &fileMeta, const char *comment, size_t commentLength) -{ - struct { - const char *const mTag; - uint32_t mKey; - } kMap[] = { - { "TITLE", kKeyTitle }, - { "ARTIST", kKeyArtist }, - { "ALBUMARTIST", kKeyAlbumArtist }, - { "ALBUM ARTIST", kKeyAlbumArtist }, - { "COMPILATION", kKeyCompilation }, - { "ALBUM", kKeyAlbum }, - { "COMPOSER", kKeyComposer }, - { "GENRE", kKeyGenre }, - { "AUTHOR", kKeyAuthor }, - { "TRACKNUMBER", kKeyCDTrackNumber }, - { "DISCNUMBER", kKeyDiscNumber }, - { "DATE", kKeyDate }, - { "YEAR", kKeyYear }, - { "LYRICIST", kKeyWriter }, - { "METADATA_BLOCK_PICTURE", kKeyAlbumArt }, - { "ANDROID_LOOP", kKeyAutoLoop }, - }; - - for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) { - size_t tagLen = strlen(kMap[j].mTag); - if (!strncasecmp(kMap[j].mTag, comment, tagLen) - && comment[tagLen] == '=') { - if (kMap[j].mKey == kKeyAlbumArt) { - extractAlbumArt( - fileMeta, - &comment[tagLen + 1], - commentLength - tagLen - 1); - } else if (kMap[j].mKey == kKeyAutoLoop) { - if (!strcasecmp(&comment[tagLen + 1], "true")) { - fileMeta->setInt32(kKeyAutoLoop, true); - } - } else { - fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]); - } - } - } - -} - class FLACParser; -class FLACSource : public MediaSourceBase { +class FLACSource : public MediaTrack { public: FLACSource( DataSourceBase *dataSource, - const sp &trackMetadata); + MetaDataBase &meta); - virtual status_t start(MetaData *params); + virtual status_t start(MetaDataBase *params); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &meta); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); @@ -180,13 +56,11 @@ protected: private: DataSourceBase *mDataSource; - sp mTrackMetadata; - sp mParser; + MetaDataBase mTrackMetadata; + FLACParser *mParser; bool mInitCheck; bool mStarted; - status_t init(); - // no copy constructor or assignment FLACSource(const FLACSource &); FLACSource &operator=(const FLACSource &); @@ -195,7 +69,7 @@ private: // FLACParser wraps a C libFLAC parser aka stream decoder -class FLACParser : public RefBase { +class FLACParser { public: enum { @@ -205,8 +79,10 @@ public: explicit FLACParser( DataSourceBase *dataSource, // If metadata pointers aren't provided, we don't fill them - const sp &fileMetadata = 0, - const sp &trackMetadata = 0); + MetaDataBase *fileMetadata = 0, + MetaDataBase *trackMetadata = 0); + + virtual ~FLACParser(); status_t initCheck() const { return mInitCheck; @@ -239,13 +115,10 @@ public: return readBuffer(true, sample); } -protected: - virtual ~FLACParser(); - private: DataSourceBase *mDataSource; - sp mFileMetadata; - sp mTrackMetadata; + MetaDataBase *mFileMetadata; + MetaDataBase *mTrackMetadata; bool mInitCheck; // media buffers @@ -613,8 +486,8 @@ static void copyTrespass( FLACParser::FLACParser( DataSourceBase *dataSource, - const sp &fileMetadata, - const sp &trackMetadata) + MetaDataBase *fileMetadata, + MetaDataBase *trackMetadata) : mDataSource(dataSource), mFileMetadata(fileMetadata), mTrackMetadata(trackMetadata), @@ -825,8 +698,8 @@ MediaBufferBase *FLACParser::readBuffer(bool doSeek, FLAC__uint64 sample) CHECK(mWriteHeader.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); FLAC__uint64 sampleNumber = mWriteHeader.number.sample_number; int64_t timeUs = (1000000LL * sampleNumber) / getSampleRate(); - buffer->meta_data()->setInt64(kKeyTime, timeUs); - buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + buffer->meta_data().setInt64(kKeyTime, timeUs); + buffer->meta_data().setInt32(kKeyIsSyncFrame, 1); return buffer; } @@ -834,7 +707,7 @@ MediaBufferBase *FLACParser::readBuffer(bool doSeek, FLAC__uint64 sample) FLACSource::FLACSource( DataSourceBase *dataSource, - const sp &trackMetadata) + MetaDataBase &trackMetadata) : mDataSource(dataSource), mTrackMetadata(trackMetadata), mParser(0), @@ -842,7 +715,9 @@ FLACSource::FLACSource( mStarted(false) { ALOGV("FLACSource::FLACSource"); - mInitCheck = init(); + // re-use the same track metadata passed into constructor from FLACExtractor + mParser = new FLACParser(mDataSource); + mInitCheck = mParser->initCheck(); } FLACSource::~FLACSource() @@ -851,9 +726,10 @@ FLACSource::~FLACSource() if (mStarted) { stop(); } + delete mParser; } -status_t FLACSource::start(MetaData * /* params */) +status_t FLACSource::start(MetaDataBase * /* params */) { ALOGV("FLACSource::start"); @@ -875,9 +751,10 @@ status_t FLACSource::stop() return OK; } -sp FLACSource::getFormat() +status_t FLACSource::getFormat(MetaDataBase &meta) { - return mTrackMetadata; + meta = mTrackMetadata; + return OK; } status_t FLACSource::read( @@ -907,28 +784,24 @@ status_t FLACSource::read( return buffer != NULL ? (status_t) OK : (status_t) ERROR_END_OF_STREAM; } -status_t FLACSource::init() -{ - ALOGV("FLACSource::init"); - // re-use the same track metadata passed into constructor from FLACExtractor - mParser = new FLACParser(mDataSource); - return mParser->initCheck(); -} - // FLACExtractor FLACExtractor::FLACExtractor( DataSourceBase *dataSource) : mDataSource(dataSource), + mParser(nullptr), mInitCheck(false) { ALOGV("FLACExtractor::FLACExtractor"); - mInitCheck = init(); + // FLACParser will fill in the metadata for us + mParser = new FLACParser(mDataSource, &mFileMetadata, &mTrackMetadata); + mInitCheck = mParser->initCheck(); } FLACExtractor::~FLACExtractor() { ALOGV("~FLACExtractor::FLACExtractor"); + delete mParser; } size_t FLACExtractor::countTracks() @@ -936,7 +809,7 @@ size_t FLACExtractor::countTracks() return mInitCheck == OK ? 1 : 0; } -MediaSourceBase *FLACExtractor::getTrack(size_t index) +MediaTrack *FLACExtractor::getTrack(size_t index) { if (mInitCheck != OK || index > 0) { return NULL; @@ -944,26 +817,20 @@ MediaSourceBase *FLACExtractor::getTrack(size_t index) return new FLACSource(mDataSource, mTrackMetadata); } -sp FLACExtractor::getTrackMetaData( +status_t FLACExtractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t /* flags */) { if (mInitCheck != OK || index > 0) { - return NULL; + return UNKNOWN_ERROR; } - return mTrackMetadata; -} - -status_t FLACExtractor::init() -{ - mFileMetadata = new MetaData; - mTrackMetadata = new MetaData; - // FLACParser will fill in the metadata for us - mParser = new FLACParser(mDataSource, mFileMetadata, mTrackMetadata); - return mParser->initCheck(); + meta = mTrackMetadata; + return OK; } -sp FLACExtractor::getMetaData() +status_t FLACExtractor::getMetaData(MetaDataBase &meta) { - return mFileMetadata; + meta = mFileMetadata; + return OK; } // Sniffer diff --git a/media/extractors/flac/FLACExtractor.h b/media/extractors/flac/FLACExtractor.h index f41d878f767640b1674df571e99dc82a52904ee9..7fb6ec612d6f756e96790e62b06007595b6b0da4 100644 --- a/media/extractors/flac/FLACExtractor.h +++ b/media/extractors/flac/FLACExtractor.h @@ -19,6 +19,7 @@ #include #include +#include #include namespace android { @@ -31,10 +32,10 @@ public: explicit FLACExtractor(DataSourceBase *source); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual const char * name() { return "FLACExtractor"; } protected: @@ -42,14 +43,12 @@ protected: private: DataSourceBase *mDataSource; - sp mParser; + FLACParser *mParser; status_t mInitCheck; - sp mFileMetadata; + MetaDataBase mFileMetadata; // There is only one track - sp mTrackMetadata; - - status_t init(); + MetaDataBase mTrackMetadata; FLACExtractor(const FLACExtractor &); FLACExtractor &operator=(const FLACExtractor &); diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp index 9af128ef8a1d8b94501b1ced8262586c4d98ad18..5412e9942e6d9551cc1247603b4f3bea1b7da3fa 100644 --- a/media/extractors/midi/Android.bp +++ b/media/extractors/midi/Android.bp @@ -9,8 +9,7 @@ cc_library_shared { shared_libs: [ "liblog", "libmediaextractor", - "libstagefright_foundation", - "libutils", + "libstagefright_foundation" ], static_libs: [ diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp index cf446dbf04a4f74c3b674455b646542a6de151be..949fbe00db6311318e2f00b2327ae736c611d9f0 100644 --- a/media/extractors/midi/MidiExtractor.cpp +++ b/media/extractors/midi/MidiExtractor.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include namespace android { @@ -33,16 +33,16 @@ namespace android { // how many Sonivox output buffers to aggregate into one MediaBufferBase static const int NUM_COMBINE_BUFFERS = 4; -class MidiSource : public MediaSourceBase { +class MidiSource : public MediaTrack { public: MidiSource( - const sp &engine, - const sp &trackMetadata); + MidiEngine &engine, + MetaDataBase &trackMetadata); - virtual status_t start(MetaData *params); + virtual status_t start(MetaDataBase *params); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase&); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); @@ -51,8 +51,8 @@ protected: virtual ~MidiSource(); private: - sp mEngine; - sp mTrackMetadata; + MidiEngine &mEngine; + MetaDataBase &mTrackMetadata; bool mInitCheck; bool mStarted; @@ -68,8 +68,8 @@ private: // Midisource MidiSource::MidiSource( - const sp &engine, - const sp &trackMetadata) + MidiEngine &engine, + MetaDataBase &trackMetadata) : mEngine(engine), mTrackMetadata(trackMetadata), mInitCheck(false), @@ -87,13 +87,13 @@ MidiSource::~MidiSource() } } -status_t MidiSource::start(MetaData * /* params */) +status_t MidiSource::start(MetaDataBase * /* params */) { ALOGV("MidiSource::start"); CHECK(!mStarted); mStarted = true; - mEngine->allocateBuffers(); + mEngine.allocateBuffers(); return OK; } @@ -103,14 +103,15 @@ status_t MidiSource::stop() CHECK(mStarted); mStarted = false; - mEngine->releaseBuffers(); + mEngine.releaseBuffers(); return OK; } -sp MidiSource::getFormat() +status_t MidiSource::getFormat(MetaDataBase &meta) { - return mTrackMetadata; + meta = mTrackMetadata; + return OK; } status_t MidiSource::read( @@ -125,9 +126,9 @@ status_t MidiSource::read( if (seekTimeUs <= 0LL) { seekTimeUs = 0LL; } - mEngine->seekTo(seekTimeUs); + mEngine.seekTo(seekTimeUs); } - buffer = mEngine->readBuffer(); + buffer = mEngine.readBuffer(); *outBuffer = buffer; ALOGV("MidiSource::read %p done", this); return buffer != NULL ? (status_t) OK : (status_t) ERROR_END_OF_STREAM; @@ -142,8 +143,8 @@ status_t MidiSource::init() // MidiEngine MidiEngine::MidiEngine(DataSourceBase *dataSource, - const sp &fileMetadata, - const sp &trackMetadata) : + MetaDataBase *fileMetadata, + MetaDataBase *trackMetadata) : mGroup(NULL), mEasData(NULL), mEasHandle(NULL), @@ -191,7 +192,7 @@ MidiEngine::~MidiEngine() { EAS_Shutdown(mEasData); } delete mGroup; - + delete mIoWrapper; } status_t MidiEngine::initCheck() { @@ -238,7 +239,7 @@ MediaBufferBase* MidiEngine::readBuffer() { EAS_I32 timeMs; EAS_GetLocation(mEasData, mEasHandle, &timeMs); int64_t timeUs = 1000ll * timeMs; - buffer->meta_data()->setInt64(kKeyTime, timeUs); + buffer->meta_data().setInt64(kKeyTime, timeUs); EAS_PCM* p = (EAS_PCM*) buffer->data(); int numBytesOutput = 0; @@ -266,9 +267,7 @@ MidiExtractor::MidiExtractor( mInitCheck(false) { ALOGV("MidiExtractor ctor"); - mFileMetadata = new MetaData; - mTrackMetadata = new MetaData; - mEngine = new MidiEngine(mDataSource, mFileMetadata, mTrackMetadata); + mEngine = new MidiEngine(mDataSource, &mFileMetadata, &mTrackMetadata); mInitCheck = mEngine->initCheck(); } @@ -282,35 +281,38 @@ size_t MidiExtractor::countTracks() return mInitCheck == OK ? 1 : 0; } -MediaSourceBase *MidiExtractor::getTrack(size_t index) +MediaTrack *MidiExtractor::getTrack(size_t index) { if (mInitCheck != OK || index > 0) { return NULL; } - return new MidiSource(mEngine, mTrackMetadata); + return new MidiSource(*mEngine, mTrackMetadata); } -sp MidiExtractor::getTrackMetaData( +status_t MidiExtractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t /* flags */) { ALOGV("MidiExtractor::getTrackMetaData"); if (mInitCheck != OK || index > 0) { - return NULL; + return UNKNOWN_ERROR; } - return mTrackMetadata; + meta = mTrackMetadata; + return OK; } -sp MidiExtractor::getMetaData() +status_t MidiExtractor::getMetaData(MetaDataBase &meta) { ALOGV("MidiExtractor::getMetaData"); - return mFileMetadata; + meta = mFileMetadata; + return OK; } // Sniffer bool SniffMidi(DataSourceBase *source, float *confidence) { - sp p = new MidiEngine(source, NULL, NULL); - if (p->initCheck() == OK) { + MidiEngine p(source, NULL, NULL); + if (p.initCheck() == OK) { *confidence = 0.8; ALOGV("SniffMidi: yes"); return true; diff --git a/media/extractors/midi/MidiExtractor.h b/media/extractors/midi/MidiExtractor.h index 427451344e211962ec5a09d638675321d1a28a32..244dd0f8ad1d8dc8a930b3821af4f915714c5f50 100644 --- a/media/extractors/midi/MidiExtractor.h +++ b/media/extractors/midi/MidiExtractor.h @@ -21,17 +21,18 @@ #include #include #include +#include #include #include #include namespace android { -class MidiEngine : public RefBase { +class MidiEngine { public: - MidiEngine(DataSourceBase *dataSource, - const sp &fileMetadata, - const sp &trackMetadata); + explicit MidiEngine(DataSourceBase *dataSource, + MetaDataBase *fileMetadata, + MetaDataBase *trackMetadata); ~MidiEngine(); status_t initCheck(); @@ -41,7 +42,7 @@ public: status_t seekTo(int64_t positionUs); MediaBufferBase* readBuffer(); private: - sp mIoWrapper; + MidiIoWrapper *mIoWrapper; MediaBufferGroup *mGroup; EAS_DATA_HANDLE mEasData; EAS_HANDLE mEasHandle; @@ -55,10 +56,10 @@ public: explicit MidiExtractor(DataSourceBase *source); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual const char * name() { return "MidiExtractor"; } protected: @@ -67,12 +68,12 @@ protected: private: DataSourceBase *mDataSource; status_t mInitCheck; - sp mFileMetadata; + MetaDataBase mFileMetadata; // There is only one track - sp mTrackMetadata; + MetaDataBase mTrackMetadata; - sp mEngine; + MidiEngine *mEngine; EAS_DATA_HANDLE mEasData; EAS_HANDLE mEasHandle; diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp index 65988d3e53caa1daaab79fac14bbaadb332a04b4..5592a880b2173f9cf888f898d362a3bf2c3b759f 100644 --- a/media/extractors/mkv/MatroskaExtractor.cpp +++ b/media/extractors/mkv/MatroskaExtractor.cpp @@ -22,7 +22,7 @@ #include "MatroskaExtractor.h" #include -#include +#include #include #include #include @@ -121,13 +121,13 @@ private: BlockIterator &operator=(const BlockIterator &); }; -struct MatroskaSource : public MediaSourceBase { +struct MatroskaSource : public MediaTrack { MatroskaSource(MatroskaExtractor *extractor, size_t index); - virtual status_t start(MetaData *params); + virtual status_t start(MetaDataBase *params); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options); @@ -219,10 +219,10 @@ MatroskaSource::MatroskaSource( mExtractor->mTracks.itemAt(index).mTrackNum, index), mNALSizeLen(-1) { - sp meta = mExtractor->mTracks.itemAt(index).mMeta; + MetaDataBase &meta = mExtractor->mTracks.editItemAt(index).mMeta; const char *mime; - CHECK(meta->findCString(kKeyMIMEType, &mime)); + CHECK(meta.findCString(kKeyMIMEType, &mime)); mIsAudio = !strncasecmp("audio/", mime, 6); @@ -233,11 +233,11 @@ MatroskaSource::MatroskaSource( const uint8_t *avcc; size_t avccSize; int32_t nalSizeLen = 0; - if (meta->findInt32(kKeyNalLengthSize, &nalSizeLen)) { + if (meta.findInt32(kKeyNalLengthSize, &nalSizeLen)) { if (nalSizeLen >= 0 && nalSizeLen <= 4) { mNALSizeLen = nalSizeLen; } - } else if (meta->findData(kKeyAVCC, &dummy, (const void **)&avcc, &avccSize) + } else if (meta.findData(kKeyAVCC, &dummy, (const void **)&avcc, &avccSize) && avccSize >= 5u) { mNALSizeLen = 1 + (avcc[4] & 3); ALOGV("mNALSizeLen = %zd", mNALSizeLen); @@ -250,7 +250,7 @@ MatroskaSource::MatroskaSource( uint32_t dummy; const uint8_t *hvcc; size_t hvccSize; - if (meta->findData(kKeyHVCC, &dummy, (const void **)&hvcc, &hvccSize) + if (meta.findData(kKeyHVCC, &dummy, (const void **)&hvcc, &hvccSize) && hvccSize >= 22u) { mNALSizeLen = 1 + (hvcc[14+7] & 3); ALOGV("mNALSizeLen = %zu", mNALSizeLen); @@ -266,7 +266,7 @@ MatroskaSource::~MatroskaSource() { clearPendingFrames(); } -status_t MatroskaSource::start(MetaData * /* params */) { +status_t MatroskaSource::start(MetaDataBase * /* params */) { if (mType == AVC && mNALSizeLen < 0) { return ERROR_MALFORMED; } @@ -282,8 +282,9 @@ status_t MatroskaSource::stop() { return OK; } -sp MatroskaSource::getFormat() { - return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; +status_t MatroskaSource::getFormat(MetaDataBase &meta) { + meta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta; + return OK; } //////////////////////////////////////////////////////////////////////////////// @@ -589,7 +590,7 @@ status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferBase *mbuf) { return ERROR_MALFORMED; } - sp meta = mbuf->meta_data(); + MetaDataBase &meta = mbuf->meta_data(); if (blockEncrypted) { /* * 0 1 2 3 @@ -612,13 +613,13 @@ status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferBase *mbuf) { uint32_t type; const uint8_t *keyId; size_t keyIdSize; - sp trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta; - CHECK(trackMeta->findData(kKeyCryptoKey, &type, (const void **)&keyId, &keyIdSize)); - meta->setData(kKeyCryptoKey, 0, keyId, keyIdSize); + const MetaDataBase &trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta; + CHECK(trackMeta.findData(kKeyCryptoKey, &type, (const void **)&keyId, &keyIdSize)); + meta.setData(kKeyCryptoKey, 0, keyId, keyIdSize); memcpy(ctrCounter, data + 1, 8); - meta->setData(kKeyCryptoIV, 0, ctrCounter, 16); - meta->setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); - meta->setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); + meta.setData(kKeyCryptoIV, 0, ctrCounter, 16); + meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); + meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); mbuf->set_range(9, mbuf->range_length() - 9); } else { /* @@ -634,8 +635,8 @@ status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferBase *mbuf) { */ int32_t plainSizes[] = { static_cast(mbuf->range_length() - 1) }; int32_t encryptedSizes[] = { 0 }; - meta->setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); - meta->setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); + meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); + meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); mbuf->set_range(1, mbuf->range_length() - 1); } @@ -668,8 +669,8 @@ status_t MatroskaSource::readBlock() { memcpy(data, trackInfo->mHeader, trackInfo->mHeaderLen); } - mbuf->meta_data()->setInt64(kKeyTime, timeUs); - mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); + mbuf->meta_data().setInt64(kKeyTime, timeUs); + mbuf->meta_data().setInt32(kKeyIsSyncFrame, block->IsKey()); status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen); if (err == OK @@ -736,7 +737,7 @@ status_t MatroskaSource::read( if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) { if (targetSampleTimeUs >= 0ll) { - frame->meta_data()->setInt64( + frame->meta_data().setInt64( kKeyTargetTime, targetSampleTimeUs); } @@ -824,12 +825,12 @@ status_t MatroskaSource::read( } int64_t timeUs; - CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(frame->meta_data().findInt64(kKeyTime, &timeUs)); int32_t isSync; - CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)); + CHECK(frame->meta_data().findInt32(kKeyIsSyncFrame, &isSync)); - buffer->meta_data()->setInt64(kKeyTime, timeUs); - buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); + buffer->meta_data().setInt64(kKeyTime, timeUs); + buffer->meta_data().setInt32(kKeyIsSyncFrame, isSync); dstPtr = (uint8_t *)buffer->data(); } @@ -841,7 +842,7 @@ status_t MatroskaSource::read( } if (targetSampleTimeUs >= 0ll) { - buffer->meta_data()->setInt64( + buffer->meta_data().setInt64( kKeyTargetTime, targetSampleTimeUs); } @@ -927,7 +928,7 @@ size_t MatroskaExtractor::countTracks() { return mTracks.size(); } -MediaSourceBase *MatroskaExtractor::getTrack(size_t index) { +MediaTrack *MatroskaExtractor::getTrack(size_t index) { if (index >= mTracks.size()) { return NULL; } @@ -935,10 +936,11 @@ MediaSourceBase *MatroskaExtractor::getTrack(size_t index) { return new MatroskaSource(this, index); } -sp MatroskaExtractor::getTrackMetaData( +status_t MatroskaExtractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t flags) { if (index >= mTracks.size()) { - return NULL; + return UNKNOWN_ERROR; } if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails @@ -947,7 +949,8 @@ sp MatroskaExtractor::getTrackMetaData( mExtractedThumbnails = true; } - return mTracks.itemAt(index).mMeta; + meta = mTracks.itemAt(index).mMeta; + return OK; } bool MatroskaExtractor::isLiveStreaming() const { @@ -982,7 +985,7 @@ static void storeSize(uint8_t *data, size_t &idx, size_t size) { } static void addESDSFromCodecPrivate( - const sp &meta, + MetaDataBase &meta, bool isAudio, const void *priv, size_t privSize) { int privSizeBytesRequired = bytesForSize(privSize); @@ -1010,14 +1013,14 @@ static void addESDSFromCodecPrivate( storeSize(esds, idx, privSize); memcpy(esds + idx, priv, privSize); - meta->setData(kKeyESDS, 0, esds, esdsSize); + meta.setData(kKeyESDS, 0, esds, esdsSize); delete[] esds; esds = NULL; } status_t addVorbisCodecInfo( - const sp &meta, + MetaDataBase &meta, const void *_codecPrivate, size_t codecPrivateSize) { // hexdump(_codecPrivate, codecPrivateSize); @@ -1075,7 +1078,7 @@ status_t addVorbisCodecInfo( if (codecPrivate[offset] != 0x01) { return ERROR_MALFORMED; } - meta->setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1); + meta.setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1); offset += len1; if (codecPrivate[offset] != 0x03) { @@ -1087,7 +1090,7 @@ status_t addVorbisCodecInfo( return ERROR_MALFORMED; } - meta->setData( + meta.setData( kKeyVorbisBooks, 0, &codecPrivate[offset], codecPrivateSize - offset); @@ -1095,11 +1098,11 @@ status_t addVorbisCodecInfo( } static status_t addFlacMetadata( - const sp &meta, + MetaDataBase &meta, const void *codecPrivate, size_t codecPrivateSize) { // hexdump(codecPrivate, codecPrivateSize); - meta->setData(kKeyFlacMetadata, 0, codecPrivate, codecPrivateSize); + meta.setData(kKeyFlacMetadata, 0, codecPrivate, codecPrivateSize); int32_t maxInputSize = 64 << 10; sp flacDecoder = FLACDecoder::Create(); @@ -1120,7 +1123,7 @@ static status_t addFlacMetadata( * streamInfo.max_blocksize * streamInfo.channels; } } - meta->setInt32(kKeyMaxInputSize, maxInputSize); + meta.setInt32(kKeyMaxInputSize, maxInputSize); return OK; } @@ -1143,14 +1146,12 @@ status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) { return ERROR_MALFORMED; } - sp avcMeta = MakeAVCCodecSpecificData(abuf); - if (avcMeta == NULL) { + if (!MakeAVCCodecSpecificData(trackInfo->mMeta, abuf)) { return ERROR_MALFORMED; } // Override the synthesized nal length size, which is arbitrary - avcMeta->setInt32(kKeyNalLengthSize, 0); - trackInfo->mMeta = avcMeta; + trackInfo->mMeta.setInt32(kKeyNalLengthSize, 0); return OK; } @@ -1172,7 +1173,7 @@ static inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) } void MatroskaExtractor::getColorInformation( - const mkvparser::VideoTrack *vtrack, sp &meta) { + const mkvparser::VideoTrack *vtrack, MetaDataBase &meta) { const mkvparser::Colour *color = vtrack->GetColour(); if (color == NULL) { return; @@ -1206,10 +1207,10 @@ void MatroskaExtractor::getColorInformation( ColorAspects aspects; ColorUtils::convertIsoColorAspectsToCodecAspects( primaries, transfer, coeffs, fullRange, aspects); - meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); - meta->setInt32(kKeyTransferFunction, aspects.mTransfer); - meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); - meta->setInt32( + meta.setInt32(kKeyColorPrimaries, aspects.mPrimaries); + meta.setInt32(kKeyTransferFunction, aspects.mTransfer); + meta.setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); + meta.setInt32( kKeyColorRange, rangeSpecified ? aspects.mRange : ColorAspects::RangeUnspecified); } @@ -1254,13 +1255,13 @@ void MatroskaExtractor::getColorInformation( // Only advertise static info if at least one of the groups have been specified. if (memcmp(&info, &nullInfo, sizeof(info)) != 0) { info.mID = HDRStaticInfo::kType1; - meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); + meta.setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); } } } status_t MatroskaExtractor::initTrackInfo( - const mkvparser::Track *track, const sp &meta, TrackInfo *trackInfo) { + const mkvparser::Track *track, MetaDataBase &meta, TrackInfo *trackInfo) { trackInfo->mTrackNum = track->GetNumber(); trackInfo->mMeta = meta; trackInfo->mExtractor = this; @@ -1273,7 +1274,7 @@ status_t MatroskaExtractor::initTrackInfo( for(size_t j = 0; j < encoding->GetEncryptionCount(); j++) { const mkvparser::ContentEncoding::ContentEncryption *encryption; encryption = encoding->GetEncryptionByIndex(j); - trackInfo->mMeta->setData(kKeyCryptoKey, 0, encryption->key_id, encryption->key_id_len); + trackInfo->mMeta.setData(kKeyCryptoKey, 0, encryption->key_id, encryption->key_id_len); trackInfo->mEncrypted = true; break; } @@ -1322,7 +1323,7 @@ void MatroskaExtractor::addTracks() { enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; - sp meta = new MetaData; + MetaDataBase meta; status_t err = OK; @@ -1333,19 +1334,19 @@ void MatroskaExtractor::addTracks() { static_cast(track); if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); - meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); + meta.setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); } else if (!strcmp("V_MPEGH/ISO/HEVC", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC); if (codecPrivateSize > 0) { - meta->setData(kKeyHVCC, kTypeHVCC, codecPrivate, codecPrivateSize); + meta.setData(kKeyHVCC, kTypeHVCC, codecPrivate, codecPrivateSize); } else { ALOGW("HEVC is detected, but does not have configuration."); continue; } } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { if (codecPrivateSize > 0) { - meta->setCString( + meta.setCString( kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); addESDSFromCodecPrivate( meta, false, codecPrivate, codecPrivateSize); @@ -1355,13 +1356,13 @@ void MatroskaExtractor::addTracks() { continue; } } else if (!strcmp("V_VP8", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); } else if (!strcmp("V_VP9", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); if (codecPrivateSize > 0) { // 'csd-0' for VP9 is the Blob of Codec Private data as // specified in http://www.webmproject.org/vp9/profiles/. - meta->setData( + meta.setData( kKeyVp9CodecPrivate, 0, codecPrivate, codecPrivateSize); } @@ -1380,8 +1381,8 @@ void MatroskaExtractor::addTracks() { ALOGW("track height exceeds int32_t, %lld", height); continue; } - meta->setInt32(kKeyWidth, (int32_t)width); - meta->setInt32(kKeyHeight, (int32_t)height); + meta.setInt32(kKeyWidth, (int32_t)width); + meta.setInt32(kKeyHeight, (int32_t)height); // setting display width/height is optional const long long displayUnit = vtrack->GetDisplayUnit(); @@ -1391,8 +1392,8 @@ void MatroskaExtractor::addTracks() { && displayHeight > 0 && displayHeight <= INT32_MAX) { switch (displayUnit) { case 0: // pixels - meta->setInt32(kKeyDisplayWidth, (int32_t)displayWidth); - meta->setInt32(kKeyDisplayHeight, (int32_t)displayHeight); + meta.setInt32(kKeyDisplayWidth, (int32_t)displayWidth); + meta.setInt32(kKeyDisplayHeight, (int32_t)displayHeight); break; case 1: // centimeters case 2: // inches @@ -1406,8 +1407,8 @@ void MatroskaExtractor::addTracks() { const long long computedHeight = std::max(height, width * displayHeight / displayWidth); if (computedWidth <= INT32_MAX && computedHeight <= INT32_MAX) { - meta->setInt32(kKeyDisplayWidth, (int32_t)computedWidth); - meta->setInt32(kKeyDisplayHeight, (int32_t)computedHeight); + meta.setInt32(kKeyDisplayWidth, (int32_t)computedWidth); + meta.setInt32(kKeyDisplayHeight, (int32_t)computedHeight); } break; } @@ -1427,34 +1428,34 @@ void MatroskaExtractor::addTracks() { static_cast(track); if (!strcmp("A_AAC", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); CHECK(codecPrivateSize >= 2); addESDSFromCodecPrivate( meta, true, codecPrivate, codecPrivateSize); } else if (!strcmp("A_VORBIS", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 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()); + 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); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); } else if (!strcmp("A_FLAC", codecID)) { - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); err = addFlacMetadata(meta, codecPrivate, codecPrivateSize); } else { ALOGW("%s is not supported.", codecID); continue; } - meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); - meta->setInt32(kKeyChannelCount, atrack->GetChannels()); + meta.setInt32(kKeySampleRate, atrack->GetSamplingRate()); + meta.setInt32(kKeyChannelCount, atrack->GetChannels()); break; } @@ -1467,7 +1468,7 @@ void MatroskaExtractor::addTracks() { char lang[4]; strncpy(lang, language, 3); lang[3] = '\0'; - meta->setCString(kKeyMediaLanguage, lang); + meta.setCString(kKeyMediaLanguage, lang); } if (err != OK) { @@ -1476,7 +1477,7 @@ void MatroskaExtractor::addTracks() { } long long durationNs = mSegment->GetDuration(); - meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); + meta.setInt64(kKeyDuration, (durationNs + 500) / 1000); mTracks.push(); size_t n = mTracks.size() - 1; @@ -1498,7 +1499,7 @@ void MatroskaExtractor::findThumbnails() { TrackInfo *info = &mTracks.editItemAt(i); const char *mime; - CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); + CHECK(info->mMeta.findCString(kKeyMIMEType, &mime)); if (strncasecmp(mime, "video/", 6)) { continue; @@ -1524,18 +1525,16 @@ void MatroskaExtractor::findThumbnails() { } iter.advance(); } - info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); + info->mMeta.setInt64(kKeyThumbnailTime, thumbnailTimeUs); } } -sp MatroskaExtractor::getMetaData() { - sp meta = new MetaData; - - meta->setCString( +status_t MatroskaExtractor::getMetaData(MetaDataBase &meta) { + meta.setCString( kKeyMIMEType, mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA); - return meta; + return OK; } uint32_t MatroskaExtractor::flags() const { diff --git a/media/extractors/mkv/MatroskaExtractor.h b/media/extractors/mkv/MatroskaExtractor.h index 095452b0362383d783caf56c30d6b1b1d48efdd2..3568ea19e8a0557dbbdfc9aad6bf3599dd3993c0 100644 --- a/media/extractors/mkv/MatroskaExtractor.h +++ b/media/extractors/mkv/MatroskaExtractor.h @@ -21,6 +21,7 @@ #include "mkvparser/mkvparser.h" #include +#include #include #include @@ -38,12 +39,11 @@ struct MatroskaExtractor : public MediaExtractor { virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); + virtual MediaTrack *getTrack(size_t index); - virtual sp getTrackMetaData( - size_t index, uint32_t flags); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual uint32_t flags() const; @@ -59,7 +59,7 @@ private: struct TrackInfo { unsigned long mTrackNum; bool mEncrypted; - sp mMeta; + MetaDataBase mMeta; const MatroskaExtractor *mExtractor; Vector mCuePoints; @@ -85,20 +85,21 @@ private: int64_t mSeekPreRollNs; status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index); - status_t initTrackInfo(const mkvparser::Track *track, const sp &meta, TrackInfo *trackInfo); + status_t initTrackInfo( + const mkvparser::Track *track, + MetaDataBase &meta, + TrackInfo *trackInfo); void addTracks(); void findThumbnails(); - void getColorInformation(const mkvparser::VideoTrack *vtrack, sp &meta); + void getColorInformation( + const mkvparser::VideoTrack *vtrack, + MetaDataBase &meta); bool isLiveStreaming() const; MatroskaExtractor(const MatroskaExtractor &); MatroskaExtractor &operator=(const MatroskaExtractor &); }; -bool SniffMatroska( - DataSourceBase *source, String8 *mimeType, float *confidence, - sp *); - } // namespace android #endif // MATROSKA_EXTRACTOR_H_ diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/extractors/mp3/MP3Extractor.cpp index 90ee653be8b2e5d7cb389673b0d8c9aafe4249cf..33cff96cd3870436bcef87c27f45b41244420f2c 100644 --- a/media/extractors/mp3/MP3Extractor.cpp +++ b/media/extractors/mp3/MP3Extractor.cpp @@ -25,7 +25,7 @@ #include "XINGSeeker.h" #include -#include +#include #include #include #include @@ -209,17 +209,17 @@ static bool Resync( return valid; } -class MP3Source : public MediaSourceBase { +class MP3Source : public MediaTrack { public: MP3Source( - const sp &meta, DataSourceBase *source, + MetaDataBase &meta, DataSourceBase *source, off64_t first_frame_pos, uint32_t fixed_header, - const sp &seeker); + MP3Seeker *seeker); - virtual status_t start(MetaData *params = NULL); + virtual status_t start(MetaDataBase *params = NULL); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &meta); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); @@ -229,14 +229,14 @@ protected: private: static const size_t kMaxFrameSize; - sp mMeta; + MetaDataBase &mMeta; DataSourceBase *mDataSource; off64_t mFirstFramePos; uint32_t mFixedHeader; off64_t mCurrentPos; int64_t mCurrentTimeUs; bool mStarted; - sp mSeeker; + MP3Seeker *mSeeker; MediaBufferGroup *mGroup; int64_t mBasisTimeUs; @@ -246,31 +246,31 @@ private: MP3Source &operator=(const MP3Source &); }; +struct Mp3Meta { + off64_t pos; + off64_t post_id3_pos; + uint32_t header; +}; + MP3Extractor::MP3Extractor( - DataSourceBase *source, const sp &meta) + DataSourceBase *source, Mp3Meta *meta) : mInitCheck(NO_INIT), mDataSource(source), mFirstFramePos(-1), - mFixedHeader(0) { + mFixedHeader(0), + mSeeker(NULL) { off64_t pos = 0; off64_t post_id3_pos; uint32_t header; bool success; - int64_t meta_offset; - uint32_t meta_header; - int64_t meta_post_id3_offset; - if (meta != NULL - && meta->findInt64("offset", &meta_offset) - && meta->findInt32("header", (int32_t *)&meta_header) - && meta->findInt64("post-id3-offset", &meta_post_id3_offset)) { + if (meta != NULL) { // The sniffer has already done all the hard work for us, simply // accept its judgement. - pos = (off64_t)meta_offset; - header = meta_header; - post_id3_pos = (off64_t)meta_post_id3_offset; - + pos = meta->pos; + header = meta->header; + post_id3_pos = meta->post_id3_pos; success = true; } else { success = Resync(mDataSource, 0, &pos, &post_id3_pos, &header); @@ -283,8 +283,7 @@ MP3Extractor::MP3Extractor( mFirstFramePos = pos; mFixedHeader = header; - mMeta = new MetaData; - sp seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); + XINGSeeker *seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos); if (seeker == NULL) { mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos); @@ -293,8 +292,8 @@ MP3Extractor::MP3Extractor( int encd = seeker->getEncoderDelay(); int encp = seeker->getEncoderPadding(); if (encd != 0 || encp != 0) { - mMeta->setInt32(kKeyEncoderDelay, encd); - mMeta->setInt32(kKeyEncoderPadding, encp); + mMeta.setInt32(kKeyEncoderDelay, encd); + mMeta.setInt32(kKeyEncoderPadding, encp); } } @@ -330,21 +329,21 @@ MP3Extractor::MP3Extractor( switch (layer) { case 1: - mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I); + mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I); break; case 2: - mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); + mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); break; case 3: - mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); + mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); break; default: TRESPASS(); } - mMeta->setInt32(kKeySampleRate, sample_rate); - mMeta->setInt32(kKeyBitRate, bitrate * 1000); - mMeta->setInt32(kKeyChannelCount, num_channels); + mMeta.setInt32(kKeySampleRate, sample_rate); + mMeta.setInt32(kKeyBitRate, bitrate * 1000); + mMeta.setInt32(kKeyChannelCount, num_channels); int64_t durationUs; @@ -364,7 +363,7 @@ MP3Extractor::MP3Extractor( } if (durationUs >= 0) { - mMeta->setInt64(kKeyDuration, durationUs); + mMeta.setInt64(kKeyDuration, durationUs); } mInitCheck = OK; @@ -391,8 +390,8 @@ MP3Extractor::MP3Extractor( int32_t delay, padding; if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) { - mMeta->setInt32(kKeyEncoderDelay, delay); - mMeta->setInt32(kKeyEncoderPadding, padding); + mMeta.setInt32(kKeyEncoderDelay, delay); + mMeta.setInt32(kKeyEncoderPadding, padding); } break; } @@ -403,11 +402,15 @@ MP3Extractor::MP3Extractor( } } +MP3Extractor::~MP3Extractor() { + delete mSeeker; +} + size_t MP3Extractor::countTracks() { return mInitCheck != OK ? 0 : 1; } -MediaSourceBase *MP3Extractor::getTrack(size_t index) { +MediaTrack *MP3Extractor::getTrack(size_t index) { if (mInitCheck != OK || index != 0) { return NULL; } @@ -417,13 +420,14 @@ MediaSourceBase *MP3Extractor::getTrack(size_t index) { mSeeker); } -sp MP3Extractor::getTrackMetaData( +status_t MP3Extractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t /* flags */) { if (mInitCheck != OK || index != 0) { - return NULL; + return UNKNOWN_ERROR; } - - return mMeta; + meta = mMeta; + return OK; } //////////////////////////////////////////////////////////////////////////////// @@ -436,9 +440,9 @@ sp MP3Extractor::getTrackMetaData( // Set our max frame size to the nearest power of 2 above this size (aka, 4kB) const size_t MP3Source::kMaxFrameSize = (1 << 12); /* 4096 bytes */ MP3Source::MP3Source( - const sp &meta, DataSourceBase *source, + MetaDataBase &meta, DataSourceBase *source, off64_t first_frame_pos, uint32_t fixed_header, - const sp &seeker) + MP3Seeker *seeker) : mMeta(meta), mDataSource(source), mFirstFramePos(first_frame_pos), @@ -458,7 +462,7 @@ MP3Source::~MP3Source() { } } -status_t MP3Source::start(MetaData *) { +status_t MP3Source::start(MetaDataBase *) { CHECK(!mStarted); mGroup = new MediaBufferGroup; @@ -487,8 +491,9 @@ status_t MP3Source::stop() { return OK; } -sp MP3Source::getFormat() { - return mMeta; +status_t MP3Source::getFormat(MetaDataBase &meta) { + meta = mMeta; + return OK; } status_t MP3Source::read( @@ -504,7 +509,7 @@ status_t MP3Source::read( if (mSeeker == NULL || !mSeeker->getOffsetForTime(&actualSeekTimeUs, &mCurrentPos)) { int32_t bitrate; - if (!mMeta->findInt32(kKeyBitRate, &bitrate)) { + if (!mMeta.findInt32(kKeyBitRate, &bitrate)) { // bitrate is in bits/sec. ALOGI("no bitrate"); @@ -587,8 +592,8 @@ status_t MP3Source::read( buffer->set_range(0, frame_size); - buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); - buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + buffer->meta_data().setInt64(kKeyTime, mCurrentTimeUs); + buffer->meta_data().setInt32(kKeyIsSyncFrame, 1); mCurrentPos += frame_size; @@ -600,19 +605,17 @@ status_t MP3Source::read( return OK; } -sp MP3Extractor::getMetaData() { - sp meta = new MetaData; - +status_t MP3Extractor::getMetaData(MetaDataBase &meta) { + meta.clear(); if (mInitCheck != OK) { - return meta; + return UNKNOWN_ERROR; } - - meta->setCString(kKeyMIMEType, "audio/mpeg"); + meta.setCString(kKeyMIMEType, "audio/mpeg"); ID3 id3(mDataSource); if (!id3.isValid()) { - return meta; + return OK; } struct Map { @@ -651,7 +654,7 @@ sp MP3Extractor::getMetaData() { it->getString(&s); delete it; - meta->setCString(kMap[i].key, s); + meta.setCString(kMap[i].key, s); } size_t dataSize; @@ -659,26 +662,20 @@ sp MP3Extractor::getMetaData() { const void *data = id3.getAlbumArt(&dataSize, &mime); if (data) { - meta->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); - meta->setCString(kKeyAlbumArtMIME, mime.string()); + meta.setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); + meta.setCString(kKeyAlbumArtMIME, mime.string()); } - return meta; + return OK; } static MediaExtractor* CreateExtractor( DataSourceBase *source, void *meta) { - sp metaData = static_cast(meta); + Mp3Meta *metaData = static_cast(meta); return new MP3Extractor(source, metaData); } -static void FreeMeta(void *meta) { - if (meta != nullptr) { - static_cast(meta)->decStrong(nullptr); - } -} - static MediaExtractor::CreatorFunc Sniff( DataSourceBase *source, float *confidence, void **meta, MediaExtractor::FreeMetaFunc *freeMeta) { @@ -698,14 +695,12 @@ static MediaExtractor::CreatorFunc Sniff( return NULL; } - AMessage *msg = new AMessage; - msg->setInt64("offset", pos); - msg->setInt32("header", header); - msg->setInt64("post-id3-offset", post_id3_pos); - *meta = msg; - *freeMeta = &FreeMeta; - // ref count will be decreased in FreeMeta. - msg->incStrong(nullptr); + Mp3Meta *mp3Meta = new Mp3Meta; + mp3Meta->pos = pos; + mp3Meta->header = header; + mp3Meta->post_id3_pos = post_id3_pos; + *meta = mp3Meta; + *freeMeta = ::free; *confidence = 0.2f; diff --git a/media/extractors/mp3/MP3Extractor.h b/media/extractors/mp3/MP3Extractor.h index 6257112366a807a209a08b39eb47760bb78354a7..485b0ca90b060ee8cf84e79391b15896217fbc1c 100644 --- a/media/extractors/mp3/MP3Extractor.h +++ b/media/extractors/mp3/MP3Extractor.h @@ -20,6 +20,7 @@ #include #include +#include namespace android { @@ -27,16 +28,18 @@ struct AMessage; class DataSourceBase; struct MP3Seeker; class String8; +struct Mp3Meta; class MP3Extractor : public MediaExtractor { public: - MP3Extractor(DataSourceBase *source, const sp &meta); + MP3Extractor(DataSourceBase *source, Mp3Meta *meta); + ~MP3Extractor(); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual const char * name() { return "MP3Extractor"; } private: @@ -44,18 +47,14 @@ private: DataSourceBase *mDataSource; off64_t mFirstFramePos; - sp mMeta; + MetaDataBase mMeta; uint32_t mFixedHeader; - sp mSeeker; + MP3Seeker *mSeeker; MP3Extractor(const MP3Extractor &); MP3Extractor &operator=(const MP3Extractor &); }; -bool SniffMP3( - DataSourceBase *source, String8 *mimeType, float *confidence, - sp *meta); - } // namespace android #endif // MP3_EXTRACTOR_H_ diff --git a/media/extractors/mp3/MP3Seeker.h b/media/extractors/mp3/MP3Seeker.h index 599542e27bb8c064f8784c2cd08eac548f075ede..0e3af25cce2c42b45fc5542462401c4f583e611e 100644 --- a/media/extractors/mp3/MP3Seeker.h +++ b/media/extractors/mp3/MP3Seeker.h @@ -23,7 +23,7 @@ namespace android { -struct MP3Seeker : public RefBase { +struct MP3Seeker { MP3Seeker() {} virtual bool getDuration(int64_t *durationUs) = 0; @@ -33,7 +33,6 @@ struct MP3Seeker : public RefBase { // the actual time that seekpoint represents. virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos) = 0; -protected: virtual ~MP3Seeker() {} private: diff --git a/media/extractors/mp3/VBRISeeker.cpp b/media/extractors/mp3/VBRISeeker.cpp index 51c5d1f7cc9f1ca968c4b65c6975d6145f1d4e13..523f14cff25505bb8a9e6fc0a470d37d395d8350 100644 --- a/media/extractors/mp3/VBRISeeker.cpp +++ b/media/extractors/mp3/VBRISeeker.cpp @@ -36,7 +36,7 @@ static uint32_t U24_AT(const uint8_t *ptr) { } // static -sp VBRISeeker::CreateFromSource( +VBRISeeker *VBRISeeker::CreateFromSource( DataSourceBase *source, off64_t post_id3_pos) { off64_t pos = post_id3_pos; @@ -87,7 +87,7 @@ sp VBRISeeker::CreateFromSource( return NULL; } - sp seeker = new (std::nothrow) VBRISeeker; + VBRISeeker *seeker = new (std::nothrow) VBRISeeker; if (seeker == NULL) { ALOGW("Couldn't allocate VBRISeeker"); return NULL; @@ -97,6 +97,7 @@ sp VBRISeeker::CreateFromSource( uint8_t *buffer = new (std::nothrow) uint8_t[totalEntrySize]; if (!buffer) { ALOGW("Couldn't allocate %zu bytes", totalEntrySize); + delete seeker; return NULL; } @@ -104,7 +105,7 @@ sp VBRISeeker::CreateFromSource( if (n < (ssize_t)totalEntrySize) { delete[] buffer; buffer = NULL; - + delete seeker; return NULL; } diff --git a/media/extractors/mp3/VBRISeeker.h b/media/extractors/mp3/VBRISeeker.h index e46af361ad6936c6d331528d989c00391321551f..9213f6e8c8945f953768361bb346361f9645fc51 100644 --- a/media/extractors/mp3/VBRISeeker.h +++ b/media/extractors/mp3/VBRISeeker.h @@ -27,7 +27,7 @@ namespace android { class DataSourceBase; struct VBRISeeker : public MP3Seeker { - static sp CreateFromSource( + static VBRISeeker *CreateFromSource( DataSourceBase *source, off64_t post_id3_pos); virtual bool getDuration(int64_t *durationUs); diff --git a/media/extractors/mp3/XINGSeeker.cpp b/media/extractors/mp3/XINGSeeker.cpp index adfa8d2c5afb11e782341a0bedddd986f1cc2153..95ca556b3e3d657b1a122436e4add35c41f89c8a 100644 --- a/media/extractors/mp3/XINGSeeker.cpp +++ b/media/extractors/mp3/XINGSeeker.cpp @@ -76,11 +76,8 @@ bool XINGSeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) { } // static -sp XINGSeeker::CreateFromSource( +XINGSeeker *XINGSeeker::CreateFromSource( DataSourceBase *source, off64_t first_frame_pos) { - sp seeker = new XINGSeeker; - - seeker->mFirstFramePos = first_frame_pos; uint8_t buffer[4]; int offset = first_frame_pos; @@ -98,8 +95,6 @@ sp XINGSeeker::CreateFromSource( NULL, &samples_per_frame)) { return NULL; } - seeker->mFirstFramePos += xingframesize; - uint8_t version = (buffer[1] >> 3) & 3; // determine offset of XING header @@ -132,9 +127,13 @@ sp XINGSeeker::CreateFromSource( offset += 4; uint32_t flags = U32_AT(buffer); + XINGSeeker *seeker = new XINGSeeker; + seeker->mFirstFramePos = first_frame_pos + xingframesize; + if (flags & 0x0001) { // Frames field is present if (source->readAt(offset, buffer, 4) < 4) { - return NULL; + delete seeker; + return NULL; } int32_t frames = U32_AT(buffer); // only update mDurationUs if the calculated duration is valid (non zero) @@ -148,6 +147,7 @@ sp XINGSeeker::CreateFromSource( } if (flags & 0x0002) { // Bytes field is present if (source->readAt(offset, buffer, 4) < 4) { + delete seeker; return NULL; } seeker->mSizeBytes = U32_AT(buffer); @@ -155,6 +155,7 @@ sp XINGSeeker::CreateFromSource( } if (flags & 0x0004) { // TOC field is present if (source->readAt(offset + 1, seeker->mTOC, 99) < 99) { + delete seeker; return NULL; } seeker->mTOCValid = true; @@ -164,6 +165,7 @@ sp XINGSeeker::CreateFromSource( #if 0 if (flags & 0x0008) { // Quality indicator field is present if (source->readAt(offset, buffer, 4) < 4) { + delete seeker; return NULL; } // do something with the quality indicator @@ -171,6 +173,7 @@ sp XINGSeeker::CreateFromSource( } if (source->readAt(xingbase + 0xaf - 0x24, &buffer, 1) < 1) { // encoding flags + delete seeker; return false; } diff --git a/media/extractors/mp3/XINGSeeker.h b/media/extractors/mp3/XINGSeeker.h index db847bcb7f80df301d583200f8a2ed6ac203468f..5867eaeb8f6adaf10d8ab3a6fe0d645e59c9d0f7 100644 --- a/media/extractors/mp3/XINGSeeker.h +++ b/media/extractors/mp3/XINGSeeker.h @@ -25,7 +25,7 @@ namespace android { class DataSourceBase; struct XINGSeeker : public MP3Seeker { - static sp CreateFromSource( + static XINGSeeker *CreateFromSource( DataSourceBase *source, off64_t first_frame_pos); virtual bool getDuration(int64_t *durationUs); diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp index 40c84a5cf765337077798fb449645c801ba0dc10..78d2ac638b84750b143377a7a96a6b64707ba951 100644 --- a/media/extractors/mp4/MPEG4Extractor.cpp +++ b/media/extractors/mp4/MPEG4Extractor.cpp @@ -31,7 +31,7 @@ #include "ItemTable.h" #include "include/ESDS.h" -#include +#include #include #include #include @@ -65,10 +65,10 @@ enum { kMaxAtomSize = 64 * 1024 * 1024, }; -class MPEG4Source : public MediaSourceBase { +class MPEG4Source : public MediaTrack { public: // Caller retains ownership of both "dataSource" and "sampleTable". - MPEG4Source(const sp &format, + MPEG4Source(MetaDataBase &format, DataSourceBase *dataSource, int32_t timeScale, const sp &sampleTable, @@ -78,10 +78,10 @@ public: const sp &itemTable); virtual status_t init(); - virtual status_t start(MetaData *params = NULL); + virtual status_t start(MetaDataBase *params = NULL); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &); virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL); virtual bool supportNonblockingRead() { return true; } @@ -92,7 +92,7 @@ public: private: Mutex mLock; - sp mFormat; + MetaDataBase &mFormat; DataSourceBase *mDataSource; int32_t mTimescale; sp mSampleTable; @@ -353,8 +353,7 @@ MPEG4Extractor::MPEG4Extractor(DataSourceBase *source, const char *mime) mHasMoovBox(false), mPreferHeif(mime != NULL && !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_HEIF)), mFirstTrack(NULL), - mLastTrack(NULL), - mFileMetaData(new MetaData) { + mLastTrack(NULL) { ALOGV("mime=%s, mPreferHeif=%d", mime, mPreferHeif); } @@ -382,13 +381,13 @@ uint32_t MPEG4Extractor::flags() const { (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); } -sp MPEG4Extractor::getMetaData() { +status_t MPEG4Extractor::getMetaData(MetaDataBase &meta) { status_t err; if ((err = readMetaData()) != OK) { - return new MetaData; + return UNKNOWN_ERROR; } - - return mFileMetaData; + meta = mFileMetaData; + return OK; } size_t MPEG4Extractor::countTracks() { @@ -409,17 +408,18 @@ size_t MPEG4Extractor::countTracks() { return n; } -sp MPEG4Extractor::getTrackMetaData( +status_t MPEG4Extractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t flags) { status_t err; if ((err = readMetaData()) != OK) { - return NULL; + return UNKNOWN_ERROR; } Track *track = mFirstTrack; while (index > 0) { if (track == NULL) { - return NULL; + return UNKNOWN_ERROR; } track = track->next; @@ -427,15 +427,15 @@ sp MPEG4Extractor::getTrackMetaData( } if (track == NULL) { - return NULL; + return UNKNOWN_ERROR; } [=] { int64_t duration; int32_t samplerate; if (track->has_elst && mHeaderTimescale != 0 && - track->meta->findInt64(kKeyDuration, &duration) && - track->meta->findInt32(kKeySampleRate, &samplerate)) { + track->meta.findInt64(kKeyDuration, &duration) && + track->meta.findInt32(kKeySampleRate, &samplerate)) { track->has_elst = false; @@ -462,7 +462,7 @@ sp MPEG4Extractor::getTrackMetaData( return; } ALOGV("delay = %" PRId64, delay); - track->meta->setInt32(kKeyEncoderDelay, delay); + track->meta.setInt32(kKeyEncoderDelay, delay); int64_t scaled_duration; // scaled_duration = duration * mHeaderTimescale; @@ -502,7 +502,7 @@ sp MPEG4Extractor::getTrackMetaData( return; } ALOGV("paddingsamples = %" PRId64, paddingsamples); - track->meta->setInt32(kKeyEncoderPadding, paddingsamples); + track->meta.setInt32(kKeyEncoderPadding, paddingsamples); } }(); @@ -511,7 +511,7 @@ sp MPEG4Extractor::getTrackMetaData( track->includes_expensive_metadata = true; const char *mime; - CHECK(track->meta->findCString(kKeyMIMEType, &mime)); + CHECK(track->meta.findCString(kKeyMIMEType, &mime)); if (!strncasecmp("video/", mime, 6)) { // MPEG2 tracks do not provide CSD, so read the stream header if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) { @@ -524,16 +524,16 @@ sp MPEG4Extractor::getTrackMetaData( } uint8_t header[kMaxTrackHeaderSize]; if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) { - track->meta->setData(kKeyStreamHeader, 'mdat', header, size); + track->meta.setData(kKeyStreamHeader, 'mdat', header, size); } } } if (mMoofOffset > 0) { int64_t duration; - if (track->meta->findInt64(kKeyDuration, &duration)) { + if (track->meta.findInt64(kKeyDuration, &duration)) { // nothing fancy, just pick a frame near 1/4th of the duration - track->meta->setInt64( + track->meta.setInt64( kKeyThumbnailTime, duration / 4); } } else { @@ -544,7 +544,7 @@ sp MPEG4Extractor::getTrackMetaData( && track->sampleTable->getMetaDataForSample( sampleIndex, NULL /* offset */, NULL /* size */, &sampleTime) == OK) { - track->meta->setInt64( + track->meta.setInt64( kKeyThumbnailTime, ((int64_t)sampleTime * 1000000) / track->timescale); } @@ -552,7 +552,8 @@ sp MPEG4Extractor::getTrackMetaData( } } - return track->meta; + meta = track->meta; + return OK; } status_t MPEG4Extractor::readMetaData() { @@ -610,8 +611,8 @@ status_t MPEG4Extractor::readMetaData() { } mLastTrack = track; - track->meta = meta; - track->meta->setInt32(kKeyTrackID, imageIndex); + track->meta = *(meta.get()); + track->meta.setInt32(kKeyTrackID, imageIndex); track->includes_expensive_metadata = false; track->skipTrack = false; track->timescale = 0; @@ -620,16 +621,16 @@ status_t MPEG4Extractor::readMetaData() { if (mInitCheck == OK) { if (findTrackByMimePrefix("video/") != NULL) { - mFileMetaData->setCString( + mFileMetaData.setCString( kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); } else if (findTrackByMimePrefix("audio/") != NULL) { - mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); + mFileMetaData.setCString(kKeyMIMEType, "audio/mp4"); } else if (findTrackByMimePrefix( MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) != NULL) { - mFileMetaData->setCString( + mFileMetaData.setCString( kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_HEIF); } else { - mFileMetaData->setCString(kKeyMIMEType, "application/octet-stream"); + mFileMetaData.setCString(kKeyMIMEType, "application/octet-stream"); } } else { mInitCheck = err; @@ -654,7 +655,7 @@ status_t MPEG4Extractor::readMetaData() { memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); ptr += (20 + mPssh[i].datalen); } - mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); + mFileMetaData.setData(kKeyPssh, 'pssh', buf, psshsize); free(buf); } @@ -902,11 +903,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } mLastTrack = track; - track->meta = new MetaData; track->includes_expensive_metadata = false; track->skipTrack = false; track->timescale = 0; - track->meta->setCString(kKeyMIMEType, "application/octet-stream"); + track->meta.setCString(kKeyMIMEType, "application/octet-stream"); track->has_elst = false; } @@ -930,7 +930,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (isTrack) { int32_t trackId; // There must be exact one track header per track. - if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { + if (!mLastTrack->meta.findInt32(kKeyTrackID, &trackId)) { mLastTrack->skipTrack = true; } @@ -1037,12 +1037,12 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return ERROR_MALFORMED; } - mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); + mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); uint32_t num_channels = 0; uint32_t sample_rate = 0; if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { - mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); - mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); + mLastTrack->meta.setInt32(kKeyChannelCount, num_channels); + mLastTrack->meta.setInt32(kKeySampleRate, sample_rate); } break; } @@ -1095,9 +1095,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (mLastTrack == NULL) return ERROR_MALFORMED; - mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); - mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); - mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); + mLastTrack->meta.setInt32(kKeyCryptoMode, defaultAlgorithmId); + mLastTrack->meta.setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); + mLastTrack->meta.setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); break; } @@ -1231,7 +1231,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } } if (duration != 0 && mLastTrack->timescale != 0) { - mLastTrack->meta->setInt64( + mLastTrack->meta.setInt64( kKeyDuration, (duration * 1000000) / mLastTrack->timescale); } @@ -1259,7 +1259,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { lang_code[2] = (lang[1] & 0x1f) + 0x60; lang_code[3] = '\0'; - mLastTrack->meta->setCString( + mLastTrack->meta.setCString( kKeyMediaLanguage, lang_code); break; @@ -1294,7 +1294,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (mLastTrack == NULL) return ERROR_MALFORMED; - CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); + CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime)); if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && strcasecmp(mime, "application/octet-stream")) { // For now we only support a single type of media per track. @@ -1335,7 +1335,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } String8 mimeFormat((const char *)(buffer->data()), chunk_data_size); - mLastTrack->meta->setCString(kKeyMIMEType, mimeFormat.string()); + mLastTrack->meta.setCString(kKeyMIMEType, mimeFormat.string()); break; } @@ -1411,13 +1411,13 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { // if the chunk type is enca, we'll get the type from the frma box later - mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); + mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); } ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", chunk, num_channels, sample_size, sample_rate); - mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); - mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); + mLastTrack->meta.setInt32(kKeyChannelCount, num_channels); + mLastTrack->meta.setInt32(kKeySampleRate, sample_rate); while (*offset < stop_offset) { status_t err = parseChunk(offset, depth + 1); @@ -1471,10 +1471,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { // if the chunk type is encv, we'll get the type from the frma box later - mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); + mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); } - mLastTrack->meta->setInt32(kKeyWidth, width); - mLastTrack->meta->setInt32(kKeyHeight, height); + mLastTrack->meta.setInt32(kKeyWidth, width); + mLastTrack->meta.setInt32(kKeyHeight, height); off64_t stop_offset = *offset + chunk_size; *offset = data_offset + sizeof(buffer); @@ -1562,12 +1562,12 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { ALOGE("max sample size too big: %zu", max_size); return ERROR_MALFORMED; } - mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); + mLastTrack->meta.setInt32(kKeyMaxInputSize, max_size + 10 * 2); } else { // No size was specified. Pick a conservatively large size. uint32_t width, height; - if (!mLastTrack->meta->findInt32(kKeyWidth, (int32_t*)&width) || - !mLastTrack->meta->findInt32(kKeyHeight,(int32_t*) &height)) { + if (!mLastTrack->meta.findInt32(kKeyWidth, (int32_t*)&width) || + !mLastTrack->meta.findInt32(kKeyHeight,(int32_t*) &height)) { ALOGE("No width or height, assuming worst case 1080p"); width = 1920; height = 1080; @@ -1582,7 +1582,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } const char *mime; - CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); + CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime)); if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { // AVC & HEVC requires compression ratio of at least 2, and uses @@ -1596,26 +1596,26 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { // HACK: allow 10% overhead // TODO: read sample size from traf atom for fragmented MPEG4. max_size += max_size / 10; - mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); + mLastTrack->meta.setInt32(kKeyMaxInputSize, max_size); } // NOTE: setting another piece of metadata invalidates any pointers (such as the // mimetype) previously obtained, so don't cache them. const char *mime; - CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); + CHECK(mLastTrack->meta.findCString(kKeyMIMEType, &mime)); // Calculate average frame rate. if (!strncasecmp("video/", mime, 6)) { size_t nSamples = mLastTrack->sampleTable->countSamples(); if (nSamples == 0) { int32_t trackId; - if (mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { + if (mLastTrack->meta.findInt32(kKeyTrackID, &trackId)) { for (size_t i = 0; i < mTrex.size(); i++) { Trex *t = &mTrex.editItemAt(i); if (t->track_ID == (uint32_t) trackId) { if (t->default_sample_duration > 0) { int32_t frameRate = mLastTrack->timescale / t->default_sample_duration; - mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); + mLastTrack->meta.setInt32(kKeyFrameRate, frameRate); } break; } @@ -1623,15 +1623,15 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } } else { int64_t durationUs; - if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { + if (mLastTrack->meta.findInt64(kKeyDuration, &durationUs)) { if (durationUs > 0) { int32_t frameRate = (nSamples * 1000000LL + (durationUs >> 1)) / durationUs; - mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); + mLastTrack->meta.setInt32(kKeyFrameRate, frameRate); } } ALOGV("setting frame count %zu", nSamples); - mLastTrack->meta->setInt32(kKeyFrameCount, nSamples); + mLastTrack->meta.setInt32(kKeyFrameCount, nSamples); } } @@ -1739,7 +1739,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (buffer[len - 1] != '/') { buffer[len] = '/'; } - mFileMetaData->setCString(kKeyLocation, &buffer[0]); + mFileMetaData.setCString(kKeyLocation, &buffer[0]); break; } @@ -1769,7 +1769,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (mLastTrack == NULL) return ERROR_MALFORMED; - mLastTrack->meta->setData( + mLastTrack->meta.setData( kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); if (mPath.size() >= 2 @@ -1794,7 +1794,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { uint8_t objectTypeIndication; if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) { if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) { - mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); + mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); } } } @@ -1821,10 +1821,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { uint32_t maxBitrate = U32_AT(&buffer[4]); uint32_t avgBitrate = U32_AT(&buffer[8]); if (maxBitrate > 0 && maxBitrate < INT32_MAX) { - mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate); + mLastTrack->meta.setInt32(kKeyMaxBitRate, (int32_t)maxBitrate); } if (avgBitrate > 0 && avgBitrate < INT32_MAX) { - mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate); + mLastTrack->meta.setInt32(kKeyBitRate, (int32_t)avgBitrate); } break; } @@ -1848,7 +1848,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (mLastTrack == NULL) return ERROR_MALFORMED; - mLastTrack->meta->setData( + mLastTrack->meta.setData( kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); break; @@ -1870,7 +1870,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (mLastTrack == NULL) return ERROR_MALFORMED; - mLastTrack->meta->setData( + mLastTrack->meta.setData( kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); *offset += chunk_size; @@ -1906,7 +1906,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { if (mLastTrack == NULL) return ERROR_MALFORMED; - mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); + mLastTrack->meta.setData(kKeyD263, kTypeD263, buffer, chunk_data_size); break; } @@ -2034,12 +2034,12 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { duration = d32; } if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) { - mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); + mFileMetaData.setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); } String8 s; if (convertTimeToDate(creationTime, &s)) { - mFileMetaData->setCString(kKeyDate, s.string()); + mFileMetaData.setCString(kKeyDate, s.string()); } @@ -2084,7 +2084,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } if (duration != 0 && mHeaderTimescale != 0) { - mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); + mFileMetaData.setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale); } break; @@ -2118,7 +2118,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { // for a practical reason as various MPEG4 containers use it. if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { if (mLastTrack != NULL) { - mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); + mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); } } @@ -2165,7 +2165,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { uint32_t type; const void *data; size_t size = 0; - if (!mLastTrack->meta->findData( + if (!mLastTrack->meta.findData( kKeyTextFormatData, &type, &data, &size)) { size = 0; } @@ -2193,7 +2193,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return ERROR_IO; } - mLastTrack->meta->setData( + mLastTrack->meta.setData( kKeyTextFormatData, 0, buffer, size + chunk_size); delete[] buffer; @@ -2206,32 +2206,30 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { { *offset += chunk_size; - if (mFileMetaData != NULL) { - ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64, - chunk_data_size, data_offset); - - if (chunk_data_size < 0 || static_cast(chunk_data_size) >= SIZE_MAX - 1) { - return ERROR_MALFORMED; - } - sp buffer = new ABuffer(chunk_data_size + 1); - if (buffer->data() == NULL) { - ALOGE("b/28471206"); - return NO_MEMORY; - } - if (mDataSource->readAt( - data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { - return ERROR_IO; - } - const int kSkipBytesOfDataBox = 16; - if (chunk_data_size <= kSkipBytesOfDataBox) { - return ERROR_MALFORMED; - } + ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64, + chunk_data_size, data_offset); - mFileMetaData->setData( - kKeyAlbumArt, MetaData::TYPE_NONE, - buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); + if (chunk_data_size < 0 || static_cast(chunk_data_size) >= SIZE_MAX - 1) { + return ERROR_MALFORMED; + } + sp buffer = new ABuffer(chunk_data_size + 1); + if (buffer->data() == NULL) { + ALOGE("b/28471206"); + return NO_MEMORY; + } + if (mDataSource->readAt( + data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { + return ERROR_IO; + } + const int kSkipBytesOfDataBox = 16; + if (chunk_data_size <= kSkipBytesOfDataBox) { + return ERROR_MALFORMED; } + mFileMetaData.setData( + kKeyAlbumArt, MetaData::TYPE_NONE, + buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); + break; } @@ -2462,9 +2460,9 @@ status_t MPEG4Extractor::parseAC3SpecificBox( if (mLastTrack == NULL) { return ERROR_MALFORMED; } - mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); - mLastTrack->meta->setInt32(kKeyChannelCount, channelCount); - mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); + mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); + mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); + mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); return OK; } @@ -2584,8 +2582,8 @@ status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { return ERROR_MALFORMED; int64_t metaDuration; - if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { - mLastTrack->meta->setInt64(kKeyDuration, sidxDuration); + if (!mLastTrack->meta.findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { + mLastTrack->meta.setInt64(kKeyDuration, sidxDuration); } return OK; } @@ -2683,7 +2681,7 @@ status_t MPEG4Extractor::parseQTMetaVal( return ERROR_MALFORMED; } if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) { - mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val); + mFileMetaData.setFloat(kKeyCaptureFramerate, *(float *)&val); } } else if (dataType == 67 && dataSize >= 4) { // BE signed int32 @@ -2692,7 +2690,7 @@ status_t MPEG4Extractor::parseQTMetaVal( return ERROR_MALFORMED; } if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) { - mFileMetaData->setInt32(kKeyTemporalLayerCount, val); + mFileMetaData.setInt32(kKeyTemporalLayerCount, val); } } else { // add more keys if needed @@ -2746,7 +2744,7 @@ status_t MPEG4Extractor::parseTrackHeader( if (mLastTrack == NULL) return ERROR_MALFORMED; - mLastTrack->meta->setInt32(kKeyTrackID, id); + mLastTrack->meta.setInt32(kKeyTrackID, id); size_t matrixOffset = dynSize + 16; int32_t a00 = U32_AT(&buffer[matrixOffset]); @@ -2782,15 +2780,15 @@ status_t MPEG4Extractor::parseTrackHeader( } if (rotationDegrees != 0) { - mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); + mLastTrack->meta.setInt32(kKeyRotation, rotationDegrees); } // Handle presentation display size, which could be different // from the image size indicated by kKeyWidth and kKeyHeight. uint32_t width = U32_AT(&buffer[dynSize + 52]); uint32_t height = U32_AT(&buffer[dynSize + 56]); - mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); - mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); + mLastTrack->meta.setInt32(kKeyDisplayWidth, width >> 16); + mLastTrack->meta.setInt32(kKeyDisplayHeight, height >> 16); return OK; } @@ -2875,7 +2873,7 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { sprintf(tmp, "%d", (int)buffer[size - 1]); - mFileMetaData->setCString(kKeyCompilation, tmp); + mFileMetaData.setCString(kKeyCompilation, tmp); } break; } @@ -2887,7 +2885,7 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); - mFileMetaData->setCString(kKeyCDTrackNumber, tmp); + mFileMetaData.setCString(kKeyCDTrackNumber, tmp); } break; } @@ -2899,7 +2897,7 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); - mFileMetaData->setCString(kKeyDiscNumber, tmp); + mFileMetaData.setCString(kKeyDiscNumber, tmp); } break; } @@ -2943,8 +2941,8 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { return ERROR_MALFORMED; } - mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); - mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); + mLastTrack->meta.setInt32(kKeyEncoderDelay, delay); + mLastTrack->meta.setInt32(kKeyEncoderPadding, padding); } } @@ -2959,9 +2957,9 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { break; } - if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { + if (size >= 8 && metadataKey && !mFileMetaData.hasData(metadataKey)) { if (metadataKey == kKeyAlbumArt) { - mFileMetaData->setData( + mFileMetaData.setData( kKeyAlbumArt, MetaData::TYPE_NONE, buffer + 8, size - 8); } else if (metadataKey == kKeyGenre) { @@ -2978,18 +2976,18 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { char genre[10]; sprintf(genre, "%d", genrecode); - mFileMetaData->setCString(metadataKey, genre); + mFileMetaData.setCString(metadataKey, genre); } else if (flags == 1) { // custom genre string buffer[size] = '\0'; - mFileMetaData->setCString( + mFileMetaData.setCString( metadataKey, (const char *)buffer + 8); } } else { buffer[size] = '\0'; - mFileMetaData->setCString( + mFileMetaData.setCString( metadataKey, (const char *)buffer + 8); } } @@ -3029,11 +3027,11 @@ status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) { primaries, transfer, coeffs, fullRange, aspects); // only store the first color specification - if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) { - mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); - mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer); - mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); - mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange); + if (!mLastTrack->meta.hasData(kKeyColorPrimaries)) { + mLastTrack->meta.setInt32(kKeyColorPrimaries, aspects.mPrimaries); + mLastTrack->meta.setInt32(kKeyTransferFunction, aspects.mTransfer); + mLastTrack->meta.setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); + mLastTrack->meta.setInt32(kKeyColorRange, aspects.mRange); } } @@ -3088,7 +3086,7 @@ status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int dept char tmp[4]; sprintf(tmp, "%u", buffer[size - 1]); - mFileMetaData->setCString(kKeyCDTrackNumber, tmp); + mFileMetaData.setCString(kKeyCDTrackNumber, tmp); } metadataKey = kKeyAlbum; @@ -3109,7 +3107,7 @@ status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int dept if (year < 10000) { sprintf(tmp, "%u", year); - mFileMetaData->setCString(kKeyYear, tmp); + mFileMetaData.setCString(kKeyYear, tmp); } break; } @@ -3154,11 +3152,11 @@ status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int dept if (isUTF8) { buffer[size] = 0; - mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); + mFileMetaData.setCString(metadataKey, (const char *)buffer + 6); } else { // Convert from UTF-16 string to UTF-8 string. String8 tmpUTF8str(framedata, len16); - mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); + mFileMetaData.setCString(metadataKey, tmpUTF8str.string()); } } @@ -3193,7 +3191,7 @@ void MPEG4Extractor::parseID3v2MetaData(off64_t offset) { static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); for (size_t i = 0; i < kNumMapEntries; ++i) { - if (!mFileMetaData->hasData(kMap[i].key)) { + if (!mFileMetaData.hasData(kMap[i].key)) { ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); if (it->done()) { delete it; @@ -3209,7 +3207,7 @@ void MPEG4Extractor::parseID3v2MetaData(off64_t offset) { it->getString(&s); delete it; - mFileMetaData->setCString(kMap[i].key, s); + mFileMetaData.setCString(kMap[i].key, s); } } @@ -3218,13 +3216,13 @@ void MPEG4Extractor::parseID3v2MetaData(off64_t offset) { const void *data = id3.getAlbumArt(&dataSize, &mime); if (data) { - mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); - mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); + mFileMetaData.setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); + mFileMetaData.setCString(kKeyAlbumArtMIME, mime.string()); } } } -MediaSourceBase *MPEG4Extractor::getTrack(size_t index) { +MediaTrack *MPEG4Extractor::getTrack(size_t index) { status_t err; if ((err = readMetaData()) != OK) { return NULL; @@ -3247,7 +3245,7 @@ MediaSourceBase *MPEG4Extractor::getTrack(size_t index) { Trex *trex = NULL; int32_t trackId; - if (track->meta->findInt32(kKeyTrackID, &trackId)) { + if (track->meta.findInt32(kKeyTrackID, &trackId)) { for (size_t i = 0; i < mTrex.size(); i++) { Trex *t = &mTrex.editItemAt(i); if (t->track_ID == (uint32_t) trackId) { @@ -3263,7 +3261,7 @@ MediaSourceBase *MPEG4Extractor::getTrack(size_t index) { ALOGV("getTrack called, pssh: %zu", mPssh.size()); const char *mime; - if (!track->meta->findCString(kKeyMIMEType, &mime)) { + if (!track->meta.findCString(kKeyMIMEType, &mime)) { return NULL; } @@ -3272,7 +3270,7 @@ MediaSourceBase *MPEG4Extractor::getTrack(size_t index) { uint32_t type; const void *data; size_t size; - if (!track->meta->findData(kKeyAVCC, &type, &data, &size)) { + if (!track->meta.findData(kKeyAVCC, &type, &data, &size)) { return NULL; } @@ -3286,7 +3284,7 @@ MediaSourceBase *MPEG4Extractor::getTrack(size_t index) { uint32_t type; const void *data; size_t size; - if (!track->meta->findData(kKeyHVCC, &type, &data, &size)) { + if (!track->meta.findData(kKeyHVCC, &type, &data, &size)) { return NULL; } @@ -3313,25 +3311,25 @@ MediaSourceBase *MPEG4Extractor::getTrack(size_t index) { // static status_t MPEG4Extractor::verifyTrack(Track *track) { const char *mime; - CHECK(track->meta->findCString(kKeyMIMEType, &mime)); + CHECK(track->meta.findCString(kKeyMIMEType, &mime)); uint32_t type; const void *data; size_t size; if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { - if (!track->meta->findData(kKeyAVCC, &type, &data, &size) + if (!track->meta.findData(kKeyAVCC, &type, &data, &size) || type != kTypeAVCC) { return ERROR_MALFORMED; } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { - if (!track->meta->findData(kKeyHVCC, &type, &data, &size) + if (!track->meta.findData(kKeyHVCC, &type, &data, &size) || type != kTypeHVCC) { return ERROR_MALFORMED; } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { - if (!track->meta->findData(kKeyESDS, &type, &data, &size) + if (!track->meta.findData(kKeyESDS, &type, &data, &size) || type != kTypeESDS) { return ERROR_MALFORMED; } @@ -3417,7 +3415,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( if (mLastTrack == NULL) return ERROR_MALFORMED; - mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); + mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); return OK; } @@ -3434,10 +3432,10 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( uint32_t avgBitrate = 0; esds.getBitRate(&maxBitrate, &avgBitrate); if (maxBitrate > 0 && maxBitrate < INT32_MAX) { - mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate); + mLastTrack->meta.setInt32(kKeyMaxBitRate, (int32_t)maxBitrate); } if (avgBitrate > 0 && avgBitrate < INT32_MAX) { - mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate); + mLastTrack->meta.setInt32(kKeyBitRate, (int32_t)avgBitrate); } } @@ -3481,7 +3479,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( return ERROR_MALFORMED; //keep AOT type - mLastTrack->meta->setInt32(kKeyAACAOT, objectType); + mLastTrack->meta.setInt32(kKeyAACAOT, objectType); uint32_t freqIndex = br.getBits(4); @@ -3519,7 +3517,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( extSampleRate = kSamplingRate[extFreqIndex]; } //TODO: save the extension sampling rate value in meta data => - // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); + // mLastTrack->meta.setInt32(kKeyExtSampleRate, extSampleRate); } switch (numChannels) { @@ -3672,24 +3670,24 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( return ERROR_MALFORMED; int32_t prevSampleRate; - CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); + CHECK(mLastTrack->meta.findInt32(kKeySampleRate, &prevSampleRate)); if (prevSampleRate != sampleRate) { ALOGV("mpeg4 audio sample rate different from previous setting. " "was: %d, now: %d", prevSampleRate, sampleRate); } - mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); + mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); int32_t prevChannelCount; - CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); + CHECK(mLastTrack->meta.findInt32(kKeyChannelCount, &prevChannelCount)); if (prevChannelCount != numChannels) { ALOGV("mpeg4 audio channel count different from previous setting. " "was: %d, now: %d", prevChannelCount, numChannels); } - mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); + mLastTrack->meta.setInt32(kKeyChannelCount, numChannels); return OK; } @@ -3697,7 +3695,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( //////////////////////////////////////////////////////////////////////////////// MPEG4Source::MPEG4Source( - const sp &format, + MetaDataBase &format, DataSourceBase *dataSource, int32_t timeScale, const sp &sampleTable, @@ -3734,20 +3732,20 @@ MPEG4Source::MPEG4Source( memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo)); - mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); + mFormat.findInt32(kKeyCryptoMode, &mCryptoMode); mDefaultIVSize = 0; - mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); + mFormat.findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); uint32_t keytype; const void *key; size_t keysize; - if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { + if (mFormat.findData(kKeyCryptoKey, &keytype, &key, &keysize)) { CHECK(keysize <= 16); memset(mCryptoKey, 0, 16); memcpy(mCryptoKey, key, keysize); } const char *mime; - bool success = mFormat->findCString(kKeyMIMEType, &mime); + bool success = mFormat.findCString(kKeyMIMEType, &mime); CHECK(success); mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); @@ -3758,7 +3756,7 @@ MPEG4Source::MPEG4Source( uint32_t type; const void *data; size_t size; - CHECK(format->findData(kKeyAVCC, &type, &data, &size)); + CHECK(format.findData(kKeyAVCC, &type, &data, &size)); const uint8_t *ptr = (const uint8_t *)data; @@ -3771,7 +3769,7 @@ MPEG4Source::MPEG4Source( uint32_t type; const void *data; size_t size; - CHECK(format->findData(kKeyHVCC, &type, &data, &size)); + CHECK(format.findData(kKeyHVCC, &type, &data, &size)); const uint8_t *ptr = (const uint8_t *)data; @@ -3781,7 +3779,7 @@ MPEG4Source::MPEG4Source( mNALLengthSize = 1 + (ptr[14 + 7] & 3); } - CHECK(format->findInt32(kKeyTrackID, &mTrackId)); + CHECK(format.findInt32(kKeyTrackID, &mTrackId)); } @@ -3801,7 +3799,7 @@ MPEG4Source::~MPEG4Source() { free(mCurrentSampleInfoOffsets); } -status_t MPEG4Source::start(MetaData *params) { +status_t MPEG4Source::start(MetaDataBase *params) { Mutex::Autolock autoLock(mLock); CHECK(!mStarted); @@ -3815,7 +3813,7 @@ status_t MPEG4Source::start(MetaData *params) { } int32_t tmp; - CHECK(mFormat->findInt32(kKeyMaxInputSize, &tmp)); + CHECK(mFormat.findInt32(kKeyMaxInputSize, &tmp)); size_t max_size = tmp; // A somewhat arbitrary limit that should be sufficient for 8k video frames @@ -4142,7 +4140,7 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( drmoffset += mCurrentMoofOffset; int ivlength; - CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); + CHECK(mFormat.findInt32(kKeyCryptoDefaultIVSize, &ivlength)); // only 0, 8 and 16 byte initialization vectors are supported if (ivlength != 0 && ivlength != 8 && ivlength != 16) { @@ -4459,10 +4457,10 @@ status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { return OK; } -sp MPEG4Source::getFormat() { +status_t MPEG4Source::getFormat(MetaDataBase &meta) { Mutex::Autolock autoLock(mLock); - - return mFormat; + meta = mFormat; + return OK; } size_t MPEG4Source::parseNALSize(const uint8_t *data) const { @@ -4510,7 +4508,7 @@ status_t MPEG4Source::read( CHECK(mSampleTable == NULL); CHECK(mItemTable != NULL); int32_t imageIndex; - if (!mFormat->findInt32(kKeyTrackID, &imageIndex)) { + if (!mFormat.findInt32(kKeyTrackID, &imageIndex)) { return ERROR_MALFORMED; } @@ -4664,19 +4662,19 @@ status_t MPEG4Source::read( CHECK(mBuffer != NULL); mBuffer->set_range(0, size); - mBuffer->meta_data()->clear(); - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().clear(); + mBuffer->meta_data().setInt64( kKeyTime, ((int64_t)cts * 1000000) / mTimescale); - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); if (targetSampleTimeUs >= 0) { - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyTargetTime, targetSampleTimeUs); } if (isSyncSample) { - mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1); } ++mCurrentSampleIndex; @@ -4732,7 +4730,7 @@ status_t MPEG4Source::read( // the start code (0x00 00 00 01). ssize_t num_bytes_read = 0; int32_t drm = 0; - bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); + bool usesDRM = (mFormat.findInt32(kKeyIsDRM, &drm) && drm != 0); if (usesDRM) { num_bytes_read = mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); @@ -4799,25 +4797,25 @@ status_t MPEG4Source::read( mBuffer->set_range(0, dstOffset); } - mBuffer->meta_data()->clear(); - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().clear(); + mBuffer->meta_data().setInt64( kKeyTime, ((int64_t)cts * 1000000) / mTimescale); - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); if (targetSampleTimeUs >= 0) { - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyTargetTime, targetSampleTimeUs); } if (mIsAVC) { uint32_t layerId = FindAVCLayerId( (const uint8_t *)mBuffer->data(), mBuffer->range_length()); - mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId); + mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId); } if (isSyncSample) { - mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1); } ++mCurrentSampleIndex; @@ -4945,18 +4943,18 @@ status_t MPEG4Source::fragmentedRead( } const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; - const sp bufmeta = mBuffer->meta_data(); - bufmeta->clear(); + MetaDataBase &bufmeta = mBuffer->meta_data(); + bufmeta.clear(); if (smpl->encryptedsizes.size()) { // store clear/encrypted lengths in metadata - bufmeta->setData(kKeyPlainSizes, 0, + bufmeta.setData(kKeyPlainSizes, 0, smpl->clearsizes.array(), smpl->clearsizes.size() * 4); - bufmeta->setData(kKeyEncryptedSizes, 0, + bufmeta.setData(kKeyEncryptedSizes, 0, smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); - bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? - bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); - bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); - bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); + bufmeta.setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? + bufmeta.setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); + bufmeta.setInt32(kKeyCryptoMode, mCryptoMode); + bufmeta.setData(kKeyCryptoKey, 0, mCryptoKey, 16); } if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { @@ -4982,24 +4980,24 @@ status_t MPEG4Source::fragmentedRead( CHECK(mBuffer != NULL); mBuffer->set_range(0, size); - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyTime, ((int64_t)cts * 1000000) / mTimescale); - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); if (targetSampleTimeUs >= 0) { - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyTargetTime, targetSampleTimeUs); } if (mIsAVC) { uint32_t layerId = FindAVCLayerId( (const uint8_t *)mBuffer->data(), mBuffer->range_length()); - mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId); + mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId); } if (isSyncSample) { - mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1); } ++mCurrentSampleIndex; @@ -5057,7 +5055,7 @@ status_t MPEG4Source::fragmentedRead( // the start code (0x00 00 00 01). ssize_t num_bytes_read = 0; int32_t drm = 0; - bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); + bool usesDRM = (mFormat.findInt32(kKeyIsDRM, &drm) && drm != 0); void *data = NULL; bool isMalFormed = false; if (usesDRM) { @@ -5068,8 +5066,7 @@ status_t MPEG4Source::fragmentedRead( } } else { int32_t max_size; - if (mFormat == NULL - || !mFormat->findInt32(kKeyMaxInputSize, &max_size) + if (!mFormat.findInt32(kKeyMaxInputSize, &max_size) || !isInRange((size_t)0u, (size_t)max_size, size)) { isMalFormed = true; } else { @@ -5149,18 +5146,18 @@ status_t MPEG4Source::fragmentedRead( mBuffer->set_range(0, dstOffset); } - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyTime, ((int64_t)cts * 1000000) / mTimescale); - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); if (targetSampleTimeUs >= 0) { - mBuffer->meta_data()->setInt64( + mBuffer->meta_data().setInt64( kKeyTargetTime, targetSampleTimeUs); } if (isSyncSample) { - mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1); } ++mCurrentSampleIndex; @@ -5176,8 +5173,7 @@ MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( const char *mimePrefix) { for (Track *track = mFirstTrack; track != NULL; track = track->next) { const char *mime; - if (track->meta != NULL - && track->meta->findCString(kKeyMIMEType, &mime) + if (track->meta.findCString(kKeyMIMEType, &mime) && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { return track; } diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h index 5c8634581c82d9b8abf28665362fa26cb8d59a98..9a9f0d149ff093a28e29cbe4b6953b9700fccea2 100644 --- a/media/extractors/mp4/MPEG4Extractor.h +++ b/media/extractors/mp4/MPEG4Extractor.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -56,10 +57,10 @@ public: explicit MPEG4Extractor(DataSourceBase *source, const char *mime = NULL); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual uint32_t flags() const; virtual const char * name() { return "MPEG4Extractor"; } @@ -75,7 +76,7 @@ private: }; struct Track { Track *next; - sp meta; + MetaDataBase meta; uint32_t timescale; sp sampleTable; bool includes_expensive_metadata; @@ -105,7 +106,7 @@ private: Track *mFirstTrack, *mLastTrack; - sp mFileMetaData; + MetaDataBase mFileMetaData; Vector mPath; String8 mLastCommentMean; diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp index c2de6e7c0dcf9fa4826efe05a549ca00ebae5e0c..6980b82185b5b203a3554a70a3ba6ca969d5f48e 100644 --- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp +++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp @@ -24,7 +24,7 @@ #include "mpeg2ts/ESQueue.h" #include -#include +#include #include #include #include @@ -40,13 +40,13 @@ namespace android { -struct MPEG2PSExtractor::Track : public MediaSourceBase, public RefBase { +struct MPEG2PSExtractor::Track : public MediaTrack, public RefBase { Track(MPEG2PSExtractor *extractor, unsigned stream_id, unsigned stream_type); - virtual status_t start(MetaData *params); + virtual status_t start(MetaDataBase *params); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options); @@ -72,12 +72,12 @@ private: DISALLOW_EVIL_CONSTRUCTORS(Track); }; -struct MPEG2PSExtractor::WrappedTrack : public MediaSourceBase { +struct MPEG2PSExtractor::WrappedTrack : public MediaTrack { WrappedTrack(MPEG2PSExtractor *extractor, const sp &track); - virtual status_t start(MetaData *params); + virtual status_t start(MetaDataBase *params); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options); @@ -108,9 +108,10 @@ MPEG2PSExtractor::MPEG2PSExtractor(DataSourceBase *source) } // Remove all tracks that were unable to determine their format. + MetaDataBase meta; for (size_t i = mTracks.size(); i > 0;) { i--; - if (mTracks.valueAt(i)->getFormat() == NULL) { + if (mTracks.valueAt(i)->getFormat(meta) != OK) { mTracks.removeItemsAt(i); } } @@ -125,7 +126,7 @@ size_t MPEG2PSExtractor::countTracks() { return mTracks.size(); } -MediaSourceBase *MPEG2PSExtractor::getTrack(size_t index) { +MediaTrack *MPEG2PSExtractor::getTrack(size_t index) { if (index >= mTracks.size()) { return NULL; } @@ -133,20 +134,20 @@ MediaSourceBase *MPEG2PSExtractor::getTrack(size_t index) { return new WrappedTrack(this, mTracks.valueAt(index)); } -sp MPEG2PSExtractor::getTrackMetaData( +status_t MPEG2PSExtractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t /* flags */) { if (index >= mTracks.size()) { - return NULL; + return UNKNOWN_ERROR; } - return mTracks.valueAt(index)->getFormat(); + return mTracks.valueAt(index)->getFormat(meta); } -sp MPEG2PSExtractor::getMetaData() { - sp meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2PS); +status_t MPEG2PSExtractor::getMetaData(MetaDataBase &meta) { + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2PS); - return meta; + return OK; } uint32_t MPEG2PSExtractor::flags() const { @@ -634,12 +635,12 @@ MPEG2PSExtractor::Track::~Track() { mQueue = NULL; } -status_t MPEG2PSExtractor::Track::start(MetaData *params) { +status_t MPEG2PSExtractor::Track::start(MetaDataBase *) { if (mSource == NULL) { return NO_INIT; } - return mSource->start(params); + return mSource->start(NULL); // AnotherPacketSource::start doesn't use its argument } status_t MPEG2PSExtractor::Track::stop() { @@ -650,12 +651,14 @@ status_t MPEG2PSExtractor::Track::stop() { return mSource->stop(); } -sp MPEG2PSExtractor::Track::getFormat() { +status_t MPEG2PSExtractor::Track::getFormat(MetaDataBase &meta) { if (mSource == NULL) { - return NULL; + return NO_INIT; } - return mSource->getFormat(); + sp sourceMeta = mSource->getFormat(); + meta = *sourceMeta; + return OK; } status_t MPEG2PSExtractor::Track::read( @@ -731,7 +734,7 @@ MPEG2PSExtractor::WrappedTrack::WrappedTrack( MPEG2PSExtractor::WrappedTrack::~WrappedTrack() { } -status_t MPEG2PSExtractor::WrappedTrack::start(MetaData *params) { +status_t MPEG2PSExtractor::WrappedTrack::start(MetaDataBase *params) { return mTrack->start(params); } @@ -739,8 +742,8 @@ status_t MPEG2PSExtractor::WrappedTrack::stop() { return mTrack->stop(); } -sp MPEG2PSExtractor::WrappedTrack::getFormat() { - return mTrack->getFormat(); +status_t MPEG2PSExtractor::WrappedTrack::getFormat(MetaDataBase &meta) { + return mTrack->getFormat(meta); } status_t MPEG2PSExtractor::WrappedTrack::read( diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.h b/media/extractors/mpeg2/MPEG2PSExtractor.h index 2541f4dc4fa5a203d1925c8f3947242febd6c5db..8b9dad9c06ef96913eeb12519bd15dfaf4c7e4ed 100644 --- a/media/extractors/mpeg2/MPEG2PSExtractor.h +++ b/media/extractors/mpeg2/MPEG2PSExtractor.h @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -34,10 +35,10 @@ struct MPEG2PSExtractor : public MediaExtractor { explicit MPEG2PSExtractor(DataSourceBase *source); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual uint32_t flags() const; virtual const char * name() { return "MPEG2PSExtractor"; } diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp index 7887a7cdbae2e0861047adc3383a7297f9b0433b..c83f7ce65c6c72635418201cbdc8615e46432617 100644 --- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp +++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -49,16 +49,16 @@ static const size_t kTSPacketSize = 188; static const int kMaxDurationReadSize = 250000LL; static const int kMaxDurationRetry = 6; -struct MPEG2TSSource : public MediaSourceBase { +struct MPEG2TSSource : public MediaTrack { MPEG2TSSource( MPEG2TSExtractor *extractor, const sp &impl, bool doesSeek); virtual ~MPEG2TSSource(); - virtual status_t start(MetaData *params = NULL); + virtual status_t start(MetaDataBase *params = NULL); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); @@ -86,16 +86,18 @@ MPEG2TSSource::MPEG2TSSource( MPEG2TSSource::~MPEG2TSSource() { } -status_t MPEG2TSSource::start(MetaData *params) { - return mImpl->start(params); +status_t MPEG2TSSource::start(MetaDataBase *) { + return mImpl->start(NULL); // AnotherPacketSource::start() doesn't use its argument } status_t MPEG2TSSource::stop() { return mImpl->stop(); } -sp MPEG2TSSource::getFormat() { - return mImpl->getFormat(); +status_t MPEG2TSSource::getFormat(MetaDataBase &meta) { + sp implMeta = mImpl->getFormat(); + meta = *implMeta; + return OK; } status_t MPEG2TSSource::read( @@ -133,7 +135,7 @@ size_t MPEG2TSExtractor::countTracks() { return mSourceImpls.size(); } -MediaSourceBase *MPEG2TSExtractor::getTrack(size_t index) { +MediaTrack *MPEG2TSExtractor::getTrack(size_t index) { if (index >= mSourceImpls.size()) { return NULL; } @@ -144,23 +146,28 @@ MediaSourceBase *MPEG2TSExtractor::getTrack(size_t index) { (mSeekSyncPoints == &mSyncPoints.editItemAt(index))); } -sp MPEG2TSExtractor::getTrackMetaData( +status_t MPEG2TSExtractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t /* flags */) { - return index < mSourceImpls.size() + sp implMeta = index < mSourceImpls.size() ? mSourceImpls.editItemAt(index)->getFormat() : NULL; + if (implMeta == NULL) { + return UNKNOWN_ERROR; + } + meta = *implMeta; + return OK; } -sp MPEG2TSExtractor::getMetaData() { - sp meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); +status_t MPEG2TSExtractor::getMetaData(MetaDataBase &meta) { + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); - return meta; + return OK; } //static -bool MPEG2TSExtractor::isScrambledFormat(const sp &format) { +bool MPEG2TSExtractor::isScrambledFormat(MetaDataBase &format) { const char *mime; - return format->findCString(kKeyMIMEType, &mime) + return format.findCString(kKeyMIMEType, &mime) && (!strcasecmp(MEDIA_MIMETYPE_VIDEO_SCRAMBLED, mime) || !strcasecmp(MEDIA_MIMETYPE_AUDIO_SCRAMBLED, mime)); } @@ -213,7 +220,7 @@ void MPEG2TSExtractor::init() { if (format != NULL) { haveVideo = true; addSource(impl); - if (!isScrambledFormat(format)) { + if (!isScrambledFormat(*(format.get()))) { mSyncPoints.push(); mSeekSyncPoints = &mSyncPoints.editTop(); } @@ -229,7 +236,7 @@ void MPEG2TSExtractor::init() { if (format != NULL) { haveAudio = true; addSource(impl); - if (!isScrambledFormat(format)) { + if (!isScrambledFormat(*(format.get()))) { mSyncPoints.push(); if (!haveVideo) { mSeekSyncPoints = &mSyncPoints.editTop(); @@ -470,7 +477,7 @@ uint32_t MPEG2TSExtractor::flags() const { } status_t MPEG2TSExtractor::seek(int64_t seekTimeUs, - const MediaSourceBase::ReadOptions::SeekMode &seekMode) { + const MediaTrack::ReadOptions::SeekMode &seekMode) { if (mSeekSyncPoints == NULL || mSeekSyncPoints->isEmpty()) { ALOGW("No sync point to seek to."); // ... and therefore we have nothing useful to do here. @@ -491,18 +498,18 @@ status_t MPEG2TSExtractor::seek(int64_t seekTimeUs, } switch (seekMode) { - case MediaSourceBase::ReadOptions::SEEK_NEXT_SYNC: + case MediaTrack::ReadOptions::SEEK_NEXT_SYNC: if (index == mSeekSyncPoints->size()) { ALOGW("Next sync not found; starting from the latest sync."); --index; } break; - case MediaSourceBase::ReadOptions::SEEK_CLOSEST_SYNC: - case MediaSourceBase::ReadOptions::SEEK_CLOSEST: + case MediaTrack::ReadOptions::SEEK_CLOSEST_SYNC: + case MediaTrack::ReadOptions::SEEK_CLOSEST: ALOGW("seekMode not supported: %d; falling back to PREVIOUS_SYNC", seekMode); // fall-through - case MediaSourceBase::ReadOptions::SEEK_PREVIOUS_SYNC: + case MediaTrack::ReadOptions::SEEK_PREVIOUS_SYNC: if (index == 0) { ALOGW("Previous sync not found; starting from the earliest " "sync."); diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h index df07fac6f0405dadc06f04e752aeebb9d172fbe6..cbdd3cb8479f215bd1536f3c6da31ccbdd332307 100644 --- a/media/extractors/mpeg2/MPEG2TSExtractor.h +++ b/media/extractors/mpeg2/MPEG2TSExtractor.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,7 +21,8 @@ #include #include -#include +#include +#include #include #include #include @@ -40,10 +42,10 @@ struct MPEG2TSExtractor : public MediaExtractor { explicit MPEG2TSExtractor(DataSourceBase *source); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) override; @@ -72,7 +74,7 @@ private: off64_t mOffset; - static bool isScrambledFormat(const sp &format); + static bool isScrambledFormat(MetaDataBase &format); void init(); void addSource(const sp &impl); diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp index 6d7576f717c994657cac454a80690ffc4bafccf4..4d49013ad0997f399f44ab2b50857b78998a1a35 100644 --- a/media/extractors/ogg/OggExtractor.cpp +++ b/media/extractors/ogg/OggExtractor.cpp @@ -22,7 +22,8 @@ #include #include -#include +#include +#include #include #include #include @@ -31,7 +32,7 @@ #include #include #include -#include +#include #include extern "C" { @@ -45,12 +46,12 @@ extern "C" { namespace android { -struct OggSource : public MediaSourceBase { +struct OggSource : public MediaTrack { explicit OggSource(OggExtractor *extractor); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &); - virtual status_t start(MetaData *params = NULL); + virtual status_t start(MetaDataBase *params = NULL); virtual status_t stop(); virtual status_t read( @@ -75,7 +76,7 @@ struct MyOggExtractor { int64_t seekPreRollUs); virtual ~MyOggExtractor(); - sp getFormat() const; + status_t getFormat(MetaDataBase &) const; // Returns an approximate bitrate in bits per second. virtual uint64_t approxBitrate() const = 0; @@ -86,7 +87,10 @@ struct MyOggExtractor { status_t init(); - sp getFileMetaData() { return mFileMeta; } + status_t getFileMetaData(MetaDataBase &meta) { + meta = mFileMeta; + return OK; + } protected: struct Page { @@ -124,8 +128,8 @@ protected: vorbis_info mVi; vorbis_comment mVc; - sp mMeta; - sp mFileMeta; + MetaDataBase mMeta; + MetaDataBase mFileMeta; Vector mTableOfContents; @@ -219,9 +223,6 @@ private: int64_t mStartGranulePosition; }; -static void extractAlbumArt( - const sp &fileMeta, const void *data, size_t size); - //////////////////////////////////////////////////////////////////////////////// OggSource::OggSource(OggExtractor *extractor) @@ -235,11 +236,11 @@ OggSource::~OggSource() { } } -sp OggSource::getFormat() { - return mExtractor->mImpl->getFormat(); +status_t OggSource::getFormat(MetaDataBase &meta) { + return mExtractor->mImpl->getFormat(meta); } -status_t OggSource::start(MetaData * /* params */) { +status_t OggSource::start(MetaDataBase * /* params */) { if (mStarted) { return INVALID_OPERATION; } @@ -277,14 +278,14 @@ status_t OggSource::read( #if 0 int64_t timeUs; - if (packet->meta_data()->findInt64(kKeyTime, &timeUs)) { + if (packet->meta_data().findInt64(kKeyTime, &timeUs)) { ALOGI("found time = %lld us", timeUs); } else { ALOGI("NO time"); } #endif - packet->meta_data()->setInt32(kKeyIsSyncFrame, 1); + packet->meta_data().setInt32(kKeyIsSyncFrame, 1); *out = packet; @@ -321,8 +322,9 @@ MyOggExtractor::~MyOggExtractor() { vorbis_info_clear(&mVi); } -sp MyOggExtractor::getFormat() const { - return mMeta; +status_t MyOggExtractor::getFormat(MetaDataBase &meta) const { + meta = mMeta; + return OK; } status_t MyOggExtractor::findNextPage( @@ -606,17 +608,17 @@ 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)) { + if ((*out)->meta_data().findInt32(kKeyValidSamples, ¤tPageSamples)) { // first packet in page if (mOffset == mFirstDataOffset) { currentPageSamples -= mStartGranulePosition; - (*out)->meta_data()->setInt32(kKeyValidSamples, currentPageSamples); + (*out)->meta_data().setInt32(kKeyValidSamples, currentPageSamples); } mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples; } int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition); - (*out)->meta_data()->setInt64(kKeyTime, timeUs); + (*out)->meta_data().setInt64(kKeyTime, timeUs); uint32_t frames = getNumSamplesInPacket(*out); mCurGranulePosition += frames; @@ -745,7 +747,7 @@ status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisT // We've just read the entire packet. if (mFirstPacketInPage) { - buffer->meta_data()->setInt32( + buffer->meta_data().setInt32( kKeyValidSamples, mCurrentPageSamples); mFirstPacketInPage = false; } @@ -767,7 +769,7 @@ status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisT mCurrentPage.mPrevPacketPos += actualBlockSize / 2; mCurrentPage.mPrevPacketSize = curBlockSize; } - buffer->meta_data()->setInt64(kKeyTime, timeUs); + buffer->meta_data().setInt64(kKeyTime, timeUs); } *out = buffer; @@ -813,10 +815,10 @@ status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisT // is already complete. if (timeUs >= 0) { - buffer->meta_data()->setInt64(kKeyTime, timeUs); + buffer->meta_data().setInt64(kKeyTime, timeUs); } - buffer->meta_data()->setInt32( + buffer->meta_data().setInt32( kKeyValidSamples, mCurrentPageSamples); mFirstPacketInPage = false; @@ -829,8 +831,7 @@ status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisT } status_t MyOggExtractor::init() { - mMeta = new MetaData; - mMeta->setCString(kKeyMIMEType, mMimeType); + mMeta.setCString(kKeyMIMEType, mMimeType); status_t err; MediaBufferBase *packet; @@ -863,7 +864,7 @@ status_t MyOggExtractor::init() { int64_t durationUs = getTimeUsOfGranule(lastGranulePosition); - mMeta->setInt64(kKeyDuration, durationUs); + mMeta.setInt64(kKeyDuration, durationUs); buildTableOfContents(); } @@ -979,25 +980,35 @@ status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) { mChannelCount = data[9]; mCodecDelay = U16LE_AT(&data[10]); - mMeta->setData(kKeyOpusHeader, 0, data, size); - mMeta->setInt32(kKeySampleRate, kOpusSampleRate); - mMeta->setInt32(kKeyChannelCount, mChannelCount); - mMeta->setInt64(kKeyOpusSeekPreRoll /* ns */, kOpusSeekPreRollUs * 1000 /* = 80 ms*/); - mMeta->setInt64(kKeyOpusCodecDelay /* ns */, + mMeta.setData(kKeyOpusHeader, 0, data, size); + mMeta.setInt32(kKeySampleRate, kOpusSampleRate); + mMeta.setInt32(kKeyChannelCount, mChannelCount); + mMeta.setInt64(kKeyOpusSeekPreRoll /* ns */, kOpusSeekPreRollUs * 1000 /* = 80 ms*/); + mMeta.setInt64(kKeyOpusCodecDelay /* ns */, mCodecDelay /* sample/s */ * 1000000000ll / kOpusSampleRate); return OK; } +struct TmpData { + uint8_t *data; + TmpData(size_t size) { + data = (uint8_t*) malloc(size); + } + ~TmpData() { + free(data); + } +}; + status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) { // add artificial framing bit so we can reuse _vorbis_unpack_comment int32_t commentSize = buffer->range_length() + 1; - sp aBuf = new ABuffer(commentSize); - if (aBuf->capacity() <= buffer->range_length()) { + TmpData commentDataHolder(commentSize); + uint8_t *commentData = commentDataHolder.data; + if (commentData == nullptr) { return ERROR_MALFORMED; } - uint8_t* commentData = aBuf->data(); memcpy(commentData, (uint8_t *)buffer->data() + buffer->range_offset(), buffer->range_length()); @@ -1120,10 +1131,10 @@ status_t MyVorbisExtractor::verifyHeader( return ERROR_MALFORMED; } - mMeta->setData(kKeyVorbisInfo, 0, data, size); - mMeta->setInt32(kKeySampleRate, mVi.rate); - mMeta->setInt32(kKeyChannelCount, mVi.channels); - mMeta->setInt32(kKeyBitRate, mVi.bitrate_nominal); + mMeta.setData(kKeyVorbisInfo, 0, data, size); + mMeta.setInt32(kKeySampleRate, mVi.rate); + mMeta.setInt32(kKeyChannelCount, mVi.channels); + mMeta.setInt32(kKeyBitRate, mVi.bitrate_nominal); ALOGV("lower-bitrate = %ld", mVi.bitrate_lower); ALOGV("upper-bitrate = %ld", mVi.bitrate_upper); @@ -1138,7 +1149,7 @@ status_t MyVorbisExtractor::verifyHeader( if (mSource->getSize(&size) == OK) { uint64_t bps = approxBitrate(); if (bps != 0) { - mMeta->setInt64(kKeyDuration, size * 8000000ll / bps); + mMeta.setInt64(kKeyDuration, size * 8000000ll / bps); } } break; @@ -1160,7 +1171,7 @@ status_t MyVorbisExtractor::verifyHeader( return ERROR_MALFORMED; } - mMeta->setData(kKeyVorbisBooks, 0, data, size); + mMeta.setData(kKeyVorbisBooks, 0, data, size); break; } } @@ -1176,138 +1187,14 @@ uint64_t MyVorbisExtractor::approxBitrate() const { return (mVi.bitrate_lower + mVi.bitrate_upper) / 2; } -// also exists in FLACExtractor, candidate for moving to utility/support library? -static void parseVorbisComment( - const sp &fileMeta, const char *comment, size_t commentLength) -{ - struct { - const char *const mTag; - uint32_t mKey; - } kMap[] = { - { "TITLE", kKeyTitle }, - { "ARTIST", kKeyArtist }, - { "ALBUMARTIST", kKeyAlbumArtist }, - { "ALBUM ARTIST", kKeyAlbumArtist }, - { "COMPILATION", kKeyCompilation }, - { "ALBUM", kKeyAlbum }, - { "COMPOSER", kKeyComposer }, - { "GENRE", kKeyGenre }, - { "AUTHOR", kKeyAuthor }, - { "TRACKNUMBER", kKeyCDTrackNumber }, - { "DISCNUMBER", kKeyDiscNumber }, - { "DATE", kKeyDate }, - { "YEAR", kKeyYear }, - { "LYRICIST", kKeyWriter }, - { "METADATA_BLOCK_PICTURE", kKeyAlbumArt }, - { "ANDROID_LOOP", kKeyAutoLoop }, - }; - - for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) { - size_t tagLen = strlen(kMap[j].mTag); - if (!strncasecmp(kMap[j].mTag, comment, tagLen) - && comment[tagLen] == '=') { - if (kMap[j].mKey == kKeyAlbumArt) { - extractAlbumArt( - fileMeta, - &comment[tagLen + 1], - commentLength - tagLen - 1); - } else if (kMap[j].mKey == kKeyAutoLoop) { - if (!strcasecmp(&comment[tagLen + 1], "true")) { - fileMeta->setInt32(kKeyAutoLoop, true); - } - } else { - fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]); - } - } - } - -} - -// also exists in FLACExtractor, candidate for moving to utility/support library? -static void extractAlbumArt( - const sp &fileMeta, const void *data, size_t size) { - ALOGV("extractAlbumArt from '%s'", (const char *)data); - - sp flacBuffer = decodeBase64(AString((const char *)data, size)); - if (flacBuffer == NULL) { - ALOGE("malformed base64 encoded data."); - return; - } - - size_t flacSize = flacBuffer->size(); - uint8_t *flac = flacBuffer->data(); - ALOGV("got flac of size %zu", flacSize); - - uint32_t picType; - uint32_t typeLen; - uint32_t descLen; - uint32_t dataLen; - char type[128]; - - if (flacSize < 8) { - return; - } - - picType = U32_AT(flac); - - if (picType != 3) { - // This is not a front cover. - return; - } - - typeLen = U32_AT(&flac[4]); - if (typeLen > sizeof(type) - 1) { - return; - } - - // we've already checked above that flacSize >= 8 - if (flacSize - 8 < typeLen) { - return; - } - - memcpy(type, &flac[8], typeLen); - type[typeLen] = '\0'; - - ALOGV("picType = %d, type = '%s'", picType, type); - - if (!strcmp(type, "-->")) { - // This is not inline cover art, but an external url instead. - return; - } - - if (flacSize < 32 || flacSize - 32 < typeLen) { - return; - } - - descLen = U32_AT(&flac[8 + typeLen]); - if (flacSize - 32 - typeLen < descLen) { - return; - } - - dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]); - - // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0 - if (flacSize - 32 - typeLen - descLen < dataLen) { - return; - } - - ALOGV("got image data, %zu trailing bytes", - flacSize - 32 - typeLen - descLen - dataLen); - - fileMeta->setData( - kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen); - - fileMeta->setCString(kKeyAlbumArtMIME, type); -} void MyOggExtractor::parseFileMetaData() { - mFileMeta = new MetaData; - mFileMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG); + mFileMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG); for (int i = 0; i < mVc.comments; ++i) { const char *comment = mVc.user_comments[i]; size_t commentLength = mVc.comment_lengths[i]; - parseVorbisComment(mFileMeta, comment, commentLength); + parseVorbisComment(&mFileMeta, comment, commentLength); //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]); } } @@ -1348,7 +1235,7 @@ size_t OggExtractor::countTracks() { return mInitCheck != OK ? 0 : 1; } -MediaSourceBase *OggExtractor::getTrack(size_t index) { +MediaTrack *OggExtractor::getTrack(size_t index) { if (index >= 1) { return NULL; } @@ -1356,17 +1243,18 @@ MediaSourceBase *OggExtractor::getTrack(size_t index) { return new OggSource(this); } -sp OggExtractor::getTrackMetaData( +status_t OggExtractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t /* flags */) { if (index >= 1) { - return NULL; + return UNKNOWN_ERROR; } - return mImpl->getFormat(); + return mImpl->getFormat(meta); } -sp OggExtractor::getMetaData() { - return mImpl->getFileMetaData(); +status_t OggExtractor::getMetaData(MetaDataBase &meta) { + return mImpl->getFileMetaData(meta); } static MediaExtractor* CreateExtractor( diff --git a/media/extractors/ogg/OggExtractor.h b/media/extractors/ogg/OggExtractor.h index c9c37eb939a1e33f7710cd37b9cff8138dcb4ea0..9fe2944de7f5694f1ca355fd9c96e9c0bf464e71 100644 --- a/media/extractors/ogg/OggExtractor.h +++ b/media/extractors/ogg/OggExtractor.h @@ -34,10 +34,10 @@ struct OggExtractor : public MediaExtractor { explicit OggExtractor(DataSourceBase *source); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual const char * name() { return "OggExtractor"; } protected: @@ -55,10 +55,6 @@ private: OggExtractor &operator=(const OggExtractor &); }; -bool SniffOgg( - DataSourceBase *source, String8 *mimeType, float *confidence, - sp *); - } // namespace android #endif // OGG_EXTRACTOR_H_ diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp index 65c71ef097e9fe447aef4b38c10a7d1528a516eb..17836bb71eabb7e8e84c21259116664397525a3a 100644 --- a/media/extractors/wav/Android.bp +++ b/media/extractors/wav/Android.bp @@ -10,7 +10,6 @@ cc_library_shared { "liblog", "libmediaextractor", "libstagefright_foundation", - "libutils", ], static_libs: [ diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp index a18cee58e1d7685bfed9d974694637a7ff66ba36..f5a1b0166912b4b603928923f4ffdf6768ae8539 100644 --- a/media/extractors/wav/WAVExtractor.cpp +++ b/media/extractors/wav/WAVExtractor.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -55,17 +55,17 @@ static uint16_t U16_LE_AT(const uint8_t *ptr) { return ptr[1] << 8 | ptr[0]; } -struct WAVSource : public MediaSourceBase { +struct WAVSource : public MediaTrack { WAVSource( DataSourceBase *dataSource, - const sp &meta, + MetaDataBase &meta, uint16_t waveFormat, int32_t bitsPerSample, off64_t offset, size_t size); - virtual status_t start(MetaData *params = NULL); + virtual status_t start(MetaDataBase *params = NULL); virtual status_t stop(); - virtual sp getFormat(); + virtual status_t getFormat(MetaDataBase &meta); virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL); @@ -79,7 +79,7 @@ private: static const size_t kMaxFrameSize; DataSourceBase *mDataSource; - sp mMeta; + MetaDataBase &mMeta; uint16_t mWaveFormat; int32_t mSampleRate; int32_t mNumChannels; @@ -104,23 +104,20 @@ WAVExtractor::WAVExtractor(DataSourceBase *source) WAVExtractor::~WAVExtractor() { } -sp WAVExtractor::getMetaData() { - sp meta = new MetaData; - - if (mInitCheck != OK) { - return meta; +status_t WAVExtractor::getMetaData(MetaDataBase &meta) { + meta.clear(); + if (mInitCheck == OK) { + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV); } - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV); - - return meta; + return OK; } size_t WAVExtractor::countTracks() { return mInitCheck == OK ? 1 : 0; } -MediaSourceBase *WAVExtractor::getTrack(size_t index) { +MediaTrack *WAVExtractor::getTrack(size_t index) { if (mInitCheck != OK || index > 0) { return NULL; } @@ -130,13 +127,15 @@ MediaSourceBase *WAVExtractor::getTrack(size_t index) { mWaveFormat, mBitsPerSample, mDataOffset, mDataSize); } -sp WAVExtractor::getTrackMetaData( +status_t WAVExtractor::getTrackMetaData( + MetaDataBase &meta, size_t index, uint32_t /* flags */) { if (mInitCheck != OK || index > 0) { - return NULL; + return UNKNOWN_ERROR; } - return mTrackMeta; + meta = mTrackMeta; + return OK; } status_t WAVExtractor::init() { @@ -285,33 +284,33 @@ status_t WAVExtractor::init() { mDataOffset = offset; mDataSize = chunkSize; - mTrackMeta = new MetaData; + mTrackMeta.clear(); switch (mWaveFormat) { case WAVE_FORMAT_PCM: case WAVE_FORMAT_IEEE_FLOAT: - mTrackMeta->setCString( + mTrackMeta.setCString( kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); break; case WAVE_FORMAT_ALAW: - mTrackMeta->setCString( + mTrackMeta.setCString( kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW); break; case WAVE_FORMAT_MSGSM: - mTrackMeta->setCString( + mTrackMeta.setCString( kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM); break; default: CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW); - mTrackMeta->setCString( + mTrackMeta.setCString( kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW); break; } - mTrackMeta->setInt32(kKeyChannelCount, mNumChannels); - mTrackMeta->setInt32(kKeyChannelMask, mChannelMask); - mTrackMeta->setInt32(kKeySampleRate, mSampleRate); - mTrackMeta->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit); + mTrackMeta.setInt32(kKeyChannelCount, mNumChannels); + mTrackMeta.setInt32(kKeyChannelMask, mChannelMask); + mTrackMeta.setInt32(kKeySampleRate, mSampleRate); + mTrackMeta.setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit); int64_t durationUs = 0; if (mWaveFormat == WAVE_FORMAT_MSGSM) { @@ -333,7 +332,7 @@ status_t WAVExtractor::init() { 1000000LL * num_samples / mSampleRate; } - mTrackMeta->setInt64(kKeyDuration, durationUs); + mTrackMeta.setInt64(kKeyDuration, durationUs); return OK; } @@ -349,7 +348,7 @@ const size_t WAVSource::kMaxFrameSize = 32768; WAVSource::WAVSource( DataSourceBase *dataSource, - const sp &meta, + MetaDataBase &meta, uint16_t waveFormat, int32_t bitsPerSample, off64_t offset, size_t size) @@ -363,10 +362,10 @@ WAVSource::WAVSource( mSize(size), mStarted(false), mGroup(NULL) { - CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate)); - CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels)); + CHECK(mMeta.findInt32(kKeySampleRate, &mSampleRate)); + CHECK(mMeta.findInt32(kKeyChannelCount, &mNumChannels)); - mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize); + mMeta.setInt32(kKeyMaxInputSize, kMaxFrameSize); } WAVSource::~WAVSource() { @@ -375,7 +374,7 @@ WAVSource::~WAVSource() { } } -status_t WAVSource::start(MetaData * /* params */) { +status_t WAVSource::start(MetaDataBase * /* params */) { ALOGV("WAVSource::start"); CHECK(!mStarted); @@ -408,10 +407,11 @@ status_t WAVSource::stop() { return OK; } -sp WAVSource::getFormat() { +status_t WAVSource::getFormat(MetaDataBase &meta) { ALOGV("WAVSource::getFormat"); - return mMeta; + meta = mMeta; + return OK; } status_t WAVSource::read( @@ -532,9 +532,9 @@ status_t WAVSource::read( / (mNumChannels * bytesPerSample) / mSampleRate; } - buffer->meta_data()->setInt64(kKeyTime, timeStampUs); + buffer->meta_data().setInt64(kKeyTime, timeStampUs); - buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); + buffer->meta_data().setInt32(kKeyIsSyncFrame, 1); mCurrentPos += n; *out = buffer; diff --git a/media/extractors/wav/WAVExtractor.h b/media/extractors/wav/WAVExtractor.h index 67661ed5db6ec4ab5f7770a9b82fb988dd1e8f40..467d0b7d968bc8ffcc0087e6ab5d081defd321b3 100644 --- a/media/extractors/wav/WAVExtractor.h +++ b/media/extractors/wav/WAVExtractor.h @@ -20,6 +20,7 @@ #include #include +#include namespace android { @@ -32,10 +33,10 @@ public: explicit WAVExtractor(DataSourceBase *source); virtual size_t countTracks(); - virtual MediaSourceBase *getTrack(size_t index); - virtual sp getTrackMetaData(size_t index, uint32_t flags); + virtual MediaTrack *getTrack(size_t index); + virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags); - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta); virtual const char * name() { return "WAVExtractor"; } virtual ~WAVExtractor(); @@ -51,7 +52,7 @@ private: uint16_t mBitsPerSample; off64_t mDataOffset; size_t mDataSize; - sp mTrackMeta; + MetaDataBase mTrackMeta; status_t init(); diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp index f6b925553b19ffcee6d6cc3334572ed8252cef17..f185fd4668f26b4167efcd7122d6c78ccebd6992 100644 --- a/media/libmedia/IMediaSource.cpp +++ b/media/libmedia/IMediaSource.cpp @@ -171,13 +171,13 @@ public: size_t length = reply.readInt32(); buf = new RemoteMediaBufferWrapper(mem); buf->set_range(offset, length); - buf->meta_data()->updateFromParcel(reply); + buf->meta_data().updateFromParcel(reply); } else { // INLINE_BUFFER int32_t len = reply.readInt32(); ALOGV("INLINE_BUFFER status %d and len %d", ret, len); buf = new MediaBuffer(len); reply.read(buf->data(), len); - buf->meta_data()->updateFromParcel(reply); + buf->meta_data().updateFromParcel(reply); } buffers->push_back(buf); ++bufferCount; @@ -408,7 +408,7 @@ status_t BnMediaSource::onTransact( } reply->writeInt32(offset); reply->writeInt32(length); - buf->meta_data()->writeToParcel(*reply); + buf->meta_data().writeToParcel(*reply); transferBuf->addRemoteRefcount(1); if (transferBuf != buf) { transferBuf->release(); // release local ref @@ -421,7 +421,7 @@ status_t BnMediaSource::onTransact( buf, buf->mMemory->size(), length); reply->writeInt32(INLINE_BUFFER); reply->writeByteArray(length, (uint8_t*)buf->data() + offset); - buf->meta_data()->writeToParcel(*reply); + buf->meta_data().writeToParcel(*reply); inlineTransferSize += length; if (inlineTransferSize > kInlineMaxTransfer) { maxNumBuffers = 0; // stop readMultiple if inline transfer is too large. diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp index 34deb5968f46569f691e99c381c05633cc2bdb0b..0d3c1bac5fbfe2b2dd716acbf3ba28c461e6453f 100644 --- a/media/libmedia/JetPlayer.cpp +++ b/media/libmedia/JetPlayer.cpp @@ -36,6 +36,7 @@ JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) : mPaused(false), mMaxTracks(maxTracks), mEasData(NULL), + mIoWrapper(NULL), mTrackBufferSize(trackBufferSize) { ALOGV("JetPlayer constructor"); @@ -50,7 +51,6 @@ JetPlayer::~JetPlayer() { ALOGV("~JetPlayer"); release(); - } //------------------------------------------------------------------------------------------------- @@ -138,7 +138,8 @@ int JetPlayer::release() JET_Shutdown(mEasData); EAS_Shutdown(mEasData); } - mIoWrapper.clear(); + delete mIoWrapper; + mIoWrapper = NULL; if (mAudioTrack != 0) { mAudioTrack->stop(); mAudioTrack->flush(); @@ -329,6 +330,7 @@ int JetPlayer::loadFromFile(const char* path) Mutex::Autolock lock(mMutex); + delete mIoWrapper; mIoWrapper = new MidiIoWrapper(path); EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator()); @@ -347,6 +349,7 @@ int JetPlayer::loadFromFD(const int fd, const long long offset, const long long Mutex::Autolock lock(mMutex); + delete mIoWrapper; mIoWrapper = new MidiIoWrapper(fd, offset, length); EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator()); diff --git a/media/libmedia/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp index 936e92f0bb2c903aec7ab49bbf790c5d6b8535f8..5e47b48e50777bacd43da4af0ef405285f74916c 100644 --- a/media/libmedia/NdkWrapper.cpp +++ b/media/libmedia/NdkWrapper.cpp @@ -574,17 +574,13 @@ bool AMediaCryptoWrapper::requiresSecureDecoderComponent(const char *mime) { //////////// AMediaCodecCryptoInfoWrapper // static -sp AMediaCodecCryptoInfoWrapper::Create(sp meta) { - if (meta == NULL) { - ALOGE("Create: Unexpected. No meta data for sample."); - return NULL; - } +sp AMediaCodecCryptoInfoWrapper::Create(MetaDataBase &meta) { uint32_t type; const void *crypteddata; size_t cryptedsize; - if (!meta->findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) { + if (!meta.findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) { return NULL; } @@ -597,7 +593,7 @@ sp AMediaCodecCryptoInfoWrapper::Create(spfindData(kKeyPlainSizes, &type, &cleardata, &clearsize)) { + if (meta.findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) { if (clearsize != cryptedsize) { // The two must be of the same length. ALOGE("Create: mismatch cryptedsize: %zu != clearsize: %zu", cryptedsize, clearsize); @@ -607,7 +603,7 @@ sp AMediaCodecCryptoInfoWrapper::Create(spfindData(kKeyCryptoKey, &type, &key, &keysize)) { + if (meta.findData(kKeyCryptoKey, &type, &key, &keysize)) { if (keysize != kAESBlockSize) { // Keys must be 16 bytes in length. ALOGE("Create: Keys must be %zu bytes in length: %zu", kAESBlockSize, keysize); @@ -617,7 +613,7 @@ sp AMediaCodecCryptoInfoWrapper::Create(spfindData(kKeyCryptoIV, &type, &iv, &ivsize)) { + if (meta.findData(kKeyCryptoIV, &type, &iv, &ivsize)) { if (ivsize != kAESBlockSize) { // IVs must be 16 bytes in length. ALOGE("Create: IV must be %zu bytes in length: %zu", kAESBlockSize, ivsize); @@ -626,7 +622,7 @@ sp AMediaCodecCryptoInfoWrapper::Create(spfindInt32(kKeyCryptoMode, &mode)) { + if (!meta.findInt32(kKeyCryptoMode, &mode)) { mode = CryptoPlugin::kMode_AES_CTR; } diff --git a/media/libmedia/include/media/JetPlayer.h b/media/libmedia/include/media/JetPlayer.h index 63d1980c67a3a5c4458b3d09992433b820e4be88..bb569bcad7bee6e02b80777bab85553e59ea426b 100644 --- a/media/libmedia/include/media/JetPlayer.h +++ b/media/libmedia/include/media/JetPlayer.h @@ -87,7 +87,7 @@ private: int mMaxTracks; // max number of MIDI tracks, usually 32 EAS_DATA_HANDLE mEasData; - sp mIoWrapper; + MidiIoWrapper* mIoWrapper; EAS_PCM* mAudioBuffer;// EAS renders the MIDI data into this buffer, sp mAudioTrack; // and we play it in this audio track int mTrackBufferSize; diff --git a/media/libmedia/include/media/MidiIoWrapper.h b/media/libmedia/include/media/MidiIoWrapper.h index a27b410c563db44f404f78b356ba0199f658f3dc..b5e565ef60721a9ebe7cd7b84096effe06d7f657 100644 --- a/media/libmedia/include/media/MidiIoWrapper.h +++ b/media/libmedia/include/media/MidiIoWrapper.h @@ -23,11 +23,11 @@ namespace android { -class MidiIoWrapper : public RefBase { +class MidiIoWrapper { public: - MidiIoWrapper(const char *path); - MidiIoWrapper(int fd, off64_t offset, int64_t size); - MidiIoWrapper(DataSourceBase *source); + explicit MidiIoWrapper(const char *path); + explicit MidiIoWrapper(int fd, off64_t offset, int64_t size); + explicit MidiIoWrapper(DataSourceBase *source); ~MidiIoWrapper(); diff --git a/media/libmedia/include/media/NdkWrapper.h b/media/libmedia/include/media/NdkWrapper.h index 49d728d85965804ebcedbfb3d2dbc404f0bbd16d..b71b758dcb1de294bd6587cca8b526d8e785f4c6 100644 --- a/media/libmedia/include/media/NdkWrapper.h +++ b/media/libmedia/include/media/NdkWrapper.h @@ -149,7 +149,7 @@ private: }; struct AMediaCodecCryptoInfoWrapper : public RefBase { - static sp Create(sp meta); + static sp Create(MetaDataBase &meta); AMediaCodecCryptoInfoWrapper(int numsubsamples, uint8_t key[16], diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp index 79af05816ec59a82e9bdd82e04688d92f0651df2..b9b47cd6058e6cf6000a33c8eb8111eacf5d7139 100644 --- a/media/libmediaextractor/Android.bp +++ b/media/libmediaextractor/Android.bp @@ -27,10 +27,12 @@ cc_library { "MediaBuffer.cpp", "MediaBufferBase.cpp", "MediaBufferGroup.cpp", - "MediaSourceBase.cpp", "MediaSource.cpp", + "MediaTrack.cpp", "MediaExtractor.cpp", "MetaData.cpp", + "MetaDataBase.cpp", + "VorbisComment.cpp", ], clang: true, diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libmediaextractor/MediaBuffer.cpp index dac3d50b07fd3b3e964f094cdeba4f1fdde905f8..39f8d6ee4fec0b0eb7f99fadc8eb5d323085f5ac 100644 --- a/media/libmediaextractor/MediaBuffer.cpp +++ b/media/libmediaextractor/MediaBuffer.cpp @@ -145,8 +145,8 @@ void MediaBuffer::set_range(size_t offset, size_t length) { mRangeLength = length; } -sp MediaBuffer::meta_data() { - return mMetaData; +MetaDataBase& MediaBuffer::meta_data() { + return *mMetaData; } void MediaBuffer::reset() { @@ -170,6 +170,7 @@ MediaBuffer::~MediaBuffer() { if (mMemory.get() != nullptr) { getSharedControl()->setDeadObject(); } + delete mMetaData; } void MediaBuffer::setObserver(MediaBufferObserver *observer) { @@ -180,7 +181,7 @@ void MediaBuffer::setObserver(MediaBufferObserver *observer) { MediaBufferBase *MediaBuffer::clone() { MediaBuffer *buffer = new MediaBuffer(mData, mSize); buffer->set_range(mRangeOffset, mRangeLength); - buffer->mMetaData = new MetaData(*mMetaData.get()); + buffer->mMetaData = new MetaDataBase(*mMetaData); add_ref(); buffer->mOriginal = this; diff --git a/media/libmediaextractor/MediaExtractor.cpp b/media/libmediaextractor/MediaExtractor.cpp index 2241567e0dc853288f546c8753990a1cfbd1f477..a6b3dc96d53b014365ccddf1dfa93dea71025edf 100644 --- a/media/libmediaextractor/MediaExtractor.cpp +++ b/media/libmediaextractor/MediaExtractor.cpp @@ -35,10 +35,6 @@ MediaExtractor::MediaExtractor() { MediaExtractor::~MediaExtractor() {} -sp MediaExtractor::getMetaData() { - return new MetaData; -} - uint32_t MediaExtractor::flags() const { return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK; } diff --git a/media/libmediaextractor/MediaSourceBase.cpp b/media/libmediaextractor/MediaTrack.cpp similarity index 69% rename from media/libmediaextractor/MediaSourceBase.cpp rename to media/libmediaextractor/MediaTrack.cpp index 6d45c9019cda752477b927045a6a02a581115102..4963f58f1734ccd3c9746307fff9be661cd25239 100644 --- a/media/libmediaextractor/MediaSourceBase.cpp +++ b/media/libmediaextractor/MediaTrack.cpp @@ -14,51 +14,51 @@ * limitations under the License. */ -#include +#include namespace android { -MediaSourceBase::MediaSourceBase() {} +MediaTrack::MediaTrack() {} -MediaSourceBase::~MediaSourceBase() {} +MediaTrack::~MediaTrack() {} //////////////////////////////////////////////////////////////////////////////// -MediaSourceBase::ReadOptions::ReadOptions() { +MediaTrack::ReadOptions::ReadOptions() { reset(); } -void MediaSourceBase::ReadOptions::reset() { +void MediaTrack::ReadOptions::reset() { mOptions = 0; mSeekTimeUs = 0; mNonBlocking = false; } -void MediaSourceBase::ReadOptions::setNonBlocking() { +void MediaTrack::ReadOptions::setNonBlocking() { mNonBlocking = true; } -void MediaSourceBase::ReadOptions::clearNonBlocking() { +void MediaTrack::ReadOptions::clearNonBlocking() { mNonBlocking = false; } -bool MediaSourceBase::ReadOptions::getNonBlocking() const { +bool MediaTrack::ReadOptions::getNonBlocking() const { return mNonBlocking; } -void MediaSourceBase::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) { +void MediaTrack::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) { mOptions |= kSeekTo_Option; mSeekTimeUs = time_us; mSeekMode = mode; } -void MediaSourceBase::ReadOptions::clearSeekTo() { +void MediaTrack::ReadOptions::clearSeekTo() { mOptions &= ~kSeekTo_Option; mSeekTimeUs = 0; mSeekMode = SEEK_CLOSEST_SYNC; } -bool MediaSourceBase::ReadOptions::getSeekTo( +bool MediaTrack::ReadOptions::getSeekTo( int64_t *time_us, SeekMode *mode) const { *time_us = mSeekTimeUs; *mode = mSeekMode; diff --git a/media/libmediaextractor/MetaData.cpp b/media/libmediaextractor/MetaData.cpp index 69beea10b29fbe46f953ed7af6ef577eee462390..1d0a607b9b4c7473eaa12ba36d991c8ca4831210 100644 --- a/media/libmediaextractor/MetaData.cpp +++ b/media/libmediaextractor/MetaData.cpp @@ -31,500 +31,20 @@ namespace android { -struct MetaData::typed_data { - typed_data(); - ~typed_data(); - typed_data(const MetaData::typed_data &); - typed_data &operator=(const MetaData::typed_data &); - - void clear(); - void setData(uint32_t type, const void *data, size_t size); - void getData(uint32_t *type, const void **data, size_t *size) const; - // may include hexdump of binary data if verbose=true - String8 asString(bool verbose) const; - -private: - uint32_t mType; - size_t mSize; - - union { - void *ext_data; - float reservoir; - } u; - - bool usesReservoir() const { - return mSize <= sizeof(u.reservoir); - } - - void *allocateStorage(size_t size); - void freeStorage(); - - void *storage() { - return usesReservoir() ? &u.reservoir : u.ext_data; - } - - const void *storage() const { - return usesReservoir() ? &u.reservoir : u.ext_data; - } -}; - -struct MetaData::Rect { - int32_t mLeft, mTop, mRight, mBottom; -}; - - -struct MetaData::MetaDataInternal { - KeyedVector mItems; -}; - - -MetaData::MetaData() - : mInternalData(new MetaDataInternal()) { +MetaData::MetaData() { } MetaData::MetaData(const MetaData &from) - : RefBase(), - mInternalData(new MetaDataInternal()) { - mInternalData->mItems = from.mInternalData->mItems; -} - -MetaData::~MetaData() { - clear(); - delete mInternalData; -} - -void MetaData::clear() { - mInternalData->mItems.clear(); -} - -bool MetaData::remove(uint32_t key) { - ssize_t i = mInternalData->mItems.indexOfKey(key); - - if (i < 0) { - return false; - } - - mInternalData->mItems.removeItemsAt(i); - - return true; -} - -bool MetaData::setCString(uint32_t key, const char *value) { - return setData(key, TYPE_C_STRING, value, strlen(value) + 1); -} - -bool MetaData::setInt32(uint32_t key, int32_t value) { - return setData(key, TYPE_INT32, &value, sizeof(value)); -} - -bool MetaData::setInt64(uint32_t key, int64_t value) { - return setData(key, TYPE_INT64, &value, sizeof(value)); -} - -bool MetaData::setFloat(uint32_t key, float value) { - return setData(key, TYPE_FLOAT, &value, sizeof(value)); -} - -bool MetaData::setPointer(uint32_t key, void *value) { - return setData(key, TYPE_POINTER, &value, sizeof(value)); -} - -bool MetaData::setRect( - uint32_t key, - int32_t left, int32_t top, - int32_t right, int32_t bottom) { - Rect r; - r.mLeft = left; - r.mTop = top; - r.mRight = right; - r.mBottom = bottom; - - return setData(key, TYPE_RECT, &r, sizeof(r)); -} - -/** - * Note that the returned pointer becomes invalid when additional metadata is set. - */ -bool MetaData::findCString(uint32_t key, const char **value) const { - uint32_t type; - const void *data; - size_t size; - if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) { - return false; - } - - *value = (const char *)data; - - return true; + : MetaDataBase(from) { } - -bool MetaData::findInt32(uint32_t key, int32_t *value) const { - uint32_t type = 0; - const void *data; - size_t size; - if (!findData(key, &type, &data, &size) || type != TYPE_INT32) { - return false; - } - - CHECK_EQ(size, sizeof(*value)); - - *value = *(int32_t *)data; - - return true; +MetaData::MetaData(const MetaDataBase &from) + : MetaDataBase(from) { } -bool MetaData::findInt64(uint32_t key, int64_t *value) const { - uint32_t type = 0; - const void *data; - size_t size; - if (!findData(key, &type, &data, &size) || type != TYPE_INT64) { - return false; - } - - CHECK_EQ(size, sizeof(*value)); - - *value = *(int64_t *)data; - - return true; -} - -bool MetaData::findFloat(uint32_t key, float *value) const { - uint32_t type = 0; - const void *data; - size_t size; - if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) { - return false; - } - - CHECK_EQ(size, sizeof(*value)); - - *value = *(float *)data; - - return true; -} - -bool MetaData::findPointer(uint32_t key, void **value) const { - uint32_t type = 0; - const void *data; - size_t size; - if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) { - return false; - } - - CHECK_EQ(size, sizeof(*value)); - - *value = *(void **)data; - - return true; -} - -bool MetaData::findRect( - uint32_t key, - int32_t *left, int32_t *top, - int32_t *right, int32_t *bottom) const { - uint32_t type = 0; - const void *data; - size_t size; - if (!findData(key, &type, &data, &size) || type != TYPE_RECT) { - return false; - } - - CHECK_EQ(size, sizeof(Rect)); - - const Rect *r = (const Rect *)data; - *left = r->mLeft; - *top = r->mTop; - *right = r->mRight; - *bottom = r->mBottom; - - return true; -} - -bool MetaData::setData( - uint32_t key, uint32_t type, const void *data, size_t size) { - bool overwrote_existing = true; - - ssize_t i = mInternalData->mItems.indexOfKey(key); - if (i < 0) { - typed_data item; - i = mInternalData->mItems.add(key, item); - - overwrote_existing = false; - } - - typed_data &item = mInternalData->mItems.editValueAt(i); - - item.setData(type, data, size); - - return overwrote_existing; -} - -bool MetaData::findData(uint32_t key, uint32_t *type, - const void **data, size_t *size) const { - ssize_t i = mInternalData->mItems.indexOfKey(key); - - if (i < 0) { - return false; - } - - const typed_data &item = mInternalData->mItems.valueAt(i); - - item.getData(type, data, size); - - return true; -} - -bool MetaData::hasData(uint32_t key) const { - ssize_t i = mInternalData->mItems.indexOfKey(key); - - if (i < 0) { - return false; - } - - return true; -} - -MetaData::typed_data::typed_data() - : mType(0), - mSize(0) { -} - -MetaData::typed_data::~typed_data() { - clear(); -} - -MetaData::typed_data::typed_data(const typed_data &from) - : mType(from.mType), - mSize(0) { - - void *dst = allocateStorage(from.mSize); - if (dst) { - memcpy(dst, from.storage(), mSize); - } -} - -MetaData::typed_data &MetaData::typed_data::operator=( - const MetaData::typed_data &from) { - if (this != &from) { - clear(); - mType = from.mType; - void *dst = allocateStorage(from.mSize); - if (dst) { - memcpy(dst, from.storage(), mSize); - } - } - - return *this; -} - -void MetaData::typed_data::clear() { - freeStorage(); - - mType = 0; -} - -void MetaData::typed_data::setData( - uint32_t type, const void *data, size_t size) { - clear(); - - mType = type; - - void *dst = allocateStorage(size); - if (dst) { - memcpy(dst, data, size); - } -} - -void MetaData::typed_data::getData( - uint32_t *type, const void **data, size_t *size) const { - *type = mType; - *size = mSize; - *data = storage(); -} - -void *MetaData::typed_data::allocateStorage(size_t size) { - mSize = size; - - if (usesReservoir()) { - return &u.reservoir; - } - - u.ext_data = malloc(mSize); - if (u.ext_data == NULL) { - ALOGE("Couldn't allocate %zu bytes for item", size); - mSize = 0; - } - return u.ext_data; -} - -void MetaData::typed_data::freeStorage() { - if (!usesReservoir()) { - if (u.ext_data) { - free(u.ext_data); - u.ext_data = NULL; - } - } - - mSize = 0; -} - -String8 MetaData::typed_data::asString(bool verbose) const { - String8 out; - const void *data = storage(); - switch(mType) { - case TYPE_NONE: - out = String8::format("no type, size %zu)", mSize); - break; - case TYPE_C_STRING: - out = String8::format("(char*) %s", (const char *)data); - break; - case TYPE_INT32: - out = String8::format("(int32_t) %d", *(int32_t *)data); - break; - case TYPE_INT64: - out = String8::format("(int64_t) %" PRId64, *(int64_t *)data); - break; - case TYPE_FLOAT: - out = String8::format("(float) %f", *(float *)data); - break; - case TYPE_POINTER: - out = String8::format("(void*) %p", *(void **)data); - break; - case TYPE_RECT: - { - const Rect *r = (const Rect *)data; - out = String8::format("Rect(%d, %d, %d, %d)", - r->mLeft, r->mTop, r->mRight, r->mBottom); - break; - } - - default: - out = String8::format("(unknown type %d, size %zu)", mType, mSize); - if (verbose && mSize <= 48) { // if it's less than three lines of hex data, dump it - AString foo; - hexdump(data, mSize, 0, &foo); - out.append("\n"); - out.append(foo.c_str()); - } - break; - } - return out; -} - -static void MakeFourCCString(uint32_t x, char *s) { - s[0] = x >> 24; - s[1] = (x >> 16) & 0xff; - s[2] = (x >> 8) & 0xff; - s[3] = x & 0xff; - s[4] = '\0'; -} - -String8 MetaData::toString() const { - String8 s; - for (int i = mInternalData->mItems.size(); --i >= 0;) { - int32_t key = mInternalData->mItems.keyAt(i); - char cc[5]; - MakeFourCCString(key, cc); - const typed_data &item = mInternalData->mItems.valueAt(i); - s.appendFormat("%s: %s", cc, item.asString(false).string()); - if (i != 0) { - s.append(", "); - } - } - return s; -} -void MetaData::dumpToLog() const { - for (int i = mInternalData->mItems.size(); --i >= 0;) { - int32_t key = mInternalData->mItems.keyAt(i); - char cc[5]; - MakeFourCCString(key, cc); - const typed_data &item = mInternalData->mItems.valueAt(i); - ALOGI("%s: %s", cc, item.asString(true /* verbose */).string()); - } -} - -status_t MetaData::writeToParcel(Parcel &parcel) { - status_t ret; - size_t numItems = mInternalData->mItems.size(); - ret = parcel.writeUint32(uint32_t(numItems)); - if (ret) { - return ret; - } - for (size_t i = 0; i < numItems; i++) { - int32_t key = mInternalData->mItems.keyAt(i); - const typed_data &item = mInternalData->mItems.valueAt(i); - uint32_t type; - const void *data; - size_t size; - item.getData(&type, &data, &size); - ret = parcel.writeInt32(key); - if (ret) { - return ret; - } - ret = parcel.writeUint32(type); - if (ret) { - return ret; - } - if (type == TYPE_NONE) { - android::Parcel::WritableBlob blob; - ret = parcel.writeUint32(static_cast(size)); - if (ret) { - return ret; - } - ret = parcel.writeBlob(size, false, &blob); - if (ret) { - return ret; - } - memcpy(blob.data(), data, size); - blob.release(); - } else { - ret = parcel.writeByteArray(size, (uint8_t*)data); - if (ret) { - return ret; - } - } - } - return OK; -} - -status_t MetaData::updateFromParcel(const Parcel &parcel) { - uint32_t numItems; - if (parcel.readUint32(&numItems) == OK) { - - for (size_t i = 0; i < numItems; i++) { - int32_t key; - uint32_t type; - uint32_t size; - status_t ret = parcel.readInt32(&key); - ret |= parcel.readUint32(&type); - ret |= parcel.readUint32(&size); - if (ret != OK) { - break; - } - // copy data from Blob, which may be inline in Parcel storage, - // then advance position - if (type == TYPE_NONE) { - android::Parcel::ReadableBlob blob; - ret = parcel.readBlob(size, &blob); - if (ret != OK) { - break; - } - setData(key, type, blob.data(), size); - blob.release(); - } else { - // copy data directly from Parcel storage, then advance position - setData(key, type, parcel.readInplace(size), size); - } - } - - return OK; - } - ALOGW("no metadata in parcel"); - return UNKNOWN_ERROR; +MetaData::~MetaData() { } - /* static */ sp MetaData::createFromParcel(const Parcel &parcel) { @@ -533,7 +53,5 @@ sp MetaData::createFromParcel(const Parcel &parcel) { return meta; } - - } // namespace android diff --git a/media/libmediaextractor/MetaDataBase.cpp b/media/libmediaextractor/MetaDataBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bfea6f15377ec9f87bc6d47e8881bb6ffd695227 --- /dev/null +++ b/media/libmediaextractor/MetaDataBase.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "MetaDataBase" +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace android { + +struct MetaDataBase::typed_data { + typed_data(); + ~typed_data(); + + typed_data(const MetaDataBase::typed_data &); + typed_data &operator=(const MetaDataBase::typed_data &); + + void clear(); + void setData(uint32_t type, const void *data, size_t size); + void getData(uint32_t *type, const void **data, size_t *size) const; + // may include hexdump of binary data if verbose=true + String8 asString(bool verbose) const; + +private: + uint32_t mType; + size_t mSize; + + union { + void *ext_data; + float reservoir; + } u; + + bool usesReservoir() const { + return mSize <= sizeof(u.reservoir); + } + + void *allocateStorage(size_t size); + void freeStorage(); + + void *storage() { + return usesReservoir() ? &u.reservoir : u.ext_data; + } + + const void *storage() const { + return usesReservoir() ? &u.reservoir : u.ext_data; + } +}; + +struct MetaDataBase::Rect { + int32_t mLeft, mTop, mRight, mBottom; +}; + + +struct MetaDataBase::MetaDataInternal { + KeyedVector mItems; +}; + + +MetaDataBase::MetaDataBase() + : mInternalData(new MetaDataInternal()) { +} + +MetaDataBase::MetaDataBase(const MetaDataBase &from) + : mInternalData(new MetaDataInternal()) { + mInternalData->mItems = from.mInternalData->mItems; +} + +MetaDataBase& MetaDataBase::operator = (const MetaDataBase &rhs) { + this->mInternalData->mItems = rhs.mInternalData->mItems; + return *this; +} + +MetaDataBase::~MetaDataBase() { + clear(); + delete mInternalData; +} + +void MetaDataBase::clear() { + mInternalData->mItems.clear(); +} + +bool MetaDataBase::remove(uint32_t key) { + ssize_t i = mInternalData->mItems.indexOfKey(key); + + if (i < 0) { + return false; + } + + mInternalData->mItems.removeItemsAt(i); + + return true; +} + +bool MetaDataBase::setCString(uint32_t key, const char *value) { + return setData(key, TYPE_C_STRING, value, strlen(value) + 1); +} + +bool MetaDataBase::setInt32(uint32_t key, int32_t value) { + return setData(key, TYPE_INT32, &value, sizeof(value)); +} + +bool MetaDataBase::setInt64(uint32_t key, int64_t value) { + return setData(key, TYPE_INT64, &value, sizeof(value)); +} + +bool MetaDataBase::setFloat(uint32_t key, float value) { + return setData(key, TYPE_FLOAT, &value, sizeof(value)); +} + +bool MetaDataBase::setPointer(uint32_t key, void *value) { + return setData(key, TYPE_POINTER, &value, sizeof(value)); +} + +bool MetaDataBase::setRect( + uint32_t key, + int32_t left, int32_t top, + int32_t right, int32_t bottom) { + Rect r; + r.mLeft = left; + r.mTop = top; + r.mRight = right; + r.mBottom = bottom; + + return setData(key, TYPE_RECT, &r, sizeof(r)); +} + +/** + * Note that the returned pointer becomes invalid when additional metadata is set. + */ +bool MetaDataBase::findCString(uint32_t key, const char **value) const { + uint32_t type; + const void *data; + size_t size; + if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) { + return false; + } + + *value = (const char *)data; + + return true; +} + +bool MetaDataBase::findInt32(uint32_t key, int32_t *value) const { + uint32_t type = 0; + const void *data; + size_t size; + if (!findData(key, &type, &data, &size) || type != TYPE_INT32) { + return false; + } + + CHECK_EQ(size, sizeof(*value)); + + *value = *(int32_t *)data; + + return true; +} + +bool MetaDataBase::findInt64(uint32_t key, int64_t *value) const { + uint32_t type = 0; + const void *data; + size_t size; + if (!findData(key, &type, &data, &size) || type != TYPE_INT64) { + return false; + } + + CHECK_EQ(size, sizeof(*value)); + + *value = *(int64_t *)data; + + return true; +} + +bool MetaDataBase::findFloat(uint32_t key, float *value) const { + uint32_t type = 0; + const void *data; + size_t size; + if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) { + return false; + } + + CHECK_EQ(size, sizeof(*value)); + + *value = *(float *)data; + + return true; +} + +bool MetaDataBase::findPointer(uint32_t key, void **value) const { + uint32_t type = 0; + const void *data; + size_t size; + if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) { + return false; + } + + CHECK_EQ(size, sizeof(*value)); + + *value = *(void **)data; + + return true; +} + +bool MetaDataBase::findRect( + uint32_t key, + int32_t *left, int32_t *top, + int32_t *right, int32_t *bottom) const { + uint32_t type = 0; + const void *data; + size_t size; + if (!findData(key, &type, &data, &size) || type != TYPE_RECT) { + return false; + } + + CHECK_EQ(size, sizeof(Rect)); + + const Rect *r = (const Rect *)data; + *left = r->mLeft; + *top = r->mTop; + *right = r->mRight; + *bottom = r->mBottom; + + return true; +} + +bool MetaDataBase::setData( + uint32_t key, uint32_t type, const void *data, size_t size) { + bool overwrote_existing = true; + + ssize_t i = mInternalData->mItems.indexOfKey(key); + if (i < 0) { + typed_data item; + i = mInternalData->mItems.add(key, item); + + overwrote_existing = false; + } + + typed_data &item = mInternalData->mItems.editValueAt(i); + + item.setData(type, data, size); + + return overwrote_existing; +} + +bool MetaDataBase::findData(uint32_t key, uint32_t *type, + const void **data, size_t *size) const { + ssize_t i = mInternalData->mItems.indexOfKey(key); + + if (i < 0) { + return false; + } + + const typed_data &item = mInternalData->mItems.valueAt(i); + + item.getData(type, data, size); + + return true; +} + +bool MetaDataBase::hasData(uint32_t key) const { + ssize_t i = mInternalData->mItems.indexOfKey(key); + + if (i < 0) { + return false; + } + + return true; +} + +MetaDataBase::typed_data::typed_data() + : mType(0), + mSize(0) { +} + +MetaDataBase::typed_data::~typed_data() { + clear(); +} + +MetaDataBase::typed_data::typed_data(const typed_data &from) + : mType(from.mType), + mSize(0) { + + void *dst = allocateStorage(from.mSize); + if (dst) { + memcpy(dst, from.storage(), mSize); + } +} + +MetaDataBase::typed_data &MetaDataBase::typed_data::operator=( + const MetaDataBase::typed_data &from) { + if (this != &from) { + clear(); + mType = from.mType; + void *dst = allocateStorage(from.mSize); + if (dst) { + memcpy(dst, from.storage(), mSize); + } + } + + return *this; +} + +void MetaDataBase::typed_data::clear() { + freeStorage(); + + mType = 0; +} + +void MetaDataBase::typed_data::setData( + uint32_t type, const void *data, size_t size) { + clear(); + + mType = type; + + void *dst = allocateStorage(size); + if (dst) { + memcpy(dst, data, size); + } +} + +void MetaDataBase::typed_data::getData( + uint32_t *type, const void **data, size_t *size) const { + *type = mType; + *size = mSize; + *data = storage(); +} + +void *MetaDataBase::typed_data::allocateStorage(size_t size) { + mSize = size; + + if (usesReservoir()) { + return &u.reservoir; + } + + u.ext_data = malloc(mSize); + if (u.ext_data == NULL) { + ALOGE("Couldn't allocate %zu bytes for item", size); + mSize = 0; + } + return u.ext_data; +} + +void MetaDataBase::typed_data::freeStorage() { + if (!usesReservoir()) { + if (u.ext_data) { + free(u.ext_data); + u.ext_data = NULL; + } + } + + mSize = 0; +} + +String8 MetaDataBase::typed_data::asString(bool verbose) const { + String8 out; + const void *data = storage(); + switch(mType) { + case TYPE_NONE: + out = String8::format("no type, size %zu)", mSize); + break; + case TYPE_C_STRING: + out = String8::format("(char*) %s", (const char *)data); + break; + case TYPE_INT32: + out = String8::format("(int32_t) %d", *(int32_t *)data); + break; + case TYPE_INT64: + out = String8::format("(int64_t) %" PRId64, *(int64_t *)data); + break; + case TYPE_FLOAT: + out = String8::format("(float) %f", *(float *)data); + break; + case TYPE_POINTER: + out = String8::format("(void*) %p", *(void **)data); + break; + case TYPE_RECT: + { + const Rect *r = (const Rect *)data; + out = String8::format("Rect(%d, %d, %d, %d)", + r->mLeft, r->mTop, r->mRight, r->mBottom); + break; + } + + default: + out = String8::format("(unknown type %d, size %zu)", mType, mSize); + if (verbose && mSize <= 48) { // if it's less than three lines of hex data, dump it + AString foo; + hexdump(data, mSize, 0, &foo); + out.append("\n"); + out.append(foo.c_str()); + } + break; + } + return out; +} + +static void MakeFourCCString(uint32_t x, char *s) { + s[0] = x >> 24; + s[1] = (x >> 16) & 0xff; + s[2] = (x >> 8) & 0xff; + s[3] = x & 0xff; + s[4] = '\0'; +} + +String8 MetaDataBase::toString() const { + String8 s; + for (int i = mInternalData->mItems.size(); --i >= 0;) { + int32_t key = mInternalData->mItems.keyAt(i); + char cc[5]; + MakeFourCCString(key, cc); + const typed_data &item = mInternalData->mItems.valueAt(i); + s.appendFormat("%s: %s", cc, item.asString(false).string()); + if (i != 0) { + s.append(", "); + } + } + return s; +} + +void MetaDataBase::dumpToLog() const { + for (int i = mInternalData->mItems.size(); --i >= 0;) { + int32_t key = mInternalData->mItems.keyAt(i); + char cc[5]; + MakeFourCCString(key, cc); + const typed_data &item = mInternalData->mItems.valueAt(i); + ALOGI("%s: %s", cc, item.asString(true /* verbose */).string()); + } +} + +status_t MetaDataBase::writeToParcel(Parcel &parcel) { + status_t ret; + size_t numItems = mInternalData->mItems.size(); + ret = parcel.writeUint32(uint32_t(numItems)); + if (ret) { + return ret; + } + for (size_t i = 0; i < numItems; i++) { + int32_t key = mInternalData->mItems.keyAt(i); + const typed_data &item = mInternalData->mItems.valueAt(i); + uint32_t type; + const void *data; + size_t size; + item.getData(&type, &data, &size); + ret = parcel.writeInt32(key); + if (ret) { + return ret; + } + ret = parcel.writeUint32(type); + if (ret) { + return ret; + } + if (type == TYPE_NONE) { + android::Parcel::WritableBlob blob; + ret = parcel.writeUint32(static_cast(size)); + if (ret) { + return ret; + } + ret = parcel.writeBlob(size, false, &blob); + if (ret) { + return ret; + } + memcpy(blob.data(), data, size); + blob.release(); + } else { + ret = parcel.writeByteArray(size, (uint8_t*)data); + if (ret) { + return ret; + } + } + } + return OK; +} + +status_t MetaDataBase::updateFromParcel(const Parcel &parcel) { + uint32_t numItems; + if (parcel.readUint32(&numItems) == OK) { + + for (size_t i = 0; i < numItems; i++) { + int32_t key; + uint32_t type; + uint32_t size; + status_t ret = parcel.readInt32(&key); + ret |= parcel.readUint32(&type); + ret |= parcel.readUint32(&size); + if (ret != OK) { + break; + } + // copy data from Blob, which may be inline in Parcel storage, + // then advance position + if (type == TYPE_NONE) { + android::Parcel::ReadableBlob blob; + ret = parcel.readBlob(size, &blob); + if (ret != OK) { + break; + } + setData(key, type, blob.data(), size); + blob.release(); + } else { + // copy data directly from Parcel storage, then advance position + setData(key, type, parcel.readInplace(size), size); + } + } + + return OK; + } + ALOGW("no metadata in parcel"); + return UNKNOWN_ERROR; +} + +} // namespace android + diff --git a/media/libmediaextractor/VorbisComment.cpp b/media/libmediaextractor/VorbisComment.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fabaf51ea993027e00854a5d3d3c63a512f28996 --- /dev/null +++ b/media/libmediaextractor/VorbisComment.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "VorbisComment" +#include + +#include "media/VorbisComment.h" + +#include +#include +#include +#include +#include + +namespace android { + +static void extractAlbumArt( + MetaDataBase *fileMeta, const void *data, size_t size) { + ALOGV("extractAlbumArt from '%s'", (const char *)data); + + sp flacBuffer = decodeBase64(AString((const char *)data, size)); + if (flacBuffer == NULL) { + ALOGE("malformed base64 encoded data."); + return; + } + + size_t flacSize = flacBuffer->size(); + uint8_t *flac = flacBuffer->data(); + ALOGV("got flac of size %zu", flacSize); + + uint32_t picType; + uint32_t typeLen; + uint32_t descLen; + uint32_t dataLen; + char type[128]; + + if (flacSize < 8) { + return; + } + + picType = U32_AT(flac); + + if (picType != 3) { + // This is not a front cover. + return; + } + + typeLen = U32_AT(&flac[4]); + if (typeLen > sizeof(type) - 1) { + return; + } + + // we've already checked above that flacSize >= 8 + if (flacSize - 8 < typeLen) { + return; + } + + memcpy(type, &flac[8], typeLen); + type[typeLen] = '\0'; + + ALOGV("picType = %d, type = '%s'", picType, type); + + if (!strcmp(type, "-->")) { + // This is not inline cover art, but an external url instead. + return; + } + + if (flacSize < 32 || flacSize - 32 < typeLen) { + return; + } + + descLen = U32_AT(&flac[8 + typeLen]); + if (flacSize - 32 - typeLen < descLen) { + return; + } + + dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]); + + // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0 + if (flacSize - 32 - typeLen - descLen < dataLen) { + return; + } + + ALOGV("got image data, %zu trailing bytes", + flacSize - 32 - typeLen - descLen - dataLen); + + fileMeta->setData( + kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen); + + fileMeta->setCString(kKeyAlbumArtMIME, type); +} + +void parseVorbisComment( + MetaDataBase *fileMeta, const char *comment, size_t commentLength) +{ + struct { + const char *const mTag; + uint32_t mKey; + } kMap[] = { + { "TITLE", kKeyTitle }, + { "ARTIST", kKeyArtist }, + { "ALBUMARTIST", kKeyAlbumArtist }, + { "ALBUM ARTIST", kKeyAlbumArtist }, + { "COMPILATION", kKeyCompilation }, + { "ALBUM", kKeyAlbum }, + { "COMPOSER", kKeyComposer }, + { "GENRE", kKeyGenre }, + { "AUTHOR", kKeyAuthor }, + { "TRACKNUMBER", kKeyCDTrackNumber }, + { "DISCNUMBER", kKeyDiscNumber }, + { "DATE", kKeyDate }, + { "YEAR", kKeyYear }, + { "LYRICIST", kKeyWriter }, + { "METADATA_BLOCK_PICTURE", kKeyAlbumArt }, + { "ANDROID_LOOP", kKeyAutoLoop }, + }; + + for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) { + size_t tagLen = strlen(kMap[j].mTag); + if (!strncasecmp(kMap[j].mTag, comment, tagLen) + && comment[tagLen] == '=') { + if (kMap[j].mKey == kKeyAlbumArt) { + extractAlbumArt( + fileMeta, + &comment[tagLen + 1], + commentLength - tagLen - 1); + } else if (kMap[j].mKey == kKeyAutoLoop) { + if (!strcasecmp(&comment[tagLen + 1], "true")) { + fileMeta->setInt32(kKeyAutoLoop, true); + } + } else { + fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]); + } + } + } + +} + +} // namespace android diff --git a/media/libmediaextractor/include/media/MediaExtractor.h b/media/libmediaextractor/include/media/MediaExtractor.h index c329903dfd17e82c67a1eaff845b4d880294adbc..4ba98da533ab4387e5bccfda48b95cbb84b360fb 100644 --- a/media/libmediaextractor/include/media/MediaExtractor.h +++ b/media/libmediaextractor/include/media/MediaExtractor.h @@ -28,8 +28,8 @@ namespace android { class DataSourceBase; -class MetaData; -struct MediaSourceBase; +class MetaDataBase; +struct MediaTrack; class ExtractorAllocTracker { @@ -49,17 +49,18 @@ class MediaExtractor public: virtual ~MediaExtractor(); virtual size_t countTracks() = 0; - virtual MediaSourceBase *getTrack(size_t index) = 0; + virtual MediaTrack *getTrack(size_t index) = 0; enum GetTrackMetaDataFlags { kIncludeExtensiveMetaData = 1 }; - virtual sp getTrackMetaData( + virtual status_t getTrackMetaData( + MetaDataBase& meta, size_t index, uint32_t flags = 0) = 0; // Return container specific meta-data. The default implementation // returns an empty metadata object. - virtual sp getMetaData(); + virtual status_t getMetaData(MetaDataBase& meta) = 0; enum Flags { CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button" diff --git a/media/libmediaextractor/include/media/MediaSource.h b/media/libmediaextractor/include/media/MediaSource.h index 45070d6de2ff67f6d9c6325ab129bfdd8989836f..73c47035b4e607f0a3862c10a0e773fc7b21a014 100644 --- a/media/libmediaextractor/include/media/MediaSource.h +++ b/media/libmediaextractor/include/media/MediaSource.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,15 +25,71 @@ #include #include -#include "media/MediaSourceBase.h" +#include namespace android { class MediaBuffer; -struct MediaSource : public MediaSourceBase, public virtual RefBase { +struct MediaSource : public virtual RefBase { MediaSource(); + // To be called before any other methods on this object, except + // getFormat(). + virtual status_t start(MetaData *params = NULL) = 0; + + // Any blocking read call returns immediately with a result of NO_INIT. + // It is an error to call any methods other than start after this call + // returns. Any buffers the object may be holding onto at the time of + // the stop() call are released. + // Also, it is imperative that any buffers output by this object and + // held onto by callers be released before a call to stop() !!! + virtual status_t stop() = 0; + + // Returns the format of the data output by this media source. + virtual sp getFormat() = 0; + + // Options that modify read() behaviour. The default is to + // a) not request a seek + // b) not be late, i.e. lateness_us = 0 + typedef MediaTrack::ReadOptions ReadOptions; + + // Returns a new buffer of data. Call blocks until a + // buffer is available, an error is encountered of the end of the stream + // is reached. + // End of stream is signalled by a result of ERROR_END_OF_STREAM. + // A result of INFO_FORMAT_CHANGED indicates that the format of this + // MediaSource has changed mid-stream, the client can continue reading + // but should be prepared for buffers of the new configuration. + virtual status_t read( + MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0; + + // Causes this source to suspend pulling data from its upstream source + // until a subsequent read-with-seek. This is currently not supported + // as such by any source. E.g. MediaCodecSource does not suspend its + // upstream source, and instead discard upstream data while paused. + virtual status_t pause() { + return ERROR_UNSUPPORTED; + } + + // The consumer of this media source requests the source stops sending + // buffers with timestamp larger than or equal to stopTimeUs. stopTimeUs + // must be in the same time base as the startTime passed in start(). If + // source does not support this request, ERROR_UNSUPPORTED will be returned. + // If stopTimeUs is invalid, BAD_VALUE will be returned. This could be + // called at any time even before source starts and it could be called + // multiple times. Setting stopTimeUs to be -1 will effectively cancel the stopTimeUs + // set previously. If stopTimeUs is larger than or equal to last buffer's timestamp, + // source will start to drop buffer when it gets a buffer with timestamp larger + // than or equal to stopTimeUs. If stopTimeUs is smaller than or equal to last + // buffer's timestamp, source will drop all the incoming buffers immediately. + // After setting stopTimeUs, source may still stop sending buffers with timestamp + // less than stopTimeUs if it is stopped by the consumer. + virtual status_t setStopTimeUs(int64_t /* stopTimeUs */) { + return ERROR_UNSUPPORTED; + } + +protected: virtual ~MediaSource(); private: diff --git a/media/libmediaextractor/include/media/MediaSourceBase.h b/media/libmediaextractor/include/media/MediaTrack.h similarity index 65% rename from media/libmediaextractor/include/media/MediaSourceBase.h rename to media/libmediaextractor/include/media/MediaTrack.h index ab56613f82808dad5bd5551f9209277dfef61554..adea61afc654115cc179a5208dbb99c0e57501e7 100644 --- a/media/libmediaextractor/include/media/MediaSourceBase.h +++ b/media/libmediaextractor/include/media/MediaTrack.h @@ -42,14 +42,14 @@ public: } }; -struct MediaSourceBase +struct MediaTrack // : public SourceBaseAllocTracker { - MediaSourceBase(); + MediaTrack(); // To be called before any other methods on this object, except // getFormat(). - virtual status_t start(MetaData *params = NULL) = 0; + virtual status_t start(MetaDataBase *params = NULL) = 0; // Any blocking read call returns immediately with a result of NO_INIT. // It is an error to call any methods other than start after this call @@ -59,8 +59,8 @@ struct MediaSourceBase // held onto by callers be released before a call to stop() !!! virtual status_t stop() = 0; - // Returns the format of the data output by this media source. - virtual sp getFormat() = 0; + // Returns the format of the data output by this media track. + virtual status_t getFormat(MetaDataBase& format) = 0; // Options that modify read() behaviour. The default is to // a) not request a seek @@ -113,36 +113,11 @@ struct MediaSourceBase virtual status_t read( MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0; - // Causes this source to suspend pulling data from its upstream source - // until a subsequent read-with-seek. This is currently not supported - // as such by any source. E.g. MediaCodecSource does not suspend its - // upstream source, and instead discard upstream data while paused. - virtual status_t pause() { - return ERROR_UNSUPPORTED; - } - - // The consumer of this media source requests the source stops sending - // buffers with timestamp larger than or equal to stopTimeUs. stopTimeUs - // must be in the same time base as the startTime passed in start(). If - // source does not support this request, ERROR_UNSUPPORTED will be returned. - // If stopTimeUs is invalid, BAD_VALUE will be returned. This could be - // called at any time even before source starts and it could be called - // multiple times. Setting stopTimeUs to be -1 will effectively cancel the stopTimeUs - // set previously. If stopTimeUs is larger than or equal to last buffer's timestamp, - // source will start to drop buffer when it gets a buffer with timestamp larger - // than or equal to stopTimeUs. If stopTimeUs is smaller than or equal to last - // buffer's timestamp, source will drop all the incoming buffers immediately. - // After setting stopTimeUs, source may still stop sending buffers with timestamp - // less than stopTimeUs if it is stopped by the consumer. - virtual status_t setStopTimeUs(int64_t /* stopTimeUs */) { - return ERROR_UNSUPPORTED; - } - - virtual ~MediaSourceBase(); + virtual ~MediaTrack(); private: - MediaSourceBase(const MediaSourceBase &); - MediaSourceBase &operator=(const MediaSourceBase &); + MediaTrack(const MediaTrack &); + MediaTrack &operator=(const MediaTrack &); }; } // namespace android diff --git a/media/libmediaextractor/include/media/VorbisComment.h b/media/libmediaextractor/include/media/VorbisComment.h new file mode 100644 index 0000000000000000000000000000000000000000..8ba329503caf4a293a04655450ad7a6d9a472c8b --- /dev/null +++ b/media/libmediaextractor/include/media/VorbisComment.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef VORBIS_COMMENT_H_ +#define VORBIS_COMMENT_H_ + +namespace android { + +class MetaDataBase; + +void parseVorbisComment( + MetaDataBase *fileMeta, const char *comment, size_t commentLength); + +} // namespace android + +#endif // VORBIS_COMMENT_H_ diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h index 85b45219f37d562e8733d5138615b1d989508551..f944d51de28f4b4eea9408aa1375c86eeff4fb74 100644 --- a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h +++ b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h @@ -33,7 +33,7 @@ namespace android { struct ABuffer; class MediaBuffer; class MediaBufferObserver; -class MetaData; +class MetaDataBase; class MediaBuffer : public MediaBufferBase { public: @@ -73,7 +73,7 @@ public: virtual void set_range(size_t offset, size_t length); - virtual sp meta_data(); + MetaDataBase& meta_data(); // Clears meta data and resets the range to the full extent. virtual void reset(); @@ -154,7 +154,7 @@ private: bool mOwnsData; - sp mMetaData; + MetaDataBase* mMetaData; MediaBuffer *mOriginal; diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h b/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h index 81dd7d931b6f0fa11d7f11b13c76b29b123b2275..6c8d94ab9875fdfc291549648898d4f21d20e219 100644 --- a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h +++ b/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h @@ -18,12 +18,10 @@ #define MEDIA_BUFFER_BASE_H_ -#include - namespace android { class MediaBufferBase; -class MetaData; +class MetaDataBase; class MediaBufferObserver { public: @@ -61,7 +59,7 @@ public: virtual void set_range(size_t offset, size_t length) = 0; - virtual sp meta_data() = 0; + virtual MetaDataBase& meta_data() = 0; // Clears meta data and resets the range to the full extent. virtual void reset() = 0; diff --git a/media/libmediaextractor/include/media/stagefright/MetaData.h b/media/libmediaextractor/include/media/stagefright/MetaData.h index 7562a721976bd19b9163172f55a6fea9c65c87fe..f625358f6c6daf97b9d2b2166dbd71b72220f663 100644 --- a/media/libmediaextractor/include/media/stagefright/MetaData.h +++ b/media/libmediaextractor/include/media/stagefright/MetaData.h @@ -24,275 +24,24 @@ #include #include +#include namespace android { -class Parcel; - -// The following keys map to int32_t data unless indicated otherwise. -enum { - kKeyMIMEType = 'mime', // cstring - kKeyWidth = 'widt', // int32_t, image pixel - kKeyHeight = 'heig', // int32_t, image pixel - kKeyDisplayWidth = 'dWid', // int32_t, display/presentation - kKeyDisplayHeight = 'dHgt', // int32_t, display/presentation - kKeySARWidth = 'sarW', // int32_t, sampleAspectRatio width - kKeySARHeight = 'sarH', // int32_t, sampleAspectRatio height - kKeyThumbnailWidth = 'thbW', // int32_t, thumbnail width - kKeyThumbnailHeight = 'thbH', // int32_t, thumbnail height - - // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1) - kKeyCropRect = 'crop', - - kKeyRotation = 'rotA', // int32_t (angle in degrees) - kKeyIFramesInterval = 'ifiv', // int32_t - kKeyStride = 'strd', // int32_t - kKeySliceHeight = 'slht', // int32_t - kKeyChannelCount = '#chn', // int32_t - kKeyChannelMask = 'chnm', // int32_t - kKeySampleRate = 'srte', // int32_t (audio sampling rate Hz) - kKeyPcmEncoding = 'PCMe', // int32_t (audio encoding enum) - kKeyFrameRate = 'frmR', // int32_t (video frame rate fps) - kKeyBitRate = 'brte', // int32_t (bps) - kKeyMaxBitRate = 'mxBr', // int32_t (bps) - kKeyStreamHeader = 'stHd', // raw data - kKeyESDS = 'esds', // raw data - kKeyAACProfile = 'aacp', // int32_t - kKeyAVCC = 'avcc', // raw data - kKeyHVCC = 'hvcc', // raw data - kKeyThumbnailHVCC = 'thvc', // raw data - kKeyD263 = 'd263', // raw data - kKeyVorbisInfo = 'vinf', // raw data - kKeyVorbisBooks = 'vboo', // raw data - kKeyOpusHeader = 'ohdr', // raw data - kKeyOpusCodecDelay = 'ocod', // uint64_t (codec delay in ns) - kKeyOpusSeekPreRoll = 'ospr', // uint64_t (seek preroll in ns) - kKeyFlacMetadata = 'flMd', // raw data - kKeyVp9CodecPrivate = 'vp9p', // raw data (vp9 csd information) - kKeyWantsNALFragments = 'NALf', - kKeyIsSyncFrame = 'sync', // int32_t (bool) - kKeyIsCodecConfig = 'conf', // int32_t (bool) - kKeyTime = 'time', // int64_t (usecs) - kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs) - kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp) - kKeyTargetTime = 'tarT', // int64_t (usecs) - kKeyDriftTime = 'dftT', // int64_t (usecs) - kKeyAnchorTime = 'ancT', // int64_t (usecs) - kKeyDuration = 'dura', // int64_t (usecs) - kKeyPixelFormat = 'pixf', // int32_t - kKeyColorFormat = 'colf', // int32_t - kKeyColorSpace = 'cols', // int32_t - kKeyPlatformPrivate = 'priv', // pointer - kKeyDecoderComponent = 'decC', // cstring - kKeyBufferID = 'bfID', - kKeyMaxInputSize = 'inpS', - kKeyMaxWidth = 'maxW', - kKeyMaxHeight = 'maxH', - kKeyThumbnailTime = 'thbT', // int64_t (usecs) - kKeyTrackID = 'trID', - kKeyIsDRM = 'idrm', // int32_t (bool) - kKeyEncoderDelay = 'encd', // int32_t (frames) - kKeyEncoderPadding = 'encp', // int32_t (frames) - - kKeyAlbum = 'albu', // cstring - kKeyArtist = 'arti', // cstring - kKeyAlbumArtist = 'aart', // cstring - kKeyComposer = 'comp', // cstring - kKeyGenre = 'genr', // cstring - kKeyTitle = 'titl', // cstring - kKeyYear = 'year', // cstring - kKeyAlbumArt = 'albA', // compressed image data - kKeyAlbumArtMIME = 'alAM', // cstring - kKeyAuthor = 'auth', // cstring - kKeyCDTrackNumber = 'cdtr', // cstring - kKeyDiscNumber = 'dnum', // cstring - kKeyDate = 'date', // cstring - kKeyWriter = 'writ', // cstring - kKeyCompilation = 'cpil', // cstring - kKeyLocation = 'loc ', // cstring - kKeyTimeScale = 'tmsl', // int32_t - kKeyCaptureFramerate = 'capF', // float (capture fps) - - // video profile and level - kKeyVideoProfile = 'vprf', // int32_t - kKeyVideoLevel = 'vlev', // int32_t - - // Set this key to enable authoring files in 64-bit offset - kKey64BitFileOffset = 'fobt', // int32_t (bool) - kKey2ByteNalLength = '2NAL', // int32_t (bool) - - // Identify the file output format for authoring - // Please see for the supported - // file output formats. - kKeyFileType = 'ftyp', // int32_t - - // Track authoring progress status - // kKeyTrackTimeStatus is used to track progress in elapsed time - kKeyTrackTimeStatus = 'tktm', // int64_t - - kKeyRealTimeRecording = 'rtrc', // bool (int32_t) - kKeyNumBuffers = 'nbbf', // int32_t - - // Ogg files can be tagged to be automatically looping... - kKeyAutoLoop = 'autL', // bool (int32_t) - - kKeyValidSamples = 'valD', // int32_t - - kKeyIsUnreadable = 'unre', // bool (int32_t) - - // An indication that a video buffer has been rendered. - kKeyRendered = 'rend', // bool (int32_t) - - // The language code for this media - kKeyMediaLanguage = 'lang', // cstring - - // To store the timed text format data - kKeyTextFormatData = 'text', // raw data - - kKeyIsADTS = 'adts', // bool (int32_t) - kKeyAACAOT = 'aaot', // int32_t - - // If a MediaBuffer's data represents (at least partially) encrypted - // data, the following fields aid in decryption. - // The data can be thought of as pairs of plain and encrypted data - // fragments, i.e. plain and encrypted data alternate. - // The first fragment is by convention plain data (if that's not the - // case, simply specify plain fragment size of 0). - // kKeyEncryptedSizes and kKeyPlainSizes each map to an array of - // size_t values. The sum total of all size_t values of both arrays - // must equal the amount of data (i.e. MediaBuffer's range_length()). - // If both arrays are present, they must be of the same size. - // If only encrypted sizes are present it is assumed that all - // plain sizes are 0, i.e. all fragments are encrypted. - // To programmatically set these array, use the MetaData::setData API, i.e. - // const size_t encSizes[]; - // meta->setData( - // kKeyEncryptedSizes, 0 /* type */, encSizes, sizeof(encSizes)); - // A plain sizes array by itself makes no sense. - kKeyEncryptedSizes = 'encr', // size_t[] - kKeyPlainSizes = 'plai', // size_t[] - kKeyCryptoKey = 'cryK', // uint8_t[16] - kKeyCryptoIV = 'cryI', // uint8_t[16] - kKeyCryptoMode = 'cryM', // int32_t - - kKeyCryptoDefaultIVSize = 'cryS', // int32_t - - kKeyPssh = 'pssh', // raw data - kKeyCASystemID = 'caid', // int32_t - kKeyCASessionID = 'seid', // raw data - - // Please see MediaFormat.KEY_IS_AUTOSELECT. - kKeyTrackIsAutoselect = 'auto', // bool (int32_t) - // Please see MediaFormat.KEY_IS_DEFAULT. - kKeyTrackIsDefault = 'dflt', // bool (int32_t) - // Similar to MediaFormat.KEY_IS_FORCED_SUBTITLE but pertains to av tracks as well. - kKeyTrackIsForced = 'frcd', // bool (int32_t) - - // H264 supplemental enhancement information offsets/sizes - kKeySEI = 'sei ', // raw data - - // MPEG user data offsets - kKeyMpegUserData = 'mpud', // size_t[] - - // Size of NALU length in mkv/mp4 - kKeyNalLengthSize = 'nals', // int32_t - - // HDR related - kKeyHdrStaticInfo = 'hdrS', // HDRStaticInfo - - // color aspects - kKeyColorRange = 'cRng', // int32_t, color range, value defined by ColorAspects.Range - kKeyColorPrimaries = 'cPrm', // int32_t, - // color Primaries, value defined by ColorAspects.Primaries - kKeyTransferFunction = 'tFun', // int32_t, - // transfer Function, value defined by ColorAspects.Transfer. - kKeyColorMatrix = 'cMtx', // int32_t, - // color Matrix, value defined by ColorAspects.MatrixCoeffs. - kKeyTemporalLayerId = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer) - kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded - - kKeyGridWidth = 'grdW', // int32_t, HEIF grid width - kKeyGridHeight = 'grdH', // int32_t, HEIF grid height - kKeyGridRows = 'grdR', // int32_t, HEIF grid rows - kKeyGridCols = 'grdC', // int32_t, HEIF grid columns - kKeyIccProfile = 'prof', // raw data, ICC prifile data - kKeyIsPrimaryImage = 'prim', // bool (int32_t), image track is the primary image - kKeyFrameCount = 'nfrm', // int32_t, total number of frame in video track -}; - -enum { - kTypeESDS = 'esds', - kTypeAVCC = 'avcc', - kTypeHVCC = 'hvcc', - kTypeD263 = 'd263', -}; - -class MetaData final : public RefBase { +class MetaData final : public MetaDataBase, public RefBase { public: MetaData(); MetaData(const MetaData &from); - - enum Type { - TYPE_NONE = 'none', - TYPE_C_STRING = 'cstr', - TYPE_INT32 = 'in32', - TYPE_INT64 = 'in64', - TYPE_FLOAT = 'floa', - TYPE_POINTER = 'ptr ', - TYPE_RECT = 'rect', - }; - - void clear(); - bool remove(uint32_t key); - - bool setCString(uint32_t key, const char *value); - bool setInt32(uint32_t key, int32_t value); - bool setInt64(uint32_t key, int64_t value); - bool setFloat(uint32_t key, float value); - bool setPointer(uint32_t key, void *value); - - bool setRect( - uint32_t key, - int32_t left, int32_t top, - int32_t right, int32_t bottom); - - bool findCString(uint32_t key, const char **value) const; - bool findInt32(uint32_t key, int32_t *value) const; - bool findInt64(uint32_t key, int64_t *value) const; - bool findFloat(uint32_t key, float *value) const; - bool findPointer(uint32_t key, void **value) const; - - bool findRect( - uint32_t key, - int32_t *left, int32_t *top, - int32_t *right, int32_t *bottom) const; - - bool setData(uint32_t key, uint32_t type, const void *data, size_t size); - - bool findData(uint32_t key, uint32_t *type, - const void **data, size_t *size) const; - - bool hasData(uint32_t key) const; - - String8 toString() const; - void dumpToLog() const; + MetaData(const MetaDataBase &from); protected: virtual ~MetaData(); private: - friend class BpMediaSource; friend class BnMediaSource; + friend class BpMediaSource; friend class BpMediaExtractor; - friend class BnMediaExtractor; - - status_t writeToParcel(Parcel &parcel); - status_t updateFromParcel(const Parcel &parcel); static sp createFromParcel(const Parcel &parcel); - struct typed_data; - struct Rect; - struct MetaDataInternal; - MetaDataInternal *mInternalData; }; } // namespace android diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h new file mode 100644 index 0000000000000000000000000000000000000000..6010af4c3e99a5728aff60e9213a7c9b5707ea94 --- /dev/null +++ b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef META_DATA_BASE_H_ + +#define META_DATA_BASE_H_ + +#include + +#include + +#include +#include + +namespace android { + +// The following keys map to int32_t data unless indicated otherwise. +enum { + kKeyMIMEType = 'mime', // cstring + kKeyWidth = 'widt', // int32_t, image pixel + kKeyHeight = 'heig', // int32_t, image pixel + kKeyDisplayWidth = 'dWid', // int32_t, display/presentation + kKeyDisplayHeight = 'dHgt', // int32_t, display/presentation + kKeySARWidth = 'sarW', // int32_t, sampleAspectRatio width + kKeySARHeight = 'sarH', // int32_t, sampleAspectRatio height + kKeyThumbnailWidth = 'thbW', // int32_t, thumbnail width + kKeyThumbnailHeight = 'thbH', // int32_t, thumbnail height + + // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1) + kKeyCropRect = 'crop', + + kKeyRotation = 'rotA', // int32_t (angle in degrees) + kKeyIFramesInterval = 'ifiv', // int32_t + kKeyStride = 'strd', // int32_t + kKeySliceHeight = 'slht', // int32_t + kKeyChannelCount = '#chn', // int32_t + kKeyChannelMask = 'chnm', // int32_t + kKeySampleRate = 'srte', // int32_t (audio sampling rate Hz) + kKeyPcmEncoding = 'PCMe', // int32_t (audio encoding enum) + kKeyFrameRate = 'frmR', // int32_t (video frame rate fps) + kKeyBitRate = 'brte', // int32_t (bps) + kKeyMaxBitRate = 'mxBr', // int32_t (bps) + kKeyStreamHeader = 'stHd', // raw data + kKeyESDS = 'esds', // raw data + kKeyAACProfile = 'aacp', // int32_t + kKeyAVCC = 'avcc', // raw data + kKeyHVCC = 'hvcc', // raw data + kKeyThumbnailHVCC = 'thvc', // raw data + kKeyD263 = 'd263', // raw data + kKeyVorbisInfo = 'vinf', // raw data + kKeyVorbisBooks = 'vboo', // raw data + kKeyOpusHeader = 'ohdr', // raw data + kKeyOpusCodecDelay = 'ocod', // uint64_t (codec delay in ns) + kKeyOpusSeekPreRoll = 'ospr', // uint64_t (seek preroll in ns) + kKeyFlacMetadata = 'flMd', // raw data + kKeyVp9CodecPrivate = 'vp9p', // raw data (vp9 csd information) + kKeyWantsNALFragments = 'NALf', + kKeyIsSyncFrame = 'sync', // int32_t (bool) + kKeyIsCodecConfig = 'conf', // int32_t (bool) + kKeyTime = 'time', // int64_t (usecs) + kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs) + kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp) + kKeyTargetTime = 'tarT', // int64_t (usecs) + kKeyDriftTime = 'dftT', // int64_t (usecs) + kKeyAnchorTime = 'ancT', // int64_t (usecs) + kKeyDuration = 'dura', // int64_t (usecs) + kKeyPixelFormat = 'pixf', // int32_t + kKeyColorFormat = 'colf', // int32_t + kKeyColorSpace = 'cols', // int32_t + kKeyPlatformPrivate = 'priv', // pointer + kKeyDecoderComponent = 'decC', // cstring + kKeyBufferID = 'bfID', + kKeyMaxInputSize = 'inpS', + kKeyMaxWidth = 'maxW', + kKeyMaxHeight = 'maxH', + kKeyThumbnailTime = 'thbT', // int64_t (usecs) + kKeyTrackID = 'trID', + kKeyIsDRM = 'idrm', // int32_t (bool) + kKeyEncoderDelay = 'encd', // int32_t (frames) + kKeyEncoderPadding = 'encp', // int32_t (frames) + + kKeyAlbum = 'albu', // cstring + kKeyArtist = 'arti', // cstring + kKeyAlbumArtist = 'aart', // cstring + kKeyComposer = 'comp', // cstring + kKeyGenre = 'genr', // cstring + kKeyTitle = 'titl', // cstring + kKeyYear = 'year', // cstring + kKeyAlbumArt = 'albA', // compressed image data + kKeyAlbumArtMIME = 'alAM', // cstring + kKeyAuthor = 'auth', // cstring + kKeyCDTrackNumber = 'cdtr', // cstring + kKeyDiscNumber = 'dnum', // cstring + kKeyDate = 'date', // cstring + kKeyWriter = 'writ', // cstring + kKeyCompilation = 'cpil', // cstring + kKeyLocation = 'loc ', // cstring + kKeyTimeScale = 'tmsl', // int32_t + kKeyCaptureFramerate = 'capF', // float (capture fps) + + // video profile and level + kKeyVideoProfile = 'vprf', // int32_t + kKeyVideoLevel = 'vlev', // int32_t + + // Set this key to enable authoring files in 64-bit offset + kKey64BitFileOffset = 'fobt', // int32_t (bool) + kKey2ByteNalLength = '2NAL', // int32_t (bool) + + // Identify the file output format for authoring + // Please see for the supported + // file output formats. + kKeyFileType = 'ftyp', // int32_t + + // Track authoring progress status + // kKeyTrackTimeStatus is used to track progress in elapsed time + kKeyTrackTimeStatus = 'tktm', // int64_t + + kKeyRealTimeRecording = 'rtrc', // bool (int32_t) + kKeyNumBuffers = 'nbbf', // int32_t + + // Ogg files can be tagged to be automatically looping... + kKeyAutoLoop = 'autL', // bool (int32_t) + + kKeyValidSamples = 'valD', // int32_t + + kKeyIsUnreadable = 'unre', // bool (int32_t) + + // An indication that a video buffer has been rendered. + kKeyRendered = 'rend', // bool (int32_t) + + // The language code for this media + kKeyMediaLanguage = 'lang', // cstring + + // To store the timed text format data + kKeyTextFormatData = 'text', // raw data + + kKeyRequiresSecureBuffers = 'secu', // bool (int32_t) + + kKeyIsADTS = 'adts', // bool (int32_t) + kKeyAACAOT = 'aaot', // int32_t + + // If a MediaBuffer's data represents (at least partially) encrypted + // data, the following fields aid in decryption. + // The data can be thought of as pairs of plain and encrypted data + // fragments, i.e. plain and encrypted data alternate. + // The first fragment is by convention plain data (if that's not the + // case, simply specify plain fragment size of 0). + // kKeyEncryptedSizes and kKeyPlainSizes each map to an array of + // size_t values. The sum total of all size_t values of both arrays + // must equal the amount of data (i.e. MediaBuffer's range_length()). + // If both arrays are present, they must be of the same size. + // If only encrypted sizes are present it is assumed that all + // plain sizes are 0, i.e. all fragments are encrypted. + // To programmatically set these array, use the MetaDataBase::setData API, i.e. + // const size_t encSizes[]; + // meta->setData( + // kKeyEncryptedSizes, 0 /* type */, encSizes, sizeof(encSizes)); + // A plain sizes array by itself makes no sense. + kKeyEncryptedSizes = 'encr', // size_t[] + kKeyPlainSizes = 'plai', // size_t[] + kKeyCryptoKey = 'cryK', // uint8_t[16] + kKeyCryptoIV = 'cryI', // uint8_t[16] + kKeyCryptoMode = 'cryM', // int32_t + + kKeyCryptoDefaultIVSize = 'cryS', // int32_t + + kKeyPssh = 'pssh', // raw data + kKeyCASystemID = 'caid', // int32_t + kKeyCASessionID = 'seid', // raw data + + // Please see MediaFormat.KEY_IS_AUTOSELECT. + kKeyTrackIsAutoselect = 'auto', // bool (int32_t) + // Please see MediaFormat.KEY_IS_DEFAULT. + kKeyTrackIsDefault = 'dflt', // bool (int32_t) + // Similar to MediaFormat.KEY_IS_FORCED_SUBTITLE but pertains to av tracks as well. + kKeyTrackIsForced = 'frcd', // bool (int32_t) + + // H264 supplemental enhancement information offsets/sizes + kKeySEI = 'sei ', // raw data + + // MPEG user data offsets + kKeyMpegUserData = 'mpud', // size_t[] + + // Size of NALU length in mkv/mp4 + kKeyNalLengthSize = 'nals', // int32_t + + // HDR related + kKeyHdrStaticInfo = 'hdrS', // HDRStaticInfo + + // color aspects + kKeyColorRange = 'cRng', // int32_t, color range, value defined by ColorAspects.Range + kKeyColorPrimaries = 'cPrm', // int32_t, + // color Primaries, value defined by ColorAspects.Primaries + kKeyTransferFunction = 'tFun', // int32_t, + // transfer Function, value defined by ColorAspects.Transfer. + kKeyColorMatrix = 'cMtx', // int32_t, + // color Matrix, value defined by ColorAspects.MatrixCoeffs. + kKeyTemporalLayerId = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer) + kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded + + kKeyGridWidth = 'grdW', // int32_t, HEIF grid width + kKeyGridHeight = 'grdH', // int32_t, HEIF grid height + kKeyGridRows = 'grdR', // int32_t, HEIF grid rows + kKeyGridCols = 'grdC', // int32_t, HEIF grid columns + kKeyIccProfile = 'prof', // raw data, ICC prifile data + kKeyIsPrimaryImage = 'prim', // bool (int32_t), image track is the primary image + kKeyFrameCount = 'nfrm', // int32_t, total number of frame in video track +}; + +enum { + kTypeESDS = 'esds', + kTypeAVCC = 'avcc', + kTypeHVCC = 'hvcc', + kTypeD263 = 'd263', +}; + +class Parcel; + +class MetaDataBase { +public: + MetaDataBase(); + MetaDataBase(const MetaDataBase &from); + MetaDataBase& operator = (const MetaDataBase &); + + virtual ~MetaDataBase(); + + enum Type { + TYPE_NONE = 'none', + TYPE_C_STRING = 'cstr', + TYPE_INT32 = 'in32', + TYPE_INT64 = 'in64', + TYPE_FLOAT = 'floa', + TYPE_POINTER = 'ptr ', + TYPE_RECT = 'rect', + }; + + void clear(); + bool remove(uint32_t key); + + bool setCString(uint32_t key, const char *value); + bool setInt32(uint32_t key, int32_t value); + bool setInt64(uint32_t key, int64_t value); + bool setFloat(uint32_t key, float value); + bool setPointer(uint32_t key, void *value); + + bool setRect( + uint32_t key, + int32_t left, int32_t top, + int32_t right, int32_t bottom); + + bool findCString(uint32_t key, const char **value) const; + bool findInt32(uint32_t key, int32_t *value) const; + bool findInt64(uint32_t key, int64_t *value) const; + bool findFloat(uint32_t key, float *value) const; + bool findPointer(uint32_t key, void **value) const; + + bool findRect( + uint32_t key, + int32_t *left, int32_t *top, + int32_t *right, int32_t *bottom) const; + + bool setData(uint32_t key, uint32_t type, const void *data, size_t size); + + bool findData(uint32_t key, uint32_t *type, + const void **data, size_t *size) const; + + bool hasData(uint32_t key) const; + + String8 toString() const; + void dumpToLog() const; + +private: + friend class BpMediaSource; + friend class BnMediaSource; + friend class BnMediaExtractor; + friend class MetaData; + + struct typed_data; + struct Rect; + struct MetaDataInternal; + MetaDataInternal *mInternalData; + status_t writeToParcel(Parcel &parcel); + status_t updateFromParcel(const Parcel &parcel); +}; + +} // namespace android + +#endif // META_DATA_H_ diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp index c34aabb9ba0f246d385a6b6072ed827701ab2e92..1b540f70e3c58d50057d0570c4b6c607f608bf5f 100644 --- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp +++ b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp @@ -1187,7 +1187,7 @@ sp NuPlayer2::GenericSource2::mediaBufferToABuffer( if (audio && mAudioIsVorbis) { int32_t numPageSamples; - if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) { + if (!mb->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) { numPageSamples = -1; } @@ -1198,12 +1198,12 @@ sp NuPlayer2::GenericSource2::mediaBufferToABuffer( sp meta = ab->meta(); int64_t timeUs; - CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(mb->meta_data().findInt64(kKeyTime, &timeUs)); meta->setInt64("timeUs", timeUs); if (trackType == MEDIA_TRACK_TYPE_VIDEO) { int32_t layerId; - if (mb->meta_data()->findInt32(kKeyTemporalLayerId, &layerId)) { + if (mb->meta_data().findInt32(kKeyTemporalLayerId, &layerId)) { meta->setInt32("temporal-layer-id", layerId); } } @@ -1216,7 +1216,7 @@ sp NuPlayer2::GenericSource2::mediaBufferToABuffer( } int64_t durationUs; - if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) { + if (mb->meta_data().findInt64(kKeyDuration, &durationUs)) { meta->setInt64("durationUs", durationUs); } @@ -1227,14 +1227,14 @@ sp NuPlayer2::GenericSource2::mediaBufferToABuffer( uint32_t dataType; // unused const void *seiData; size_t seiLength; - if (mb->meta_data()->findData(kKeySEI, &dataType, &seiData, &seiLength)) { + if (mb->meta_data().findData(kKeySEI, &dataType, &seiData, &seiLength)) { sp sei = ABuffer::CreateAsCopy(seiData, seiLength);; meta->setBuffer("sei", sei); } const void *mpegUserDataPointer; size_t mpegUserDataLength; - if (mb->meta_data()->findData( + if (mb->meta_data().findData( kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) { sp mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength); meta->setBuffer("mpegUserData", mpegUserData); @@ -1366,8 +1366,8 @@ void NuPlayer2::GenericSource2::readBuffer( for (; id < count; ++id) { int64_t timeUs; MediaBufferBase *mbuf = mediaBuffers[id]; - if (!mbuf->meta_data()->findInt64(kKeyTime, &timeUs)) { - mbuf->meta_data()->dumpToLog(); + if (!mbuf->meta_data().findInt64(kKeyTime, &timeUs)) { + mbuf->meta_data().dumpToLog(); track->mPackets->signalEOS(ERROR_MALFORMED); break; } diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp index c49bccb60fa100a26858ac411046a2a80e3575e7..645138a722f0b055b0bcc24f1c6006b0f45fec0c 100644 --- a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp +++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp @@ -1091,7 +1091,7 @@ bool NuPlayer2::Decoder::onInputBufferFetched(const sp &msg) { codecBuffer->setRange(0, mediaBuf->size()); memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size()); - sp meta_data = mediaBuf->meta_data(); + MetaDataBase &meta_data = mediaBuf->meta_data(); cryptInfo = AMediaCodecCryptoInfoWrapper::Create(meta_data); } else { // No mediaBuf ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p", diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index b0c82f26c697e15177b890b1d588c6e734429298..49e3555ee938af2420e0988199806a9a7c0e8b7d 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -1180,7 +1180,7 @@ sp NuPlayer::GenericSource::mediaBufferToABuffer( if (audio && mAudioIsVorbis) { int32_t numPageSamples; - if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) { + if (!mb->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) { numPageSamples = -1; } @@ -1191,12 +1191,12 @@ sp NuPlayer::GenericSource::mediaBufferToABuffer( sp meta = ab->meta(); int64_t timeUs; - CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(mb->meta_data().findInt64(kKeyTime, &timeUs)); meta->setInt64("timeUs", timeUs); if (trackType == MEDIA_TRACK_TYPE_VIDEO) { int32_t layerId; - if (mb->meta_data()->findInt32(kKeyTemporalLayerId, &layerId)) { + if (mb->meta_data().findInt32(kKeyTemporalLayerId, &layerId)) { meta->setInt32("temporal-layer-id", layerId); } } @@ -1209,7 +1209,7 @@ sp NuPlayer::GenericSource::mediaBufferToABuffer( } int64_t durationUs; - if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) { + if (mb->meta_data().findInt64(kKeyDuration, &durationUs)) { meta->setInt64("durationUs", durationUs); } @@ -1220,14 +1220,14 @@ sp NuPlayer::GenericSource::mediaBufferToABuffer( uint32_t dataType; // unused const void *seiData; size_t seiLength; - if (mb->meta_data()->findData(kKeySEI, &dataType, &seiData, &seiLength)) { + if (mb->meta_data().findData(kKeySEI, &dataType, &seiData, &seiLength)) { sp sei = ABuffer::CreateAsCopy(seiData, seiLength);; meta->setBuffer("sei", sei); } const void *mpegUserDataPointer; size_t mpegUserDataLength; - if (mb->meta_data()->findData( + if (mb->meta_data().findData( kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) { sp mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength); meta->setBuffer("mpegUserData", mpegUserData); @@ -1359,8 +1359,8 @@ void NuPlayer::GenericSource::readBuffer( for (; id < count; ++id) { int64_t timeUs; MediaBufferBase *mbuf = mediaBuffers[id]; - if (!mbuf->meta_data()->findInt64(kKeyTime, &timeUs)) { - mbuf->meta_data()->dumpToLog(); + if (!mbuf->meta_data().findInt64(kKeyTime, &timeUs)) { + mbuf->meta_data().dumpToLog(); track->mPackets->signalEOS(ERROR_MALFORMED); break; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 88594d202472522adb03ecdc21f2725b7fd534a7..2a08f6282060b21a949c390f1b16c83b4c72352d 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -1071,7 +1071,7 @@ bool NuPlayer::Decoder::onInputBufferFetched(const sp &msg) { codecBuffer->setRange(0, mediaBuf->size()); memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size()); - sp meta_data = mediaBuf->meta_data(); + MetaDataBase &meta_data = mediaBuf->meta_data(); cryptInfo = NuPlayerDrm::getSampleCryptoInfo(meta_data); } else { // No mediaBuf ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p", diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp index b7c9db7900070995172acacb329a554f234c5b61..165e483403a8833e9dc0177d65b22aeb805eddab 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp @@ -265,18 +265,13 @@ NuPlayerDrm::CryptoInfo *NuPlayerDrm::makeCryptoInfo( return ret; } -NuPlayerDrm::CryptoInfo *NuPlayerDrm::getSampleCryptoInfo(sp meta) +NuPlayerDrm::CryptoInfo *NuPlayerDrm::getSampleCryptoInfo(MetaDataBase &meta) { uint32_t type; const void *crypteddata; size_t cryptedsize; - if (meta == NULL) { - ALOGE("getSampleCryptoInfo: Unexpected. No meta data for sample."); - return NULL; - } - - if (!meta->findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) { + if (!meta.findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) { return NULL; } size_t numSubSamples = cryptedsize / sizeof(size_t); @@ -288,7 +283,7 @@ NuPlayerDrm::CryptoInfo *NuPlayerDrm::getSampleCryptoInfo(sp meta) const void *cleardata; size_t clearsize; - if (meta->findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) { + if (meta.findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) { if (clearsize != cryptedsize) { // The two must be of the same length. ALOGE("getSampleCryptoInfo mismatch cryptedsize: %zu != clearsize: %zu", @@ -299,7 +294,7 @@ NuPlayerDrm::CryptoInfo *NuPlayerDrm::getSampleCryptoInfo(sp meta) const void *key; size_t keysize; - if (meta->findData(kKeyCryptoKey, &type, &key, &keysize)) { + if (meta.findData(kKeyCryptoKey, &type, &key, &keysize)) { if (keysize != kBlockSize) { ALOGE("getSampleCryptoInfo Keys must be %d bytes in length: %zu", kBlockSize, keysize); @@ -310,7 +305,7 @@ NuPlayerDrm::CryptoInfo *NuPlayerDrm::getSampleCryptoInfo(sp meta) const void *iv; size_t ivsize; - if (meta->findData(kKeyCryptoIV, &type, &iv, &ivsize)) { + if (meta.findData(kKeyCryptoIV, &type, &iv, &ivsize)) { if (ivsize != kBlockSize) { ALOGE("getSampleCryptoInfo IV must be %d bytes in length: %zu", kBlockSize, ivsize); @@ -320,7 +315,7 @@ NuPlayerDrm::CryptoInfo *NuPlayerDrm::getSampleCryptoInfo(sp meta) } int32_t mode; - if (!meta->findInt32(kKeyCryptoMode, &mode)) { + if (!meta.findInt32(kKeyCryptoMode, &mode)) { mode = CryptoPlugin::kMode_AES_CTR; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h index 6b8a2d9b77dac4af47892f670bba4586d3cf7c8c..50f69ff40ee414158cd6d5de7b1828ad94e9ed88 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h @@ -109,7 +109,7 @@ namespace android { size_t *clearbytes, size_t *encryptedbytes); - static CryptoInfo *getSampleCryptoInfo(sp meta); + static CryptoInfo *getSampleCryptoInfo(MetaDataBase &meta); }; // NuPlayerDrm diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp index d64138ef0b6d22bd7a4b942e800e550e6149609c..2ea5fcdd190b1a02e7f2cc250a833f9869db7e31 100644 --- a/media/libstagefright/AACWriter.cpp +++ b/media/libstagefright/AACWriter.cpp @@ -316,7 +316,7 @@ status_t AACWriter::threadFunc() { } int32_t isCodecSpecific = 0; - if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecSpecific) && isCodecSpecific) { + if (buffer->meta_data().findInt32(kKeyIsCodecConfig, &isCodecSpecific) && isCodecSpecific) { ALOGV("Drop codec specific info buffer"); buffer->release(); buffer = NULL; @@ -324,7 +324,7 @@ status_t AACWriter::threadFunc() { } int64_t timestampUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, ×tampUs)); if (timestampUs > mEstimatedDurationUs) { mEstimatedDurationUs = timestampUs; } diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp index e33d3da812d7a537510be4ed8952eb0738e43647..41106a1186ab3a72e24a9f6eb813c215116da109 100644 --- a/media/libstagefright/AMRWriter.cpp +++ b/media/libstagefright/AMRWriter.cpp @@ -215,7 +215,7 @@ status_t AMRWriter::threadFunc() { } int64_t timestampUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, ×tampUs)); if (timestampUs > mEstimatedDurationUs) { mEstimatedDurationUs = timestampUs; } diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index 16ea5b5bb23a17864b995cd162bd2584246933b8..a6f0a0ba407d2830d3b46728dc3a87e5942937a1 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -543,7 +543,7 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) { } if(mInputBuffer->range_length() != 0) { - CHECK(mInputBuffer->meta_data()->findInt64( + CHECK(mInputBuffer->meta_data().findInt64( kKeyTime, &mPositionTimeMediaUs)); } diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp index d8545824dddc9294854965ac7258a67799db9c96..2ae3218ddaefb14d4fdb0348b254192c9f173c8f 100644 --- a/media/libstagefright/AudioSource.cpp +++ b/media/libstagefright/AudioSource.cpp @@ -265,7 +265,7 @@ status_t AudioSource::read( // Mute/suppress the recording sound int64_t timeUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs)); int64_t elapsedTimeUs = timeUs - mStartTimeUs; if (elapsedTimeUs < kAutoRampStartUs) { memset((uint8_t *) buffer->data(), 0, buffer->range_length()); @@ -289,7 +289,7 @@ status_t AudioSource::read( if (mSampleRate != mOutSampleRate) { timeUs *= (int64_t)mSampleRate / (int64_t)mOutSampleRate; - buffer->meta_data()->setInt64(kKeyTime, timeUs); + buffer->meta_data().setInt64(kKeyTime, timeUs); } *out = buffer; @@ -433,11 +433,11 @@ void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) { (mSampleRate >> 1)) / mSampleRate; if (mNumFramesReceived == 0) { - buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs); + buffer->meta_data().setInt64(kKeyAnchorTime, mStartTimeUs); } - buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs); - buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs); + buffer->meta_data().setInt64(kKeyTime, mPrevSampleTimeUs); + buffer->meta_data().setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs); mPrevSampleTimeUs = timestampUs; mNumFramesReceived += bufferSize / frameSize; mBuffersReceived.push_back(buffer); diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 4960418dd36b02366fc59592f58936b8588c5464..db37021c6a63b84933dd436f0a5ddd364677e041 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -1100,7 +1100,7 @@ status_t CameraSource::read( *buffer = new MediaBuffer(frame->pointer(), frame->size()); (*buffer)->setObserver(this); (*buffer)->add_ref(); - (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); + (*buffer)->meta_data().setInt64(kKeyTime, frameTime); } return OK; } diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp index f3f06d8e92e9effe4a406c364aa2470c9abdb2c9..3ad82d9431d3dbc3dd3d67351be47826cc004400 100644 --- a/media/libstagefright/CameraSourceTimeLapse.cpp +++ b/media/libstagefright/CameraSourceTimeLapse.cpp @@ -191,13 +191,13 @@ void createMediaBufferCopy( (*newBuffer) = new MediaBuffer(sourceSize); memcpy((*newBuffer)->data(), sourcePointer, sourceSize); - (*newBuffer)->meta_data()->setInt64(kKeyTime, frameTime); + (*newBuffer)->meta_data().setInt64(kKeyTime, frameTime); } void CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBufferBase& sourceBuffer) { ALOGV("fillLastReadBufferCopy"); int64_t frameTime; - CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime)); + CHECK(sourceBuffer.meta_data().findInt64(kKeyTime, &frameTime)); createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy); mLastReadBufferCopy->add_ref(); mLastReadBufferCopy->setObserver(this); diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp index 6f88c0ec93c895ac19e7713337fea0122c045cb4..9748a8bd0637ab7d9527e35771ad07c4dea01edf 100644 --- a/media/libstagefright/FrameDecoder.cpp +++ b/media/libstagefright/FrameDecoder.cpp @@ -251,7 +251,7 @@ status_t FrameDecoder::extractInternal( } else { codecBuffer->setRange(0, mediaBuffer->range_length()); - CHECK(mediaBuffer->meta_data()->findInt64(kKeyTime, &ptsUs)); + CHECK(mediaBuffer->meta_data().findInt64(kKeyTime, &ptsUs)); memcpy(codecBuffer->data(), (const uint8_t*)mediaBuffer->data() + mediaBuffer->range_offset(), mediaBuffer->range_length()); @@ -387,12 +387,12 @@ sp VideoFrameDecoder::onGetFormatAndSeekOptions( status_t VideoFrameDecoder::onInputReceived( const sp &codecBuffer, - const sp &sampleMeta, bool firstSample, uint32_t *flags) { + MetaDataBase &sampleMeta, bool firstSample, uint32_t *flags) { bool isSeekingClosest = (mSeekMode == MediaSource::ReadOptions::SEEK_CLOSEST) || (mSeekMode == MediaSource::ReadOptions::SEEK_FRAME_INDEX); if (firstSample && isSeekingClosest) { - sampleMeta->findInt64(kKeyTargetTime, &mTargetTimeUs); + sampleMeta.findInt64(kKeyTargetTime, &mTargetTimeUs); ALOGV("Seeking closest: targetTimeUs=%lld", (long long)mTargetTimeUs); } diff --git a/media/libstagefright/InterfaceUtils.cpp b/media/libstagefright/InterfaceUtils.cpp index 70fbbd744ed1858cb39f66364ebb6c19f021565e..56c5908931bc1361f3a89714175baff6859f6e21 100644 --- a/media/libstagefright/InterfaceUtils.cpp +++ b/media/libstagefright/InterfaceUtils.cpp @@ -56,7 +56,7 @@ sp CreateMediaSourceFromIMediaSource(const sp &source sp CreateIMediaSourceFromMediaSourceBase( const sp &extractor, - MediaSourceBase *source, const sp &plugin) { + MediaTrack *source, const sp &plugin) { if (source == nullptr) { return nullptr; } diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp index cdcd657bf0b1fdf48a01a762d8269a5ffe018838..770535c2f52a92fe3f69449245727233d9368181 100644 --- a/media/libstagefright/MPEG2TSWriter.cpp +++ b/media/libstagefright/MPEG2TSWriter.cpp @@ -264,11 +264,11 @@ void MPEG2TSWriter::SourceInfo::appendAVCFrame(MediaBufferBase *buffer) { buffer->range_length()); int64_t timeUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs)); mBuffer->meta()->setInt64("timeUs", timeUs); int32_t isSync; - if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync) + if (buffer->meta_data().findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) { mBuffer->meta()->setInt32("isSync", true); } @@ -288,7 +288,7 @@ void MPEG2TSWriter::SourceInfo::appendAACFrames(MediaBufferBase *buffer) { } int64_t timeUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs)); mBuffer->meta()->setInt64("timeUs", timeUs); mBuffer->meta()->setInt32("isSync", true); diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 387cb13df111a6ce5f926d1aa0ad6712c9dbf5b1..cfbbcb2eaba8b73bf11c56e4c3f979132c0ef43f 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -2831,7 +2831,7 @@ status_t MPEG4Writer::Track::threadEntry() { ++count; int32_t isCodecConfig; - if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) + if (buffer->meta_data().findInt32(kKeyIsCodecConfig, &isCodecConfig) && isCodecConfig) { // if config format (at track addition) already had CSD, keep that // UNLESS we have not received any frames yet. @@ -2890,7 +2890,7 @@ status_t MPEG4Writer::Track::threadEntry() { memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), buffer->range_length()); copy->set_range(0, buffer->range_length()); - meta_data = new MetaData(*buffer->meta_data().get()); + meta_data = new MetaData(buffer->meta_data()); buffer->release(); buffer = NULL; diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index 08331ad62e77e67166cd80e76bf92336d561a075..20881a4bb542be1966225e68d09f9cca1a9583b5 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -692,7 +692,7 @@ status_t MediaCodecSource::feedEncoderInputBuffers() { size_t size = 0; if (mbuf != NULL) { - CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(mbuf->meta_data().findInt64(kKeyTime, &timeUs)); if (mFirstSampleSystemTimeUs < 0ll) { mFirstSampleSystemTimeUs = systemTime() / 1000; if (mPausePending) { @@ -715,7 +715,7 @@ status_t MediaCodecSource::feedEncoderInputBuffers() { mFirstSampleTimeUs = timeUs; } int64_t driftTimeUs = 0; - if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs) + if (mbuf->meta_data().findInt64(kKeyDriftTime, &driftTimeUs) && driftTimeUs) { driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs; } @@ -937,7 +937,7 @@ void MediaCodecSource::onMessageReceived(const sp &msg) { decodingTimeUs = *(mDecodingTimeQueue.begin()); mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); } - mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); + mbuf->meta_data().setInt64(kKeyDecodingTime, decodingTimeUs); ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, timeUs, timeUs / 1E6, decodingTimeUs - timeUs); @@ -947,18 +947,18 @@ void MediaCodecSource::onMessageReceived(const sp &msg) { CHECK(!mDriftTimeQueue.empty()); driftTimeUs = *(mDriftTimeQueue.begin()); mDriftTimeQueue.erase(mDriftTimeQueue.begin()); - mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); + mbuf->meta_data().setInt64(kKeyDriftTime, driftTimeUs); #endif // DEBUG_DRIFT_TIME ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, timeUs, timeUs / 1E6, driftTimeUs); } - mbuf->meta_data()->setInt64(kKeyTime, timeUs); + mbuf->meta_data().setInt64(kKeyTime, timeUs); } else { - mbuf->meta_data()->setInt64(kKeyTime, 0ll); - mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); + mbuf->meta_data().setInt64(kKeyTime, 0ll); + mbuf->meta_data().setInt32(kKeyIsCodecConfig, true); } if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { - mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); + mbuf->meta_data().setInt32(kKeyIsSyncFrame, true); } memcpy(mbuf->data(), outbuf->data(), outbuf->size()); diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp index 62daac8841421e7533317bea8c6c78a542ea6e4e..23e543dc3c675653f0879a449093fc0033eaddbb 100644 --- a/media/libstagefright/MediaMuxer.cpp +++ b/media/libstagefright/MediaMuxer.cpp @@ -181,13 +181,13 @@ status_t MediaMuxer::writeSampleData(const sp &buffer, size_t trackInde mediaBuffer->add_ref(); // Released in MediaAdapter::signalBufferReturned(). mediaBuffer->set_range(buffer->offset(), buffer->size()); - sp sampleMetaData = mediaBuffer->meta_data(); - sampleMetaData->setInt64(kKeyTime, timeUs); + MetaDataBase &sampleMetaData = mediaBuffer->meta_data(); + sampleMetaData.setInt64(kKeyTime, timeUs); // Just set the kKeyDecodingTime as the presentation time for now. - sampleMetaData->setInt64(kKeyDecodingTime, timeUs); + sampleMetaData.setInt64(kKeyDecodingTime, timeUs); if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { - sampleMetaData->setInt32(kKeyIsSyncFrame, true); + sampleMetaData.setInt32(kKeyIsSyncFrame, true); } sp currentTrack = mTrackList[trackIndex]; diff --git a/media/libstagefright/MetaDataUtils.cpp b/media/libstagefright/MetaDataUtils.cpp index ac1f33f202b290f3af769a7e963b844ace1973c2..af8f539e3588f03160f2b81f21d07d5a2b30b492 100644 --- a/media/libstagefright/MetaDataUtils.cpp +++ b/media/libstagefright/MetaDataUtils.cpp @@ -24,33 +24,33 @@ namespace android { -sp MakeAVCCodecSpecificData(const sp &accessUnit) { +bool MakeAVCCodecSpecificData(MetaDataBase &meta, const sp &accessUnit) { int32_t width; int32_t height; int32_t sarWidth; int32_t sarHeight; sp csd = MakeAVCCodecSpecificData(accessUnit, &width, &height, &sarWidth, &sarHeight); if (csd == nullptr) { - return nullptr; + return false; } - sp meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); - meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size()); - meta->setInt32(kKeyWidth, width); - meta->setInt32(kKeyHeight, height); + meta.setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size()); + meta.setInt32(kKeyWidth, width); + meta.setInt32(kKeyHeight, height); if (sarWidth > 0 && sarHeight > 0) { - meta->setInt32(kKeySARWidth, sarWidth); - meta->setInt32(kKeySARHeight, sarHeight); + meta.setInt32(kKeySARWidth, sarWidth); + meta.setInt32(kKeySARHeight, sarHeight); } - return meta; + return true; } -sp MakeAACCodecSpecificData( +bool MakeAACCodecSpecificData( + MetaDataBase &meta, unsigned profile, unsigned sampling_freq_index, unsigned channel_configuration) { if(sampling_freq_index > 11u) { - return nullptr; + return false; } int32_t sampleRate; int32_t channelCount; @@ -91,15 +91,14 @@ sp MakeAACCodecSpecificData( csd[sizeof(kStaticESDS) + 1] = ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3); - sp meta = new MetaData; - meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); + meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); - meta->setInt32(kKeySampleRate, sampleRate); - meta->setInt32(kKeyChannelCount, channelCount); + meta.setInt32(kKeySampleRate, sampleRate); + meta.setInt32(kKeyChannelCount, channelCount); - meta->setData(kKeyESDS, 0, csd, csdSize); + meta.setData(kKeyESDS, 0, csd, csdSize); delete [] csd; - return meta; + return true; } } // namespace android diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp index c6cbb2f085813242f3351f72707f44e5d94c5452..540cf8cb8f232ada90c522b97c6db05a643c5a15 100644 --- a/media/libstagefright/NuMediaExtractor.cpp +++ b/media/libstagefright/NuMediaExtractor.cpp @@ -525,10 +525,10 @@ void NuMediaExtractor::fetchTrackSamples(TrackInfo *info, mbuf->release(); continue; } - if (mbuf->meta_data()->findInt64(kKeyTime, &timeUs)) { + if (mbuf->meta_data().findInt64(kKeyTime, &timeUs)) { info->mSamples.emplace_back(mbuf, timeUs); } else { - mbuf->meta_data()->dumpToLog(); + mbuf->meta_data().dumpToLog(); info->mFinalResult = ERROR_MALFORMED; mbuf->release(); releaseRemaining = true; @@ -568,7 +568,7 @@ status_t NuMediaExtractor::advance() { status_t NuMediaExtractor::appendVorbisNumPageSamples( MediaBufferBase *mbuf, const sp &buffer) { int32_t numPageSamples; - if (!mbuf->meta_data()->findInt32( + if (!mbuf->meta_data().findInt32( kKeyValidSamples, &numPageSamples)) { numPageSamples = -1; } @@ -580,7 +580,7 @@ status_t NuMediaExtractor::appendVorbisNumPageSamples( uint32_t type; const void *data; size_t size, size2; - if (mbuf->meta_data()->findData(kKeyEncryptedSizes, &type, &data, &size)) { + if (mbuf->meta_data().findData(kKeyEncryptedSizes, &type, &data, &size)) { // Signal numPageSamples (a plain int32_t) is appended at the end, // i.e. sizeof(numPageSamples) plain bytes + 0 encrypted bytes if (SIZE_MAX - size < sizeof(int32_t)) { @@ -598,9 +598,9 @@ status_t NuMediaExtractor::appendVorbisNumPageSamples( int32_t zero = 0; memcpy(adata, data, size); memcpy(adata + size, &zero, sizeof(zero)); - mbuf->meta_data()->setData(kKeyEncryptedSizes, type, adata, newSize); + mbuf->meta_data().setData(kKeyEncryptedSizes, type, adata, newSize); - if (mbuf->meta_data()->findData(kKeyPlainSizes, &type, &data, &size2)) { + if (mbuf->meta_data().findData(kKeyPlainSizes, &type, &data, &size2)) { if (size2 != size) { return ERROR_MALFORMED; } @@ -613,7 +613,7 @@ status_t NuMediaExtractor::appendVorbisNumPageSamples( // append sizeof(numPageSamples) to plain sizes. int32_t int32Size = sizeof(numPageSamples); memcpy(adata + size, &int32Size, sizeof(int32Size)); - mbuf->meta_data()->setData(kKeyPlainSizes, type, adata, newSize); + mbuf->meta_data().setData(kKeyPlainSizes, type, adata, newSize); } return OK; @@ -725,7 +725,7 @@ status_t NuMediaExtractor::getSampleMeta(sp *sampleMeta) { } TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); - *sampleMeta = info->mSamples.begin()->mBuffer->meta_data(); + *sampleMeta = new MetaData(info->mSamples.begin()->mBuffer->meta_data()); return OK; } diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp index 7efb91c44d1d27a8fbd589b09fac35f68fe38191..9d2c42b6cd02573ba4baf96200863bd9b4d30214 100644 --- a/media/libstagefright/RemoteMediaExtractor.cpp +++ b/media/libstagefright/RemoteMediaExtractor.cpp @@ -57,13 +57,13 @@ RemoteMediaExtractor::RemoteMediaExtractor( // tracks (size_t) mAnalyticsItem->setInt32(kExtractorTracks, ntracks); // metadata - sp pMetaData = extractor->getMetaData(); - if (pMetaData != nullptr) { - String8 xx = pMetaData->toString(); + MetaDataBase pMetaData; + if (extractor->getMetaData(pMetaData) == OK) { + String8 xx = pMetaData.toString(); // 'titl' -- but this verges into PII // 'mime' const char *mime = nullptr; - if (pMetaData->findCString(kKeyMIMEType, &mime)) { + if (pMetaData.findCString(kKeyMIMEType, &mime)) { mAnalyticsItem->setCString(kExtractorMime, mime); } // what else is interesting and not already available? @@ -95,17 +95,25 @@ size_t RemoteMediaExtractor::countTracks() { } sp RemoteMediaExtractor::getTrack(size_t index) { - MediaSourceBase *source = mExtractor->getTrack(index); + MediaTrack *source = mExtractor->getTrack(index); return (source == nullptr) ? nullptr : CreateIMediaSourceFromMediaSourceBase(this, source, mExtractorPlugin); } sp RemoteMediaExtractor::getTrackMetaData(size_t index, uint32_t flags) { - return mExtractor->getTrackMetaData(index, flags); + sp meta = new MetaData(); + if (mExtractor->getTrackMetaData(*meta.get(), index, flags) == OK) { + return meta; + } + return nullptr; } sp RemoteMediaExtractor::getMetaData() { - return mExtractor->getMetaData(); + sp meta = new MetaData(); + if (mExtractor->getMetaData(*meta.get()) == OK) { + return meta; + } + return nullptr; } status_t RemoteMediaExtractor::getMetrics(Parcel *reply) { diff --git a/media/libstagefright/RemoteMediaSource.cpp b/media/libstagefright/RemoteMediaSource.cpp index d038454426c2fc03da992ed7c635f22fa6512508..d07afec21db776504bac5c100edf18f2e30e760f 100644 --- a/media/libstagefright/RemoteMediaSource.cpp +++ b/media/libstagefright/RemoteMediaSource.cpp @@ -22,7 +22,7 @@ namespace android { RemoteMediaSource::RemoteMediaSource( const sp &extractor, - MediaSourceBase *source, + MediaTrack *source, const sp &plugin) : mExtractor(extractor), mSource(source), @@ -42,7 +42,11 @@ status_t RemoteMediaSource::stop() { } sp RemoteMediaSource::getFormat() { - return mSource->getFormat(); + sp meta = new MetaData(); + if (mSource->getFormat(*meta.get()) == OK) { + return meta; + } + return nullptr; } status_t RemoteMediaSource::read( @@ -51,11 +55,11 @@ status_t RemoteMediaSource::read( } status_t RemoteMediaSource::pause() { - return mSource->pause(); + return ERROR_UNSUPPORTED; } -status_t RemoteMediaSource::setStopTimeUs(int64_t stopTimeUs) { - return mSource->setStopTimeUs(stopTimeUs); +status_t RemoteMediaSource::setStopTimeUs(int64_t /* stopTimeUs */) { + return ERROR_UNSUPPORTED; } //////////////////////////////////////////////////////////////////////////////// @@ -63,7 +67,7 @@ status_t RemoteMediaSource::setStopTimeUs(int64_t stopTimeUs) { // static sp RemoteMediaSource::wrap( const sp &extractor, - MediaSourceBase *source, const sp &plugin) { + MediaTrack *source, const sp &plugin) { if (source == nullptr) { return nullptr; } diff --git a/media/libstagefright/SimpleDecodingSource.cpp b/media/libstagefright/SimpleDecodingSource.cpp index f93a0b7ac1af5555a87068da4309e26400b51e0f..404c53718ff542331210ed9893918962b344b6a1 100644 --- a/media/libstagefright/SimpleDecodingSource.cpp +++ b/media/libstagefright/SimpleDecodingSource.cpp @@ -309,7 +309,7 @@ status_t SimpleDecodingSource::doRead( if (in_buf != NULL) { int64_t timestampUs = 0; - CHECK(in_buf->meta_data()->findInt64(kKeyTime, ×tampUs)); + CHECK(in_buf->meta_data().findInt64(kKeyTime, ×tampUs)); if (in_buf->range_length() + (mIsVorbis ? 4 : 0) > in_buffer->capacity()) { ALOGW("'%s' received %zu input bytes for buffer of size %zu", mComponentName.c_str(), @@ -321,7 +321,7 @@ status_t SimpleDecodingSource::doRead( if (mIsVorbis) { int32_t numPageSamples; - if (!in_buf->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) { + if (!in_buf->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) { numPageSamples = -1; } memcpy(in_buffer->base() + cpLen, &numPageSamples, sizeof(numPageSamples)); @@ -393,7 +393,7 @@ status_t SimpleDecodingSource::doRead( *buffer = new MediaBuffer(out_size); CHECK_LE(out_buffer->size(), (*buffer)->size()); memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size()); - (*buffer)->meta_data()->setInt64(kKeyTime, out_pts); + (*buffer)->meta_data().setInt64(kKeyTime, out_pts); mCodec->releaseOutputBuffer(out_ix); } return OK; diff --git a/media/libstagefright/codecs/cmds/codec2.cpp b/media/libstagefright/codecs/cmds/codec2.cpp index 26f96c3aef484122476885902253f2d08a131fb2..0ec1a779cf64df621a6e3ca115c10b51bb5c92ae 100644 --- a/media/libstagefright/codecs/cmds/codec2.cpp +++ b/media/libstagefright/codecs/cmds/codec2.cpp @@ -309,8 +309,8 @@ void SimplePlayer::play(const sp &source) { break; } - sp meta = buffer->meta_data(); - CHECK(meta->findInt64(kKeyTime, ×tamp)); + MetaDataBase &meta = buffer->meta_data(); + CHECK(meta.findInt64(kKeyTime, ×tamp)); size = buffer->size(); data = buffer->data(); diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp index 55fc6808700074c3b29e12676076d6660a7214dc..5624f4a7962d732b46cf837b69f54eaf809b38c5 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.cpp +++ b/media/libstagefright/httplive/PlaylistFetcher.cpp @@ -2066,7 +2066,8 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits( CHECK_NE(channel_configuration, 0u); bits.skipBits(2); // original_copy, home - sp meta = MakeAACCodecSpecificData( + sp meta = new MetaData(); + MakeAACCodecSpecificData(*meta, profile, sampling_freq_index, channel_configuration); meta->setInt32(kKeyIsADTS, true); diff --git a/media/libstagefright/include/FrameDecoder.h b/media/libstagefright/include/FrameDecoder.h index c40324b6cd53b6d471bbfeca4536bf6edde75bcc..dfbe2cdf2665487b3d5bc8add5c1aca9c96d4d6e 100644 --- a/media/libstagefright/include/FrameDecoder.h +++ b/media/libstagefright/include/FrameDecoder.h @@ -68,7 +68,7 @@ protected: virtual status_t onInputReceived( const sp &codecBuffer, - const sp &sampleMeta, + MetaDataBase &sampleMeta, bool firstSample, uint32_t *flags) = 0; @@ -123,7 +123,7 @@ protected: virtual status_t onInputReceived( const sp &codecBuffer, - const sp &sampleMeta, + MetaDataBase &sampleMeta, bool firstSample, uint32_t *flags) override; @@ -158,7 +158,7 @@ protected: virtual status_t onInputReceived( const sp &codecBuffer __unused, - const sp &sampleMeta __unused, + MetaDataBase &sampleMeta __unused, bool firstSample __unused, uint32_t *flags __unused) override { return OK; } diff --git a/media/libstagefright/include/media/stagefright/InterfaceUtils.h b/media/libstagefright/include/media/stagefright/InterfaceUtils.h index 568c7356e4052ebb7c5d507c9215be07bba45f58..f0ebd48347340cc5c62b3fef5b39d4d3c20165ae 100644 --- a/media/libstagefright/include/media/stagefright/InterfaceUtils.h +++ b/media/libstagefright/include/media/stagefright/InterfaceUtils.h @@ -51,7 +51,7 @@ sp CreateMediaSourceFromIMediaSource(const sp &source // Creates an IMediaSource wrapper to the given MediaSource. sp CreateIMediaSourceFromMediaSourceBase( const sp &extractor, - MediaSourceBase *source, const sp &plugin); + MediaTrack *source, const sp &plugin); } // namespace android diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h new file mode 120000 index 0000000000000000000000000000000000000000..1e1219357899e8a46c87e72a5dac52cae4decdc7 --- /dev/null +++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h @@ -0,0 +1 @@ +../../../../libmediaextractor/include/media/stagefright/MetaDataBase.h \ No newline at end of file diff --git a/media/libstagefright/include/media/stagefright/MetaDataUtils.h b/media/libstagefright/include/media/stagefright/MetaDataUtils.h index 7c18bc2cef99c92cce006294e4dad90596f9ed4a..3af2218663c922f02632f4a5ff3c89cdb01c1d85 100644 --- a/media/libstagefright/include/media/stagefright/MetaDataUtils.h +++ b/media/libstagefright/include/media/stagefright/MetaDataUtils.h @@ -23,8 +23,8 @@ namespace android { struct ABuffer; -sp MakeAVCCodecSpecificData(const sp &accessUnit); -sp MakeAACCodecSpecificData(unsigned profile, unsigned sampling_freq_index, +bool MakeAVCCodecSpecificData(MetaDataBase &meta, const sp &accessUnit); +bool MakeAACCodecSpecificData(MetaDataBase &meta, unsigned profile, unsigned sampling_freq_index, unsigned channel_configuration); } // namespace android diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaSource.h b/media/libstagefright/include/media/stagefright/RemoteMediaSource.h index a9bf8206f51b3362ef24213b4f5acb9fffd156f9..1d720af88919429ba0647e7d0868ee2e9c73b2a5 100644 --- a/media/libstagefright/include/media/stagefright/RemoteMediaSource.h +++ b/media/libstagefright/include/media/stagefright/RemoteMediaSource.h @@ -28,7 +28,7 @@ class RemoteMediaSource : public BnMediaSource { public: static sp wrap( const sp &extractor, - MediaSourceBase *source, + MediaTrack *source, const sp &plugin); virtual ~RemoteMediaSource(); virtual status_t start(MetaData *params = NULL); @@ -42,12 +42,12 @@ public: private: sp mExtractor; - MediaSourceBase *mSource; + MediaTrack *mSource; sp mExtractorPlugin; explicit RemoteMediaSource( const sp &extractor, - MediaSourceBase *source, + MediaTrack *source, const sp &plugin); DISALLOW_EVIL_CONSTRUCTORS(RemoteMediaSource); diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp index d0b17e09d23485f009f857cbf80efcde302b3425..8488d10b52ef212718dd5266bca1242171306e96 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp @@ -203,23 +203,23 @@ status_t AnotherPacketSource::read( } MediaBufferBase *mediaBuffer = new MediaBuffer(buffer); - sp bufmeta = mediaBuffer->meta_data(); + MetaDataBase &bufmeta = mediaBuffer->meta_data(); - bufmeta->setInt64(kKeyTime, timeUs); + bufmeta.setInt64(kKeyTime, timeUs); int32_t isSync; if (buffer->meta()->findInt32("isSync", &isSync)) { - bufmeta->setInt32(kKeyIsSyncFrame, isSync); + bufmeta.setInt32(kKeyIsSyncFrame, isSync); } sp sei; if (buffer->meta()->findBuffer("sei", &sei) && sei != NULL) { - bufmeta->setData(kKeySEI, 0, sei->data(), sei->size()); + bufmeta.setData(kKeySEI, 0, sei->data(), sei->size()); } sp mpegUserData; if (buffer->meta()->findBuffer("mpegUserData", &mpegUserData) && mpegUserData != NULL) { - bufmeta->setData( + bufmeta.setData( kKeyMpegUserData, 0, mpegUserData->data(), mpegUserData->size()); } @@ -234,18 +234,18 @@ status_t AnotherPacketSource::read( CHECK(buffer->meta()->findBuffer("encBytes", &encBytesBuffer) && encBytesBuffer != NULL); - bufmeta->setInt32(kKeyCryptoMode, cryptoMode); + bufmeta.setInt32(kKeyCryptoMode, cryptoMode); uint8_t array[16] = {0}; - bufmeta->setData(kKeyCryptoIV, 0, array, 16); + bufmeta.setData(kKeyCryptoIV, 0, array, 16); array[0] = (uint8_t) (cryptoKey & 0xff); - bufmeta->setData(kKeyCryptoKey, 0, array, 16); + bufmeta.setData(kKeyCryptoKey, 0, array, 16); - bufmeta->setData(kKeyPlainSizes, 0, + bufmeta.setData(kKeyPlainSizes, 0, clearBytesBuffer->data(), clearBytesBuffer->size()); - bufmeta->setData(kKeyEncryptedSizes, 0, + bufmeta.setData(kKeyEncryptedSizes, 0, encBytesBuffer->data(), encBytesBuffer->size()); } diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index 850facefbbed635b9d1747b65487ebf2d4e530ed..59fba1afe3810d46363a1ad79765d9ce3bb7817d 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -633,7 +633,10 @@ sp ElementaryStreamQueue::dequeueAccessUnit() { mBuffer->setRange(0, mBuffer->size() - info.mLength); if (mFormat == NULL) { - mFormat = MakeAVCCodecSpecificData(accessUnit); + mFormat = new MetaData; + if (!MakeAVCCodecSpecificData(*mFormat, accessUnit)) { + mFormat.clear(); + } } return accessUnit; @@ -862,7 +865,7 @@ sp ElementaryStreamQueue::dequeueAccessUnitAAC() { } bits.skipBits(2); // original_copy, home - mFormat = MakeAACCodecSpecificData( + MakeAACCodecSpecificData(*mFormat, profile, sampling_freq_index, channel_configuration); mFormat->setInt32(kKeyIsADTS, true); @@ -1005,9 +1008,9 @@ sp ElementaryStreamQueue::dequeueAccessUnitH264() { return NULL; } if (mFormat == NULL) { - mFormat = MakeAVCCodecSpecificData(mBuffer); - if (mFormat == NULL) { - ALOGI("Creating dummy AVC format for scrambled content"); + mFormat = new MetaData; + if (!MakeAVCCodecSpecificData(*mFormat, mBuffer)) { + ALOGW("Creating dummy AVC format for scrambled content"); mFormat = new MetaData; mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); mFormat->setInt32(kKeyWidth, 1280); @@ -1167,7 +1170,10 @@ sp ElementaryStreamQueue::dequeueAccessUnitH264() { } if (mFormat == NULL) { - mFormat = MakeAVCCodecSpecificData(accessUnit); + mFormat = new MetaData; + if (!MakeAVCCodecSpecificData(*mFormat, accessUnit)) { + mFormat.clear(); + } } if (mSampleDecryptor != NULL && shrunkBytes > 0) { diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp index 3d9c791d566f7fb1d7fb87dc846b876ca5fcd3a1..895a4cef4cde58f102ad5b456a30945a750a6cf7 100644 --- a/media/libstagefright/omx/tests/OMXHarness.cpp +++ b/media/libstagefright/omx/tests/OMXHarness.cpp @@ -667,7 +667,7 @@ status_t Harness::testSeek( actualSeekTimeUs = -1; } else { CHECK(buffer != NULL); - CHECK(buffer->meta_data()->findInt64(kKeyTime, &actualSeekTimeUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, &actualSeekTimeUs)); CHECK(actualSeekTimeUs >= 0); buffer->release(); @@ -728,7 +728,7 @@ status_t Harness::testSeek( CHECK(buffer != NULL); int64_t bufferTimeUs; - CHECK(buffer->meta_data()->findInt64(kKeyTime, &bufferTimeUs)); + CHECK(buffer->meta_data().findInt64(kKeyTime, &bufferTimeUs)); if (!CloseEnough(bufferTimeUs, actualSeekTimeUs)) { printf("\n * Attempted seeking to %" PRId64 " us (%.2f secs)", requestedSeekTimeUs, requestedSeekTimeUs / 1E6); diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp index 4ce8a0c2537c239b7fbdded8ed19e29364d8ae84..0667df1c6d88932026c75c8d4703717e3810d38f 100644 --- a/media/libstagefright/rtsp/ARTPWriter.cpp +++ b/media/libstagefright/rtsp/ARTPWriter.cpp @@ -572,7 +572,7 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) { CHECK_GE(kMaxPacketSize, 12u + 2u); int64_t timeUs; - CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs)); uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); @@ -667,7 +667,7 @@ void ARTPWriter::sendH263Data(MediaBufferBase *mediaBuf) { CHECK_GE(kMaxPacketSize, 12u + 2u); int64_t timeUs; - CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs)); uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); @@ -752,7 +752,7 @@ void ARTPWriter::sendAMRData(MediaBufferBase *mediaBuf) { const bool isWide = (mMode == AMR_WB); int64_t timeUs; - CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); + CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs)); uint32_t rtpTime = mRTPTimeBase + (timeUs / (isWide ? 250 : 125)); // hexdump(mediaData, mediaLength); diff --git a/media/libstagefright/webm/WebmFrameThread.cpp b/media/libstagefright/webm/WebmFrameThread.cpp index 0d4c6998a0478d2947138c35e5468b223ce13a90..23269afa9e61d717630bbf878fa303fcd5abb65a 100644 --- a/media/libstagefright/webm/WebmFrameThread.cpp +++ b/media/libstagefright/webm/WebmFrameThread.cpp @@ -345,8 +345,8 @@ void WebmFrameMediaSourceThread::run() { continue; } - sp md = buffer->meta_data(); - CHECK(md->findInt64(kKeyTime, ×tampUs)); + MetaDataBase &md = buffer->meta_data(); + CHECK(md.findInt64(kKeyTime, ×tampUs)); if (mStartTimeUs == kUninitialized) { mStartTimeUs = timestampUs; } @@ -374,7 +374,7 @@ void WebmFrameMediaSourceThread::run() { CHECK_GE(timestampUs, 0ll); int32_t isSync = false; - md->findInt32(kKeyIsSyncFrame, &isSync); + md.findInt32(kKeyIsSyncFrame, &isSync); const sp f = new WebmFrame( mType, isSync,