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