NuPlayerDecoderPassThrough.cpp revision 14532f2383c3849d0db59a607ed0bd802f57155c
1bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia/* 2bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * Copyright (C) 2014 The Android Open Source Project 3bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * 4bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * Licensed under the Apache License, Version 2.0 (the "License"); 5bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * you may not use this file except in compliance with the License. 6bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * You may obtain a copy of the License at 7bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * 8bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * http://www.apache.org/licenses/LICENSE-2.0 9bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * 10bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * Unless required by applicable law or agreed to in writing, software 11bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * distributed under the License is distributed on an "AS IS" BASIS, 12bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * See the License for the specific language governing permissions and 14bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia * limitations under the License. 15bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia */ 16bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 17bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia//#define LOG_NDEBUG 0 18bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#define LOG_TAG "NuPlayerDecoderPassThrough" 19bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <utils/Log.h> 20bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <inttypes.h> 21bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 22bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include "NuPlayerDecoderPassThrough.h" 23bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 24c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h" 25c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h" 26c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 27bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/ICrypto.h> 28bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/foundation/ABuffer.h> 29bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/foundation/ADebug.h> 30bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/foundation/AMessage.h> 31bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include <media/stagefright/MediaErrors.h> 32bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h" 347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 35bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jianamespace android { 36bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang// TODO optimize buffer size for power consumption 387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang// The offload read buffer size is 32 KB but 24 KB uses less power. 397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatic const size_t kAggregateBufferSizeBytes = 24 * 1024; 40c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burkstatic const size_t kMaxCachedBytes = 200000; 41bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 42bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei JiaNuPlayer::DecoderPassThrough::DecoderPassThrough( 43c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<AMessage> ¬ify, 44c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Source> &source, 45c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Renderer> &renderer) 46202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung : DecoderBase(notify), 47c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSource(source), 48c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer(renderer), 49c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs(-1ll), 50bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mReachedEOS(true), 517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingAudioErr(OK), 52c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk mPendingBuffersToDrain(0), 53de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang mCachedBytes(0), 54bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mComponentName("pass through decoder") { 55c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGW_IF(renderer == NULL, "expect a non-NULL renderer"); 56bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 57bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 58bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei JiaNuPlayer::DecoderPassThrough::~DecoderPassThrough() { 59bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 60bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 61bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) { 62bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia ALOGV("[%s] onConfigure", mComponentName.c_str()); 63de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang mCachedBytes = 0; 64c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk mPendingBuffersToDrain = 0; 65bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mReachedEOS = false; 66bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia ++mBufferGeneration; 67bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 69bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 708b63533e6aaff121378878998925c57dbe9a9e16Haynes Mathew George int32_t hasVideo = 0; 718b63533e6aaff121378878998925c57dbe9a9e16Haynes Mathew George format->findInt32("has-video", &hasVideo); 728b63533e6aaff121378878998925c57dbe9a9e16Haynes Mathew George 73202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung // The audio sink is already opened before the PassThrough decoder is created. 74202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung // Opening again might be relevant if decoder is instantiated after shutdown and 75202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung // format is different. 76202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung status_t err = mRenderer->openAudioSink( 778b63533e6aaff121378878998925c57dbe9a9e16Haynes Mathew George format, true /* offloadOnly */, hasVideo, 78202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */); 79202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (err != OK) { 80202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung handleError(err); 81c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 82bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 83bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 848db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::DecoderPassThrough::onSetParameters(const sp<AMessage> &/*params*/) { 858db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu ALOGW("onSetParameters() called unexpectedly"); 868db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu} 878db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu 887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderPassThrough::onSetRenderer( 897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<Renderer> &renderer) { 907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // renderer can't be changed during offloading 917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGW_IF(renderer != mRenderer, 927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang "ignoring request to change renderer"); 937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderPassThrough::onGetInputBuffers( 967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang Vector<sp<ABuffer> > * /* dstBuffers */) { 977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("onGetInputBuffers() called unexpectedly"); 987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 100bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiabool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) { 101bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia int32_t generation; 102bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia CHECK(msg->findInt32("generation", &generation)); 103bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return generation != mBufferGeneration; 104bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 105bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 106f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wubool NuPlayer::DecoderPassThrough::isDoneFetching() const { 107f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu ALOGV("[%s] mCachedBytes = %zu, mReachedEOS = %d mPaused = %d", 108f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu mComponentName.c_str(), mCachedBytes, mReachedEOS, mPaused); 1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 110f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu return mCachedBytes >= kMaxCachedBytes || mReachedEOS || mPaused; 1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1133b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/* 1143b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data 1153b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */ 1163b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::DecoderPassThrough::doRequestBuffers() { 1177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 118f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu while (!isDoneFetching()) { 1197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 1207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = fetchInputData(msg); 1227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 1237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onInputBufferFetched(msg); 127c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk } 1287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1293b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return err == -EWOULDBLOCK 1303b032b3865fd93173aadca0591eeea32853206f9Chong Zhang && mSource->feedMoreTSData() == OK; 1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 132bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 1337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::DecoderPassThrough::dequeueAccessUnit(sp<ABuffer> *accessUnit) { 1347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err; 1357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // Did we save an accessUnit earlier because of a discontinuity? 1377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mPendingAudioAccessUnit != NULL) { 1387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang *accessUnit = mPendingAudioAccessUnit; 1397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingAudioAccessUnit.clear(); 1407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mPendingAudioErr; 1417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit"); 1427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 1437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mSource->dequeueAccessUnit(true /* audio */, accessUnit); 1447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == INFO_DISCONTINUITY || err == ERROR_END_OF_STREAM) { 1477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mAggregateBuffer != NULL) { 1487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // We already have some data so save this for later. 1497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingAudioErr = err; 1507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingAudioAccessUnit = *accessUnit; 1517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (*accessUnit).clear(); 1527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGD("return aggregated buffer and save err(=%d) for later", err); 1537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = OK; 1547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return err; 1587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangsp<ABuffer> NuPlayer::DecoderPassThrough::aggregateBuffer( 1617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<ABuffer> &accessUnit) { 1627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> aggregate; 1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (accessUnit == NULL) { 1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // accessUnit is saved to mPendingAudioAccessUnit 1667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // return current mAggregateBuffer 1677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang aggregate = mAggregateBuffer; 1687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mAggregateBuffer.clear(); 1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return aggregate; 1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t smallSize = accessUnit->size(); 1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if ((mAggregateBuffer == NULL) 1747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // Don't bother if only room for a few small buffers. 1757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && (smallSize < (kAggregateBufferSizeBytes / 3))) { 1767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // Create a larger buffer for combining smaller buffers from the extractor. 1777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes); 1787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mAggregateBuffer->setRange(0, 0); // start empty 1797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mAggregateBuffer != NULL) { 1827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t timeUs; 1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t dummy; 1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs); 1857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy); 1867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // Will the smaller buffer fit? 1877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bigSize = mAggregateBuffer->size(); 1887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t roomLeft = mAggregateBuffer->capacity() - bigSize; 1897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // Should we save this small buffer for the next big buffer? 1907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // If the first small buffer did not have a timestamp then save 1917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // any buffer that does have a timestamp until the next big buffer. 1927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if ((smallSize > roomLeft) 1937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) { 1947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingAudioErr = OK; 1957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingAudioAccessUnit = accessUnit; 1967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang aggregate = mAggregateBuffer; 1977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mAggregateBuffer.clear(); 1987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 1997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // Grab time from first small buffer if available. 2007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if ((bigSize == 0) && smallTimestampValid) { 2017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mAggregateBuffer->meta()->setInt64("timeUs", timeUs); 2027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // Append small buffer to the bigger buffer. 2047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize); 2057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bigSize += smallSize; 2067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mAggregateBuffer->setRange(0, bigSize); 2077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu", 2097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang smallSize, bigSize, mAggregateBuffer->capacity()); 2107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 2127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // decided not to aggregate 2137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang aggregate = accessUnit; 2147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return aggregate; 2177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 2187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::DecoderPassThrough::fetchInputData(sp<AMessage> &reply) { 2207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> accessUnit; 2217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang do { 2237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = dequeueAccessUnit(&accessUnit); 2247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == -EWOULDBLOCK) { 22614532f2383c3849d0db59a607ed0bd802f57155cWei Jia // Flush out the aggregate buffer to try to avoid underrun. 22714532f2383c3849d0db59a607ed0bd802f57155cWei Jia accessUnit = aggregateBuffer(NULL /* accessUnit */); 22814532f2383c3849d0db59a607ed0bd802f57155cWei Jia if (accessUnit != NULL) { 22914532f2383c3849d0db59a607ed0bd802f57155cWei Jia break; 23014532f2383c3849d0db59a607ed0bd802f57155cWei Jia } 2317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return err; 2327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (err != OK) { 2337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == INFO_DISCONTINUITY) { 2347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t type; 2357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 2367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool formatChange = 2387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0; 2397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool timeChange = 2417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_TIME) != 0; 2427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGI("audio discontinuity (formatChange=%d, time=%d)", 2447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang formatChange, timeChange); 2457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange || timeChange) { 2477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = mNotify->dup(); 2487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setInt32("what", kWhatInputDiscontinuity); 2497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // will perform seamless format change, 2507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // only notify NuPlayer to scan sources 2517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setInt32("formatChange", false); 2527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->post(); 2537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (timeChange) { 25666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang doFlush(false /* notifyComplete */); 2577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = OK; 2587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (formatChange) { 2597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // do seamless format change 2607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = OK; 2617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 2627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // This stream is unaffected by the discontinuity 2637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return -EWOULDBLOCK; 2647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("err", err); 2687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 2697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 270bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 2717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang accessUnit = aggregateBuffer(accessUnit); 2727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } while (accessUnit == NULL); 273bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 2747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0 2757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t mediaTimeUs; 2767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 2777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("feeding audio input buffer at media time %.2f secs", 2787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaTimeUs / 1E6); 2797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif 2807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setBuffer("buffer", accessUnit); 2827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 284bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 285bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 2867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderPassThrough::onInputBufferFetched( 287bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia const sp<AMessage> &msg) { 288bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (mReachedEOS) { 289bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return; 290bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 291bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 292bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia sp<ABuffer> buffer; 2937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hasBuffer = msg->findBuffer("buffer", &buffer); 294bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (buffer == NULL) { 2957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t streamErr = ERROR_END_OF_STREAM; 2967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 2977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (streamErr == OK) { 2987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return; 2997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 301bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mReachedEOS = true; 302c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (mRenderer != NULL) { 303c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer->queueEOS(true /* audio */, ERROR_END_OF_STREAM); 304c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 305bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia return; 306bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 307bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 308c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<AMessage> extra; 309c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 310c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t resumeAtMediaTimeUs; 311c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (extra->findInt64( 312c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { 313c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGI("[%s] suppressing rendering until %lld us", 314c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 315c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 316c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 317c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 318c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 319c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int32_t bufferSize = buffer->size(); 320c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mCachedBytes += bufferSize; 321c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 322c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (mSkipRenderingUntilMediaTimeUs >= 0) { 323c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t timeUs = 0; 324c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 325c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 326c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (timeUs < mSkipRenderingUntilMediaTimeUs) { 327c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGV("[%s] dropping buffer at time %lld as requested.", 328c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mComponentName.c_str(), (long long)timeUs); 329c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 330c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia onBufferConsumed(bufferSize); 331c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia return; 332c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 333c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 334c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = -1; 335c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 336c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 337c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (mRenderer == NULL) { 338c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia onBufferConsumed(bufferSize); 339c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia return; 340c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 341de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang 3421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatBufferConsumed, this); 343bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia reply->setInt32("generation", mBufferGeneration); 344c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia reply->setInt32("size", bufferSize); 345c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 346c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer->queueBuffer(true /* audio */, buffer, reply); 347bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 348c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk ++mPendingBuffersToDrain; 3497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("onInputBufferFilled: #ToDrain = %zu, cachedBytes = %zu", 3507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingBuffersToDrain, mCachedBytes); 351bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 352bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 353de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhangvoid NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) { 354c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk --mPendingBuffersToDrain; 355de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang mCachedBytes -= size; 3567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("onBufferConsumed: #ToDrain = %zu, cachedBytes = %zu", 3577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingBuffersToDrain, mCachedBytes); 3587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 3597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 3607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 361f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::DecoderPassThrough::onResume(bool notifyComplete) { 362f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu mPaused = false; 363f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu 3647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 365f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 366f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (notifyComplete) { 367f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang sp<AMessage> notify = mNotify->dup(); 368f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->setInt32("what", kWhatResumeCompleted); 369f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->post(); 370f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 371bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 372bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 37366704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::DecoderPassThrough::doFlush(bool notifyComplete) { 374bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia ++mBufferGeneration; 375c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = -1; 376f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu mPendingAudioAccessUnit.clear(); 377f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu mPendingAudioErr = OK; 378f1828910d48bbd22e1392e6ab0ce31298d1f115cRonghua Wu mAggregateBuffer.clear(); 379c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 380c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (mRenderer != NULL) { 3817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->flush(true /* audio */, notifyComplete); 3827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->signalTimeDiscontinuity(); 3837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 385c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk mPendingBuffersToDrain = 0; 386de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang mCachedBytes = 0; 387bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mReachedEOS = false; 388bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 389bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 39066704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::DecoderPassThrough::onFlush() { 39166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang doFlush(true /* notifyComplete */); 39266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 39366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mPaused = true; 39466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> notify = mNotify->dup(); 39566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->setInt32("what", kWhatFlushCompleted); 39666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->post(); 39766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 39866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 39966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 4007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderPassThrough::onShutdown(bool notifyComplete) { 401bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia ++mBufferGeneration; 402c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = -1; 403bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 4047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 4057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 4067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatShutdownCompleted); 4077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 4087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 410bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia mReachedEOS = true; 411bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 412bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 413bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiavoid NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) { 414bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia ALOGV("[%s] onMessage: %s", mComponentName.c_str(), 415bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia msg->debugString().c_str()); 416bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 417bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia switch (msg->what()) { 418bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia case kWhatBufferConsumed: 419bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia { 420bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (!isStaleReply(msg)) { 421de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang int32_t size; 422de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang CHECK(msg->findInt32("size", &size)); 423de01afbbc55ac9c5c23ec66154603f34217aed2cChong Zhang onBufferConsumed(size); 424bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 425bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 426bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 427bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 428bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia default: 4297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang DecoderBase::onMessageReceived(msg); 430bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia break; 431bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 432bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} 433bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 434bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia} // namespace android 435