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> &notify,
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", &timestampNs));
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