StagefrightMetadataRetriever.cpp revision ee35aff74494e6c0b718e219427af6a6c573b928
153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber/*
2aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber *
4aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * you may not use this file except in compliance with the License.
6aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * You may obtain a copy of the License at
7aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber *
8aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber *
10aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * Unless required by applicable law or agreed to in writing, software
11aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * See the License for the specific language governing permissions and
14aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * limitations under the License.
15aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber */
1653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
1753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber//#define LOG_NDEBUG 0
1853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#define LOG_TAG "StagefrightMetadataRetriever"
1953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <utils/Log.h>
2053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
21e4a838051de5e56f44c71117073a035b804b5d04Andreas Huber#include "include/StagefrightMetadataRetriever.h"
2253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
2353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/ColorConverter.h>
2453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/DataSource.h>
2527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/FileSource.h>
2653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/MediaDebug.h>
2753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/MediaExtractor.h>
2853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/MetaData.h>
2953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/OMXCodec.h>
3053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
3153a76bd0c918082847e52570c307ed3ba325992dAndreas Hubernamespace android {
3253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
33aee3c6394a367abf283936cb8b8bd85ed028c050Andreas HuberStagefrightMetadataRetriever::StagefrightMetadataRetriever()
34aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    : mParsedMetaData(false),
35aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber      mAlbumArt(NULL) {
3653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    LOGV("StagefrightMetadataRetriever()");
3753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
3853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    DataSource::RegisterDefaultSniffers();
3953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    CHECK_EQ(mClient.connect(), OK);
4053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}
4153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
4253a76bd0c918082847e52570c307ed3ba325992dAndreas HuberStagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
4353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    LOGV("~StagefrightMetadataRetriever()");
44aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
45aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    delete mAlbumArt;
46aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mAlbumArt = NULL;
47aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
4853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    mClient.disconnect();
4953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}
5053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
5153a76bd0c918082847e52570c307ed3ba325992dAndreas Huberstatus_t StagefrightMetadataRetriever::setDataSource(const char *uri) {
5253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    LOGV("setDataSource(%s)", uri);
5353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
54aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mParsedMetaData = false;
55aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mMetaData.clear();
56aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    delete mAlbumArt;
57aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mAlbumArt = NULL;
58aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
59aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mSource = DataSource::CreateFromURI(uri);
60aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
61aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (mSource == NULL) {
62aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return UNKNOWN_ERROR;
63aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
64aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
65aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mExtractor = MediaExtractor::Create(mSource);
66aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
67aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (mExtractor == NULL) {
68aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mSource.clear();
6953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
70aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return UNKNOWN_ERROR;
71aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
72aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
73aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    return OK;
7453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}
7553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
76aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber// Warning caller retains ownership of the filedescriptor! Dup it if necessary.
7753a76bd0c918082847e52570c307ed3ba325992dAndreas Huberstatus_t StagefrightMetadataRetriever::setDataSource(
7853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber        int fd, int64_t offset, int64_t length) {
79aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    fd = dup(fd);
80aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
8153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
8253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
83aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mParsedMetaData = false;
84aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mMetaData.clear();
85aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    delete mAlbumArt;
86aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mAlbumArt = NULL;
87aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
88aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mSource = new FileSource(fd, offset, length);
89aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
90aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    status_t err;
91aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if ((err = mSource->initCheck()) != OK) {
92aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mSource.clear();
93aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
94aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return err;
95aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
96aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
97aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mExtractor = MediaExtractor::Create(mSource);
98aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
99aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (mExtractor == NULL) {
100aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mSource.clear();
101aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
102aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return UNKNOWN_ERROR;
103aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
10453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
10553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    return OK;
10653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}
10753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
1080ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huberstatic VideoFrame *extractVideoFrameWithCodecFlags(
1090ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        OMXClient *client,
1100ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        const sp<MetaData> &trackMeta,
111faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        const sp<MediaSource> &source,
112faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        uint32_t flags,
113faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        int64_t frameTimeUs,
114faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        int seekMode) {
11553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    sp<MediaSource> decoder =
11653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber        OMXCodec::Create(
1170ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber                client->interface(), source->getFormat(), false, source,
1185a40e394f1e6b0511542e171eaf4c3e5927efc13Andreas Huber                NULL, flags | OMXCodec::kClientNeedsFramebuffer);
11953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
12053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    if (decoder.get() == NULL) {
121ad28543022101d0b01845e3f53dcd57e524816efAndreas Huber        LOGV("unable to instantiate video decoder.");
12253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
12353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber        return NULL;
12453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    }
12553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
1261919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber    status_t err = decoder->start();
1271919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber    if (err != OK) {
1281919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber        LOGW("OMXCodec::start returned error %d (0x%08x)\n", err, err);
1291919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber        return NULL;
1301919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber    }
13153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
132f68c168d366e8aad58454917f96344398a02efd8Andreas Huber    // Read one output buffer, ignore format change notifications
133f68c168d366e8aad58454917f96344398a02efd8Andreas Huber    // and spurious empty buffers.
134f68c168d366e8aad58454917f96344398a02efd8Andreas Huber
135e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber    MediaSource::ReadOptions options;
136faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong    if (seekMode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC ||
137faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        seekMode > MediaSource::ReadOptions::SEEK_CLOSEST) {
138faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong
139faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        LOGE("Unknown seek mode: %d", seekMode);
140faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        return NULL;
141faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong    }
142faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong
143faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong    MediaSource::ReadOptions::SeekMode mode =
144faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong            static_cast<MediaSource::ReadOptions::SeekMode>(seekMode);
145faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong
146e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber    int64_t thumbNailTime;
147b1d49ded620fc9c80f793f32742bf1fef0281271Andreas Huber    if (frameTimeUs < 0) {
148b1d49ded620fc9c80f793f32742bf1fef0281271Andreas Huber        if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) {
149b1d49ded620fc9c80f793f32742bf1fef0281271Andreas Huber            thumbNailTime = 0;
150b1d49ded620fc9c80f793f32742bf1fef0281271Andreas Huber        }
151faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        options.setSeekTo(thumbNailTime, mode);
1520ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    } else {
1530ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        thumbNailTime = -1;
154faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        options.setSeekTo(frameTimeUs, mode);
155e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber    }
156e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber
157f68c168d366e8aad58454917f96344398a02efd8Andreas Huber    MediaBuffer *buffer = NULL;
158cfd55579c2e20514b181809dfaf30bd6f7e04c7eAndreas Huber    do {
159f68c168d366e8aad58454917f96344398a02efd8Andreas Huber        if (buffer != NULL) {
160f68c168d366e8aad58454917f96344398a02efd8Andreas Huber            buffer->release();
161f68c168d366e8aad58454917f96344398a02efd8Andreas Huber            buffer = NULL;
162f68c168d366e8aad58454917f96344398a02efd8Andreas Huber        }
163e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        err = decoder->read(&buffer, &options);
164e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        options.clearSeekTo();
165f68c168d366e8aad58454917f96344398a02efd8Andreas Huber    } while (err == INFO_FORMAT_CHANGED
166f68c168d366e8aad58454917f96344398a02efd8Andreas Huber             || (buffer != NULL && buffer->range_length() == 0));
16753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
16853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    if (err != OK) {
16953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber        CHECK_EQ(buffer, NULL);
17053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
171ad28543022101d0b01845e3f53dcd57e524816efAndreas Huber        LOGV("decoding frame failed.");
17253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber        decoder->stop();
17353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
17453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber        return NULL;
17553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    }
17653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
177ad28543022101d0b01845e3f53dcd57e524816efAndreas Huber    LOGV("successfully decoded video frame.");
17853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
1791e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber    int32_t unreadable;
1801e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber    if (buffer->meta_data()->findInt32(kKeyIsUnreadable, &unreadable)
1811e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber            && unreadable != 0) {
1821e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber        LOGV("video frame is unreadable, decoder does not give us access "
1831e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber             "to the video data.");
1841e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber
1851e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber        buffer->release();
1861e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber        buffer = NULL;
1871e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber
1881e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber        decoder->stop();
1891e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber
1901e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber        return NULL;
1911e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber    }
1921e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber
1930ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    int64_t timeUs;
1940ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
1950ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    if (thumbNailTime >= 0) {
1960ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        if (timeUs != thumbNailTime) {
1970ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber            const char *mime;
1980ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber            CHECK(trackMeta->findCString(kKeyMIMEType, &mime));
1990ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
2000ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber            LOGV("thumbNailTime = %lld us, timeUs = %lld us, mime = %s",
2010ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber                 thumbNailTime, timeUs, mime);
2020ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        }
2030ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    }
2040ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
2050ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    sp<MetaData> meta = decoder->getFormat();
20653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
20753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    int32_t width, height;
20853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    CHECK(meta->findInt32(kKeyWidth, &width));
20953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    CHECK(meta->findInt32(kKeyHeight, &height));
21053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
2111bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    int32_t crop_left, crop_top, crop_right, crop_bottom;
2121bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    if (!meta->findRect(
2131bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber                kKeyCropRect,
2141bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber                &crop_left, &crop_top, &crop_right, &crop_bottom)) {
2151bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber        crop_left = crop_top = 0;
2161bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber        crop_right = width - 1;
2171bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber        crop_bottom = height - 1;
2181bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    }
2191bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber
22053ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong    int32_t rotationAngle;
22153ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong    if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
22253ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong        rotationAngle = 0;  // By default, no rotation
22353ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong    }
22453ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong
22553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    VideoFrame *frame = new VideoFrame;
2261bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    frame->mWidth = crop_right - crop_left + 1;
2271bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    frame->mHeight = crop_bottom - crop_top + 1;
2281bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    frame->mDisplayWidth = frame->mWidth;
2291bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    frame->mDisplayHeight = frame->mHeight;
2301bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber    frame->mSize = frame->mWidth * frame->mHeight * 2;
23153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    frame->mData = new uint8_t[frame->mSize];
23253ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong    frame->mRotationAngle = rotationAngle;
23353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
23453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    int32_t srcFormat;
23553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &srcFormat));
23653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
23753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    ColorConverter converter(
23853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber            (OMX_COLOR_FORMATTYPE)srcFormat, OMX_COLOR_Format16bitRGB565);
23953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    CHECK(converter.isValid());
24053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
241c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber    err = converter.convert(
24253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber            (const uint8_t *)buffer->data() + buffer->range_offset(),
2431bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber            width, height,
2441bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber            crop_left, crop_top, crop_right, crop_bottom,
2451bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber            frame->mData,
2461bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber            frame->mWidth,
2471bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber            frame->mHeight,
2481bb0ffd0981bec26f906bc62d449e136111af4f8Andreas Huber            0, 0, frame->mWidth - 1, frame->mHeight - 1);
24953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
25053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    buffer->release();
25153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    buffer = NULL;
25253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
25353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    decoder->stop();
25453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
255c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber    if (err != OK) {
256c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber        LOGE("Colorconverter failed to convert frame.");
257c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber
258c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber        delete frame;
259c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber        frame = NULL;
260c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber    }
261c0dbe3a4457020bdba6ce311d383faecb7950a90Andreas Huber
26253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    return frame;
26353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}
26453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
265faf09ba9405ff019b5ca7e2317debe4ff269d4f8James DongVideoFrame *StagefrightMetadataRetriever::getFrameAtTime(
266faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        int64_t timeUs, int option) {
2670ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
268faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong    LOGV("getFrameAtTime: %lld us option: %d", timeUs, option);
269e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber    if (0 == (mMode & METADATA_MODE_FRAME_CAPTURE_ONLY)) {
2706e77de71ac6d23b6591028d04e1f2a4b5fc14d94James Dong        LOGV("getFrameAtTime disabled by mode (0x%08x)", mMode);
271e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber
272e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber        return NULL;
273e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber    }
274e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber
2750ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    if (mExtractor.get() == NULL) {
2760ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        LOGV("no extractor.");
2770ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        return NULL;
2780ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    }
2790ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
2800ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    size_t n = mExtractor->countTracks();
2810ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    size_t i;
2820ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    for (i = 0; i < n; ++i) {
2830ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        sp<MetaData> meta = mExtractor->getTrackMetaData(i);
2840ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
2850ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        const char *mime;
2860ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
2870ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
2880ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        if (!strncasecmp(mime, "video/", 6)) {
2890ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber            break;
2900ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        }
2910ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    }
2920ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
2930ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    if (i == n) {
2940ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        LOGV("no video track found.");
2950ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        return NULL;
2960ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    }
2970ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
2980ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    sp<MetaData> trackMeta = mExtractor->getTrackMetaData(
2990ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber            i, MediaExtractor::kIncludeExtensiveMetaData);
3000ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
3010ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    sp<MediaSource> source = mExtractor->getTrack(i);
3020ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
3030ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    if (source.get() == NULL) {
3040ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        LOGV("unable to instantiate video track.");
3050ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        return NULL;
3060ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    }
3070ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
3080ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    VideoFrame *frame =
3090ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        extractVideoFrameWithCodecFlags(
310faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong                &mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs,
311faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong                timeUs, option);
3120ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
3130ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    if (frame == NULL) {
3140ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber        LOGV("Software decoder failed to extract thumbnail, "
3150ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber             "trying hardware decoder.");
3160ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
317faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong        frame = extractVideoFrameWithCodecFlags(&mClient, trackMeta, source, 0,
318faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong                        timeUs, option);
3190ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    }
3200ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
3210ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber    return frame;
3220ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber}
3230ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber
32453a76bd0c918082847e52570c307ed3ba325992dAndreas HuberMediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() {
32553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO");
32653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
327e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber    if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) {
328e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber        LOGV("extractAlbumArt/metadata retrieval disabled by mode");
329e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber
330e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber        return NULL;
331e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber    }
332e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber
333aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (mExtractor == NULL) {
334aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return NULL;
335aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
336aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
337aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (!mParsedMetaData) {
338aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        parseMetaData();
339aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
340aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mParsedMetaData = true;
341aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
342aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
343aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (mAlbumArt) {
344aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return new MediaAlbumArt(*mAlbumArt);
345aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
346aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
34753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber    return NULL;
34853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}
34953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
35053a76bd0c918082847e52570c307ed3ba325992dAndreas Huberconst char *StagefrightMetadataRetriever::extractMetadata(int keyCode) {
351e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber    if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) {
352e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber        LOGV("extractAlbumArt/metadata retrieval disabled by mode");
353e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber
354e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber        return NULL;
355e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber    }
356e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber
357aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (mExtractor == NULL) {
358aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return NULL;
359aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
360aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
361aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (!mParsedMetaData) {
362aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        parseMetaData();
363aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
364aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mParsedMetaData = true;
365aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
366aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
367aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    ssize_t index = mMetaData.indexOfKey(keyCode);
368aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
369aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (index < 0) {
370aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return NULL;
371aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
372aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
373aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    return strdup(mMetaData.valueAt(index).string());
37453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}
37553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber
376aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Hubervoid StagefrightMetadataRetriever::parseMetaData() {
377aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    sp<MetaData> meta = mExtractor->getMetaData();
378aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
379aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    struct Map {
380aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        int from;
381aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        int to;
382aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    };
383aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    static const Map kMap[] = {
3841cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber        { kKeyMIMEType, METADATA_KEY_MIMETYPE },
3853a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyCDTrackNumber, METADATA_KEY_CD_TRACK_NUMBER },
386655306f8a80b3e9fc52daf458ef319a8ed8c564cMarco Nelissen        { kKeyDiscNumber, METADATA_KEY_DISC_NUMBER },
387aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyAlbum, METADATA_KEY_ALBUM },
388aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyArtist, METADATA_KEY_ARTIST },
389c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen        { kKeyAlbumArtist, METADATA_KEY_ALBUMARTIST },
3903a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyAuthor, METADATA_KEY_AUTHOR },
391aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyComposer, METADATA_KEY_COMPOSER },
3923a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyDate, METADATA_KEY_DATE },
393aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyGenre, METADATA_KEY_GENRE },
394aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyTitle, METADATA_KEY_TITLE },
395aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyYear, METADATA_KEY_YEAR },
396c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        { kKeyWriter, METADATA_KEY_WRITER },
397ee35aff74494e6c0b718e219427af6a6c573b928Marco Nelissen        { kKeyCompilation, METADATA_KEY_COMPILATION },
398aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    };
399aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
400aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
401aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    for (size_t i = 0; i < kNumMapEntries; ++i) {
402aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        const char *value;
403aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        if (meta->findCString(kMap[i].from, &value)) {
404aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            mMetaData.add(kMap[i].to, String8(value));
405aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        }
406aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
407aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
408aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    const void *data;
409aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    uint32_t type;
410aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    size_t dataSize;
411aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)) {
412aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mAlbumArt = new MediaAlbumArt;
413aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mAlbumArt->mSize = dataSize;
414aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        mAlbumArt->mData = new uint8_t[dataSize];
415aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        memcpy(mAlbumArt->mData, data, dataSize);
416aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
417aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
4183a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber    size_t numTracks = mExtractor->countTracks();
4193a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber
4203a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber    char tmp[32];
4213a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber    sprintf(tmp, "%d", numTracks);
4223a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber
4233a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber    mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));
4243a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber
425aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    // The overall duration is the duration of the longest track.
426aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    int64_t maxDurationUs = 0;
4273a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
428aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
429aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
430aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        int64_t durationUs;
431aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        if (trackMeta->findInt64(kKeyDuration, &durationUs)) {
432aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            if (durationUs > maxDurationUs) {
433aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber                maxDurationUs = durationUs;
434aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            }
435aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        }
436aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
437aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
438aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    // The duration value is a string representing the duration in ms.
439aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
440aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
441072f5247ef893e683728263a540bb93daafda376Andreas Huber
442072f5247ef893e683728263a540bb93daafda376Andreas Huber    if (numTracks == 1) {
443072f5247ef893e683728263a540bb93daafda376Andreas Huber        const char *fileMIME;
444072f5247ef893e683728263a540bb93daafda376Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &fileMIME));
445072f5247ef893e683728263a540bb93daafda376Andreas Huber
446072f5247ef893e683728263a540bb93daafda376Andreas Huber        if (!strcasecmp(fileMIME, "video/x-matroska")) {
447072f5247ef893e683728263a540bb93daafda376Andreas Huber            sp<MetaData> trackMeta = mExtractor->getTrackMetaData(0);
448072f5247ef893e683728263a540bb93daafda376Andreas Huber            const char *trackMIME;
449072f5247ef893e683728263a540bb93daafda376Andreas Huber            CHECK(trackMeta->findCString(kKeyMIMEType, &trackMIME));
450072f5247ef893e683728263a540bb93daafda376Andreas Huber
451072f5247ef893e683728263a540bb93daafda376Andreas Huber            if (!strncasecmp("audio/", trackMIME, 6)) {
452072f5247ef893e683728263a540bb93daafda376Andreas Huber                // The matroska file only contains a single audio track,
453072f5247ef893e683728263a540bb93daafda376Andreas Huber                // rewrite its mime type.
454072f5247ef893e683728263a540bb93daafda376Andreas Huber                mMetaData.add(
455072f5247ef893e683728263a540bb93daafda376Andreas Huber                        METADATA_KEY_MIMETYPE, String8("audio/x-matroska"));
456072f5247ef893e683728263a540bb93daafda376Andreas Huber            }
457072f5247ef893e683728263a540bb93daafda376Andreas Huber        }
458072f5247ef893e683728263a540bb93daafda376Andreas Huber    }
459aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber}
460aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
46153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber}  // namespace android
462