From: Steve Kondik Date: Mon, 4 Jan 2016 09:56:36 +0000 (-0800) Subject: stagefright-plugins: Parse file metadata tags X-Git-Tag: android-x86-7.1-r1~53 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=78f9d45bf5d4bc53bfca8979d197f1fafbd8e142;p=android-x86%2Fexternal-stagefright-plugins.git stagefright-plugins: Parse file metadata tags * Convert from AVFormat tags into the corresponding Android tags when file metadata is requested. * Also extract embedded album art. Change-Id: I49aec64dc30c9afd6510a25f8c2261029d8bdadf --- diff --git a/extractor/FFmpegExtractor.cpp b/extractor/FFmpegExtractor.cpp index d881209..2ff3345 100644 --- a/extractor/FFmpegExtractor.cpp +++ b/extractor/FFmpegExtractor.cpp @@ -116,7 +116,8 @@ FFmpegExtractor::FFmpegExtractor(const sp &source, const sp FFmpegExtractor::getMetaData() { return NULL; } + if (!mParsedMetadata) { + parseMetadataTags(mFormatCtx, mMeta); + mParsedMetadata = true; + } + return mMeta; } diff --git a/extractor/FFmpegExtractor.h b/extractor/FFmpegExtractor.h index 141e25d..8fe3d9a 100644 --- a/extractor/FFmpegExtractor.h +++ b/extractor/FFmpegExtractor.h @@ -130,6 +130,8 @@ private: static void *ReaderWrapper(void *me); void readerEntry(); + bool mParsedMetadata; + DISALLOW_EVIL_CONSTRUCTORS(FFmpegExtractor); }; diff --git a/utils/codec_utils.cpp b/utils/codec_utils.cpp index b228e9e..5cf30de 100644 --- a/utils/codec_utils.cpp +++ b/utils/codec_utils.cpp @@ -519,5 +519,72 @@ int getDivXVersion(AVCodecContext *avctx) return -1; } +status_t parseMetadataTags(AVFormatContext *ctx, const sp &meta) { + if (meta == NULL || ctx == NULL) { + return NO_INIT; + } + + AVDictionary *dict = ctx->metadata; + if (dict == NULL) { + return NO_INIT; + } + + struct MetadataMapping { + const char *from; + int to; + }; + + // avformat -> android mapping + static const MetadataMapping kMap[] = { + { "track", kKeyCDTrackNumber }, + { "disc", kKeyDiscNumber }, + { "album", kKeyAlbum }, + { "artist", kKeyArtist }, + { "album_artist", kKeyAlbumArtist }, + { "composer", kKeyComposer }, + { "date", kKeyDate }, + { "genre", kKeyGenre }, + { "title", kKeyTitle }, + { "year", kKeyYear }, + { "compilation", kKeyCompilation }, + { "location", kKeyLocation }, + }; + + static const size_t kNumEntries = sizeof(kMap) / sizeof(kMap[0]); + + for (size_t i = 0; i < kNumEntries; ++i) { + AVDictionaryEntry *entry = av_dict_get(dict, kMap[i].from, NULL, 0); + if (entry != NULL) { + ALOGV("found key %s with value %s", entry->key, entry->value); + meta->setCString(kMap[i].to, entry->value); + } + } + + // now look for album art- this will be in a separate stream + for (size_t i = 0; i < ctx->nb_streams; i++) { + if (ctx->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) { + AVPacket pkt = ctx->streams[i]->attached_pic; + if (pkt.size > 0) { + if (ctx->streams[i]->codec != NULL) { + const char *mime; + if (ctx->streams[i]->codec->codec_id == AV_CODEC_ID_MJPEG) { + mime = MEDIA_MIMETYPE_IMAGE_JPEG; + } else if (ctx->streams[i]->codec->codec_id == AV_CODEC_ID_PNG) { + mime = "image/png"; + } else { + mime = NULL; + } + if (mime != NULL) { + ALOGV("found albumart in stream %d with type %s len %d", i, mime, pkt.size); + meta->setData(kKeyAlbumArt, MetaData::TYPE_NONE, pkt.data, pkt.size); + meta->setCString(kKeyAlbumArtMIME, mime); + } + } + } + } + } + return OK; +} + } // namespace android diff --git a/utils/codec_utils.h b/utils/codec_utils.h index b630e07..c363e18 100644 --- a/utils/codec_utils.h +++ b/utils/codec_utils.h @@ -66,6 +66,8 @@ status_t convertNal2AnnexB(uint8_t *dst, size_t dst_size, int getDivXVersion(AVCodecContext *avctx); +status_t parseMetadataTags(AVFormatContext *ctx, const sp &meta); + } // namespace android #endif // CODEC_UTILS_H_