100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar/* 200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * Copyright 2016, The Android Open Source Project 300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * 400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License"); 500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * you may not use this file except in compliance with the License. 600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * You may obtain a copy of the License at 700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * 800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * http://www.apache.org/licenses/LICENSE-2.0 900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * 1000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * Unless required by applicable law or agreed to in writing, software 1100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS, 1200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * See the License for the specific language governing permissions and 1400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * limitations under the License. 1500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar */ 1600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 1700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <gui/Surface.h> 1800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 1900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/ICrypto.h> 2000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/ABuffer.h> 2100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/ALooper.h> 2200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AMessage.h> 2300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 2400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaBuffer.h> 2500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodecList.h> 2600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodec.h> 2700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MetaData.h> 2800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/SimpleDecodingSource.h> 2900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/Utils.h> 3000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 3100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarusing namespace android; 3200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 3300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarconst int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds 343ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnarconst int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds 3500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 3600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar//static 3700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<SimpleDecodingSource> SimpleDecodingSource::Create( 38963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar const sp<IMediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow, 39963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar const char *desiredCodec) { 4000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<Surface> surface = static_cast<Surface*>(nativeWindow.get()); 4100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar const char *mime = NULL; 4200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<MetaData> meta = source->getFormat(); 4300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar CHECK(meta->findCString(kKeyMIMEType, &mime)); 4400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 4500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<AMessage> format = new AMessage; 4600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar convertMetaDataToMessage(source->getFormat(), &format); 4700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 4800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Vector<AString> matchingCodecs; 4900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar MediaCodecList::findMatchingCodecs( 5000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mime, false /* encoder */, flags, &matchingCodecs); 5100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 5200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<ALooper> looper = new ALooper; 5300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar looper->setName("stagefright"); 5400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar looper->start(); 5500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 5600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<MediaCodec> codec; 5700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 5800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar for (size_t i = 0; i < matchingCodecs.size(); ++i) { 5900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar const AString &componentName = matchingCodecs[i]; 60963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar if (desiredCodec != NULL && componentName.compare(desiredCodec)) { 61963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar continue; 62963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar } 6300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 6400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGV("Attempting to allocate codec '%s'", componentName.c_str()); 6500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 6600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar codec = MediaCodec::CreateByComponentName(looper, componentName); 6700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (codec != NULL) { 6800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGI("Successfully allocated codec '%s'", componentName.c_str()); 6900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 7000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t err = codec->configure(format, surface, NULL /* crypto */, 0 /* flags */); 7100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (err == OK) { 7200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar err = codec->getOutputFormat(&format); 7300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 7400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (err == OK) { 7500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return new SimpleDecodingSource(codec, source, looper, surface != NULL, format); 7600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 7700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 7800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGD("Failed to configure codec '%s'", componentName.c_str()); 7900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar codec->release(); 8000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar codec = NULL; 8100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 8200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 8300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 8400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar looper->stop(); 8500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGE("No matching decoder! (mime: %s)", mime); 8600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return NULL; 8700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 8800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 8900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::SimpleDecodingSource( 9000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper, 9100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar bool usingSurface, const sp<AMessage> &format) 9200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar : mCodec(codec), 9300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mSource(source), 9400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mLooper(looper), 9500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mUsingSurface(usingSurface), 9600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mProtectedState(format) { 9700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->getName(&mComponentName); 9800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 9900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 10000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::~SimpleDecodingSource() { 10100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->release(); 10200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mLooper->stop(); 10300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 10400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 10500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::start(MetaData *params) { 10600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar (void)params; 10700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 10800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != INIT) { 10900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return -EINVAL; 11000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 11100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res = mCodec->start(); 11200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 11300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mSource->start(); 11400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 11500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 11600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 11700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = STARTED; 11800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mQueuedInputEOS = false; 11900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mGotOutputEOS = false; 12000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else { 12100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 12200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 12300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 12400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 12500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 12600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 12700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::stop() { 12800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 12900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 13000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return -EINVAL; 13100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 13200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 13300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // wait for any pending reads to complete 13400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = STOPPING; 13500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar while (me->mReading) { 13600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.waitForCondition(me->mReadCondition); 13700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 13800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 13900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res1 = mCodec->stop(); 14000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res1 != OK) { 14100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->release(); 14200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 14300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res2 = mSource->stop(); 14400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res1 == OK && res2 == OK) { 14500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = STOPPED; 14600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else { 14700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 14800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 14900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res1 != OK ? res1 : res2; 15000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 15100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 15200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<MetaData> SimpleDecodingSource::getFormat() { 15300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 15400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState == STARTED || me->mState == INIT) { 15500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<MetaData> meta = new MetaData(); 15600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar convertMessageToMetaData(me->mFormat, meta); 15700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return meta; 15800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 15900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return NULL; 16000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 16100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 16200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format) 16300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar : mReading(false), 16400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mFormat(format), 16500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mState(INIT), 16600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mQueuedInputEOS(false), 16700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mGotOutputEOS(false) { 16800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 16900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 17000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::read( 17100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar MediaBuffer **buffer, const ReadOptions *options) { 17200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *buffer = NULL; 17300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 17400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 17500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 17600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 17700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 17800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mReading = true; 17900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 18000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res = doRead(me, buffer, options); 18100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 18200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.lock(); 18300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mReading = false; 18400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 18500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mReadCondition.signal(); 18600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 18700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 18800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 18900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 19000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 19100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::doRead( 19200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked &me, MediaBuffer **buffer, const ReadOptions *options) { 19300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // |me| is always locked on entry, but is allowed to be unlocked on exit 19400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar CHECK_EQ(me->mState, STARTED); 19500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 19600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar size_t out_ix, in_ix, out_offset, out_size; 19700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar int64_t out_pts; 19800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar uint32_t out_flags; 19900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res; 20000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 20100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // flush codec on seek 20200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar IMediaSource::ReadOptions::SeekMode mode; 20300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (options != NULL && options->getSeekTo(&out_pts, &mode)) { 20400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mQueuedInputEOS = false; 20500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mGotOutputEOS = false; 20600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->flush(); 20700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 20800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 20900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mGotOutputEOS) { 21000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 21100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 21200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 2133ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar for (int retries = 0; ++retries; ) { 21400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // If we fill all available input buffers, we should expect that 21500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // the codec produces at least one output buffer. Also, the codec 21600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // should produce an output buffer in at most 1 seconds. Retry a 21700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // few times nonetheless. 21800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar while (!me->mQueuedInputEOS) { 2193ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar // allow some time to get input buffer after flush 2203ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs); 22100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == -EAGAIN) { 22200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // no available input buffers 22300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar break; 22400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 22500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 22600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<ABuffer> in_buffer; 22700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 22800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->getInputBuffer(in_ix, &in_buffer); 22900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 23000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 23100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK || in_buffer == NULL) { 23200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGW("[%s] could not get input buffer #%zu", 23300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), in_ix); 23400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 23500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return UNKNOWN_ERROR; 23600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 23700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 23800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar MediaBuffer *in_buf; 23900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar while (true) { 24000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf = NULL; 24100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.unlock(); 24200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mSource->read(&in_buf, options); 24300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.lock(); 24400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK || me->mState != STARTED) { 24500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (in_buf != NULL) { 24600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf->release(); 24700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf = NULL; 24800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 24900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 25000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // queue EOS 25100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mQueuedInputEOS = true; 25200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (mCodec->queueInputBuffer( 25300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_ix, 0 /* offset */, 0 /* size */, 25400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 0 /* pts */, MediaCodec::BUFFER_FLAG_EOS) != OK) { 25500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGI("[%s] failed to queue input EOS", mComponentName.c_str()); 25600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 25700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return UNKNOWN_ERROR; 25800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 25900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 26000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // don't stop on EOS, but report error or EOS on stop 26100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != ERROR_END_OF_STREAM) { 26200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 26300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 26400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 26500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 26600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 26700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 26800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar break; 26900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 27000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (in_buf == NULL) { // should not happen 27100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar continue; 27200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (in_buf->range_length() != 0) { 27300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar break; 27400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 27500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf->release(); 27600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 27700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 27800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (in_buf != NULL) { 27900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar int64_t timestampUs = 0; 28000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar CHECK(in_buf->meta_data()->findInt64(kKeyTime, ×tampUs)); 28100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (in_buf->range_length() > in_buffer->capacity()) { 28200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGW("'%s' received %zu input bytes for buffer of size %zu", 28300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), 28400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf->range_length(), in_buffer->capacity()); 28500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 28600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(), 28700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar min(in_buf->range_length(), in_buffer->capacity())); 28800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 28900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->queueInputBuffer( 29000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_ix, 0 /* offset */, in_buf->range_length(), 29100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar timestampUs, 0 /* flags */); 29200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK) { 29300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix); 29400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 29500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 29600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf->release(); 29700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 29800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 29900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 30000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.unlock(); 30100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->dequeueOutputBuffer( 30200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar &out_ix, &out_offset, &out_size, &out_pts, 30300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar &out_flags, kTimeoutWaitForOutputUs /* timeoutUs */); 30400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.lock(); 30500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // abort read on stop 30600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 30700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 30800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->releaseOutputBuffer(out_ix); 30900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 31000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 31100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 31200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 31300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == -EAGAIN) { 31400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGD("[%s] did not produce an output buffer. retry count: %d", 31500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), retries); 31600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar continue; 31700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (res == INFO_FORMAT_CHANGED) { 31800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (mCodec->getOutputFormat(&me->mFormat) != OK) { 31900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 32000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = UNKNOWN_ERROR; 32100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 32200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 32300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (res == INFO_OUTPUT_BUFFERS_CHANGED) { 32400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGV("output buffers changed"); 32500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar continue; 32600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (res != OK) { 32700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 32800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 32900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 33000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 33100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<ABuffer> out_buffer; 33200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->getOutputBuffer(out_ix, &out_buffer); 33300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK) { 33400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGW("[%s] could not get output buffer #%zu", 33500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), out_ix); 33600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 33700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return UNKNOWN_ERROR; 33800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 33900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (out_flags & MediaCodec::BUFFER_FLAG_EOS) { 34000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mGotOutputEOS = true; 34100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // return EOS immediately if last buffer is empty 34200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (out_size == 0) { 34300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->releaseOutputBuffer(out_ix); 34400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 34500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 34600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 34700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 34800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (mUsingSurface && out_size > 0) { 34900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *buffer = new MediaBuffer(0); 35000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->renderOutputBufferAndRelease(out_ix); 35100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else { 35200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *buffer = new MediaBuffer(out_size); 35300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar CHECK_LE(out_buffer->size(), (*buffer)->size()); 35400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size()); 35500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar (*buffer)->meta_data()->setInt64(kKeyTime, out_pts); 35600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->releaseOutputBuffer(out_ix); 35700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 35800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return OK; 35900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 36000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 36100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return TIMED_OUT; 36200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 363