1/* 2 * Copyright 2016, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gui/Surface.h> 18 19#include <media/ICrypto.h> 20#include <media/MediaCodecBuffer.h> 21#include <media/stagefright/MediaDefs.h> 22#include <media/stagefright/foundation/ALooper.h> 23#include <media/stagefright/foundation/AMessage.h> 24#include <media/stagefright/foundation/AUtils.h> 25#include <media/stagefright/MediaBuffer.h> 26#include <media/stagefright/MediaCodecList.h> 27#include <media/stagefright/MediaCodec.h> 28#include <media/stagefright/MetaData.h> 29#include <media/stagefright/SimpleDecodingSource.h> 30#include <media/stagefright/Utils.h> 31 32using namespace android; 33 34const int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds 35const int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds 36 37//static 38sp<SimpleDecodingSource> SimpleDecodingSource::Create( 39 const sp<IMediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow, 40 const char *desiredCodec) { 41 sp<Surface> surface = static_cast<Surface*>(nativeWindow.get()); 42 const char *mime = NULL; 43 sp<MetaData> meta = source->getFormat(); 44 CHECK(meta->findCString(kKeyMIMEType, &mime)); 45 46 sp<AMessage> format = new AMessage; 47 if (convertMetaDataToMessage(source->getFormat(), &format) != OK) { 48 return NULL; 49 } 50 51 Vector<AString> matchingCodecs; 52 MediaCodecList::findMatchingCodecs( 53 mime, false /* encoder */, flags, &matchingCodecs); 54 55 sp<ALooper> looper = new ALooper; 56 looper->setName("stagefright"); 57 looper->start(); 58 59 sp<MediaCodec> codec; 60 61 for (size_t i = 0; i < matchingCodecs.size(); ++i) { 62 const AString &componentName = matchingCodecs[i]; 63 if (desiredCodec != NULL && componentName.compare(desiredCodec)) { 64 continue; 65 } 66 67 ALOGV("Attempting to allocate codec '%s'", componentName.c_str()); 68 69 codec = MediaCodec::CreateByComponentName(looper, componentName); 70 if (codec != NULL) { 71 ALOGI("Successfully allocated codec '%s'", componentName.c_str()); 72 73 status_t err = codec->configure(format, surface, NULL /* crypto */, 0 /* flags */); 74 if (err == OK) { 75 err = codec->getOutputFormat(&format); 76 } 77 if (err == OK) { 78 return new SimpleDecodingSource(codec, source, looper, 79 surface != NULL, 80 strcmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS) == 0, 81 format); 82 } 83 84 ALOGD("Failed to configure codec '%s'", componentName.c_str()); 85 codec->release(); 86 codec = NULL; 87 } 88 } 89 90 looper->stop(); 91 ALOGE("No matching decoder! (mime: %s)", mime); 92 return NULL; 93} 94 95SimpleDecodingSource::SimpleDecodingSource( 96 const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper, 97 bool usingSurface, bool isVorbis, const sp<AMessage> &format) 98 : mCodec(codec), 99 mSource(source), 100 mLooper(looper), 101 mUsingSurface(usingSurface), 102 mIsVorbis(isVorbis), 103 mProtectedState(format) { 104 mCodec->getName(&mComponentName); 105} 106 107SimpleDecodingSource::~SimpleDecodingSource() { 108 mCodec->release(); 109 mLooper->stop(); 110} 111 112status_t SimpleDecodingSource::start(MetaData *params) { 113 (void)params; 114 Mutexed<ProtectedState>::Locked me(mProtectedState); 115 if (me->mState != INIT) { 116 return -EINVAL; 117 } 118 status_t res = mCodec->start(); 119 if (res == OK) { 120 res = mSource->start(); 121 } 122 123 if (res == OK) { 124 me->mState = STARTED; 125 me->mQueuedInputEOS = false; 126 me->mGotOutputEOS = false; 127 } else { 128 me->mState = ERROR; 129 } 130 131 return res; 132} 133 134status_t SimpleDecodingSource::stop() { 135 Mutexed<ProtectedState>::Locked me(mProtectedState); 136 if (me->mState != STARTED) { 137 return -EINVAL; 138 } 139 140 // wait for any pending reads to complete 141 me->mState = STOPPING; 142 while (me->mReading) { 143 me.waitForCondition(me->mReadCondition); 144 } 145 146 status_t res1 = mCodec->stop(); 147 if (res1 != OK) { 148 mCodec->release(); 149 } 150 status_t res2 = mSource->stop(); 151 if (res1 == OK && res2 == OK) { 152 me->mState = STOPPED; 153 } else { 154 me->mState = ERROR; 155 } 156 return res1 != OK ? res1 : res2; 157} 158 159sp<MetaData> SimpleDecodingSource::getFormat() { 160 Mutexed<ProtectedState>::Locked me(mProtectedState); 161 if (me->mState == STARTED || me->mState == INIT) { 162 sp<MetaData> meta = new MetaData(); 163 convertMessageToMetaData(me->mFormat, meta); 164 return meta; 165 } 166 return NULL; 167} 168 169SimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format) 170 : mReading(false), 171 mFormat(format), 172 mState(INIT), 173 mQueuedInputEOS(false), 174 mGotOutputEOS(false) { 175} 176 177status_t SimpleDecodingSource::read( 178 MediaBuffer **buffer, const ReadOptions *options) { 179 *buffer = NULL; 180 181 Mutexed<ProtectedState>::Locked me(mProtectedState); 182 if (me->mState != STARTED) { 183 return ERROR_END_OF_STREAM; 184 } 185 me->mReading = true; 186 187 status_t res = doRead(me, buffer, options); 188 189 me.lock(); 190 me->mReading = false; 191 if (me->mState != STARTED) { 192 me->mReadCondition.signal(); 193 } 194 195 return res; 196} 197 198status_t SimpleDecodingSource::doRead( 199 Mutexed<ProtectedState>::Locked &me, MediaBuffer **buffer, const ReadOptions *options) { 200 // |me| is always locked on entry, but is allowed to be unlocked on exit 201 CHECK_EQ(me->mState, STARTED); 202 203 size_t out_ix, in_ix, out_offset, out_size; 204 int64_t out_pts; 205 uint32_t out_flags; 206 status_t res; 207 208 // flush codec on seek 209 IMediaSource::ReadOptions::SeekMode mode; 210 if (options != NULL && options->getSeekTo(&out_pts, &mode)) { 211 me->mQueuedInputEOS = false; 212 me->mGotOutputEOS = false; 213 mCodec->flush(); 214 } 215 216 if (me->mGotOutputEOS) { 217 return ERROR_END_OF_STREAM; 218 } 219 220 for (int retries = 0; ++retries; ) { 221 // If we fill all available input buffers, we should expect that 222 // the codec produces at least one output buffer. Also, the codec 223 // should produce an output buffer in at most 1 seconds. Retry a 224 // few times nonetheless. 225 while (!me->mQueuedInputEOS) { 226 // allow some time to get input buffer after flush 227 res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs); 228 if (res == -EAGAIN) { 229 // no available input buffers 230 break; 231 } 232 233 sp<MediaCodecBuffer> in_buffer; 234 if (res == OK) { 235 res = mCodec->getInputBuffer(in_ix, &in_buffer); 236 } 237 238 if (res != OK || in_buffer == NULL) { 239 ALOGW("[%s] could not get input buffer #%zu", 240 mComponentName.c_str(), in_ix); 241 me->mState = ERROR; 242 return UNKNOWN_ERROR; 243 } 244 245 MediaBuffer *in_buf; 246 while (true) { 247 in_buf = NULL; 248 me.unlock(); 249 res = mSource->read(&in_buf, options); 250 me.lock(); 251 if (res != OK || me->mState != STARTED) { 252 if (in_buf != NULL) { 253 in_buf->release(); 254 in_buf = NULL; 255 } 256 257 // queue EOS 258 me->mQueuedInputEOS = true; 259 if (mCodec->queueInputBuffer( 260 in_ix, 0 /* offset */, 0 /* size */, 261 0 /* pts */, MediaCodec::BUFFER_FLAG_EOS) != OK) { 262 ALOGI("[%s] failed to queue input EOS", mComponentName.c_str()); 263 me->mState = ERROR; 264 return UNKNOWN_ERROR; 265 } 266 267 // don't stop on EOS, but report error or EOS on stop 268 if (res != ERROR_END_OF_STREAM) { 269 me->mState = ERROR; 270 return res; 271 } 272 if (me->mState != STARTED) { 273 return ERROR_END_OF_STREAM; 274 } 275 break; 276 } 277 if (in_buf == NULL) { // should not happen 278 continue; 279 } else if (in_buf->range_length() != 0) { 280 break; 281 } 282 in_buf->release(); 283 } 284 285 if (in_buf != NULL) { 286 int64_t timestampUs = 0; 287 CHECK(in_buf->meta_data()->findInt64(kKeyTime, ×tampUs)); 288 if (in_buf->range_length() + (mIsVorbis ? 4 : 0) > in_buffer->capacity()) { 289 ALOGW("'%s' received %zu input bytes for buffer of size %zu", 290 mComponentName.c_str(), 291 in_buf->range_length() + (mIsVorbis ? 4 : 0), in_buffer->capacity()); 292 } 293 size_t cpLen = min(in_buf->range_length(), in_buffer->capacity()); 294 memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(), 295 cpLen ); 296 297 if (mIsVorbis) { 298 int32_t numPageSamples; 299 if (!in_buf->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) { 300 numPageSamples = -1; 301 } 302 memcpy(in_buffer->base() + cpLen, &numPageSamples, sizeof(numPageSamples)); 303 } 304 305 res = mCodec->queueInputBuffer( 306 in_ix, 0 /* offset */, in_buf->range_length() + (mIsVorbis ? 4 : 0), 307 timestampUs, 0 /* flags */); 308 if (res != OK) { 309 ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix); 310 me->mState = ERROR; 311 } 312 in_buf->release(); 313 } 314 } 315 316 me.unlock(); 317 res = mCodec->dequeueOutputBuffer( 318 &out_ix, &out_offset, &out_size, &out_pts, 319 &out_flags, kTimeoutWaitForOutputUs /* timeoutUs */); 320 me.lock(); 321 // abort read on stop 322 if (me->mState != STARTED) { 323 if (res == OK) { 324 mCodec->releaseOutputBuffer(out_ix); 325 } 326 return ERROR_END_OF_STREAM; 327 } 328 329 if (res == -EAGAIN) { 330 ALOGD("[%s] did not produce an output buffer. retry count: %d", 331 mComponentName.c_str(), retries); 332 continue; 333 } else if (res == INFO_FORMAT_CHANGED) { 334 if (mCodec->getOutputFormat(&me->mFormat) != OK) { 335 me->mState = ERROR; 336 res = UNKNOWN_ERROR; 337 } 338 return res; 339 } else if (res == INFO_OUTPUT_BUFFERS_CHANGED) { 340 ALOGV("output buffers changed"); 341 continue; 342 } else if (res != OK) { 343 me->mState = ERROR; 344 return res; 345 } 346 347 sp<MediaCodecBuffer> out_buffer; 348 res = mCodec->getOutputBuffer(out_ix, &out_buffer); 349 if (res != OK) { 350 ALOGW("[%s] could not get output buffer #%zu", 351 mComponentName.c_str(), out_ix); 352 me->mState = ERROR; 353 return UNKNOWN_ERROR; 354 } 355 if (out_flags & MediaCodec::BUFFER_FLAG_EOS) { 356 me->mGotOutputEOS = true; 357 // return EOS immediately if last buffer is empty 358 if (out_size == 0) { 359 mCodec->releaseOutputBuffer(out_ix); 360 return ERROR_END_OF_STREAM; 361 } 362 } 363 364 if (mUsingSurface && out_size > 0) { 365 *buffer = new MediaBuffer(0); 366 mCodec->renderOutputBufferAndRelease(out_ix); 367 } else { 368 *buffer = new MediaBuffer(out_size); 369 CHECK_LE(out_buffer->size(), (*buffer)->size()); 370 memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size()); 371 (*buffer)->meta_data()->setInt64(kKeyTime, out_pts); 372 mCodec->releaseOutputBuffer(out_ix); 373 } 374 return OK; 375 } 376 377 return TIMED_OUT; 378} 379