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 174f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim//#define LOG_NDEBUG 0 184f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim#define LOG_TAG "SimpleDecodingSource" 194f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim#include <utils/Log.h> 204f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim 2100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <gui/Surface.h> 2200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 2300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/ICrypto.h> 247e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h> 254278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen#include <media/stagefright/MediaDefs.h> 2600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/ALooper.h> 2700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AMessage.h> 2800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 2900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaBuffer.h> 3000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodecList.h> 3100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodec.h> 3200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MetaData.h> 3300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/SimpleDecodingSource.h> 3400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/Utils.h> 3500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 3600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarusing namespace android; 3700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 3800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarconst int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds 393ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnarconst int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds 4000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 4100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar//static 4200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<SimpleDecodingSource> SimpleDecodingSource::Create( 43ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang const sp<MediaSource> &source, uint32_t flags) { 44defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian return SimpleDecodingSource::Create(source, flags, nullptr, nullptr); 45defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian} 46defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian 47defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian//static 48defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopiansp<SimpleDecodingSource> SimpleDecodingSource::Create( 49ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang const sp<MediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow, 504f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim const char *desiredCodec, bool skipMediaCodecList) { 5100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<Surface> surface = static_cast<Surface*>(nativeWindow.get()); 5200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar const char *mime = NULL; 5300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<MetaData> meta = source->getFormat(); 5400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar CHECK(meta->findCString(kKeyMIMEType, &mime)); 5500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 5600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<AMessage> format = new AMessage; 575bd99f9211c533058be9f41bc966be1f2f501f13Lajos Molnar if (convertMetaDataToMessage(source->getFormat(), &format) != OK) { 585bd99f9211c533058be9f41bc966be1f2f501f13Lajos Molnar return NULL; 595bd99f9211c533058be9f41bc966be1f2f501f13Lajos Molnar } 6000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 6100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Vector<AString> matchingCodecs; 6200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar MediaCodecList::findMatchingCodecs( 6300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mime, false /* encoder */, flags, &matchingCodecs); 6400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 6500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<ALooper> looper = new ALooper; 6600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar looper->setName("stagefright"); 6700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar looper->start(); 6800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 6900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<MediaCodec> codec; 704f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim auto configure = [=](const sp<MediaCodec> &codec, const AString &componentName) 714f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim -> sp<SimpleDecodingSource> { 7200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (codec != NULL) { 7300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGI("Successfully allocated codec '%s'", componentName.c_str()); 7400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 7500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t err = codec->configure(format, surface, NULL /* crypto */, 0 /* flags */); 764f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim sp<AMessage> outFormat; 7700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (err == OK) { 784f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim err = codec->getOutputFormat(&outFormat); 7900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 8000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (err == OK) { 814278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen return new SimpleDecodingSource(codec, source, looper, 824278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen surface != NULL, 834278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen strcmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS) == 0, 844f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim outFormat); 8500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 8600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 8700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGD("Failed to configure codec '%s'", componentName.c_str()); 8800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar codec->release(); 894f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim } 904f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim return NULL; 914f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim }; 924f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim 934f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim if (skipMediaCodecList) { 944f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim codec = MediaCodec::CreateByComponentName(looper, desiredCodec); 954f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim return configure(codec, desiredCodec); 964f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim } 974f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim 984f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim for (size_t i = 0; i < matchingCodecs.size(); ++i) { 994f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim const AString &componentName = matchingCodecs[i]; 1004f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim if (desiredCodec != NULL && componentName.compare(desiredCodec)) { 1014f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim continue; 1024f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim } 1034f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim 1044f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim ALOGV("Attempting to allocate codec '%s'", componentName.c_str()); 1054f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim 1064f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim codec = MediaCodec::CreateByComponentName(looper, componentName); 1074f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim sp<SimpleDecodingSource> res = configure(codec, componentName); 1084f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim if (res != NULL) { 1094f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim return res; 1104f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim } else { 11100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar codec = NULL; 11200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 11300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 11400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 11500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar looper->stop(); 11600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGE("No matching decoder! (mime: %s)", mime); 11700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return NULL; 11800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 11900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 12000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::SimpleDecodingSource( 121ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang const sp<MediaCodec> &codec, const sp<MediaSource> &source, const sp<ALooper> &looper, 1224278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen bool usingSurface, bool isVorbis, const sp<AMessage> &format) 12300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar : mCodec(codec), 12400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mSource(source), 12500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mLooper(looper), 12600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mUsingSurface(usingSurface), 1274278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen mIsVorbis(isVorbis), 12800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mProtectedState(format) { 12900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->getName(&mComponentName); 13000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 13100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 13200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::~SimpleDecodingSource() { 13300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->release(); 13400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mLooper->stop(); 13500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 13600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 13700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::start(MetaData *params) { 13800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar (void)params; 13900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 14000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != INIT) { 14100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return -EINVAL; 14200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 14300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res = mCodec->start(); 14400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 14500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mSource->start(); 14600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 14700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 14800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 14900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = STARTED; 15000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mQueuedInputEOS = false; 15100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mGotOutputEOS = false; 15200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else { 15300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 15400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 15500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 15600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 15700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 15800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 15900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::stop() { 16000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 16100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 16200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return -EINVAL; 16300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 16400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 16500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // wait for any pending reads to complete 16600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = STOPPING; 16700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar while (me->mReading) { 16800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.waitForCondition(me->mReadCondition); 16900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 17000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 17100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res1 = mCodec->stop(); 17200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res1 != OK) { 17300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->release(); 17400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 17500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res2 = mSource->stop(); 17600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res1 == OK && res2 == OK) { 17700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = STOPPED; 17800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else { 17900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 18000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 18100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res1 != OK ? res1 : res2; 18200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 18300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 18400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<MetaData> SimpleDecodingSource::getFormat() { 18500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 18600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState == STARTED || me->mState == INIT) { 18700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar sp<MetaData> meta = new MetaData(); 18800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar convertMessageToMetaData(me->mFormat, meta); 18900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return meta; 19000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 19100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return NULL; 19200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 19300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 19400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format) 19500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar : mReading(false), 19600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mFormat(format), 19700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mState(INIT), 19800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mQueuedInputEOS(false), 19900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mGotOutputEOS(false) { 20000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 20100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 20200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::read( 2031889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase **buffer, const ReadOptions *options) { 20400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *buffer = NULL; 20500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 20600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar Mutexed<ProtectedState>::Locked me(mProtectedState); 20700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 20800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 20900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 21000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mReading = true; 21100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 21200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res = doRead(me, buffer, options); 21300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 21400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.lock(); 21500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mReading = false; 21600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 21700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mReadCondition.signal(); 21800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 21900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 22000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 22100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 22200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 22300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::doRead( 2241889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang Mutexed<ProtectedState>::Locked &me, MediaBufferBase **buffer, const ReadOptions *options) { 22500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // |me| is always locked on entry, but is allowed to be unlocked on exit 22600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar CHECK_EQ(me->mState, STARTED); 22700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 22800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar size_t out_ix, in_ix, out_offset, out_size; 22900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar int64_t out_pts; 23000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar uint32_t out_flags; 23100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar status_t res; 23200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 23300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // flush codec on seek 234ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang MediaSource::ReadOptions::SeekMode mode; 23500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (options != NULL && options->getSeekTo(&out_pts, &mode)) { 23600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mQueuedInputEOS = false; 23700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mGotOutputEOS = false; 23800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->flush(); 23900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 24000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 24100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mGotOutputEOS) { 24200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 24300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 24400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 2453ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar for (int retries = 0; ++retries; ) { 24600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // If we fill all available input buffers, we should expect that 24700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // the codec produces at least one output buffer. Also, the codec 24800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // should produce an output buffer in at most 1 seconds. Retry a 24900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // few times nonetheless. 25000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar while (!me->mQueuedInputEOS) { 2513ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar // allow some time to get input buffer after flush 2523ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs); 25300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == -EAGAIN) { 25400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // no available input buffers 25500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar break; 25600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 25700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 2587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> in_buffer; 25900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 26000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->getInputBuffer(in_ix, &in_buffer); 26100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 26200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 26300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK || in_buffer == NULL) { 26400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGW("[%s] could not get input buffer #%zu", 26500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), in_ix); 26600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 26700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return UNKNOWN_ERROR; 26800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 26900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 2701889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase *in_buf; 27100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar while (true) { 27200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf = NULL; 27300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.unlock(); 27400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mSource->read(&in_buf, options); 27500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.lock(); 27600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK || me->mState != STARTED) { 27700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (in_buf != NULL) { 27800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf->release(); 27900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf = NULL; 28000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 28100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 28200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // queue EOS 28300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mQueuedInputEOS = true; 28400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (mCodec->queueInputBuffer( 28500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_ix, 0 /* offset */, 0 /* size */, 28600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 0 /* pts */, MediaCodec::BUFFER_FLAG_EOS) != OK) { 28700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGI("[%s] failed to queue input EOS", mComponentName.c_str()); 28800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 28900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return UNKNOWN_ERROR; 29000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 29100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 29200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // don't stop on EOS, but report error or EOS on stop 29300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != ERROR_END_OF_STREAM) { 29400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 29500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 29600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 29700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 29800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 29900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 30000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar break; 30100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 30200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (in_buf == NULL) { // should not happen 30300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar continue; 30400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (in_buf->range_length() != 0) { 30500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar break; 30600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 30700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf->release(); 30800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 30900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 31000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (in_buf != NULL) { 31100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar int64_t timestampUs = 0; 3123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(in_buf->meta_data().findInt64(kKeyTime, ×tampUs)); 3134278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen if (in_buf->range_length() + (mIsVorbis ? 4 : 0) > in_buffer->capacity()) { 31400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGW("'%s' received %zu input bytes for buffer of size %zu", 31500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), 3164278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen in_buf->range_length() + (mIsVorbis ? 4 : 0), in_buffer->capacity()); 31700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 3184278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen size_t cpLen = min(in_buf->range_length(), in_buffer->capacity()); 31900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(), 3204278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen cpLen ); 3214278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen 3224278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen if (mIsVorbis) { 3234278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen int32_t numPageSamples; 3243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen if (!in_buf->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) { 3254278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen numPageSamples = -1; 3264278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen } 3274278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen memcpy(in_buffer->base() + cpLen, &numPageSamples, sizeof(numPageSamples)); 3284278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen } 32900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 33000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->queueInputBuffer( 3314278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen in_ix, 0 /* offset */, in_buf->range_length() + (mIsVorbis ? 4 : 0), 33200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar timestampUs, 0 /* flags */); 33300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK) { 33400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix); 33500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 33600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 33700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar in_buf->release(); 33800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 33900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 34000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 34100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.unlock(); 34200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->dequeueOutputBuffer( 34300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar &out_ix, &out_offset, &out_size, &out_pts, 34400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar &out_flags, kTimeoutWaitForOutputUs /* timeoutUs */); 34500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me.lock(); 34600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // abort read on stop 34700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (me->mState != STARTED) { 34800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == OK) { 34900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->releaseOutputBuffer(out_ix); 35000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 35100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 35200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 35300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 35400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res == -EAGAIN) { 35500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGD("[%s] did not produce an output buffer. retry count: %d", 35600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), retries); 35700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar continue; 35800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (res == INFO_FORMAT_CHANGED) { 35900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (mCodec->getOutputFormat(&me->mFormat) != OK) { 36000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 36100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = UNKNOWN_ERROR; 36200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 36300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 36400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (res == INFO_OUTPUT_BUFFERS_CHANGED) { 36500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGV("output buffers changed"); 36600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar continue; 36700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else if (res != OK) { 36800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 36900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return res; 37000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 37100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 3727e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> out_buffer; 37300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar res = mCodec->getOutputBuffer(out_ix, &out_buffer); 37400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (res != OK) { 37500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar ALOGW("[%s] could not get output buffer #%zu", 37600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mComponentName.c_str(), out_ix); 37700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mState = ERROR; 37800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return UNKNOWN_ERROR; 37900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 38000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (out_flags & MediaCodec::BUFFER_FLAG_EOS) { 38100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar me->mGotOutputEOS = true; 38200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar // return EOS immediately if last buffer is empty 38300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (out_size == 0) { 38400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->releaseOutputBuffer(out_ix); 38500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return ERROR_END_OF_STREAM; 38600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 38700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 38800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 38900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar if (mUsingSurface && out_size > 0) { 39000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *buffer = new MediaBuffer(0); 39100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->renderOutputBufferAndRelease(out_ix); 39200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } else { 39300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *buffer = new MediaBuffer(out_size); 39400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar CHECK_LE(out_buffer->size(), (*buffer)->size()); 39500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size()); 3963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen (*buffer)->meta_data().setInt64(kKeyTime, out_pts); 39700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar mCodec->releaseOutputBuffer(out_ix); 39800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 39900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return OK; 40000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar } 40100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar 40200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar return TIMED_OUT; 40300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar} 404