StagefrightMetadataRetriever.cpp revision 11f8109ad8646d3acd9a0987613229cde59d52c1
12a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber/*
2fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *
4fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * you may not use this file except in compliance with the License.
6fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * You may obtain a copy of the License at
7fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *
8fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *
10fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * Unless required by applicable law or agreed to in writing, software
11fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * See the License for the specific language governing permissions and
14fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * limitations under the License.
15fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber */
162a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
172a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber//#define LOG_NDEBUG 0
182a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#define LOG_TAG "StagefrightMetadataRetriever"
192a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <utils/Log.h>
202a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
2167e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber#include "include/StagefrightMetadataRetriever.h"
222a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
232a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/ColorConverter.h>
242a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/DataSource.h>
25bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/FileSource.h>
262a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/MediaDebug.h>
272a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/MediaExtractor.h>
282a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/MetaData.h>
292a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/OMXCodec.h>
302a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
312a4a7d5af053a17586a262a1267ba993e31790f1Andreas Hubernamespace android {
322a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
33fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberStagefrightMetadataRetriever::StagefrightMetadataRetriever()
34fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    : mParsedMetaData(false),
35fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber      mAlbumArt(NULL) {
362a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    LOGV("StagefrightMetadataRetriever()");
372a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
382a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    DataSource::RegisterDefaultSniffers();
392a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CHECK_EQ(mClient.connect(), OK);
402a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}
412a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
422a4a7d5af053a17586a262a1267ba993e31790f1Andreas HuberStagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
432a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    LOGV("~StagefrightMetadataRetriever()");
44fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
45fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    delete mAlbumArt;
46fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mAlbumArt = NULL;
47fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
482a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    mClient.disconnect();
492a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}
502a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
512a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huberstatus_t StagefrightMetadataRetriever::setDataSource(const char *uri) {
522a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    LOGV("setDataSource(%s)", uri);
532a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
54fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mParsedMetaData = false;
55fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mMetaData.clear();
56fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    delete mAlbumArt;
57fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mAlbumArt = NULL;
58fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
59fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mSource = DataSource::CreateFromURI(uri);
60fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
61fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (mSource == NULL) {
62fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return UNKNOWN_ERROR;
63fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
64fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
65fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mExtractor = MediaExtractor::Create(mSource);
66fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
67fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (mExtractor == NULL) {
68fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mSource.clear();
692a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
70fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return UNKNOWN_ERROR;
71fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
72fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
73fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    return OK;
742a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}
752a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
76fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber// Warning caller retains ownership of the filedescriptor! Dup it if necessary.
772a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huberstatus_t StagefrightMetadataRetriever::setDataSource(
782a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        int fd, int64_t offset, int64_t length) {
79fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    fd = dup(fd);
80fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
812a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
822a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
83fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mParsedMetaData = false;
84fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mMetaData.clear();
85fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    delete mAlbumArt;
86fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mAlbumArt = NULL;
87fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
88fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mSource = new FileSource(fd, offset, length);
89fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
90fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    status_t err;
91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if ((err = mSource->initCheck()) != OK) {
92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mSource.clear();
93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return err;
95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
96fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mExtractor = MediaExtractor::Create(mSource);
98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (mExtractor == NULL) {
100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mSource.clear();
101fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
102fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return UNKNOWN_ERROR;
103fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
1042a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
1052a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    return OK;
1062a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}
1072a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
1084e202e779a8495091ab189fd88fc295a3e619c61Andreas Huberstatic VideoFrame *extractVideoFrameWithCodecFlags(
1094e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        OMXClient *client,
1104e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        const sp<MetaData> &trackMeta,
11116afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        const sp<MediaSource> &source,
11216afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        uint32_t flags,
11316afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        int64_t frameTimeUs,
11416afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        int seekMode) {
1152a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    sp<MediaSource> decoder =
1162a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        OMXCodec::Create(
1174e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber                client->interface(), source->getFormat(), false, source,
118f3712f026aad1fc46b1df18d1dba718281e39726Andreas Huber                NULL, flags | OMXCodec::kClientNeedsFramebuffer);
1192a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
1202a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    if (decoder.get() == NULL) {
12147bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber        LOGV("unable to instantiate video decoder.");
1222a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
1232a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        return NULL;
1242a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    }
1252a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
126139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber    status_t err = decoder->start();
127139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber    if (err != OK) {
128139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        LOGW("OMXCodec::start returned error %d (0x%08x)\n", err, err);
129139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        return NULL;
130139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber    }
1312a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
132c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    // Read one output buffer, ignore format change notifications
133c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    // and spurious empty buffers.
134c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber
1357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    MediaSource::ReadOptions options;
13616afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong    if (seekMode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC ||
13716afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        seekMode > MediaSource::ReadOptions::SEEK_CLOSEST) {
13816afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong
13916afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        LOGE("Unknown seek mode: %d", seekMode);
14016afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        return NULL;
14116afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong    }
14216afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong
14316afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong    MediaSource::ReadOptions::SeekMode mode =
14416afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong            static_cast<MediaSource::ReadOptions::SeekMode>(seekMode);
14516afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong
1467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    int64_t thumbNailTime;
147cb0cb25002f1b5fe0d02c997bac487b5b6c5c682Andreas Huber    if (frameTimeUs < 0) {
148cb0cb25002f1b5fe0d02c997bac487b5b6c5c682Andreas Huber        if (!trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) {
149cb0cb25002f1b5fe0d02c997bac487b5b6c5c682Andreas Huber            thumbNailTime = 0;
150cb0cb25002f1b5fe0d02c997bac487b5b6c5c682Andreas Huber        }
15116afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        options.setSeekTo(thumbNailTime, mode);
1524e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    } else {
1534e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        thumbNailTime = -1;
15416afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        options.setSeekTo(frameTimeUs, mode);
1557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
1567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
157c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    MediaBuffer *buffer = NULL;
1587f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    do {
159c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber        if (buffer != NULL) {
160c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber            buffer->release();
161c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber            buffer = NULL;
162c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber        }
1637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        err = decoder->read(&buffer, &options);
1647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        options.clearSeekTo();
165c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    } while (err == INFO_FORMAT_CHANGED
166c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber             || (buffer != NULL && buffer->range_length() == 0));
1672a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
1682a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    if (err != OK) {
1692a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        CHECK_EQ(buffer, NULL);
1702a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
17147bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber        LOGV("decoding frame failed.");
1722a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        decoder->stop();
1732a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
1742a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        return NULL;
1752a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    }
1762a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
17747bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber    LOGV("successfully decoded video frame.");
1782a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
1792b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber    int32_t unreadable;
1802b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber    if (buffer->meta_data()->findInt32(kKeyIsUnreadable, &unreadable)
1812b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber            && unreadable != 0) {
1822b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber        LOGV("video frame is unreadable, decoder does not give us access "
1832b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber             "to the video data.");
1842b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber
1852b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber        buffer->release();
1862b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber        buffer = NULL;
1872b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber
1882b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber        decoder->stop();
1892b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber
1902b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber        return NULL;
1912b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber    }
1922b82e9652ba049e754c2cc74e381282f231d5fbfAndreas Huber
1934e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    int64_t timeUs;
1944e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
1954e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    if (thumbNailTime >= 0) {
1964e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        if (timeUs != thumbNailTime) {
1974e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber            const char *mime;
1984e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber            CHECK(trackMeta->findCString(kKeyMIMEType, &mime));
1994e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
2004e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber            LOGV("thumbNailTime = %lld us, timeUs = %lld us, mime = %s",
2014e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber                 thumbNailTime, timeUs, mime);
2024e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        }
2034e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    }
2044e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
2054e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    sp<MetaData> meta = decoder->getFormat();
2062a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
2072a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    int32_t width, height;
2082a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CHECK(meta->findInt32(kKeyWidth, &width));
2092a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CHECK(meta->findInt32(kKeyHeight, &height));
2102a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
211f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t crop_left, crop_top, crop_right, crop_bottom;
212f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findRect(
213f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                kKeyCropRect,
214f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                &crop_left, &crop_top, &crop_right, &crop_bottom)) {
215f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        crop_left = crop_top = 0;
216f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        crop_right = width - 1;
217f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        crop_bottom = height - 1;
218f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
219f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
220ce0febae177d1816ee7a6750ed9fba52472b9a71James Dong    int32_t rotationAngle;
221ce0febae177d1816ee7a6750ed9fba52472b9a71James Dong    if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
222ce0febae177d1816ee7a6750ed9fba52472b9a71James Dong        rotationAngle = 0;  // By default, no rotation
223ce0febae177d1816ee7a6750ed9fba52472b9a71James Dong    }
224ce0febae177d1816ee7a6750ed9fba52472b9a71James Dong
2252a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    VideoFrame *frame = new VideoFrame;
226f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    frame->mWidth = crop_right - crop_left + 1;
227f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    frame->mHeight = crop_bottom - crop_top + 1;
228f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    frame->mDisplayWidth = frame->mWidth;
229f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    frame->mDisplayHeight = frame->mHeight;
230f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    frame->mSize = frame->mWidth * frame->mHeight * 2;
2312a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    frame->mData = new uint8_t[frame->mSize];
232ce0febae177d1816ee7a6750ed9fba52472b9a71James Dong    frame->mRotationAngle = rotationAngle;
2332a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
2342a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    int32_t srcFormat;
2352a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &srcFormat));
2362a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
2372a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    ColorConverter converter(
2382a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber            (OMX_COLOR_FORMATTYPE)srcFormat, OMX_COLOR_Format16bitRGB565);
2392a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CHECK(converter.isValid());
2402a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
241b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber    err = converter.convert(
2422a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber            (const uint8_t *)buffer->data() + buffer->range_offset(),
243f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber            width, height,
244f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber            crop_left, crop_top, crop_right, crop_bottom,
245f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber            frame->mData,
246f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber            frame->mWidth,
247f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber            frame->mHeight,
248f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber            0, 0, frame->mWidth - 1, frame->mHeight - 1);
2492a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
2502a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    buffer->release();
2512a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    buffer = NULL;
2522a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
2532a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    decoder->stop();
2542a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
255b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber    if (err != OK) {
256b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber        LOGE("Colorconverter failed to convert frame.");
257b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber
258b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber        delete frame;
259b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber        frame = NULL;
260b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber    }
261b1787e3b95e96cc002377d41518cc183f64b58c4Andreas Huber
2622a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    return frame;
2632a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}
2642a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
26516afe2fb439cab6125bb46a07a8078d4ce1c1ea5James DongVideoFrame *StagefrightMetadataRetriever::getFrameAtTime(
26616afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        int64_t timeUs, int option) {
2674e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
26816afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong    LOGV("getFrameAtTime: %lld us option: %d", timeUs, option);
26993e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber    if (0 == (mMode & METADATA_MODE_FRAME_CAPTURE_ONLY)) {
2706e5cf568f4a5dee4be6ec991e1a96497303fb019James Dong        LOGV("getFrameAtTime disabled by mode (0x%08x)", mMode);
27193e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber
27293e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber        return NULL;
27393e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber    }
27493e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber
2754e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    if (mExtractor.get() == NULL) {
2764e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        LOGV("no extractor.");
2774e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        return NULL;
2784e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    }
2794e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
2804e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    size_t n = mExtractor->countTracks();
2814e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    size_t i;
2824e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    for (i = 0; i < n; ++i) {
2834e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        sp<MetaData> meta = mExtractor->getTrackMetaData(i);
2844e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
2854e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        const char *mime;
2864e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
2874e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
2884e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        if (!strncasecmp(mime, "video/", 6)) {
2894e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber            break;
2904e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        }
2914e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    }
2924e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
2934e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    if (i == n) {
2944e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        LOGV("no video track found.");
2954e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        return NULL;
2964e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    }
2974e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
2984e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    sp<MetaData> trackMeta = mExtractor->getTrackMetaData(
2994e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber            i, MediaExtractor::kIncludeExtensiveMetaData);
3004e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
3014e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    sp<MediaSource> source = mExtractor->getTrack(i);
3024e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
3034e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    if (source.get() == NULL) {
3044e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        LOGV("unable to instantiate video track.");
3054e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        return NULL;
3064e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    }
3074e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
3084e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    VideoFrame *frame =
3094e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        extractVideoFrameWithCodecFlags(
31016afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong                &mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs,
31116afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong                timeUs, option);
3124e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
3134e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    if (frame == NULL) {
3144e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber        LOGV("Software decoder failed to extract thumbnail, "
3154e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber             "trying hardware decoder.");
3164e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
31716afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong        frame = extractVideoFrameWithCodecFlags(&mClient, trackMeta, source, 0,
31816afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong                        timeUs, option);
3194e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    }
3204e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
3214e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber    return frame;
3224e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber}
3234e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber
3242a4a7d5af053a17586a262a1267ba993e31790f1Andreas HuberMediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() {
3252a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO");
3262a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
32793e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber    if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) {
32893e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber        LOGV("extractAlbumArt/metadata retrieval disabled by mode");
32993e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber
33093e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber        return NULL;
33193e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber    }
33293e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber
333fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (mExtractor == NULL) {
334fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return NULL;
335fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
336fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
337fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (!mParsedMetaData) {
338fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        parseMetaData();
339fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
340fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mParsedMetaData = true;
341fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
342fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
343fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (mAlbumArt) {
344fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return new MediaAlbumArt(*mAlbumArt);
345fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
346fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
3472a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    return NULL;
3482a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}
3492a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
3502a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huberconst char *StagefrightMetadataRetriever::extractMetadata(int keyCode) {
35193e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber    if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) {
35293e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber        LOGV("extractAlbumArt/metadata retrieval disabled by mode");
35393e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber
35493e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber        return NULL;
35593e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber    }
35693e1fb99a0c66784b49b105ce84a23baf054ee9cAndreas Huber
357fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (mExtractor == NULL) {
358fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return NULL;
359fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
360fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
361fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (!mParsedMetaData) {
362fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        parseMetaData();
363fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
364fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mParsedMetaData = true;
365fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
366fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
367fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    ssize_t index = mMetaData.indexOfKey(keyCode);
368fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
369fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (index < 0) {
370fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return NULL;
371fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
372fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
373fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    return strdup(mMetaData.valueAt(index).string());
3742a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}
3752a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber
376fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid StagefrightMetadataRetriever::parseMetaData() {
377fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    sp<MetaData> meta = mExtractor->getMetaData();
378fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
379fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    struct Map {
380fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        int from;
381fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        int to;
382fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    };
383fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    static const Map kMap[] = {
3847be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber        { kKeyMIMEType, METADATA_KEY_MIMETYPE },
385bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber        { kKeyCDTrackNumber, METADATA_KEY_CD_TRACK_NUMBER },
3866c8a9a4132337a3419a72a735f0b40df0b82061fMarco Nelissen        { kKeyDiscNumber, METADATA_KEY_DISC_NUMBER },
387fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        { kKeyAlbum, METADATA_KEY_ALBUM },
388fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        { kKeyArtist, METADATA_KEY_ARTIST },
38966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        { kKeyAlbumArtist, METADATA_KEY_ALBUMARTIST },
390bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber        { kKeyAuthor, METADATA_KEY_AUTHOR },
391fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        { kKeyComposer, METADATA_KEY_COMPOSER },
392bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber        { kKeyDate, METADATA_KEY_DATE },
393fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        { kKeyGenre, METADATA_KEY_GENRE },
394fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        { kKeyTitle, METADATA_KEY_TITLE },
395fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        { kKeyYear, METADATA_KEY_YEAR },
39672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        { kKeyWriter, METADATA_KEY_WRITER },
39711f8109ad8646d3acd9a0987613229cde59d52c1Marco Nelissen        { kKeyCompilation, METADATA_KEY_COMPILATION },
398fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    };
399fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
400fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
401fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    for (size_t i = 0; i < kNumMapEntries; ++i) {
402fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        const char *value;
403fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        if (meta->findCString(kMap[i].from, &value)) {
404fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber            mMetaData.add(kMap[i].to, String8(value));
405fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        }
406fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
407fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
408fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    const void *data;
409fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    uint32_t type;
410fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    size_t dataSize;
411fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)) {
412fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mAlbumArt = new MediaAlbumArt;
413fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mAlbumArt->mSize = dataSize;
414fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mAlbumArt->mData = new uint8_t[dataSize];
415fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        memcpy(mAlbumArt->mData, data, dataSize);
416fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
417fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
418bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber    size_t numTracks = mExtractor->countTracks();
419bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber
420bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber    char tmp[32];
421bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber    sprintf(tmp, "%d", numTracks);
422bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber
423bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber    mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));
424bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber
425fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    // The overall duration is the duration of the longest track.
426fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    int64_t maxDurationUs = 0;
427bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber    for (size_t i = 0; i < numTracks; ++i) {
428fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
429fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
430fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        int64_t durationUs;
431fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        if (trackMeta->findInt64(kKeyDuration, &durationUs)) {
432fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber            if (durationUs > maxDurationUs) {
433fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber                maxDurationUs = durationUs;
434fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber            }
435fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        }
436fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
437fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
438fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    // The duration value is a string representing the duration in ms.
439fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
440fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
441093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
442093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (numTracks == 1) {
443093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const char *fileMIME;
444093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &fileMIME));
445093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
446093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (!strcasecmp(fileMIME, "video/x-matroska")) {
447093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            sp<MetaData> trackMeta = mExtractor->getTrackMetaData(0);
448093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            const char *trackMIME;
449093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            CHECK(trackMeta->findCString(kKeyMIMEType, &trackMIME));
450093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
451093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            if (!strncasecmp("audio/", trackMIME, 6)) {
452093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                // The matroska file only contains a single audio track,
453093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                // rewrite its mime type.
454093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                mMetaData.add(
455093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                        METADATA_KEY_MIMETYPE, String8("audio/x-matroska"));
456093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
457093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
458093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
459fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber}
460fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
4612a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber}  // namespace android
462