NuPlayerDecoder.cpp revision 62ca0231787d5fe23ee95c482d15b8434add2427
1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/* 2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Copyright 2014 The Android Open Source Project 3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * 4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * you may not use this file except in compliance with the License. 6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * You may obtain a copy of the License at 7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * 8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * 10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Unless required by applicable law or agreed to in writing, software 11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * See the License for the specific language governing permissions and 14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * limitations under the License. 15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */ 16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy//#define LOG_NDEBUG 0 185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define LOG_TAG "NuPlayerDecoder" 199d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <utils/Log.h> 209d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <inttypes.h> 219d5316e3f56d138504565ff311145ac01621dff4Romain Guy 2285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "NuPlayerCCDecoder.h" 23ce0537b80087a6225273040a987414b1dd081aa0Romain Guy#include "NuPlayerDecoder.h" 2476d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger#include "NuPlayerRenderer.h" 2576d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger#include "NuPlayerSource.h" 26f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 27ce0537b80087a6225273040a987414b1dd081aa0Romain Guy#include <media/ICrypto.h> 28079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy#include <media/stagefright/foundation/ABuffer.h> 2985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <media/stagefright/foundation/ADebug.h> 30e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <media/stagefright/foundation/AMessage.h> 31c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger#include <media/stagefright/MediaBuffer.h> 32daf98e941e140e8739458126640183b9f296a2abChet Haase#include <media/stagefright/MediaCodec.h> 33bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy#include <media/stagefright/MediaDefs.h> 34ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy#include <media/stagefright/MediaErrors.h> 358694230ff25fa0a60e480d424843e56b718f0516Romain Guy 36bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy#include "avc_utils.h" 377953745dd565167113f8cbfc461bc0521d32d870Romain Guy#include "ATSParser.h" 387953745dd565167113f8cbfc461bc0521d32d870Romain Guy 393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android { 403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 41c15008e72ec00ca20a271c3006dac649fd07533bRomain GuyNuPlayer::Decoder::Decoder( 4251769a68a5cb34e9564740c6a854fcb93018789dRomain Guy const sp<AMessage> ¬ify, 43f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy const sp<Source> &source, 445cbbce535744b89df5ecea95de21ee3733298260Romain Guy const sp<Renderer> &renderer, 45bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy const sp<NativeWindowWrapper> &nativeWindow, 46b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik const sp<CCDecoder> &ccDecoder) 47b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik : DecoderBase(notify), 48d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mNativeWindow(nativeWindow), 493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mSource(source), 50b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik mRenderer(renderer), 51fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy mCCDecoder(ccDecoder), 5252244fff29042926e21fa897ef5ab11148e35299John Reck mSkipRenderingUntilMediaTimeUs(-1ll), 53bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mNumFramesTotal(0ll), 54d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mNumFramesDropped(0ll), 55d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mIsAudio(true), 56e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy mIsVideoAVC(false), 579d5316e3f56d138504565ff311145ac01621dff4Romain Guy mIsSecure(false), 58e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy mFormatChangePending(false), 59b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik mPaused(true), 603b20251a355c88193c439f928a84ae69483fb488John Reck mResumePending(false), 61e18264b079481a244b30e3f71012c53bbd861f92John Reck mComponentName("decoder") { 62b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik mCodecLooper = new ALooper; 63b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik mCodecLooper->setName("NPDecoder-CL"); 64b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 65c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik} 669b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy 679b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain GuyNuPlayer::Decoder::~Decoder() { 689b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy releaseAndResetMediaBuffers(); 699b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy} 709b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy 719b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guyvoid NuPlayer::Decoder::getStats( 729b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy int64_t *numFramesTotal, 739b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy int64_t *numFramesDropped) const { 7416ecda5317c40fc3da284952d9b3add34d6763aeChris Craik *numFramesTotal = mNumFramesTotal; 75c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik *numFramesDropped = mNumFramesDropped; 76c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik} 77c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 78c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 79c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 80c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 81c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik switch (msg->what()) { 82ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik case kWhatCodecNotify: 83ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik { 84ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik if (!isStaleReply(msg)) { 85ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik int32_t numInput, numOutput; 86ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 8728ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik if (!msg->findInt32("input-buffers", &numInput)) { 88a02c4ed885d97e516f844ddb0a96083f1b45b4cbChris Craik numInput = INT32_MAX; 8928ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik } 9028ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik 9128ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik if (!msg->findInt32("output-buffers", &numOutput)) { 9228ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik numOutput = INT32_MAX; 93d72b73cea49f29c41661e55eb6bfdbc04f09d809Chris Craik } 94d72b73cea49f29c41661e55eb6bfdbc04f09d809Chris Craik 9528ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik if (!mPaused) { 9628ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik while (numInput-- > 0 && handleAnInputBuffer()) {} 974063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 984063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik 994063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik while (numOutput-- > 0 && handleAnOutputBuffer()) {} 1004063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 1014063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik 1024063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik requestCodecNotification(); 1034063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik break; 1044063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 1054063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik 1064063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik case kWhatRenderBuffer: 1074063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik { 1084063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik if (!isStaleReply(msg)) { 1094063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik onRenderBuffer(msg); 1104063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 1114063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik break; 1124063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 1134063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik 1144063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik default: 115f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy DecoderBase::onMessageReceived(msg); 116f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy break; 117f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy } 1185cbbce535744b89df5ecea95de21ee3733298260Romain Guy} 11914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 1205cbbce535744b89df5ecea95de21ee3733298260Romain Guyvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik CHECK(mCodec == NULL); 122e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 1233b20251a355c88193c439f928a84ae69483fb488John Reck mFormatChangePending = false; 124e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy 125e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy ++mBufferGeneration; 1263b20251a355c88193c439f928a84ae69483fb488John Reck 127058fc640017c90120c599d378a4cbc55668b05b7Chris Craik AString mime; 128058fc640017c90120c599d378a4cbc55668b05b7Chris Craik CHECK(format->findString("mime", &mime)); 12987e2f757be9b24d369bab354e37c276e851b1fc7Romain Guy 130797b95b26bbb7557678af78b9a2a61830158920fChris Craik mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 1317c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 13217112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy 133c89b14bba0f6cc2c91629080617f7ed215f697f3Romain Guy sp<Surface> surface = NULL; 1343b20251a355c88193c439f928a84ae69483fb488John Reck if (mNativeWindow != NULL) { 13578dd96d5af20f489f0e8b288617d57774ec284f7Romain Guy surface = mNativeWindow->getSurfaceTextureClient(); 13678dd96d5af20f489f0e8b288617d57774ec284f7Romain Guy } 13778dd96d5af20f489f0e8b288617d57774ec284f7Romain Guy 1383b20251a355c88193c439f928a84ae69483fb488John Reck mComponentName = mime; 13978dd96d5af20f489f0e8b288617d57774ec284f7Romain Guy mComponentName.append(" decoder"); 14078dd96d5af20f489f0e8b288617d57774ec284f7Romain Guy ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), surface.get()); 14178dd96d5af20f489f0e8b288617d57774ec284f7Romain Guy 1428f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); 14308ae317c21ec3086b5017672bba87420cc38a407Romain Guy int32_t secure = 0; 1443b20251a355c88193c439f928a84ae69483fb488John Reck if (format->findInt32("secure", &secure) && secure != 0) { 1453b20251a355c88193c439f928a84ae69483fb488John Reck if (mCodec != NULL) { 1463b20251a355c88193c439f928a84ae69483fb488John Reck mCodec->getName(&mComponentName); 1473b20251a355c88193c439f928a84ae69483fb488John Reck mComponentName.append(".secure"); 14811cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy mCodec->release(); 1493b20251a355c88193c439f928a84ae69483fb488John Reck ALOGI("[%s] creating", mComponentName.c_str()); 1503f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik mCodec = MediaCodec::CreateByComponentName( 1513f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik mCodecLooper, mComponentName.c_str()); 1523f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik } 1533f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik } 1543f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik if (mCodec == NULL) { 1553f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik ALOGE("Failed to create %s%s decoder", 1563f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik (secure ? "secure " : ""), mime.c_str()); 1573f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik handleError(UNKNOWN_ERROR); 158bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy return; 159d90144db52c7297879b950cbbc85137ed123ab5bChris Craik } 160d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger mIsSecure = secure; 161d90144db52c7297879b950cbbc85137ed123ab5bChris Craik 162a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik mCodec->getName(&mComponentName); 163a08f95cfeca7217f9c533b03663bf0dceedd259aChris Craik 164d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik status_t err; 165d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik if (mNativeWindow != NULL) { 166d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik // disconnect from surface as MediaCodec will reconnect 167d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik err = native_window_api_disconnect( 168139088228faa7f3c446af7387e017933998a5570Derek Sollenberger surface.get(), NATIVE_WINDOW_API_MEDIA); 169d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik // We treat this as a warning, as this is a preparatory step. 170d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik // Codec will try to connect to the surface, which is where 171e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy // any error signaling will occur. 172d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err); 173d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik } 174d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik err = mCodec->configure( 175d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik format, surface, NULL /* crypto */, 0 /* flags */); 176d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik if (err != OK) { 177d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 178d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mCodec->release(); 179d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mCodec.clear(); 180d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik handleError(err); 181d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik return; 182d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik } 183486590963e2207d68eebd6944fec70d50d41116aChet Haase rememberCodecSpecificData(format); 184d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik 185d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik // the following should work in configured state 186486590963e2207d68eebd6944fec70d50d41116aChet Haase CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 187d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 188d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik 189d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik err = mCodec->start(); 190d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik if (err != OK) { 191486590963e2207d68eebd6944fec70d50d41116aChet Haase ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 192d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mCodec->release(); 193d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mCodec.clear(); 194d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik handleError(err); 195d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik return; 196d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik } 197d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik 198486590963e2207d68eebd6944fec70d50d41116aChet Haase // the following should work after start 199d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers)); 200c25259519f1b74bb62a2b051b74537f073436b5cRomain Guy releaseAndResetMediaBuffers(); 201d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers)); 202527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik ALOGV("[%s] got %zu input and %zu output buffers", 203d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mComponentName.c_str(), 20485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy mInputBuffers.size(), 20505f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik mOutputBuffers.size()); 20605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 207f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik if (mRenderer != NULL) { 2085ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy requestCodecNotification(); 2095ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy } 2105ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy mPaused = false; 21116ecda5317c40fc3da284952d9b3add34d6763aeChris Craik mResumePending = false; 21216ecda5317c40fc3da284952d9b3add34d6763aeChris Craik} 21316ecda5317c40fc3da284952d9b3add34d6763aeChris Craik 214d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { 2155ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy bool hadNoRenderer = (mRenderer == NULL); 2165e49b307eb99269db2db257760508b8efd7bb97dChris Craik mRenderer = renderer; 2175e49b307eb99269db2db257760508b8efd7bb97dChris Craik if (hadNoRenderer && mRenderer != NULL) { 2185e49b307eb99269db2db257760508b8efd7bb97dChris Craik requestCodecNotification(); 2195e49b307eb99269db2db257760508b8efd7bb97dChris Craik } 2205e49b307eb99269db2db257760508b8efd7bb97dChris Craik} 2215e49b307eb99269db2db257760508b8efd7bb97dChris Craik 222ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikvoid NuPlayer::Decoder::onGetInputBuffers( 223527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik Vector<sp<ABuffer> > *dstBuffers) { 22428ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik dstBuffers->clear(); 225c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik for (size_t i = 0; i < mInputBuffers.size(); i++) { 226d90144db52c7297879b950cbbc85137ed123ab5bChris Craik dstBuffers->push(mInputBuffers[i]); 227d90144db52c7297879b950cbbc85137ed123ab5bChris Craik } 228d90144db52c7297879b950cbbc85137ed123ab5bChris Craik} 2293b20251a355c88193c439f928a84ae69483fb488John Reck 230d6b65f67717025b1162f86f04e2caa5723566cacChris Craikvoid NuPlayer::Decoder::onResume(bool notifyComplete) { 231672433d90fab7383cd28beac9d4485b566a90940Romain Guy mPaused = false; 232672433d90fab7383cd28beac9d4485b566a90940Romain Guy 2330f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy if (notifyComplete) { 2340f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy mResumePending = true; 2350f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy } 2360f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy} 237ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 238ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikvoid NuPlayer::Decoder::onFlush(bool notifyComplete) { 239ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik if (mCCDecoder != NULL) { 240ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik mCCDecoder->flush(); 241ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 242a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik 243a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik if (mRenderer != NULL) { 2440e87f00f8cb79635aa70b9a2dfa02bf19dc7473dChris Craik mRenderer->flush(mIsAudio, notifyComplete); 24517112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy mRenderer->signalTimeDiscontinuity(); 246a08f95cfeca7217f9c533b03663bf0dceedd259aChris Craik } 24717112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy 24817112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy status_t err = OK; 249a08f95cfeca7217f9c533b03663bf0dceedd259aChris Craik if (mCodec != NULL) { 250a08f95cfeca7217f9c533b03663bf0dceedd259aChris Craik err = mCodec->flush(); 25117112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 25217112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy ++mBufferGeneration; 25317112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy } 2540f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy 2550f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy if (err != OK) { 2560f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 2570f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy handleError(err); 2580f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy // finish with posting kWhatFlushCompleted. 25962d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik // we attempt to release the buffers even if flush fails. 26062d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik } 26162d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik releaseAndResetMediaBuffers(); 26262d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik 26362d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik if (notifyComplete) { 26417112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy sp<AMessage> notify = mNotify->dup(); 26517112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy notify->setInt32("what", kWhatFlushCompleted); 26617112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy notify->post(); 26717112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy mPaused = true; 26813631f3da855f200a151e7837ed9f6b079622b58Romain Guy } 26917112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy} 27017112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy 27117112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guyvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) { 27217112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy status_t err = OK; 27313631f3da855f200a151e7837ed9f6b079622b58Romain Guy 27413631f3da855f200a151e7837ed9f6b079622b58Romain Guy // if there is a pending resume request, notify complete now 275d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase notifyResumeCompleteIfNecessary(); 276d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase 277d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase if (mCodec != NULL) { 27816ecda5317c40fc3da284952d9b3add34d6763aeChris Craik err = mCodec->release(); 27916ecda5317c40fc3da284952d9b3add34d6763aeChris Craik mCodec = NULL; 280d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase ++mBufferGeneration; 281d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase 282d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase if (mNativeWindow != NULL) { 283d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase // reconnect to surface as MediaCodec disconnected from it 284d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase status_t error = 285d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik native_window_api_connect( 286527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik mNativeWindow->getNativeWindow().get(), 287527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik NATIVE_WINDOW_API_MEDIA); 288527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik ALOGW_IF(error != NO_ERROR, 289527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik "[%s] failed to connect to native window, error=%d", 290d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mComponentName.c_str(), error); 291527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 292527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik mComponentName = "decoder"; 293527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 294527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 295c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik releaseAndResetMediaBuffers(); 296527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 297527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik if (err != OK) { 298d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 299d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase handleError(err); 300c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger // finish with posting kWhatShutdownCompleted. 301c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 302c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger 303c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger if (notifyComplete) { 304c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger sp<AMessage> notify = mNotify->dup(); 305c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger notify->setInt32("what", kWhatShutdownCompleted); 306c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger notify->post(); 307c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger mPaused = true; 308c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 309c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger} 310c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger 311c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenbergervoid NuPlayer::Decoder::doRequestBuffers() { 312c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger if (mFormatChangePending) { 313c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger return; 314c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 315c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger status_t err = OK; 316c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger while (!mDequeuedInputBuffers.empty()) { 317c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger size_t bufferIx = *mDequeuedInputBuffers.begin(); 318c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger sp<AMessage> msg = new AMessage(); 319c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger msg->setSize("buffer-ix", bufferIx); 320c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger err = fetchInputData(msg); 321c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger if (err != OK) { 322c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger break; 323c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 324c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); 325624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy 32659744b79ec302000802cd56d30a1bf70f0183c80Chris Craik if (!mPendingInputMessages.empty() 32759744b79ec302000802cd56d30a1bf70f0183c80Chris Craik || !onInputBufferFetched(msg)) { 32859744b79ec302000802cd56d30a1bf70f0183c80Chris Craik mPendingInputMessages.push_back(msg); 32959744b79ec302000802cd56d30a1bf70f0183c80Chris Craik } 330624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy } 33159744b79ec302000802cd56d30a1bf70f0183c80Chris Craik 332624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy if (err == -EWOULDBLOCK 333527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik && mSource->feedMoreTSData() == OK) { 334527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik scheduleRequestBuffers(); 335527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 336527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik} 337527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 338527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craikbool NuPlayer::Decoder::handleAnInputBuffer() { 339527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik if (mFormatChangePending) { 340527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik return false; 341527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 342527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik size_t bufferIx = -1; 343527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik status_t res = mCodec->dequeueInputBuffer(&bufferIx); 344527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik ALOGV("[%s] dequeued input: %d", 345527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik mComponentName.c_str(), res == OK ? (int)bufferIx : res); 346527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik if (res != OK) { 34705f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik if (res != -EAGAIN) { 34805f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik ALOGE("Failed to dequeue input buffer for %s (err=%d)", 34905f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik mComponentName.c_str(), res); 350e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy handleError(res); 351e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy } 35296885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy return false; 35396885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy } 35496885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy 35596885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy CHECK_LT(bufferIx, mInputBuffers.size()); 35696885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy 35796885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy if (mMediaBuffers[bufferIx] != NULL) { 35896885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy mMediaBuffers[bufferIx]->release(); 35996885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy mMediaBuffers.editItemAt(bufferIx) = NULL; 36096885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy } 36196885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy mInputBufferIsDequeued.editItemAt(bufferIx) = true; 36296885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy 36396885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy if (!mCSDsToSubmit.isEmpty()) { 3647c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy sp<AMessage> msg = new AMessage(); 3657c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy msg->setSize("buffer-ix", bufferIx); 3667c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy 3677c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 3687c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 36935643ddc689913f5b5f80ceed864470d987bd6cdRomain Guy msg->setBuffer("buffer", buffer); 37035643ddc689913f5b5f80ceed864470d987bd6cdRomain Guy mCSDsToSubmit.removeAt(0); 37135643ddc689913f5b5f80ceed864470d987bd6cdRomain Guy CHECK(onInputBufferFetched(msg)); 37235643ddc689913f5b5f80ceed864470d987bd6cdRomain Guy return true; 37335643ddc689913f5b5f80ceed864470d987bd6cdRomain Guy } 3748ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 3758ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy while (!mPendingInputMessages.empty()) { 3768ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy sp<AMessage> msg = *mPendingInputMessages.begin(); 3778ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy if (!onInputBufferFetched(msg)) { 3788ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy break; 3798ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy } 3808ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy mPendingInputMessages.erase(mPendingInputMessages.begin()); 3818ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy } 3828ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 3838ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy if (!mInputBufferIsDequeued.editItemAt(bufferIx)) { 3848ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy return true; 3858ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy } 386f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik 387d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mDequeuedInputBuffers.push_back(bufferIx); 388d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik 389f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik onRequestInputBuffers(); 390f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik return true; 391f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik} 392f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik 3938ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guybool NuPlayer::Decoder::handleAnOutputBuffer() { 394e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy if (mFormatChangePending) { 395e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy return false; 396e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy } 397e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy size_t bufferIx = -1; 398e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy size_t offset; 399e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy size_t size; 400e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy int64_t timeUs; 401e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy uint32_t flags; 40214e513058ed4168c94e015638d16f5f87fd8063aChris Craik status_t res = mCodec->dequeueOutputBuffer( 403694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy &bufferIx, &offset, &size, &timeUs, &flags); 404ada830f639591b99c3e40de22b07296c7932a33fRomain Guy 405f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy if (res != OK) { 406ada830f639591b99c3e40de22b07296c7932a33fRomain Guy ALOGV("[%s] dequeued output: %d", mComponentName.c_str(), res); 407f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy } else { 408ada830f639591b99c3e40de22b07296c7932a33fRomain Guy ALOGV("[%s] dequeued output: %d (time=%lld flags=%" PRIu32 ")", 40942f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy mComponentName.c_str(), (int)bufferIx, timeUs, flags); 41042f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy } 41142f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy 412624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy if (res == INFO_OUTPUT_BUFFERS_CHANGED) { 413f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy res = mCodec->getOutputBuffers(&mOutputBuffers); 414f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy if (res != OK) { 415f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy ALOGE("Failed to get output buffers for %s after INFO event (err=%d)", 41642f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy mComponentName.c_str(), res); 41742f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy handleError(res); 41842f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy return false; 419624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy } 420f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // NuPlayer ignores this 421f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy return true; 4221bd1bad0b4a75e633c5edbe802bf6fb4dd765161Romain Guy } else if (res == INFO_FORMAT_CHANGED) { 42342f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy sp<AMessage> format = new AMessage(); 42442f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy res = mCodec->getOutputFormat(&format); 42542f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy if (res != OK) { 42614e513058ed4168c94e015638d16f5f87fd8063aChris Craik ALOGE("Failed to get output format for %s after INFO event (err=%d)", 42742f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy mComponentName.c_str(), res); 42842f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy handleError(res); 42942f3a4b7c35dd1ea1922356eb3611af8cde05179Romain Guy return false; 43077a811610f99e21da7f88dafef60d09f345d0506Romain Guy } 43177a811610f99e21da7f88dafef60d09f345d0506Romain Guy 43277a811610f99e21da7f88dafef60d09f345d0506Romain Guy if (!mIsAudio) { 43377a811610f99e21da7f88dafef60d09f345d0506Romain Guy sp<AMessage> notify = mNotify->dup(); 43477a811610f99e21da7f88dafef60d09f345d0506Romain Guy notify->setInt32("what", kWhatVideoSizeChanged); 43577a811610f99e21da7f88dafef60d09f345d0506Romain Guy notify->setMessage("format", format); 43677a811610f99e21da7f88dafef60d09f345d0506Romain Guy notify->post(); 43777a811610f99e21da7f88dafef60d09f345d0506Romain Guy } else if (mRenderer != NULL) { 438be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy uint32_t flags; 439be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy int64_t durationUs; 44016ecda5317c40fc3da284952d9b3add34d6763aeChris Craik bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 44116ecda5317c40fc3da284952d9b3add34d6763aeChris Craik if (!hasVideo && 442be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy mSource->getDuration(&durationUs) == OK && 443be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy durationUs 444be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 445be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 446be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy } else { 447d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik flags = AUDIO_OUTPUT_FLAG_NONE; 44816ecda5317c40fc3da284952d9b3add34d6763aeChris Craik } 44916ecda5317c40fc3da284952d9b3add34d6763aeChris Craik 45016ecda5317c40fc3da284952d9b3add34d6763aeChris Craik res = mRenderer->openAudioSink( 45116ecda5317c40fc3da284952d9b3add34d6763aeChris Craik format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaded */); 45216ecda5317c40fc3da284952d9b3add34d6763aeChris Craik if (res != OK) { 45316ecda5317c40fc3da284952d9b3add34d6763aeChris Craik ALOGE("Failed to open AudioSink on format change for %s (err=%d)", 45476d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger mComponentName.c_str(), res); 455be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy handleError(res); 456be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy return false; 45776d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger } 45876d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger } 459be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy return true; 46076d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger } else if (res == INFO_DISCONTINUITY) { 46176d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger // nothing to do 462be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy return true; 463be6f9dc1e71b425b7ac1c40c0a2c72d03eb9fbeeRomain Guy } else if (res != OK) { 46411cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy if (res != -EAGAIN) { 465d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III ALOGE("Failed to dequeue output buffer for %s (err=%d)", 466d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mComponentName.c_str(), res); 467d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III handleError(res); 468d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 469d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return false; 470d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 471d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 472d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III CHECK_LT(bufferIx, mOutputBuffers.size()); 47311cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 47411cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy buffer->setRange(offset, size); 475624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy buffer->meta()->clear(); 47611cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy buffer->meta()->setInt64("timeUs", timeUs); 47711cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy if (flags & MediaCodec::BUFFER_FLAG_EOS) { 47811cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy buffer->meta()->setInt32("eos", true); 4793b20251a355c88193c439f928a84ae69483fb488John Reck notifyResumeCompleteIfNecessary(); 4803b20251a355c88193c439f928a84ae69483fb488John Reck } 48108ae317c21ec3086b5017672bba87420cc38a407Romain Guy // we do not expect CODECCONFIG or SYNCFRAME for decoder 4825cbbce535744b89df5ecea95de21ee3733298260Romain Guy 483dcfc836b457a87881da409e1acf251515f121446Romain Guy sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id()); 484dcfc836b457a87881da409e1acf251515f121446Romain Guy reply->setSize("buffer-ix", bufferIx); 485dcfc836b457a87881da409e1acf251515f121446Romain Guy reply->setInt32("generation", mBufferGeneration); 486dcfc836b457a87881da409e1acf251515f121446Romain Guy 487dcfc836b457a87881da409e1acf251515f121446Romain Guy if (mSkipRenderingUntilMediaTimeUs >= 0) { 488dcfc836b457a87881da409e1acf251515f121446Romain Guy if (timeUs < mSkipRenderingUntilMediaTimeUs) { 489dcfc836b457a87881da409e1acf251515f121446Romain Guy ALOGV("[%s] dropping buffer at time %lld as requested.", 490ddf74373616c89e0880a28a2185fd7ce3db91de6Romain Guy mComponentName.c_str(), (long long)timeUs); 491ddf74373616c89e0880a28a2185fd7ce3db91de6Romain Guy 492ddf74373616c89e0880a28a2185fd7ce3db91de6Romain Guy reply->post(); 493ddf74373616c89e0880a28a2185fd7ce3db91de6Romain Guy return true; 494ddf74373616c89e0880a28a2185fd7ce3db91de6Romain Guy } 495ddf74373616c89e0880a28a2185fd7ce3db91de6Romain Guy 4962b7028eabac80cec170572bc0e945a1d4224e595Romain Guy mSkipRenderingUntilMediaTimeUs = -1; 497d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 4982b7028eabac80cec170572bc0e945a1d4224e595Romain Guy 4992b7028eabac80cec170572bc0e945a1d4224e595Romain Guy // wait until 1st frame comes out to signal resume complete 5002b7028eabac80cec170572bc0e945a1d4224e595Romain Guy notifyResumeCompleteIfNecessary(); 50133f5a59ac3e304970920dda824958870f85f76efhenry.uh_chen 5022b7028eabac80cec170572bc0e945a1d4224e595Romain Guy if (mRenderer != NULL) { 5032b7028eabac80cec170572bc0e945a1d4224e595Romain Guy // send the buffer to renderer. 504c3fedafc5f50100219449125a000e3138f6fb987Romain Guy mRenderer->queueBuffer(mIsAudio, buffer, reply); 505c3fedafc5f50100219449125a000e3138f6fb987Romain Guy if (flags & MediaCodec::BUFFER_FLAG_EOS) { 506c3fedafc5f50100219449125a000e3138f6fb987Romain Guy mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); 507c3fedafc5f50100219449125a000e3138f6fb987Romain Guy } 50833f5a59ac3e304970920dda824958870f85f76efhenry.uh_chen } 509c3fedafc5f50100219449125a000e3138f6fb987Romain Guy 510c3fedafc5f50100219449125a000e3138f6fb987Romain Guy return true; 5112b7028eabac80cec170572bc0e945a1d4224e595Romain Guy} 5122b7028eabac80cec170572bc0e945a1d4224e595Romain Guy 5132b7028eabac80cec170572bc0e945a1d4224e595Romain Guyvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 5142b7028eabac80cec170572bc0e945a1d4224e595Romain Guy for (size_t i = 0; i < mMediaBuffers.size(); i++) { 5152b7028eabac80cec170572bc0e945a1d4224e595Romain Guy if (mMediaBuffers[i] != NULL) { 51614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mMediaBuffers[i]->release(); 517bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mMediaBuffers.editItemAt(i) = NULL; 5185cbbce535744b89df5ecea95de21ee3733298260Romain Guy } 5195cbbce535744b89df5ecea95de21ee3733298260Romain Guy } 5205cbbce535744b89df5ecea95de21ee3733298260Romain Guy mMediaBuffers.resize(mInputBuffers.size()); 5215cbbce535744b89df5ecea95de21ee3733298260Romain Guy for (size_t i = 0; i < mMediaBuffers.size(); i++) { 522bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mMediaBuffers.editItemAt(i) = NULL; 523bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 5245cbbce535744b89df5ecea95de21ee3733298260Romain Guy mInputBufferIsDequeued.clear(); 5258ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy mInputBufferIsDequeued.resize(mInputBuffers.size()); 5268ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 5278ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy mInputBufferIsDequeued.editItemAt(i) = false; 5288ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy } 5298ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 5308ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy mPendingInputMessages.clear(); 531408eb12631376cbdc96803e918decf6ea804d346Chris Craik mDequeuedInputBuffers.clear(); 532d90144db52c7297879b950cbbc85137ed123ab5bChris Craik mSkipRenderingUntilMediaTimeUs = -1; 533d90144db52c7297879b950cbbc85137ed123ab5bChris Craik} 534d90144db52c7297879b950cbbc85137ed123ab5bChris Craik 535d90144db52c7297879b950cbbc85137ed123ab5bChris Craikvoid NuPlayer::Decoder::requestCodecNotification() { 536408eb12631376cbdc96803e918decf6ea804d346Chris Craik if (mFormatChangePending) { 537408eb12631376cbdc96803e918decf6ea804d346Chris Craik return; 538408eb12631376cbdc96803e918decf6ea804d346Chris Craik } 539408eb12631376cbdc96803e918decf6ea804d346Chris Craik if (mCodec != NULL) { 540408eb12631376cbdc96803e918decf6ea804d346Chris Craik sp<AMessage> reply = new AMessage(kWhatCodecNotify, id()); 541408eb12631376cbdc96803e918decf6ea804d346Chris Craik reply->setInt32("generation", mBufferGeneration); 542d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy mCodec->requestActivityNotification(reply); 543d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy } 544d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy} 545d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy 546d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guybool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 547d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy int32_t generation; 548d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy CHECK(msg->findInt32("generation", &generation)); 549d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy return generation != mBufferGeneration; 550d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy} 551d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy 5523f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craikstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { 553d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy sp<ABuffer> accessUnit; 554d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy bool dropAccessUnit; 555d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy do { 556d48885a6c8cd27a8a62552c33b5282e9882e19f6Chet Haase status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); 5573f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 558d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy if (err == -EWOULDBLOCK) { 559d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy return err; 5605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy } else if (err != OK) { 5615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy if (err == INFO_DISCONTINUITY) { 5625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy int32_t type; 5635b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 5645b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 5655b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy bool formatChange = 566e63f7c622a2086aefa80983c6f41b74fb166bb42Chris Craik (mIsAudio && 5675b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 5685b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy || (!mIsAudio && 5695b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 5705b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 5715b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 5725b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 5735b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy ALOGI("%s discontinuity (format=%d, time=%d)", 5745b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy mIsAudio ? "audio" : "video", formatChange, timeChange); 5755b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 5765b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy bool seamlessFormatChange = false; 5775b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy sp<AMessage> newFormat = mSource->getFormat(mIsAudio); 5785b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy if (formatChange) { 5795b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy seamlessFormatChange = 5805b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy supportsSeamlessFormatChange(newFormat); 5815b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy // treat seamless format change separately 5825b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy formatChange = !seamlessFormatChange; 5835b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy } 5845b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 58554be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy if (formatChange || timeChange) { 58654be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy sp<AMessage> msg = mNotify->dup(); 58754be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy msg->setInt32("what", kWhatInputDiscontinuity); 58854be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy msg->setInt32("formatChange", formatChange); 58954be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy msg->post(); 59054be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy } 59154be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 592f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy if (formatChange /* not seamless */) { 593f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // must change decoder 594f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // return EOS and wait to be killed 595f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy mFormatChangePending = true; 596f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy return ERROR_END_OF_STREAM; 597f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy } else if (timeChange) { 598f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // need to flush 599f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // TODO: Ideally we shouldn't need a flush upon time 600f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // discontinuity, flushing will cause loss of frames. 601f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // We probably should queue a time change marker to the 602f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy // output queue, and handles it in renderer instead. 603f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy rememberCodecSpecificData(newFormat); 604f219da5e32e85deb442468ee9a63bb28eb198557Romain Guy onFlush(false /* notifyComplete */); 6055cbbce535744b89df5ecea95de21ee3733298260Romain Guy err = OK; 606735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy } else if (seamlessFormatChange) { 607735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy // reuse existing decoder and don't flush 6085cbbce535744b89df5ecea95de21ee3733298260Romain Guy rememberCodecSpecificData(newFormat); 6095cbbce535744b89df5ecea95de21ee3733298260Romain Guy err = OK; 6105cbbce535744b89df5ecea95de21ee3733298260Romain Guy } else { 6115cbbce535744b89df5ecea95de21ee3733298260Romain Guy // This stream is unaffected by the discontinuity 6125cbbce535744b89df5ecea95de21ee3733298260Romain Guy return -EWOULDBLOCK; 61376d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger } 6143d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy } 6155cbbce535744b89df5ecea95de21ee3733298260Romain Guy 616026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy reply->setInt32("err", err); 61776d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger return OK; 6185cbbce535744b89df5ecea95de21ee3733298260Romain Guy } 61954be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 620735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy if (!mIsAudio) { 621735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy ++mNumFramesTotal; 622735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy } 623735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy 624735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy dropAccessUnit = false; 625735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy if (!mIsAudio 62676d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger && !mIsSecure 627735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy && mRenderer->getVideoLateByUs() > 100000ll 6288ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy && mIsVideoAVC 6293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy && !IsAVCReferenceFrame(accessUnit)) { 630735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy dropAccessUnit = true; 63176d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger ++mNumFramesDropped; 63276d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger } 633735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy } while (dropAccessUnit); 634735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy 63554be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); 63654be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy#if 0 63754be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy int64_t mediaTimeUs; 63854be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 63954be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy ALOGV("feeding %s input buffer at media time %.2f secs", 64054be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy mIsAudio ? "audio" : "video", 64154be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy mediaTimeUs / 1E6); 64254be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy#endif 64354be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 64454be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy if (mCCDecoder != NULL) { 645d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik mCCDecoder->decode(accessUnit); 64654be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy } 64754be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 64854be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy reply->setBuffer("buffer", accessUnit); 64954be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 65054be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy return OK; 65154be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy} 65254be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 65354be1cdf3d63095512120fa7ced5c16e462abffaRomain Guybool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) { 65454be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy size_t bufferIx; 65554be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy CHECK(msg->findSize("buffer-ix", &bufferIx)); 656d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik CHECK_LT(bufferIx, mInputBuffers.size()); 657a168d7372132d6c87835878794b6ed43d0d282fdRomain Guy sp<ABuffer> codecBuffer = mInputBuffers[bufferIx]; 65854be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 65965cd612face362d054a85d0f7e5881c59cd523beChris Craik sp<ABuffer> buffer; 66065cd612face362d054a85d0f7e5881c59cd523beChris Craik bool hasBuffer = msg->findBuffer("buffer", &buffer); 66165cd612face362d054a85d0f7e5881c59cd523beChris Craik 66265cd612face362d054a85d0f7e5881c59cd523beChris Craik // handle widevine classic source - that fills an arbitrary input buffer 66365cd612face362d054a85d0f7e5881c59cd523beChris Craik MediaBuffer *mediaBuffer = NULL; 66465cd612face362d054a85d0f7e5881c59cd523beChris Craik if (hasBuffer) { 66505f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase()); 66663d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui if (mediaBuffer != NULL) { 66765cd612face362d054a85d0f7e5881c59cd523beChris Craik // likely filled another buffer than we requested: adjust buffer index 66865cd612face362d054a85d0f7e5881c59cd523beChris Craik size_t ix; 66905f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik for (ix = 0; ix < mInputBuffers.size(); ix++) { 67005f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik const sp<ABuffer> &buf = mInputBuffers[ix]; 67105f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik if (buf->data() == mediaBuffer->data()) { 67205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik // all input buffers are dequeued on start, hence the check 67305f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik if (!mInputBufferIsDequeued[ix]) { 67405f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", 67505f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik mComponentName.c_str(), ix, bufferIx); 67605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik mediaBuffer->release(); 677710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik return false; 67854be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy } 679710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik 680cb4d6009576cf08195dc23f341a3f4939c0878bbChris Craik // TRICKY: need buffer for the metadata, so instead, set 68154be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy // codecBuffer to the same (though incorrect) buffer to 682d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik // avoid a memcpy into the codecBuffer 683858aa93ddb6e69e0503382af63bb681b6728aef1Chet Haase codecBuffer = buffer; 6845cbbce535744b89df5ecea95de21ee3733298260Romain Guy codecBuffer->setRange( 6855cbbce535744b89df5ecea95de21ee3733298260Romain Guy mediaBuffer->range_offset(), 6865cbbce535744b89df5ecea95de21ee3733298260Romain Guy mediaBuffer->range_length()); 6875cbbce535744b89df5ecea95de21ee3733298260Romain Guy bufferIx = ix; 6885cbbce535744b89df5ecea95de21ee3733298260Romain Guy break; 6895cbbce535744b89df5ecea95de21ee3733298260Romain Guy } 6905cbbce535744b89df5ecea95de21ee3733298260Romain Guy } 6915cbbce535744b89df5ecea95de21ee3733298260Romain Guy CHECK(ix < mInputBuffers.size()); 69282ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy } 69382ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy } 69482ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy 695a979474f15b454c8e2963f239a3770e200bb227cRomain Guy if (buffer == NULL /* includes !hasBuffer */) { 696d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik int32_t streamErr = ERROR_END_OF_STREAM; 69782ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 69882ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy 69903750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy if (streamErr == OK) { 70003750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy /* buffers are returned to hold on to */ 70103750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy return true; 70282ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy } 70382ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy 70482ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy // attempt to queue EOS 70582ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy status_t err = mCodec->queueInputBuffer( 70682ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy bufferIx, 70782ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy 0, 70876d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger 0, 70982ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy 0, 71082ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy MediaCodec::BUFFER_FLAG_EOS); 71182ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy if (err == OK) { 71282ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy mInputBufferIsDequeued.editItemAt(bufferIx) = false; 713f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy } else if (streamErr == ERROR_END_OF_STREAM) { 714f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy streamErr = err; 71503750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy // err will not be ERROR_END_OF_STREAM 7164063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 7175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 718f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy if (streamErr != ERROR_END_OF_STREAM) { 719f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy ALOGE("Stream error for %s (err=%d), EOS %s queued", 72076d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger mComponentName.c_str(), 7216820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy streamErr, 7225b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy err == OK ? "successfully" : "unsuccessfully"); 7234063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik handleError(streamErr); 724f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy } 7253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } else { 72676d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger sp<AMessage> extra; 7273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 7283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy int64_t resumeAtMediaTimeUs; 7294063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik if (extra->findInt64( 7303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { 731886b275e529e44a59c54b933453d9bc902973178Romain Guy ALOGI("[%s] suppressing rendering until %lld us", 73276d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 733886b275e529e44a59c54b933453d9bc902973178Romain Guy mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 7344063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 7354063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } 736886b275e529e44a59c54b933453d9bc902973178Romain Guy 737f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy int64_t timeUs = 0; 738448455fe783b0a711340322dca272b8cc0ebe473Romain Guy uint32_t flags = 0; 739448455fe783b0a711340322dca272b8cc0ebe473Romain Guy CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 740448455fe783b0a711340322dca272b8cc0ebe473Romain Guy 741448455fe783b0a711340322dca272b8cc0ebe473Romain Guy int32_t eos, csd; 7424063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik // we do not expect SYNCFRAME for decoder 743448455fe783b0a711340322dca272b8cc0ebe473Romain Guy if (buffer->meta()->findInt32("eos", &eos) && eos) { 744448455fe783b0a711340322dca272b8cc0ebe473Romain Guy flags |= MediaCodec::BUFFER_FLAG_EOS; 7450a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 7460a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 7470a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy } 7480a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy 74941541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik // copy into codec buffer 7500a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy if (buffer != codecBuffer) { 7510a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy CHECK_LE(buffer->size(), codecBuffer->capacity()); 7520a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy codecBuffer->setRange(0, buffer->size()); 7530a41749953f35d33f61b3119e3161a82bb5fa59eRomain Guy memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 754d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik } 7551e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 756416a847633680d94efb926837efdc18726d54918Raph Levien status_t err = mCodec->queueInputBuffer( 757416a847633680d94efb926837efdc18726d54918Raph Levien bufferIx, 758416a847633680d94efb926837efdc18726d54918Raph Levien codecBuffer->offset(), 759416a847633680d94efb926837efdc18726d54918Raph Levien codecBuffer->size(), 760416a847633680d94efb926837efdc18726d54918Raph Levien timeUs, 761416a847633680d94efb926837efdc18726d54918Raph Levien flags); 762416a847633680d94efb926837efdc18726d54918Raph Levien if (err != OK) { 763416a847633680d94efb926837efdc18726d54918Raph Levien if (mediaBuffer != NULL) { 764416a847633680d94efb926837efdc18726d54918Raph Levien mediaBuffer->release(); 765416a847633680d94efb926837efdc18726d54918Raph Levien } 766416a847633680d94efb926837efdc18726d54918Raph Levien ALOGE("Failed to queue input buffer for %s (err=%d)", 767416a847633680d94efb926837efdc18726d54918Raph Levien mComponentName.c_str(), err); 768416a847633680d94efb926837efdc18726d54918Raph Levien handleError(err); 769d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik } else { 77076d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger mInputBufferIsDequeued.editItemAt(bufferIx) = false; 771416a847633680d94efb926837efdc18726d54918Raph Levien if (mediaBuffer != NULL) { 772416a847633680d94efb926837efdc18726d54918Raph Levien CHECK(mMediaBuffers[bufferIx] == NULL); 77354be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; 77454be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy } 77554be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy } 77654be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy } 77754be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy return true; 77854be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy} 77954be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy 78054be1cdf3d63095512120fa7ced5c16e462abffaRomain Guyvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 78154be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy status_t err; 782d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik int32_t render; 78301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy size_t bufferIx; 7841e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy CHECK(msg->findSize("buffer-ix", &bufferIx)); 785ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 786026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy if (!mIsAudio) { 787026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy int64_t timeUs; 7888ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 789026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy buffer->meta()->findInt64("timeUs", &timeUs); 790026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy 791026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy if (mCCDecoder != NULL && mCCDecoder->isSelected()) { 792026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy mCCDecoder->display(timeUs); 793026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy } 794026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy } 795026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy 796026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy if (msg->findInt32("render", &render) && render) { 7978ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy int64_t timestampNs; 798768bffc9b814f6a1f7d9ff59d91285895c23bbe9Romain Guy CHECK(msg->findInt64("timestampNs", ×tampNs)); 799768bffc9b814f6a1f7d9ff59d91285895c23bbe9Romain Guy err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs); 800768bffc9b814f6a1f7d9ff59d91285895c23bbe9Romain Guy } else { 801768bffc9b814f6a1f7d9ff59d91285895c23bbe9Romain Guy err = mCodec->releaseOutputBuffer(bufferIx); 802768bffc9b814f6a1f7d9ff59d91285895c23bbe9Romain Guy } 803746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy if (err != OK) { 804746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy ALOGE("failed to release output buffer for %s (err=%d)", 805a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy mComponentName.c_str(), err); 806746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy handleError(err); 8078aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy } 808746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy} 809746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy 810746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guybool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( 811aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy const sp<AMessage> &targetFormat) const { 812aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy if (targetFormat == NULL) { 813aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return true; 814aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 8158aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 816aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy AString mime; 817aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy if (!targetFormat->findString("mime", &mime)) { 818aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return false; 81982ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy } 82082ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy 82182ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 822f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy // field-by-field comparison 823f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 824a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 825f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy int32_t oldVal, newVal; 826d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy if (!mInputFormat->findInt32(keys[i], &oldVal) || 827d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy !targetFormat->findInt32(keys[i], &newVal) || 828d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy oldVal != newVal) { 829d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy return false; 8306926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy } 831d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy } 832d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy 833d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy sp<ABuffer> oldBuf, newBuf; 834260e102162322958cf17dbd895cd6bd30dc87e32Romain Guy if (mInputFormat->findBuffer("csd-0", &oldBuf) && 835889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy targetFormat->findBuffer("csd-0", &newBuf)) { 836260e102162322958cf17dbd895cd6bd30dc87e32Romain Guy if (oldBuf->size() != newBuf->size()) { 837746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy return false; 838746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy } 839746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 84054be1cdf3d63095512120fa7ced5c16e462abffaRomain Guy } 84117112ad8a21a77620eb1ff14dcf8bdd6b7859712Romain Guy } 84270ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy return false; 84370ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy} 84470ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy 84570ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guybool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 846ff316ec7a76e52572a2e89b691e6b3bba0cafba3Romain Guy if (mInputFormat == NULL) { 847aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return false; 84815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy } 849710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik 8508d0d4783a0206c5884bf0b958d181f450ba5207dRomain Guy if (targetFormat == NULL) { 85170ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy return true; 85286568198f2c83d4ce5c4cd692eda074ba9de9ed2Romain Guy } 8534121063313ac0d6f69f6253cac821d0c1c122086Romain Guy 854d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III AString oldMime, newMime; 85576d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger if (!mInputFormat->findString("mime", &oldMime) 85676d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger || !targetFormat->findString("mime", &newMime) 85776d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger || !(oldMime == newMime)) { 85870ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy return false; 85970ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy } 8604063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik 8614063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 8624063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik bool seamless; 8634063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik if (audio) { 8644063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik seamless = supportsSeamlessAudioFormatChange(targetFormat); 8654063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik } else { 8664063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik int32_t isAdaptive; 8674063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik seamless = (mCodec != NULL && 8684063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 8694063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik isAdaptive); 870564acf7c9bff822f608cda0d5df0a64a9f9aaefdChris Craik } 8714063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik 8724063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 8734063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik return seamless; 8744063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik} 8754063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik 8764063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craikvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 8774063a0e03ba2e354cc6d19c0ffc073fd5b8aa2caChris Craik if (format == NULL) { 878d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return; 87986568198f2c83d4ce5c4cd692eda074ba9de9ed2Romain Guy } 880d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mCSDsForCurrentFormat.clear(); 881d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III for (int32_t i = 0; ; ++i) { 882d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III AString tag = "csd-"; 883d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III tag.append(i); 884d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III sp<ABuffer> buffer; 885d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!format->findBuffer(tag.c_str(), &buffer)) { 886d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 887d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 888d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mCSDsForCurrentFormat.push(buffer); 88976d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger } 89070ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy} 89170ca14e08ae197547ac412e8a1210e1ebdfb2eb1Romain Guy 892aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { 8938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (mResumePending) { 8948f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mResumePending = false; 8954121063313ac0d6f69f6253cac821d0c1c122086Romain Guy 896564acf7c9bff822f608cda0d5df0a64a9f9aaefdChris Craik sp<AMessage> notify = mNotify->dup(); 897564acf7c9bff822f608cda0d5df0a64a9f9aaefdChris Craik notify->setInt32("what", kWhatResumeCompleted); 898564acf7c9bff822f608cda0d5df0a64a9f9aaefdChris Craik notify->post(); 899448455fe783b0a711340322dca272b8cc0ebe473Romain Guy } 900f09ef51889f75289b041f9e9f949b7b82ed5b686Romain Guy} 901746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy 90211cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy} // namespace android 90311cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy 90496885eb480c5e0526fe2f77d30f6e551f3f3ceabRomain Guy