StagefrightMetadataRetriever.cpp revision 66ac4df65516ebfd0e500bfca75dc4b5ef8d674e
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/CachingDataSource.h> 242a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/ColorConverter.h> 252a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/DataSource.h> 26bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/FileSource.h> 272a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/HTTPDataSource.h> 282a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/MediaDebug.h> 292a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/MediaExtractor.h> 302a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/MetaData.h> 312a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber#include <media/stagefright/OMXCodec.h> 322a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 332a4a7d5af053a17586a262a1267ba993e31790f1Andreas Hubernamespace android { 342a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 35fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberStagefrightMetadataRetriever::StagefrightMetadataRetriever() 36fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mParsedMetaData(false), 37fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mAlbumArt(NULL) { 382a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber LOGV("StagefrightMetadataRetriever()"); 392a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 402a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber DataSource::RegisterDefaultSniffers(); 412a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber CHECK_EQ(mClient.connect(), OK); 422a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} 432a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 442a4a7d5af053a17586a262a1267ba993e31790f1Andreas HuberStagefrightMetadataRetriever::~StagefrightMetadataRetriever() { 452a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber LOGV("~StagefrightMetadataRetriever()"); 46fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 47fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete mAlbumArt; 48fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mAlbumArt = NULL; 49fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 502a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber mClient.disconnect(); 512a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} 522a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 532a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huberstatus_t StagefrightMetadataRetriever::setDataSource(const char *uri) { 542a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber LOGV("setDataSource(%s)", uri); 552a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 56fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mParsedMetaData = false; 57fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mMetaData.clear(); 58fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete mAlbumArt; 59fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mAlbumArt = NULL; 60fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 61fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSource = DataSource::CreateFromURI(uri); 62fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 63fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mSource == NULL) { 64fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return UNKNOWN_ERROR; 65fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 66fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 67fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mExtractor = MediaExtractor::Create(mSource); 68fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 69fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mExtractor == NULL) { 70fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSource.clear(); 712a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 72fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return UNKNOWN_ERROR; 73fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 74fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 75fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return OK; 762a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} 772a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 78fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber// Warning caller retains ownership of the filedescriptor! Dup it if necessary. 792a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huberstatus_t StagefrightMetadataRetriever::setDataSource( 802a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber int fd, int64_t offset, int64_t length) { 81fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber fd = dup(fd); 82fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 832a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 842a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 85fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mParsedMetaData = false; 86fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mMetaData.clear(); 87fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete mAlbumArt; 88fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mAlbumArt = NULL; 89fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 90fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSource = new FileSource(fd, offset, length); 91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber status_t err; 93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if ((err = mSource->initCheck()) != OK) { 94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSource.clear(); 95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 96fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return err; 97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mExtractor = MediaExtractor::Create(mSource); 100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 101fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mExtractor == NULL) { 102fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSource.clear(); 103fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 104fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return UNKNOWN_ERROR; 105fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 1062a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1072a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber return OK; 1082a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} 1092a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1104e202e779a8495091ab189fd88fc295a3e619c61Andreas Huberstatic VideoFrame *extractVideoFrameWithCodecFlags( 1114e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber OMXClient *client, 1124e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber const sp<MetaData> &trackMeta, 1134e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber const sp<MediaSource> &source, uint32_t flags) { 1142a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber sp<MediaSource> decoder = 1152a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber OMXCodec::Create( 1164e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber client->interface(), source->getFormat(), false, source, 1174e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber NULL, flags); 1182a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1192a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber if (decoder.get() == NULL) { 12047bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber LOGV("unable to instantiate video decoder."); 1212a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1222a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber return NULL; 1232a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber } 1242a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1252a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber decoder->start(); 1262a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 127c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber // Read one output buffer, ignore format change notifications 128c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber // and spurious empty buffers. 129c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber 1307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber MediaSource::ReadOptions options; 1317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber int64_t thumbNailTime; 1327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) { 1337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber options.setSeekTo(thumbNailTime); 1344e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } else { 1354e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber thumbNailTime = -1; 1367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 1377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 138c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber MediaBuffer *buffer = NULL; 1397f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber status_t err; 1407f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber do { 141c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber if (buffer != NULL) { 142c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber buffer->release(); 143c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber buffer = NULL; 144c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber } 1457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber err = decoder->read(&buffer, &options); 1467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber options.clearSeekTo(); 147c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber } while (err == INFO_FORMAT_CHANGED 148c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber || (buffer != NULL && buffer->range_length() == 0)); 1492a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1502a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber if (err != OK) { 1512a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber CHECK_EQ(buffer, NULL); 1522a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 15347bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber LOGV("decoding frame failed."); 1542a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber decoder->stop(); 1552a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1562a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber return NULL; 1572a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber } 1582a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 15947bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber LOGV("successfully decoded video frame."); 1602a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1614e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber int64_t timeUs; 1624e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 1634e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber if (thumbNailTime >= 0) { 1644e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber if (timeUs != thumbNailTime) { 1654e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber const char *mime; 1664e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber CHECK(trackMeta->findCString(kKeyMIMEType, &mime)); 1674e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 1684e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber LOGV("thumbNailTime = %lld us, timeUs = %lld us, mime = %s", 1694e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber thumbNailTime, timeUs, mime); 1704e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 1714e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 1724e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 1734e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber sp<MetaData> meta = decoder->getFormat(); 1742a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1752a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber int32_t width, height; 1762a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 1772a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 1782a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1792a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber VideoFrame *frame = new VideoFrame; 1802a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber frame->mWidth = width; 1812a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber frame->mHeight = height; 1822a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber frame->mDisplayWidth = width; 1832a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber frame->mDisplayHeight = height; 1842a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber frame->mSize = width * height * 2; 1852a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber frame->mData = new uint8_t[frame->mSize]; 1862a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1872a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber int32_t srcFormat; 1882a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber CHECK(meta->findInt32(kKeyColorFormat, &srcFormat)); 1892a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1902a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber ColorConverter converter( 1912a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber (OMX_COLOR_FORMATTYPE)srcFormat, OMX_COLOR_Format16bitRGB565); 1922a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber CHECK(converter.isValid()); 1932a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 1942a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber converter.convert( 1952a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber width, height, 1962a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(), 1972a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 0, 1982a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber frame->mData, width * 2); 1992a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 2002a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber buffer->release(); 2012a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber buffer = NULL; 2022a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 2032a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber decoder->stop(); 2042a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 2052a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber return frame; 2062a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} 2072a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 2084e202e779a8495091ab189fd88fc295a3e619c61Andreas HuberVideoFrame *StagefrightMetadataRetriever::captureFrame() { 2094e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber LOGV("captureFrame"); 2104e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2114e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber if (mExtractor.get() == NULL) { 2124e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber LOGV("no extractor."); 2134e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber return NULL; 2144e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 2154e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2164e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber size_t n = mExtractor->countTracks(); 2174e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber size_t i; 2184e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber for (i = 0; i < n; ++i) { 2194e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber sp<MetaData> meta = mExtractor->getTrackMetaData(i); 2204e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2214e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber const char *mime; 2224e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 2234e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2244e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber if (!strncasecmp(mime, "video/", 6)) { 2254e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber break; 2264e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 2274e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 2284e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2294e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber if (i == n) { 2304e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber LOGV("no video track found."); 2314e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber return NULL; 2324e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 2334e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2344e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber sp<MetaData> trackMeta = mExtractor->getTrackMetaData( 2354e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber i, MediaExtractor::kIncludeExtensiveMetaData); 2364e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2374e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber sp<MediaSource> source = mExtractor->getTrack(i); 2384e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2394e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber if (source.get() == NULL) { 2404e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber LOGV("unable to instantiate video track."); 2414e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber return NULL; 2424e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 2434e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2444e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber VideoFrame *frame = 2454e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber extractVideoFrameWithCodecFlags( 2464e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber &mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs); 2474e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2484e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber if (frame == NULL) { 2494e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber LOGV("Software decoder failed to extract thumbnail, " 2504e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber "trying hardware decoder."); 2514e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2524e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber frame = extractVideoFrameWithCodecFlags(&mClient, trackMeta, source, 0); 2534e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber } 2544e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2554e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber return frame; 2564e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber} 2574e202e779a8495091ab189fd88fc295a3e619c61Andreas Huber 2582a4a7d5af053a17586a262a1267ba993e31790f1Andreas HuberMediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() { 2592a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO"); 2602a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 261fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mExtractor == NULL) { 262fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 263fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 264fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 265fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mParsedMetaData) { 266fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber parseMetaData(); 267fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 268fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mParsedMetaData = true; 269fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 270fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 271fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mAlbumArt) { 272fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return new MediaAlbumArt(*mAlbumArt); 273fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 274fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 2752a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber return NULL; 2762a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} 2772a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 2782a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huberconst char *StagefrightMetadataRetriever::extractMetadata(int keyCode) { 279fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mExtractor == NULL) { 280fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 281fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 282fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 283fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mParsedMetaData) { 284fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber parseMetaData(); 285fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 286fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mParsedMetaData = true; 287fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 288fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 289fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ssize_t index = mMetaData.indexOfKey(keyCode); 290fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 291fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (index < 0) { 292fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 293fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 294fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 295fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return strdup(mMetaData.valueAt(index).string()); 2962a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} 2972a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber 298fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid StagefrightMetadataRetriever::parseMetaData() { 299fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber sp<MetaData> meta = mExtractor->getMetaData(); 300fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 301fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber struct Map { 302fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber int from; 303fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber int to; 304fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 305fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber static const Map kMap[] = { 3067be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber { kKeyMIMEType, METADATA_KEY_MIMETYPE }, 307bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber { kKeyCDTrackNumber, METADATA_KEY_CD_TRACK_NUMBER }, 3086c8a9a4132337a3419a72a735f0b40df0b82061fMarco Nelissen { kKeyDiscNumber, METADATA_KEY_DISC_NUMBER }, 309fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyAlbum, METADATA_KEY_ALBUM }, 310fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyArtist, METADATA_KEY_ARTIST }, 31166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen { kKeyAlbumArtist, METADATA_KEY_ALBUMARTIST }, 312bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber { kKeyAuthor, METADATA_KEY_AUTHOR }, 313fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyComposer, METADATA_KEY_COMPOSER }, 314bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber { kKeyDate, METADATA_KEY_DATE }, 315fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyGenre, METADATA_KEY_GENRE }, 316fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyTitle, METADATA_KEY_TITLE }, 317fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyYear, METADATA_KEY_YEAR }, 31872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { kKeyWriter, METADATA_KEY_WRITER }, 319fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 320fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 321fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 322fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < kNumMapEntries; ++i) { 323fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const char *value; 324fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (meta->findCString(kMap[i].from, &value)) { 325fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mMetaData.add(kMap[i].to, String8(value)); 326fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 327fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 328fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 329fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const void *data; 330fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint32_t type; 331fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t dataSize; 332fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)) { 333fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mAlbumArt = new MediaAlbumArt; 334fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mAlbumArt->mSize = dataSize; 335fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mAlbumArt->mData = new uint8_t[dataSize]; 336fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(mAlbumArt->mData, data, dataSize); 337fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 338fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 339bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber size_t numTracks = mExtractor->countTracks(); 340bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber 341bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber char tmp[32]; 342bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber sprintf(tmp, "%d", numTracks); 343bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber 344bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp)); 345bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber 346fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // The overall duration is the duration of the longest track. 347fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber int64_t maxDurationUs = 0; 348bd4bc59262df90dc85752684a1d4a92833a535a3Andreas Huber for (size_t i = 0; i < numTracks; ++i) { 349fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i); 350fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 351fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber int64_t durationUs; 352fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (trackMeta->findInt64(kKeyDuration, &durationUs)) { 353fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (durationUs > maxDurationUs) { 354fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber maxDurationUs = durationUs; 355fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 356fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 357fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 358fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 359fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // The duration value is a string representing the duration in ms. 360fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000); 361fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mMetaData.add(METADATA_KEY_DURATION, String8(tmp)); 362fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 363fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 364fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 3652a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber} // namespace android 366