StagefrightMetadataRetriever.cpp revision 67e5a4f6f6879d512a859e5dba92e9beec7a2f91
1/* 2** 3** Copyright 2009, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "StagefrightMetadataRetriever" 20#include <utils/Log.h> 21 22#include "include/StagefrightMetadataRetriever.h" 23 24#include <media/stagefright/CachingDataSource.h> 25#include <media/stagefright/ColorConverter.h> 26#include <media/stagefright/DataSource.h> 27#include <media/stagefright/FileSource.h> 28#include <media/stagefright/HTTPDataSource.h> 29#include <media/stagefright/MediaDebug.h> 30#include <media/stagefright/MediaExtractor.h> 31#include <media/stagefright/MetaData.h> 32#include <media/stagefright/OMXCodec.h> 33 34namespace android { 35 36StagefrightMetadataRetriever::StagefrightMetadataRetriever() { 37 LOGV("StagefrightMetadataRetriever()"); 38 39 DataSource::RegisterDefaultSniffers(); 40 CHECK_EQ(mClient.connect(), OK); 41} 42 43StagefrightMetadataRetriever::~StagefrightMetadataRetriever() { 44 LOGV("~StagefrightMetadataRetriever()"); 45 mClient.disconnect(); 46} 47 48status_t StagefrightMetadataRetriever::setDataSource(const char *uri) { 49 LOGV("setDataSource(%s)", uri); 50 51 mExtractor = MediaExtractor::CreateFromURI(uri); 52 53 return mExtractor.get() != NULL ? OK : UNKNOWN_ERROR; 54} 55 56status_t StagefrightMetadataRetriever::setDataSource( 57 int fd, int64_t offset, int64_t length) { 58 LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 59 60 mExtractor = MediaExtractor::Create( 61 new FileSource(fd, offset, length)); 62 63 return OK; 64} 65 66VideoFrame *StagefrightMetadataRetriever::captureFrame() { 67 LOGV("captureFrame"); 68 69 if (mExtractor.get() == NULL) { 70 LOGV("no extractor."); 71 return NULL; 72 } 73 74 size_t n = mExtractor->countTracks(); 75 size_t i; 76 for (i = 0; i < n; ++i) { 77 sp<MetaData> meta = mExtractor->getTrackMetaData(i); 78 79 const char *mime; 80 CHECK(meta->findCString(kKeyMIMEType, &mime)); 81 82 if (!strncasecmp(mime, "video/", 6)) { 83 break; 84 } 85 } 86 87 if (i == n) { 88 LOGV("no video track found."); 89 return NULL; 90 } 91 92 sp<MetaData> trackMeta = mExtractor->getTrackMetaData( 93 i, MediaExtractor::kIncludeExtensiveMetaData); 94 95 sp<MediaSource> source = mExtractor->getTrack(i); 96 97 if (source.get() == NULL) { 98 LOGV("unable to instantiate video track."); 99 return NULL; 100 } 101 102 sp<MetaData> meta = source->getFormat(); 103 104 sp<MediaSource> decoder = 105 OMXCodec::Create( 106 mClient.interface(), meta, false, source, 107 NULL, OMXCodec::kPreferSoftwareCodecs); 108 109 if (decoder.get() == NULL) { 110 LOGV("unable to instantiate video decoder."); 111 112 return NULL; 113 } 114 115 decoder->start(); 116 117 // Read one output buffer, ignore format change notifications 118 // and spurious empty buffers. 119 120 MediaSource::ReadOptions options; 121 int64_t thumbNailTime; 122 if (trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) { 123 options.setSeekTo(thumbNailTime); 124 } 125 126 MediaBuffer *buffer = NULL; 127 status_t err; 128 do { 129 if (buffer != NULL) { 130 buffer->release(); 131 buffer = NULL; 132 } 133 err = decoder->read(&buffer, &options); 134 options.clearSeekTo(); 135 } while (err == INFO_FORMAT_CHANGED 136 || (buffer != NULL && buffer->range_length() == 0)); 137 138 if (err != OK) { 139 CHECK_EQ(buffer, NULL); 140 141 LOGV("decoding frame failed."); 142 decoder->stop(); 143 144 return NULL; 145 } 146 147 LOGV("successfully decoded video frame."); 148 149 meta = decoder->getFormat(); 150 151 int32_t width, height; 152 CHECK(meta->findInt32(kKeyWidth, &width)); 153 CHECK(meta->findInt32(kKeyHeight, &height)); 154 155 VideoFrame *frame = new VideoFrame; 156 frame->mWidth = width; 157 frame->mHeight = height; 158 frame->mDisplayWidth = width; 159 frame->mDisplayHeight = height; 160 frame->mSize = width * height * 2; 161 frame->mData = new uint8_t[frame->mSize]; 162 163 int32_t srcFormat; 164 CHECK(meta->findInt32(kKeyColorFormat, &srcFormat)); 165 166 ColorConverter converter( 167 (OMX_COLOR_FORMATTYPE)srcFormat, OMX_COLOR_Format16bitRGB565); 168 CHECK(converter.isValid()); 169 170 converter.convert( 171 width, height, 172 (const uint8_t *)buffer->data() + buffer->range_offset(), 173 0, 174 frame->mData, width * 2); 175 176 buffer->release(); 177 buffer = NULL; 178 179 decoder->stop(); 180 181 return frame; 182} 183 184MediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() { 185 LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO"); 186 187 return NULL; 188} 189 190const char *StagefrightMetadataRetriever::extractMetadata(int keyCode) { 191 LOGV("extractMetadata %d (extractor: %s)", 192 keyCode, mExtractor.get() != NULL ? "YES" : "NO"); 193 194 return NULL; 195} 196 197} // namespace android 198