/*
 * 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 "StagefrightMetadataRetriever"

#include <inttypes.h>

#include <utils/Log.h>
#include <cutils/properties.h>

#include "StagefrightMetadataRetriever.h"
#include "FrameDecoder.h"

#include <datasource/PlayerServiceDataSourceFactory.h>
#include <datasource/PlayerServiceFileSource.h>
#include <media/IMediaHTTPService.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaExtractorFactory.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
#include <media/CharacterEncodingDetector.h>

namespace android {

StagefrightMetadataRetriever::StagefrightMetadataRetriever()
    : mParsedMetaData(false),
      mAlbumArt(NULL),
      mLastDecodedIndex(-1) {
    ALOGV("StagefrightMetadataRetriever()");
}

StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
    ALOGV("~StagefrightMetadataRetriever()");
    clearMetadata();
    if (mSource != NULL) {
        mSource->close();
    }
}

status_t StagefrightMetadataRetriever::setDataSource(
        const sp<IMediaHTTPService> &httpService,
        const char *uri,
        const KeyedVector<String8, String8> *headers) {
    ALOGV("setDataSource(%s)", uri);

    clearMetadata();
    mSource = PlayerServiceDataSourceFactory::getInstance()->CreateFromURI(
            httpService, uri, headers);

    if (mSource == NULL) {
        ALOGE("Unable to create data source for '%s'.", uri);
        return UNKNOWN_ERROR;
    }

    mExtractor = MediaExtractorFactory::Create(mSource);

    if (mExtractor == NULL) {
        ALOGE("Unable to instantiate an extractor for '%s'.", uri);

        mSource.clear();

        return UNKNOWN_ERROR;
    }

    return OK;
}

// Warning caller retains ownership of the filedescriptor! Dup it if necessary.
status_t StagefrightMetadataRetriever::setDataSource(
        int fd, int64_t offset, int64_t length) {
    fd = dup(fd);

    ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);

    clearMetadata();
    mSource = new PlayerServiceFileSource(fd, offset, length);

    status_t err;
    if ((err = mSource->initCheck()) != OK) {
        mSource.clear();

        return err;
    }

    mExtractor = MediaExtractorFactory::Create(mSource);

    if (mExtractor == NULL) {
        mSource.clear();

        return UNKNOWN_ERROR;
    }

    return OK;
}

status_t StagefrightMetadataRetriever::setDataSource(
        const sp<DataSource>& source, const char *mime) {
    ALOGV("setDataSource(DataSource)");

    clearMetadata();
    mSource = source;
    mExtractor = MediaExtractorFactory::Create(mSource, mime);

    if (mExtractor == NULL) {
        ALOGE("Failed to instantiate a MediaExtractor.");
        mSource.clear();
        return UNKNOWN_ERROR;
    }

    return OK;
}

sp<IMemory> StagefrightMetadataRetriever::getImageAtIndex(
        int index, int colorFormat, bool metaOnly, bool thumbnail) {
    ALOGV("getImageAtIndex: index(%d) colorFormat(%d) metaOnly(%d) thumbnail(%d)",
            index, colorFormat, metaOnly, thumbnail);

    return getImageInternal(index, colorFormat, metaOnly, thumbnail, NULL);
}

sp<IMemory> StagefrightMetadataRetriever::getImageRectAtIndex(
        int index, int colorFormat, int left, int top, int right, int bottom) {
    ALOGV("getImageRectAtIndex: index(%d) colorFormat(%d) rect {%d, %d, %d, %d}",
            index, colorFormat, left, top, right, bottom);

    FrameRect rect = {left, top, right, bottom};

    if (mDecoder != NULL && index == mLastDecodedIndex) {
        return mDecoder->extractFrame(&rect);
    }

    return getImageInternal(
            index, colorFormat, false /*metaOnly*/, false /*thumbnail*/, &rect);
}

sp<IMemory> StagefrightMetadataRetriever::getImageInternal(
        int index, int colorFormat, bool metaOnly, bool thumbnail, FrameRect* rect) {
    mDecoder.clear();
    mLastDecodedIndex = -1;

    if (mExtractor.get() == NULL) {
        ALOGE("no extractor.");
        return NULL;
    }

    size_t n = mExtractor->countTracks();
    size_t i;
    int imageCount = 0;

    for (i = 0; i < n; ++i) {
        sp<MetaData> meta = mExtractor->getTrackMetaData(i);
        if (!meta) {
            continue;
        }
        ALOGV("getting track %zu of %zu, meta=%s", i, n, meta->toString().c_str());

        const char *mime;
        if (meta->findCString(kKeyMIMEType, &mime) && !strncasecmp(mime, "image/", 6)) {
            int32_t isPrimary;
            if ((index < 0 && meta->findInt32(
                    kKeyTrackIsDefault, &isPrimary) && isPrimary)
                    || (index == imageCount++)) {
                break;
            }
        }
    }

    if (i == n) {
        ALOGE("image track not found.");
        return NULL;
    }

    sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
    if (!trackMeta) {
        return NULL;
    }

    const char *mime;
    bool isHeif = false;
    if (!trackMeta->findCString(kKeyMIMEType, &mime)) {
        ALOGE("image track has no mime type");
        return NULL;
    }
    ALOGV("extracting from %s track", mime);
    if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
        mime = MEDIA_MIMETYPE_VIDEO_HEVC;
        trackMeta = new MetaData(*trackMeta);
        trackMeta->setCString(kKeyMIMEType, mime);
        isHeif = true;
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_AVIF)) {
        mime = MEDIA_MIMETYPE_VIDEO_AV1;
        trackMeta = new MetaData(*trackMeta);
        trackMeta->setCString(kKeyMIMEType, mime);
        isHeif = true;
    }

    sp<AMessage> format = new AMessage;
    status_t err = convertMetaDataToMessage(trackMeta, &format);
    if (err != OK) {
        ALOGE("getImageInternal: convertMetaDataToMessage() failed, unable to extract image");
        return NULL;
    }

    uint32_t bitDepth = 8;
    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
        int32_t profile;
        if (format->findInt32("profile", &profile)) {
            if (HEVCProfileMain10 == profile || HEVCProfileMain10HDR10 == profile ||
                    HEVCProfileMain10HDR10Plus == profile) {
                  bitDepth = 10;
            }
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)) {
        int32_t profile;
        if (format->findInt32("profile", &profile)) {
            if (AV1ProfileMain10 == profile || AV1ProfileMain10HDR10 == profile ||
                    AV1ProfileMain10HDR10Plus == profile) {
                  bitDepth = 10;
            }
        }
    }

    if (metaOnly) {
        return FrameDecoder::getMetadataOnly(trackMeta, colorFormat, thumbnail, bitDepth);
    }

    sp<IMediaSource> source = mExtractor->getTrack(i);

    if (source.get() == NULL) {
        ALOGE("unable to instantiate image track.");
        return NULL;
    }

    bool preferhw = property_get_bool(
            "media.stagefright.thumbnail.prefer_hw_codecs", false);
    uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
    Vector<AString> matchingCodecs;

    // If decoding thumbnail check decoder supports thumbnail dimensions instead
    int32_t thumbHeight, thumbWidth;
    if (thumbnail && format != NULL
            && trackMeta->findInt32(kKeyThumbnailHeight, &thumbHeight)
            && trackMeta->findInt32(kKeyThumbnailWidth, &thumbWidth)) {
        format->setInt32("height", thumbHeight);
        format->setInt32("width", thumbWidth);
    }

    // If decoding tiled HEIF check decoder supports tile dimensions instead
    if (!thumbnail && isHeif && format != NULL) {
        int32_t tileWidth, tileHeight;
        if (trackMeta->findInt32(kKeyTileWidth, &tileWidth) && tileWidth > 0
                && trackMeta->findInt32(kKeyTileHeight, &tileHeight) && tileHeight > 0) {
            format->setInt32("height", tileHeight);
            format->setInt32("width", tileWidth);
        }
    }

    MediaCodecList::findMatchingCodecs(
            mime,
            false, /* encoder */
            flags,
            format,
            &matchingCodecs);

    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
        const AString &componentName = matchingCodecs[i];
        sp<MediaImageDecoder> decoder = new MediaImageDecoder(componentName, trackMeta, source);
        int64_t frameTimeUs = thumbnail ? -1 : 0;
        if (decoder->init(frameTimeUs, 0 /*option*/, colorFormat) == OK) {
            sp<IMemory> frame = decoder->extractFrame(rect);

            if (frame != NULL) {
                if (rect != NULL) {
                    // keep the decoder if slice decoding
                    mDecoder = decoder;
                    mLastDecodedIndex = index;
                }
                return frame;
            }
        }
        ALOGV("%s failed to extract thumbnail, trying next decoder.", componentName.c_str());
    }

    ALOGE("all codecs failed to extract frame.");
    return NULL;
}

sp<IMemory> StagefrightMetadataRetriever::getFrameAtTime(
        int64_t timeUs, int option, int colorFormat, bool metaOnly) {
    ALOGV("getFrameAtTime: %" PRId64 " us option: %d colorFormat: %d, metaOnly: %d",
            timeUs, option, colorFormat, metaOnly);

    return getFrameInternal(timeUs, option, colorFormat, metaOnly);
}

sp<IMemory> StagefrightMetadataRetriever::getFrameAtIndex(
        int frameIndex, int colorFormat, bool metaOnly) {
    ALOGV("getFrameAtIndex: frameIndex %d, colorFormat: %d, metaOnly: %d",
            frameIndex, colorFormat, metaOnly);
    if (mDecoder != NULL && frameIndex == mLastDecodedIndex + 1) {
        sp<IMemory> frame = mDecoder->extractFrame();
        if (frame != nullptr) {
            mLastDecodedIndex = frameIndex;
        }
        return frame;
    }

    return getFrameInternal(frameIndex,
            MediaSource::ReadOptions::SEEK_FRAME_INDEX, colorFormat, metaOnly);
}

sp<IMemory> StagefrightMetadataRetriever::getFrameInternal(
        int64_t timeUs, int option, int colorFormat, bool metaOnly) {
    mDecoder.clear();
    mLastDecodedIndex = -1;

    if (mExtractor.get() == NULL) {
        ALOGE("no extractor.");
        return NULL;
    }

    sp<MetaData> fileMeta = mExtractor->getMetaData();

    if (fileMeta == NULL) {
        ALOGE("extractor doesn't publish metadata, failed to initialize?");
        return NULL;
    }

    size_t n = mExtractor->countTracks();
    size_t i;
    for (i = 0; i < n; ++i) {
        sp<MetaData> meta = mExtractor->getTrackMetaData(i);
        if (!meta) {
            continue;
        }

        const char *mime;
        if (meta->findCString(kKeyMIMEType, &mime) && !strncasecmp(mime, "video/", 6)) {
            break;
        }
    }

    if (i == n) {
        ALOGE("no video track found.");
        return NULL;
    }

    sp<MetaData> trackMeta = mExtractor->getTrackMetaData(
            i, MediaExtractor::kIncludeExtensiveMetaData);
    if (!trackMeta) {
        return NULL;
    }

    if (metaOnly) {
        return FrameDecoder::getMetadataOnly(trackMeta, colorFormat);
    }

    sp<IMediaSource> source = mExtractor->getTrack(i);

    if (source.get() == NULL) {
        ALOGV("unable to instantiate video track.");
        return NULL;
    }

    const void *data;
    uint32_t type;
    size_t dataSize;
    if (fileMeta->findData(kKeyAlbumArt, &type, &data, &dataSize)
            && mAlbumArt == NULL) {
        mAlbumArt = MediaAlbumArt::fromData(dataSize, data);
    }

    const char *mime;
    if (!trackMeta->findCString(kKeyMIMEType, &mime)) {
        ALOGE("video track has no mime information.");
        return NULL;
    }

    bool preferhw = property_get_bool(
            "media.stagefright.thumbnail.prefer_hw_codecs", false);
    uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
    sp<AMessage> format = new AMessage;
    status_t err = convertMetaDataToMessage(trackMeta, &format);
    if (err != OK) {
        ALOGE("getFrameInternal: convertMetaDataToMessage() failed, unable to extract frame");
        return NULL;
    }

    Vector<AString> matchingCodecs;
    MediaCodecList::findMatchingCodecs(
            mime,
            false, /* encoder */
            flags,
            format,
            &matchingCodecs);

    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
        const AString &componentName = matchingCodecs[i];
        sp<VideoFrameDecoder> decoder = new VideoFrameDecoder(componentName, trackMeta, source);
        if (decoder->init(timeUs, option, colorFormat) == OK) {
            sp<IMemory> frame = decoder->extractFrame();
            if (frame != nullptr) {
                // keep the decoder if seeking by frame index
                if (option == MediaSource::ReadOptions::SEEK_FRAME_INDEX) {
                    mDecoder = decoder;
                    mLastDecodedIndex = timeUs;
                }
                return frame;
            }
        }
        ALOGV("%s failed to extract frame, trying next decoder.", componentName.c_str());
    }

    ALOGE("all codecs failed to extract frame.");
    return NULL;
}

MediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() {
    ALOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO");

    if (mExtractor == NULL) {
        return NULL;
    }

    if (!mParsedMetaData) {
        parseMetaData();

        mParsedMetaData = true;
    }

    if (mAlbumArt) {
        return mAlbumArt->clone();
    }

    return NULL;
}

const char *StagefrightMetadataRetriever::extractMetadata(int keyCode) {
    if (mExtractor == NULL) {
        return NULL;
    }

    if (!mParsedMetaData) {
        parseMetaData();

        mParsedMetaData = true;
    }

    ssize_t index = mMetaData.indexOfKey(keyCode);

    if (index < 0) {
        return NULL;
    }

    return mMetaData.valueAt(index).string();
}

void StagefrightMetadataRetriever::parseColorAspects(const sp<MetaData>& meta) {
    sp<AMessage> format = new AMessage();
    if (convertMetaDataToMessage(meta, &format) != OK) {
        return;
    }

    int32_t standard, transfer, range;
    if (format->findInt32("color-standard", &standard)
            && format->findInt32("color-transfer", &transfer)
            && format->findInt32("color-range", &range)) {
        ALOGV("found color aspects : standard=%d, transfer=%d, range=%d",
                standard, transfer, range);

        mMetaData.add(METADATA_KEY_COLOR_STANDARD, String8::format("%d", standard));
        mMetaData.add(METADATA_KEY_COLOR_TRANSFER, String8::format("%d", transfer));
        mMetaData.add(METADATA_KEY_COLOR_RANGE, String8::format("%d", range));
    }
}

void StagefrightMetadataRetriever::parseMetaData() {
    sp<MetaData> meta = mExtractor->getMetaData();

    if (meta == NULL) {
        ALOGV("extractor doesn't publish metadata, failed to initialize?");
        return;
    }

    struct Map {
        int from;
        int to;
        const char *name;
    };
    static const Map kMap[] = {
        { kKeyMIMEType, METADATA_KEY_MIMETYPE, NULL },
        { kKeyCDTrackNumber, METADATA_KEY_CD_TRACK_NUMBER, "tracknumber" },
        { kKeyDiscNumber, METADATA_KEY_DISC_NUMBER, "discnumber" },
        { kKeyAlbum, METADATA_KEY_ALBUM, "album" },
        { kKeyArtist, METADATA_KEY_ARTIST, "artist" },
        { kKeyAlbumArtist, METADATA_KEY_ALBUMARTIST, "albumartist" },
        { kKeyAuthor, METADATA_KEY_AUTHOR, NULL },
        { kKeyComposer, METADATA_KEY_COMPOSER, "composer" },
        { kKeyDate, METADATA_KEY_DATE, NULL },
        { kKeyGenre, METADATA_KEY_GENRE, "genre" },
        { kKeyTitle, METADATA_KEY_TITLE, "title" },
        { kKeyYear, METADATA_KEY_YEAR, "year" },
        { kKeyWriter, METADATA_KEY_WRITER, "writer" },
        { kKeyCompilation, METADATA_KEY_COMPILATION, "compilation" },
        { kKeyLocation, METADATA_KEY_LOCATION, NULL },
    };

    static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);

    CharacterEncodingDetector *detector = new CharacterEncodingDetector();

    for (size_t i = 0; i < kNumMapEntries; ++i) {
        const char *value;
        if (meta->findCString(kMap[i].from, &value)) {
            if (kMap[i].name) {
                // add to charset detector
                detector->addTag(kMap[i].name, value);
            } else {
                // directly add to output list
                mMetaData.add(kMap[i].to, String8(value));
            }
        }
    }

    detector->detectAndConvert();
    int size = detector->size();
    if (size) {
        for (int i = 0; i < size; i++) {
            const char *name;
            const char *value;
            detector->getTag(i, &name, &value);
            for (size_t j = 0; j < kNumMapEntries; ++j) {
                if (kMap[j].name && !strcmp(kMap[j].name, name)) {
                    mMetaData.add(kMap[j].to, String8(value));
                }
            }
        }
    }
    delete detector;

    const void *data;
    uint32_t type;
    size_t dataSize;
    if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)
            && mAlbumArt == NULL) {
        mAlbumArt = MediaAlbumArt::fromData(dataSize, data);
    }

    size_t numTracks = mExtractor->countTracks();

    char tmp[32];
    sprintf(tmp, "%zu", numTracks);

    mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));

    float captureFps;
    if (meta->findFloat(kKeyCaptureFramerate, &captureFps)) {
        sprintf(tmp, "%f", captureFps);
        mMetaData.add(METADATA_KEY_CAPTURE_FRAMERATE, String8(tmp));
    }

    int64_t exifOffset, exifSize;
    if (meta->findInt64(kKeyExifOffset, &exifOffset)
     && meta->findInt64(kKeyExifSize, &exifSize)) {
        sprintf(tmp, "%lld", (long long)exifOffset);
        mMetaData.add(METADATA_KEY_EXIF_OFFSET, String8(tmp));
        sprintf(tmp, "%lld", (long long)exifSize);
        mMetaData.add(METADATA_KEY_EXIF_LENGTH, String8(tmp));
    }

    int64_t xmpOffset, xmpSize;
    if (meta->findInt64(kKeyXmpOffset, &xmpOffset)
     && meta->findInt64(kKeyXmpSize, &xmpSize)) {
        sprintf(tmp, "%lld", (long long)xmpOffset);
        mMetaData.add(METADATA_KEY_XMP_OFFSET, String8(tmp));
        sprintf(tmp, "%lld", (long long)xmpSize);
        mMetaData.add(METADATA_KEY_XMP_LENGTH, String8(tmp));
    }

    bool hasAudio = false;
    bool hasVideo = false;
    int32_t videoWidth = -1;
    int32_t videoHeight = -1;
    int32_t videoFrameCount = 0;
    int32_t audioBitrate = -1;
    int32_t rotationAngle = -1;
    int32_t imageCount = 0;
    int32_t imagePrimary = -1;
    int32_t imageWidth = -1;
    int32_t imageHeight = -1;
    int32_t imageRotation = -1;

    // The overall duration is the duration of the longest track.
    int64_t maxDurationUs = 0;
    String8 timedTextLang, videoMime;
    for (size_t i = 0; i < numTracks; ++i) {
        sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
        if (!trackMeta) {
            continue;
        }

        int64_t durationUs;
        if (trackMeta->findInt64(kKeyDuration, &durationUs)) {
            if (durationUs > maxDurationUs) {
                maxDurationUs = durationUs;
            }
        }

        const char *mime;
        if (trackMeta->findCString(kKeyMIMEType, &mime)) {
            if (!hasAudio && !strncasecmp("audio/", mime, 6)) {
                hasAudio = true;

                if (!trackMeta->findInt32(kKeyBitRate, &audioBitrate)) {
                    audioBitrate = -1;
                }

                int32_t bitsPerSample = -1;
                int32_t sampleRate = -1;
                trackMeta->findInt32(kKeyBitsPerSample, &bitsPerSample);
                trackMeta->findInt32(kKeySampleRate, &sampleRate);
                if (bitsPerSample >= 0) {
                    sprintf(tmp, "%d", bitsPerSample);
                    mMetaData.add(METADATA_KEY_BITS_PER_SAMPLE, String8(tmp));
                }
                if (sampleRate >= 0) {
                    sprintf(tmp, "%d", sampleRate);
                    mMetaData.add(METADATA_KEY_SAMPLERATE, String8(tmp));
                }
            } else if (!hasVideo && !strncasecmp("video/", mime, 6)) {
                if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
                    rotationAngle = 0;
                }
                if (!trackMeta->findInt32(kKeyFrameCount, &videoFrameCount)) {
                    videoFrameCount = 0;
                }
                if (trackMeta->findInt32(kKeyWidth, &videoWidth)
                    && trackMeta->findInt32(kKeyHeight, &videoHeight)) {
                    hasVideo = true;
                    videoMime = String8(mime);
                    parseColorAspects(trackMeta);
                } else {
                    ALOGE("video track ignored for missing dimensions");
                }
            } else if (!strncasecmp("image/", mime, 6)) {
                int32_t isPrimary;
                if (trackMeta->findInt32(
                        kKeyTrackIsDefault, &isPrimary) && isPrimary) {
                    if (!trackMeta->findInt32(kKeyRotation, &imageRotation)) {
                        imageRotation = 0;
                    }
                    if (trackMeta->findInt32(kKeyWidth, &imageWidth)
                        && trackMeta->findInt32(kKeyHeight, &imageHeight)) {
                        imagePrimary = imageCount;
                    } else {
                        ALOGE("primary image track ignored for missing dimensions");
                    }
                }
                imageCount++;
            } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
                const char *lang;
                if (trackMeta->findCString(kKeyMediaLanguage, &lang)) {
                    timedTextLang.append(String8(lang));
                    timedTextLang.append(String8(":"));
                } else {
                    ALOGE("No language found for timed text");
                }
            }
        }
    }

    // To save the language codes for all timed text tracks
    // If multiple text tracks present, the format will look
    // like "eng:chi"
    if (!timedTextLang.isEmpty()) {
        mMetaData.add(METADATA_KEY_TIMED_TEXT_LANGUAGES, timedTextLang);
    }

    // The duration value is a string representing the duration in ms.
    sprintf(tmp, "%" PRId64,
           (maxDurationUs > (INT64_MAX - 500) ? INT64_MAX : (maxDurationUs + 500)) / 1000);
    mMetaData.add(METADATA_KEY_DURATION, String8(tmp));

    if (hasAudio) {
        mMetaData.add(METADATA_KEY_HAS_AUDIO, String8("yes"));
    }

    if (hasVideo) {
        mMetaData.add(METADATA_KEY_HAS_VIDEO, String8("yes"));

        CHECK(videoWidth >= 0);
        sprintf(tmp, "%d", videoWidth);
        mMetaData.add(METADATA_KEY_VIDEO_WIDTH, String8(tmp));

        CHECK(videoHeight >= 0);
        sprintf(tmp, "%d", videoHeight);
        mMetaData.add(METADATA_KEY_VIDEO_HEIGHT, String8(tmp));

        sprintf(tmp, "%d", rotationAngle);
        mMetaData.add(METADATA_KEY_VIDEO_ROTATION, String8(tmp));

        mMetaData.add(METADATA_KEY_VIDEO_CODEC_MIME_TYPE, videoMime);

        if (videoFrameCount > 0) {
            sprintf(tmp, "%d", videoFrameCount);
            mMetaData.add(METADATA_KEY_VIDEO_FRAME_COUNT, String8(tmp));
        }
    }

    // only if we have a primary image
    if (imageCount > 0 && imagePrimary >= 0) {
        mMetaData.add(METADATA_KEY_HAS_IMAGE, String8("yes"));

        sprintf(tmp, "%d", imageCount);
        mMetaData.add(METADATA_KEY_IMAGE_COUNT, String8(tmp));

        sprintf(tmp, "%d", imagePrimary);
        mMetaData.add(METADATA_KEY_IMAGE_PRIMARY, String8(tmp));

        CHECK(imageWidth >= 0);
        sprintf(tmp, "%d", imageWidth);
        mMetaData.add(METADATA_KEY_IMAGE_WIDTH, String8(tmp));

        CHECK(imageHeight >= 0);
        sprintf(tmp, "%d", imageHeight);
        mMetaData.add(METADATA_KEY_IMAGE_HEIGHT, String8(tmp));

        sprintf(tmp, "%d", imageRotation);
        mMetaData.add(METADATA_KEY_IMAGE_ROTATION, String8(tmp));
    }

    if (numTracks == 1 && hasAudio && audioBitrate >= 0) {
        sprintf(tmp, "%d", audioBitrate);
        mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
    } else {
        off64_t sourceSize;
        if (mSource != NULL && mSource->getSize(&sourceSize) == OK) {
            int64_t avgBitRate = (int64_t)(sourceSize * 8E6 / maxDurationUs);

            sprintf(tmp, "%" PRId64, avgBitRate);
            mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
        }
    }

    if (numTracks == 1) {
        const char *fileMIME;

        if (meta->findCString(kKeyMIMEType, &fileMIME) &&
                !strcasecmp(fileMIME, "video/x-matroska")) {
            sp<MetaData> trackMeta = mExtractor->getTrackMetaData(0);
            const char *trackMIME;
            if (trackMeta != nullptr
                && trackMeta->findCString(kKeyMIMEType, &trackMIME)
                && !strncasecmp("audio/", trackMIME, 6)) {
                // The matroska file only contains a single audio track,
                // rewrite its mime type.
                mMetaData.add(
                        METADATA_KEY_MIMETYPE, String8("audio/x-matroska"));
            }
        }
    }
}

void StagefrightMetadataRetriever::clearMetadata() {
    mParsedMetaData = false;
    mMetaData.clear();
    delete mAlbumArt;
    mAlbumArt = NULL;
}

}  // namespace android
