153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia/* 253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * Copyright 2017 The Android Open Source Project 353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * 453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * Licensed under the Apache License, Version 2.0 (the "License"); 553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * you may not use this file except in compliance with the License. 653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * You may obtain a copy of the License at 753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * 853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * http://www.apache.org/licenses/LICENSE-2.0 953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * 1053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * Unless required by applicable law or agreed to in writing, software 1153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * distributed under the License is distributed on an "AS IS" BASIS, 1253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * See the License for the specific language governing permissions and 1453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * limitations under the License. 1553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia */ 1653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 1753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia//#define LOG_NDEBUG 0 1853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#define LOG_TAG "NuPlayer2DecoderPassThrough" 1953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <utils/Log.h> 2053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <inttypes.h> 2153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 2253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include "NuPlayer2DecoderPassThrough.h" 2353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 2453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include "NuPlayer2Renderer.h" 2553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include "NuPlayer2Source.h" 2653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 2753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/MediaCodecBuffer.h> 2853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/foundation/ABuffer.h> 2953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/foundation/ADebug.h> 3053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/foundation/AMessage.h> 3153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include <media/stagefright/MediaErrors.h> 3253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 3353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#include "ATSParser.h" 3453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 3553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jianamespace android { 3653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 3753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// TODO optimize buffer size for power consumption 3853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia// The offload read buffer size is 32 KB but 24 KB uses less power. 3953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatic const size_t kAggregateBufferSizeBytes = 24 * 1024; 4053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatic const size_t kMaxCachedBytes = 200000; 4153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 4253692fa54d0bf1d69184035a4c05ea0601a09c14Wei JiaNuPlayer2::DecoderPassThrough::DecoderPassThrough( 4353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia const sp<AMessage> ¬ify, 4453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia const sp<Source> &source, 4553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia const sp<Renderer> &renderer) 4653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia : DecoderBase(notify), 4753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mSource(source), 4853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mRenderer(renderer), 4953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mSkipRenderingUntilMediaTimeUs(-1ll), 5053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mReachedEOS(true), 5153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioErr(OK), 5253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingBuffersToDrain(0), 5353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mCachedBytes(0), 5453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mComponentName("pass through decoder") { 5553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGW_IF(renderer == NULL, "expect a non-NULL renderer"); 5653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 5753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 5853692fa54d0bf1d69184035a4c05ea0601a09c14Wei JiaNuPlayer2::DecoderPassThrough::~DecoderPassThrough() { 5953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 6053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 6153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onConfigure(const sp<AMessage> &format) { 6253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("[%s] onConfigure", mComponentName.c_str()); 6353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mCachedBytes = 0; 6453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingBuffersToDrain = 0; 6553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mReachedEOS = false; 6653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ++mBufferGeneration; 6753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 6853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia onRequestInputBuffers(); 6953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 7053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int32_t hasVideo = 0; 7153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia format->findInt32("has-video", &hasVideo); 7253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 7353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // The audio sink is already opened before the PassThrough decoder is created. 7453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Opening again might be relevant if decoder is instantiated after shutdown and 7553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // format is different. 7653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia status_t err = mRenderer->openAudioSink( 7753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia format, true /* offloadOnly */, hasVideo, 7853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */, mSource->isStreaming()); 7953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (err != OK) { 8053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia handleError(err); 8153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 8253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 8353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 8453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onSetParameters(const sp<AMessage> &/*params*/) { 8553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGW("onSetParameters() called unexpectedly"); 8653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 8753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 8853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onSetRenderer( 8953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia const sp<Renderer> &renderer) { 9053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // renderer can't be changed during offloading 9153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGW_IF(renderer != mRenderer, 9253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia "ignoring request to change renderer"); 9353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 9453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 9553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiabool NuPlayer2::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) { 9653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int32_t generation; 9753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia CHECK(msg->findInt32("generation", &generation)); 9853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return generation != mBufferGeneration; 9953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 10053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 10153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiabool NuPlayer2::DecoderPassThrough::isDoneFetching() const { 10253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("[%s] mCachedBytes = %zu, mReachedEOS = %d mPaused = %d", 10353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mComponentName.c_str(), mCachedBytes, mReachedEOS, mPaused); 10453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 10553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return mCachedBytes >= kMaxCachedBytes || mReachedEOS || mPaused; 10653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 10753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 10853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia/* 10953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia * returns true if we should request more data 11053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia */ 11153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiabool NuPlayer2::DecoderPassThrough::doRequestBuffers() { 11253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia status_t err = OK; 11353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia while (!isDoneFetching()) { 11453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<AMessage> msg = new AMessage(); 11553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 11653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia err = fetchInputData(msg); 11753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (err != OK) { 11853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia break; 11953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 12053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 12153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia onInputBufferFetched(msg); 12253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 12353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 12453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return err == -EWOULDBLOCK 12553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia && mSource->feedMoreTSData() == OK; 12653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 12753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 12853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::DecoderPassThrough::dequeueAccessUnit(sp<ABuffer> *accessUnit) { 12953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia status_t err; 13053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 13153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Did we save an accessUnit earlier because of a discontinuity? 13253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mPendingAudioAccessUnit != NULL) { 13353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia *accessUnit = mPendingAudioAccessUnit; 13453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioAccessUnit.clear(); 13553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia err = mPendingAudioErr; 13653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit"); 13753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } else { 13853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia err = mSource->dequeueAccessUnit(true /* audio */, accessUnit); 13953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 14053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 14153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (err == INFO_DISCONTINUITY || err == ERROR_END_OF_STREAM) { 14253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mAggregateBuffer != NULL) { 14353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // We already have some data so save this for later. 14453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioErr = err; 14553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioAccessUnit = *accessUnit; 14653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia (*accessUnit).clear(); 14753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGD("return aggregated buffer and save err(=%d) for later", err); 14853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia err = OK; 14953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 15053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 15153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 15253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return err; 15353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 15453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 15553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiasp<ABuffer> NuPlayer2::DecoderPassThrough::aggregateBuffer( 15653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia const sp<ABuffer> &accessUnit) { 15753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<ABuffer> aggregate; 15853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 15953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (accessUnit == NULL) { 16053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // accessUnit is saved to mPendingAudioAccessUnit 16153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // return current mAggregateBuffer 16253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia aggregate = mAggregateBuffer; 16353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mAggregateBuffer.clear(); 16453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return aggregate; 16553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 16653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 16753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia size_t smallSize = accessUnit->size(); 16853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if ((mAggregateBuffer == NULL) 16953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Don't bother if only room for a few small buffers. 17053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia && (smallSize < (kAggregateBufferSizeBytes / 3))) { 17153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Create a larger buffer for combining smaller buffers from the extractor. 17253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes); 17353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mAggregateBuffer->setRange(0, 0); // start empty 17453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 17553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 17653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mAggregateBuffer != NULL) { 17753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int64_t timeUs; 17853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int64_t dummy; 17953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs); 18053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy); 18153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Will the smaller buffer fit? 18253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia size_t bigSize = mAggregateBuffer->size(); 18353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia size_t roomLeft = mAggregateBuffer->capacity() - bigSize; 18453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Should we save this small buffer for the next big buffer? 18553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // If the first small buffer did not have a timestamp then save 18653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // any buffer that does have a timestamp until the next big buffer. 18753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if ((smallSize > roomLeft) 18853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) { 18953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioErr = OK; 19053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioAccessUnit = accessUnit; 19153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia aggregate = mAggregateBuffer; 19253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mAggregateBuffer.clear(); 19353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } else { 19453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Grab time from first small buffer if available. 19553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if ((bigSize == 0) && smallTimestampValid) { 19653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mAggregateBuffer->meta()->setInt64("timeUs", timeUs); 19753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 19853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Append small buffer to the bigger buffer. 19953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize); 20053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia bigSize += smallSize; 20153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mAggregateBuffer->setRange(0, bigSize); 20253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 20353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu", 20453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia smallSize, bigSize, mAggregateBuffer->capacity()); 20553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 20653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } else { 20753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // decided not to aggregate 20853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia aggregate = accessUnit; 20953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 21053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 21153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return aggregate; 21253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 21353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 21453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiastatus_t NuPlayer2::DecoderPassThrough::fetchInputData(sp<AMessage> &reply) { 21553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<ABuffer> accessUnit; 21653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 21753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia do { 21853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia status_t err = dequeueAccessUnit(&accessUnit); 21953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 22053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (err == -EWOULDBLOCK) { 22153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // Flush out the aggregate buffer to try to avoid underrun. 22253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia accessUnit = aggregateBuffer(NULL /* accessUnit */); 22353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (accessUnit != NULL) { 22453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia break; 22553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 22653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return err; 22753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } else if (err != OK) { 22853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (err == INFO_DISCONTINUITY) { 22953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int32_t type; 23053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 23153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 23253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia bool formatChange = 23353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0; 23453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 23553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia bool timeChange = 23653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia (type & ATSParser::DISCONTINUITY_TIME) != 0; 23753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 23853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGI("audio discontinuity (formatChange=%d, time=%d)", 23953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia formatChange, timeChange); 24053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 24153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (formatChange || timeChange) { 24253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<AMessage> msg = mNotify->dup(); 24353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia msg->setInt32("what", kWhatInputDiscontinuity); 24453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // will perform seamless format change, 24553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // only notify NuPlayer2 to scan sources 24653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia msg->setInt32("formatChange", false); 24753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia msg->post(); 24853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 24953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 25053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (timeChange) { 25153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia doFlush(false /* notifyComplete */); 25253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia err = OK; 25353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } else if (formatChange) { 25453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // do seamless format change 25553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia err = OK; 25653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } else { 25753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia // This stream is unaffected by the discontinuity 25853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return -EWOULDBLOCK; 25953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 26053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 26153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 26253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia reply->setInt32("err", err); 26353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return OK; 26453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 26553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 26653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia accessUnit = aggregateBuffer(accessUnit); 26753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } while (accessUnit == NULL); 26853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 26953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#if 0 27053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int64_t mediaTimeUs; 27153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 27253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("feeding audio input buffer at media time %.2f secs", 27353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mediaTimeUs / 1E6); 27453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia#endif 27553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 27653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia reply->setBuffer("buffer", accessUnit); 27753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 27853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return OK; 27953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 28053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 28153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onInputBufferFetched( 28253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia const sp<AMessage> &msg) { 28353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mReachedEOS) { 28453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return; 28553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 28653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 28753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<ABuffer> buffer; 28853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia bool hasBuffer = msg->findBuffer("buffer", &buffer); 28953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (buffer == NULL) { 29053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int32_t streamErr = ERROR_END_OF_STREAM; 29153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 29253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (streamErr == OK) { 29353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return; 29453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 29553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 29653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (streamErr != ERROR_END_OF_STREAM) { 29753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia handleError(streamErr); 29853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 29953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mReachedEOS = true; 30053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mRenderer != NULL) { 30153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mRenderer->queueEOS(true /* audio */, ERROR_END_OF_STREAM); 30253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 30353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return; 30453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 30553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 30653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<AMessage> extra; 30753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 30853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int64_t resumeAtMediaTimeUs; 30953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (extra->findInt64( 31053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { 31153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGI("[%s] suppressing rendering until %lld us", 31253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 31353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 31453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 31553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 31653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 31753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int32_t bufferSize = buffer->size(); 31853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mCachedBytes += bufferSize; 31953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 32053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int64_t timeUs = 0; 32153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 32253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mSkipRenderingUntilMediaTimeUs >= 0) { 32353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (timeUs < mSkipRenderingUntilMediaTimeUs) { 32453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("[%s] dropping buffer at time %lld as requested.", 32553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mComponentName.c_str(), (long long)timeUs); 32653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 32753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia onBufferConsumed(bufferSize); 32853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return; 32953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 33053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 33153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mSkipRenderingUntilMediaTimeUs = -1; 33253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 33353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 33453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mRenderer == NULL) { 33553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia onBufferConsumed(bufferSize); 33653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia return; 33753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 33853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 33953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<AMessage> reply = new AMessage(kWhatBufferConsumed, this); 34053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia reply->setInt32("generation", mBufferGeneration); 34153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia reply->setInt32("size", bufferSize); 34253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 34353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<MediaCodecBuffer> mcBuffer = new MediaCodecBuffer(nullptr, buffer); 34453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mcBuffer->meta()->setInt64("timeUs", timeUs); 34553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 34653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mRenderer->queueBuffer(true /* audio */, mcBuffer, reply); 34753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 34853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ++mPendingBuffersToDrain; 34953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("onInputBufferFilled: #ToDrain = %zu, cachedBytes = %zu", 35053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingBuffersToDrain, mCachedBytes); 35153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 35253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 35353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onBufferConsumed(int32_t size) { 35453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia --mPendingBuffersToDrain; 35553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mCachedBytes -= size; 35653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("onBufferConsumed: #ToDrain = %zu, cachedBytes = %zu", 35753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingBuffersToDrain, mCachedBytes); 35853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia onRequestInputBuffers(); 35953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 36053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 36153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onResume(bool notifyComplete) { 36253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPaused = false; 36353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 36453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia onRequestInputBuffers(); 36553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 36653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (notifyComplete) { 36753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<AMessage> notify = mNotify->dup(); 36853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia notify->setInt32("what", kWhatResumeCompleted); 36953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia notify->post(); 37053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 37153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 37253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 37353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::doFlush(bool notifyComplete) { 37453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ++mBufferGeneration; 37553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mSkipRenderingUntilMediaTimeUs = -1; 37653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioAccessUnit.clear(); 37753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingAudioErr = OK; 37853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mAggregateBuffer.clear(); 37953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 38053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (mRenderer != NULL) { 38153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mRenderer->flush(true /* audio */, notifyComplete); 38253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mRenderer->signalTimeDiscontinuity(); 38353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 38453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 38553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPendingBuffersToDrain = 0; 38653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mCachedBytes = 0; 38753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mReachedEOS = false; 38853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 38953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 39053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onFlush() { 39153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia doFlush(true /* notifyComplete */); 39253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 39353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mPaused = true; 39453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<AMessage> notify = mNotify->dup(); 39553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia notify->setInt32("what", kWhatFlushCompleted); 39653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia notify->post(); 39753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 39853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 39953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 40053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onShutdown(bool notifyComplete) { 40153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ++mBufferGeneration; 40253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mSkipRenderingUntilMediaTimeUs = -1; 40353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 40453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (notifyComplete) { 40553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia sp<AMessage> notify = mNotify->dup(); 40653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia notify->setInt32("what", kWhatShutdownCompleted); 40753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia notify->post(); 40853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 40953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 41053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia mReachedEOS = true; 41153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 41253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 41353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jiavoid NuPlayer2::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) { 41453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia ALOGV("[%s] onMessage: %s", mComponentName.c_str(), 41553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia msg->debugString().c_str()); 41653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 41753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia switch (msg->what()) { 41853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia case kWhatBufferConsumed: 41953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia { 42053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia if (!isStaleReply(msg)) { 42153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia int32_t size; 42253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia CHECK(msg->findInt32("size", &size)); 42353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia onBufferConsumed(size); 42453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 42553692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia break; 42653692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 42753692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 42853692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia default: 42953692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia DecoderBase::onMessageReceived(msg); 43053692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia break; 43153692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia } 43253692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} 43353692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia 43453692fa54d0bf1d69184035a4c05ea0601a09c14Wei Jia} // namespace android 435