StagefrightMetadataRetriever.cpp revision 1e1941638398e5e3e1d7b9ad88e66f574576bcfa
153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber/* 2aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * Copyright (C) 2009 The Android Open Source Project 3aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * 4aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * you may not use this file except in compliance with the License. 6aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * You may obtain a copy of the License at 7aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * 8aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * 10aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * Unless required by applicable law or agreed to in writing, software 11aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * See the License for the specific language governing permissions and 14aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber * limitations under the License. 15aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber */ 1653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 1753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber//#define LOG_NDEBUG 0 1853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#define LOG_TAG "StagefrightMetadataRetriever" 1953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <utils/Log.h> 2053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 21e4a838051de5e56f44c71117073a035b804b5d04Andreas Huber#include "include/StagefrightMetadataRetriever.h" 2253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 2353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/ColorConverter.h> 2453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/DataSource.h> 2527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/FileSource.h> 2653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/MediaDebug.h> 2753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/MediaExtractor.h> 2853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/MetaData.h> 2953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber#include <media/stagefright/OMXCodec.h> 3053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 3153a76bd0c918082847e52570c307ed3ba325992dAndreas Hubernamespace android { 3253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 33aee3c6394a367abf283936cb8b8bd85ed028c050Andreas HuberStagefrightMetadataRetriever::StagefrightMetadataRetriever() 34aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber : mParsedMetaData(false), 35aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAlbumArt(NULL) { 3653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber LOGV("StagefrightMetadataRetriever()"); 3753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 3853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber DataSource::RegisterDefaultSniffers(); 3953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber CHECK_EQ(mClient.connect(), OK); 4053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} 4153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 4253a76bd0c918082847e52570c307ed3ba325992dAndreas HuberStagefrightMetadataRetriever::~StagefrightMetadataRetriever() { 4353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber LOGV("~StagefrightMetadataRetriever()"); 44aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 45aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber delete mAlbumArt; 46aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAlbumArt = NULL; 47aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 4853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber mClient.disconnect(); 4953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} 5053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 5153a76bd0c918082847e52570c307ed3ba325992dAndreas Huberstatus_t StagefrightMetadataRetriever::setDataSource(const char *uri) { 5253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber LOGV("setDataSource(%s)", uri); 5353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 54aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mParsedMetaData = false; 55aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mMetaData.clear(); 56aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber delete mAlbumArt; 57aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAlbumArt = NULL; 58aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 59aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mSource = DataSource::CreateFromURI(uri); 60aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 61aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (mSource == NULL) { 62aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return UNKNOWN_ERROR; 63aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 64aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 65aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mExtractor = MediaExtractor::Create(mSource); 66aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 67aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (mExtractor == NULL) { 68aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mSource.clear(); 6953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 70aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return UNKNOWN_ERROR; 71aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 72aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 73aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return OK; 7453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} 7553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 76aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber// Warning caller retains ownership of the filedescriptor! Dup it if necessary. 7753a76bd0c918082847e52570c307ed3ba325992dAndreas Huberstatus_t StagefrightMetadataRetriever::setDataSource( 7853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber int fd, int64_t offset, int64_t length) { 79aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber fd = dup(fd); 80aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 8153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 8253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 83aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mParsedMetaData = false; 84aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mMetaData.clear(); 85aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber delete mAlbumArt; 86aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAlbumArt = NULL; 87aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 88aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mSource = new FileSource(fd, offset, length); 89aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 90aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber status_t err; 91aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if ((err = mSource->initCheck()) != OK) { 92aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mSource.clear(); 93aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 94aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return err; 95aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 96aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 97aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mExtractor = MediaExtractor::Create(mSource); 98aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 99aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (mExtractor == NULL) { 100aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mSource.clear(); 101aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 102aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return UNKNOWN_ERROR; 103aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 10453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 10553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber return OK; 10653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} 10753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 1080ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huberstatic VideoFrame *extractVideoFrameWithCodecFlags( 1090ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber OMXClient *client, 1100ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber const sp<MetaData> &trackMeta, 1110ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber const sp<MediaSource> &source, uint32_t flags) { 11253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber sp<MediaSource> decoder = 11353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber OMXCodec::Create( 1140ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber client->interface(), source->getFormat(), false, source, 1150ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber NULL, flags); 11653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 11753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber if (decoder.get() == NULL) { 118ad28543022101d0b01845e3f53dcd57e524816efAndreas Huber LOGV("unable to instantiate video decoder."); 11953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 12053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber return NULL; 12153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber } 12253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 1231919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber status_t err = decoder->start(); 1241919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber if (err != OK) { 1251919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber LOGW("OMXCodec::start returned error %d (0x%08x)\n", err, err); 1261919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber return NULL; 1271919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber } 12853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 129f68c168d366e8aad58454917f96344398a02efd8Andreas Huber // Read one output buffer, ignore format change notifications 130f68c168d366e8aad58454917f96344398a02efd8Andreas Huber // and spurious empty buffers. 131f68c168d366e8aad58454917f96344398a02efd8Andreas Huber 132e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber MediaSource::ReadOptions options; 133e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber int64_t thumbNailTime; 134e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if (trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) { 135e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber options.setSeekTo(thumbNailTime); 1360ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } else { 1370ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber thumbNailTime = -1; 138e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 139e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber 140f68c168d366e8aad58454917f96344398a02efd8Andreas Huber MediaBuffer *buffer = NULL; 141cfd55579c2e20514b181809dfaf30bd6f7e04c7eAndreas Huber do { 142f68c168d366e8aad58454917f96344398a02efd8Andreas Huber if (buffer != NULL) { 143f68c168d366e8aad58454917f96344398a02efd8Andreas Huber buffer->release(); 144f68c168d366e8aad58454917f96344398a02efd8Andreas Huber buffer = NULL; 145f68c168d366e8aad58454917f96344398a02efd8Andreas Huber } 146e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber err = decoder->read(&buffer, &options); 147e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber options.clearSeekTo(); 148f68c168d366e8aad58454917f96344398a02efd8Andreas Huber } while (err == INFO_FORMAT_CHANGED 149f68c168d366e8aad58454917f96344398a02efd8Andreas Huber || (buffer != NULL && buffer->range_length() == 0)); 15053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 15153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber if (err != OK) { 15253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber CHECK_EQ(buffer, NULL); 15353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 154ad28543022101d0b01845e3f53dcd57e524816efAndreas Huber LOGV("decoding frame failed."); 15553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber decoder->stop(); 15653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 15753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber return NULL; 15853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber } 15953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 160ad28543022101d0b01845e3f53dcd57e524816efAndreas Huber LOGV("successfully decoded video frame."); 16153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 1621e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber int32_t unreadable; 1631e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber if (buffer->meta_data()->findInt32(kKeyIsUnreadable, &unreadable) 1641e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber && unreadable != 0) { 1651e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber LOGV("video frame is unreadable, decoder does not give us access " 1661e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber "to the video data."); 1671e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber 1681e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber buffer->release(); 1691e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber buffer = NULL; 1701e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber 1711e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber decoder->stop(); 1721e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber 1731e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber return NULL; 1741e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber } 1751e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber 1760ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber int64_t timeUs; 1770ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 1780ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber if (thumbNailTime >= 0) { 1790ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber if (timeUs != thumbNailTime) { 1800ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber const char *mime; 1810ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber CHECK(trackMeta->findCString(kKeyMIMEType, &mime)); 1820ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 1830ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber LOGV("thumbNailTime = %lld us, timeUs = %lld us, mime = %s", 1840ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber thumbNailTime, timeUs, mime); 1850ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 1860ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 1870ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 1880ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber sp<MetaData> meta = decoder->getFormat(); 18953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 19053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber int32_t width, height; 19153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 19253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 19353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 19453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber VideoFrame *frame = new VideoFrame; 19553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber frame->mWidth = width; 19653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber frame->mHeight = height; 19753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber frame->mDisplayWidth = width; 19853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber frame->mDisplayHeight = height; 19953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber frame->mSize = width * height * 2; 20053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber frame->mData = new uint8_t[frame->mSize]; 20153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 20253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber int32_t srcFormat; 20353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber CHECK(meta->findInt32(kKeyColorFormat, &srcFormat)); 20453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 20553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber ColorConverter converter( 20653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber (OMX_COLOR_FORMATTYPE)srcFormat, OMX_COLOR_Format16bitRGB565); 20753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber CHECK(converter.isValid()); 20853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 20953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber converter.convert( 21053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber width, height, 21153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(), 21253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 0, 21353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber frame->mData, width * 2); 21453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 21553a76bd0c918082847e52570c307ed3ba325992dAndreas Huber buffer->release(); 21653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber buffer = NULL; 21753a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 21853a76bd0c918082847e52570c307ed3ba325992dAndreas Huber decoder->stop(); 21953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 22053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber return frame; 22153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} 22253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 2230ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas HuberVideoFrame *StagefrightMetadataRetriever::captureFrame() { 2240ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber LOGV("captureFrame"); 2250ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 226e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber if (0 == (mMode & METADATA_MODE_FRAME_CAPTURE_ONLY)) { 227e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber LOGV("captureFrame disabled by mode (0x%08x)", mMode); 228e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber 229e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber return NULL; 230e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber } 231e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber 2320ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber if (mExtractor.get() == NULL) { 2330ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber LOGV("no extractor."); 2340ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber return NULL; 2350ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 2360ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2370ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber size_t n = mExtractor->countTracks(); 2380ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber size_t i; 2390ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber for (i = 0; i < n; ++i) { 2400ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber sp<MetaData> meta = mExtractor->getTrackMetaData(i); 2410ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2420ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber const char *mime; 2430ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 2440ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2450ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber if (!strncasecmp(mime, "video/", 6)) { 2460ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber break; 2470ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 2480ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 2490ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2500ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber if (i == n) { 2510ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber LOGV("no video track found."); 2520ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber return NULL; 2530ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 2540ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2550ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber sp<MetaData> trackMeta = mExtractor->getTrackMetaData( 2560ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber i, MediaExtractor::kIncludeExtensiveMetaData); 2570ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2580ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber sp<MediaSource> source = mExtractor->getTrack(i); 2590ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2600ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber if (source.get() == NULL) { 2610ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber LOGV("unable to instantiate video track."); 2620ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber return NULL; 2630ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 2640ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2650ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber VideoFrame *frame = 2660ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber extractVideoFrameWithCodecFlags( 2670ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber &mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs); 2680ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2690ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber if (frame == NULL) { 2700ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber LOGV("Software decoder failed to extract thumbnail, " 2710ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber "trying hardware decoder."); 2720ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2730ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber frame = extractVideoFrameWithCodecFlags(&mClient, trackMeta, source, 0); 2740ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber } 2750ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 2760ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber return frame; 2770ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber} 2780ffc90f6edd5f09a49e2f97351723ef1e1a3128aAndreas Huber 27953a76bd0c918082847e52570c307ed3ba325992dAndreas HuberMediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() { 28053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO"); 28153a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 282e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) { 283e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber LOGV("extractAlbumArt/metadata retrieval disabled by mode"); 284e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber 285e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber return NULL; 286e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber } 287e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber 288aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (mExtractor == NULL) { 289aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return NULL; 290aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 291aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 292aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (!mParsedMetaData) { 293aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber parseMetaData(); 294aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 295aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mParsedMetaData = true; 296aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 297aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 298aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (mAlbumArt) { 299aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return new MediaAlbumArt(*mAlbumArt); 300aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 301aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 30253a76bd0c918082847e52570c307ed3ba325992dAndreas Huber return NULL; 30353a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} 30453a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 30553a76bd0c918082847e52570c307ed3ba325992dAndreas Huberconst char *StagefrightMetadataRetriever::extractMetadata(int keyCode) { 306e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) { 307e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber LOGV("extractAlbumArt/metadata retrieval disabled by mode"); 308e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber 309e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber return NULL; 310e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber } 311e3452d3fe1da014a6db9a326df08230e0d5339ecAndreas Huber 312aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (mExtractor == NULL) { 313aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return NULL; 314aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 315aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 316aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (!mParsedMetaData) { 317aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber parseMetaData(); 318aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 319aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mParsedMetaData = true; 320aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 321aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 322aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber ssize_t index = mMetaData.indexOfKey(keyCode); 323aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 324aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (index < 0) { 325aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return NULL; 326aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 327aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 328aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber return strdup(mMetaData.valueAt(index).string()); 32953a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} 33053a76bd0c918082847e52570c307ed3ba325992dAndreas Huber 331aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Hubervoid StagefrightMetadataRetriever::parseMetaData() { 332aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber sp<MetaData> meta = mExtractor->getMetaData(); 333aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 334aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber struct Map { 335aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber int from; 336aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber int to; 337aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber }; 338aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber static const Map kMap[] = { 3391cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber { kKeyMIMEType, METADATA_KEY_MIMETYPE }, 3403a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber { kKeyCDTrackNumber, METADATA_KEY_CD_TRACK_NUMBER }, 341655306f8a80b3e9fc52daf458ef319a8ed8c564cMarco Nelissen { kKeyDiscNumber, METADATA_KEY_DISC_NUMBER }, 342aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber { kKeyAlbum, METADATA_KEY_ALBUM }, 343aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber { kKeyArtist, METADATA_KEY_ARTIST }, 344c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen { kKeyAlbumArtist, METADATA_KEY_ALBUMARTIST }, 3453a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber { kKeyAuthor, METADATA_KEY_AUTHOR }, 346aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber { kKeyComposer, METADATA_KEY_COMPOSER }, 3473a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber { kKeyDate, METADATA_KEY_DATE }, 348aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber { kKeyGenre, METADATA_KEY_GENRE }, 349aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber { kKeyTitle, METADATA_KEY_TITLE }, 350aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber { kKeyYear, METADATA_KEY_YEAR }, 351c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber { kKeyWriter, METADATA_KEY_WRITER }, 352aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber }; 353aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 354aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 355aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber for (size_t i = 0; i < kNumMapEntries; ++i) { 356aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber const char *value; 357aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (meta->findCString(kMap[i].from, &value)) { 358aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mMetaData.add(kMap[i].to, String8(value)); 359aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 360aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 361aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 362aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber const void *data; 363aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber uint32_t type; 364aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber size_t dataSize; 365aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)) { 366aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAlbumArt = new MediaAlbumArt; 367aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAlbumArt->mSize = dataSize; 368aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAlbumArt->mData = new uint8_t[dataSize]; 369aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber memcpy(mAlbumArt->mData, data, dataSize); 370aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 371aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 3723a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber size_t numTracks = mExtractor->countTracks(); 3733a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber 3743a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber char tmp[32]; 3753a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber sprintf(tmp, "%d", numTracks); 3763a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber 3773a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp)); 3783a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber 379aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber // The overall duration is the duration of the longest track. 380aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber int64_t maxDurationUs = 0; 3813a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber for (size_t i = 0; i < numTracks; ++i) { 382aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i); 383aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 384aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber int64_t durationUs; 385aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (trackMeta->findInt64(kKeyDuration, &durationUs)) { 386aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber if (durationUs > maxDurationUs) { 387aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber maxDurationUs = durationUs; 388aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 389aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 390aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber } 391aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 392aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber // The duration value is a string representing the duration in ms. 393aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000); 394aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mMetaData.add(METADATA_KEY_DURATION, String8(tmp)); 395072f5247ef893e683728263a540bb93daafda376Andreas Huber 396072f5247ef893e683728263a540bb93daafda376Andreas Huber if (numTracks == 1) { 397072f5247ef893e683728263a540bb93daafda376Andreas Huber const char *fileMIME; 398072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &fileMIME)); 399072f5247ef893e683728263a540bb93daafda376Andreas Huber 400072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strcasecmp(fileMIME, "video/x-matroska")) { 401072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<MetaData> trackMeta = mExtractor->getTrackMetaData(0); 402072f5247ef893e683728263a540bb93daafda376Andreas Huber const char *trackMIME; 403072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(trackMeta->findCString(kKeyMIMEType, &trackMIME)); 404072f5247ef893e683728263a540bb93daafda376Andreas Huber 405072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strncasecmp("audio/", trackMIME, 6)) { 406072f5247ef893e683728263a540bb93daafda376Andreas Huber // The matroska file only contains a single audio track, 407072f5247ef893e683728263a540bb93daafda376Andreas Huber // rewrite its mime type. 408072f5247ef893e683728263a540bb93daafda376Andreas Huber mMetaData.add( 409072f5247ef893e683728263a540bb93daafda376Andreas Huber METADATA_KEY_MIMETYPE, String8("audio/x-matroska")); 410072f5247ef893e683728263a540bb93daafda376Andreas Huber } 411072f5247ef893e683728263a540bb93daafda376Andreas Huber } 412072f5247ef893e683728263a540bb93daafda376Andreas Huber } 413aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber} 414aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 415aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 41653a76bd0c918082847e52570c307ed3ba325992dAndreas Huber} // namespace android 417