1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/*
27137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * Copyright 2014 The Android Open Source Project
3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License.
6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at
7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software
11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and
14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License.
15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */
16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "NuPlayerDecoder"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h>
201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <inttypes.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerCCDecoder.h"
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h"
24c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h"
25c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h"
26c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
27288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h>
281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h>
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
315bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h>
32095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h>
331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
381de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h"
407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h"
417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() {
45288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung    return property_get_bool("media.stagefright.audio.deep", false /* default_value */);
46288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung}
47288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung
48f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder(
491173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<AMessage> &notify,
50c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Source> &source,
5168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        pid_t pid,
52c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Renderer> &renderer,
531de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        const sp<Surface> &surface,
547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<CCDecoder> &ccDecoder)
55202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    : DecoderBase(notify),
561de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar      mSurface(surface),
57c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSource(source),
58c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mRenderer(renderer),
597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mCCDecoder(ccDecoder),
6068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu      mPid(pid),
61c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSkipRenderingUntilMediaTimeUs(-1ll),
627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mNumFramesTotal(0ll),
63e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumInputFramesDropped(0ll),
64e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumOutputFramesDropped(0ll),
65e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoWidth(0),
66e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoHeight(0),
677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsAudio(true),
687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsVideoAVC(false),
697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsSecure(false),
707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mFormatChangePending(false),
7166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang      mTimeChangePending(false),
72f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang      mResumePending(false),
731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar      mComponentName("decoder") {
741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper = new ALooper;
759e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen    mCodecLooper->setName("NPDecoder-CL");
761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() {
80faeb0f291330134dc4468359a36e099aae508449Ronghua Wu    mCodec->release();
814923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia    releaseAndResetMediaBuffers();
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const {
85e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-total", mNumFramesTotal);
86e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
87e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
88e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    return mStats;
897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
90095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
91a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnarstatus_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) {
92a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) {
93a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        return BAD_VALUE;
94a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    }
95a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
96a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
97a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
98a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    msg->setObject("surface", surface);
99a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    sp<AMessage> response;
100a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
101a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    if (err == OK && response != NULL) {
102a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        CHECK(response->findInt32("err", &err));
103a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    }
104a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    return err;
105a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar}
106a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
109095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatCodecNotify:
1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1133b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            int32_t cbID;
1143b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            CHECK(msg->findInt32("callbackID", &cbID));
1153b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
1163b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
1173b032b3865fd93173aadca0591eeea32853206f9Chong Zhang                    mIsAudio ? "audio" : "video", cbID, mPaused);
1183b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
119421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            if (mPaused) {
120421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                break;
121421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            }
122421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
123421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            switch (cbID) {
124421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_INPUT_AVAILABLE:
125421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
126421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
127421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
128095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
129421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnInputBuffer(index);
130421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
131421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
132421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
133421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_AVAILABLE:
134421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
135421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
136421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t offset;
137421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t size;
138421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int64_t timeUs;
139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t flags;
140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
141421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
142421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("offset", &offset));
143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("size", &size));
144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt64("timeUs", &timeUs));
145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("flags", &flags));
146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
150095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
152421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
153421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    sp<AMessage> format;
154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findMessage("format", &format));
155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleOutputFormatChange(format);
157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
160421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_ERROR:
161421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
162421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    status_t err;
163421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("err", &err));
164421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    ALOGE("Decoder (%s) reported error : 0x%x",
165421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                            mIsAudio ? "audio" : "video", err);
166421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
167421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleError(err);
168421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
171421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                default:
172421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
173421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    TRESPASS();
174421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
175421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
1767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
1777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
17887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            break;
17987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        }
1807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRenderBuffer:
1827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (!isStaleReply(msg)) {
1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                onRenderBuffer(msg);
1857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
1867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
189a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        case kWhatSetVideoSurface:
190a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        {
191a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<AReplyToken> replyID;
192a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
193a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
194a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<RefBase> obj;
195a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            CHECK(msg->findObject("surface", &obj));
196a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null
197a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            int32_t err = INVALID_OPERATION;
198a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            // NOTE: in practice mSurface is always non-null, but checking here for completeness
199a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            if (mCodec != NULL && mSurface != NULL) {
200a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // TODO: once AwesomePlayer is removed, remove this automatic connecting
201a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // to the surface by MediaPlayerService.
202a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                //
203a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // at this point MediaPlayerService::client has already connected to the
204a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // surface, which MediaCodec does not expect
205a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                err = native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
206a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                if (err == OK) {
207a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    err = mCodec->setSurface(surface);
208a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    ALOGI_IF(err, "codec setSurface returned: %d", err);
209a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    if (err == OK) {
210a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        // reconnect to the old surface as MPS::Client will expect to
211a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        // be able to disconnect from it.
212a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        (void)native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
213a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        mSurface = surface;
214a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    }
215a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                }
216a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                if (err != OK) {
217a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    // reconnect to the new surface on error as MPS::Client will expect to
218a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    // be able to disconnect from it.
219a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    (void)native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
220a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                }
221a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            }
222a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
223a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<AMessage> response = new AMessage;
224a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            response->setInt32("err", err);
225a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            response->postReply(replyID);
226a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            break;
227a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        }
228a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
2297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
2307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            DecoderBase::onMessageReceived(msg);
2317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
23287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
23387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
23487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
2351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mCodec == NULL);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mFormatChangePending = false;
23966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
2407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ++mBufferGeneration;
2421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
243840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    AString mime;
244840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    CHECK(format->findString("mime", &mime));
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
2477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
2487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName = mime;
2501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName.append(" decoder");
2511de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
252840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
25368845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    mCodec = MediaCodec::CreateByType(
25468845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu            mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid);
255095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    int32_t secure = 0;
256095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (format->findInt32("secure", &secure) && secure != 0) {
257095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (mCodec != NULL) {
258095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->getName(&mComponentName);
259095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mComponentName.append(".secure");
260095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->release();
261095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            ALOGI("[%s] creating", mComponentName.c_str());
262095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec = MediaCodec::CreateByComponentName(
26368845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu                    mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid);
264095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
265095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
2661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec == NULL) {
267095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        ALOGE("Failed to create %s%s decoder",
268095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                (secure ? "secure " : ""), mime.c_str());
2691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(UNKNOWN_ERROR);
2701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
271840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
2727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsSecure = secure;
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodec->getName(&mComponentName);
2751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
27614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    status_t err;
2771de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    if (mSurface != NULL) {
2781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // disconnect from surface as MediaCodec will reconnect
27914986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        err = native_window_api_disconnect(
2801de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar                mSurface.get(), NATIVE_WINDOW_API_MEDIA);
28114986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // We treat this as a warning, as this is a preparatory step.
28214986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // Codec will try to connect to the surface, which is where
28314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // any error signaling will occur.
28414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
2851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
28614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    err = mCodec->configure(
2871de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            format, mSurface, NULL /* crypto */, 0 /* flags */);
2881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
2891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
2902abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
2912abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
2921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
2931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
2941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
29587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    rememberCodecSpecificData(format);
29687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
2971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    // the following should work in configured state
2981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
2991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
3001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
301e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("mime", mime.c_str());
302e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("component-name", mComponentName.c_str());
303e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
304e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    if (!mIsAudio) {
305e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
306e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (mOutputFormat->findInt32("width", &width)
307e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && mOutputFormat->findInt32("height", &height)) {
308e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
309e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
310e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
311e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    }
312e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
313421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
314421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->setCallback(reply);
315421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
3161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    err = mCodec->start();
3171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
3181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
3192abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
3202abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
3211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
3221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    releaseAndResetMediaBuffers();
326078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
327704e72658b1082264a26a83c50046da34f07d1a1Wei Jia    mPaused = false;
328f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    mResumePending = false;
3291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
330078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
3318db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> &params) {
3328db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (mCodec == NULL) {
3338db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        ALOGW("onSetParameters called before codec is created.");
3348db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        return;
3358db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
3368db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mCodec->setParameters(params);
3378db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu}
3388db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
3397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
3407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hadNoRenderer = (mRenderer == NULL);
3417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mRenderer = renderer;
3427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hadNoRenderer && mRenderer != NULL) {
343e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar        // this means that the widevine legacy source is ready
344e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar        onRequestInputBuffers();
34581e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia    }
3467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
3477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers(
3497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        Vector<sp<ABuffer> > *dstBuffers) {
350e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers));
3517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
3522245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
353f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) {
3547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPaused = false;
355f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
356f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (notifyComplete) {
357f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = true;
358f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
359421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->start();
360095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
361095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
36266704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) {
3637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
3647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->flush();
3657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
3687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->flush(mIsAudio, notifyComplete);
3697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->signalTimeDiscontinuity();
3707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
3731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec != NULL) {
3747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->flush();
3757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
3767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
377078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber    }
378078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
3797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
3807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
3817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
3827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatFlushCompleted.
3837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // we attempt to release the buffers even if flush fails.
3847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
386421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mPaused = true;
38766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
39066704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() {
39166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    doFlush(true);
39266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
39366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
39466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // This could happen if the client starts seeking/shutdown
39566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // after we queued an EOS for discontinuities.
39666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // We can consider discontinuity handled.
39766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(false /* flushOnTimeChange */);
3987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
39966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
40066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> notify = mNotify->dup();
40166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->setInt32("what", kWhatFlushCompleted);
40266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->post();
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) {
4067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
407f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
408f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // if there is a pending resume request, notify complete now
409f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
410f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
4117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
4127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->release();
4137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec = NULL;
4147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
4151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
4161de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        if (mSurface != NULL) {
4177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // reconnect to surface as MediaCodec disconnected from it
4187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            status_t error =
4191de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar                    native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
4207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGW_IF(error != NO_ERROR,
4217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    "[%s] failed to connect to native window, error=%d",
4227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), error);
4237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mComponentName = "decoder";
4257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
4287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
4307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
4317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
4327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatShutdownCompleted.
4337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
434c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
4357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (notifyComplete) {
4367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> notify = mNotify->dup();
4377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->setInt32("what", kWhatShutdownCompleted);
4387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->post();
4397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mPaused = true;
4407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
44187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
44287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
4433b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/*
4443b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data
4453b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */
4463b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() {
447e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    // mRenderer is only NULL if we have a legacy widevine source that
448e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    // is not yet ready. In this case we must not fetch input.
449e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    if (isDiscontinuityPending() || mRenderer == NULL) {
4503b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        return false;
4517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
45366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    while (err == OK && !mDequeuedInputBuffers.empty()) {
4547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        size_t bufferIx = *mDequeuedInputBuffers.begin();
4557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
4567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setSize("buffer-ix", bufferIx);
4577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = fetchInputData(msg);
45866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (err != OK && err != ERROR_END_OF_STREAM) {
45966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // if EOS, need to queue EOS buffer
4607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
4617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
4637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mPendingInputMessages.empty()
4657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                || !onInputBufferFetched(msg)) {
4667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mPendingInputMessages.push_back(msg);
4677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
469095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
4703b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    return err == -EWOULDBLOCK
4713b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            && mSource->feedMoreTSData() == OK;
472095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
473095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
474421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err)
475421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{
476421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // We cannot immediately release the codec due to buffers still outstanding
477421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // in the renderer.  We signal to the player the error so it can shutdown/release the
478421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // decoder after flushing and increment the generation to discard unnecessary messages.
479421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
480421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    ++mBufferGeneration;
481421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
482421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> notify = mNotify->dup();
483421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("what", kWhatError);
484421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("err", err);
485421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->post();
486421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
487421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
488421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) {
48966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
4907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return false;
4917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
492421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
493421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<ABuffer> buffer;
494421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getInputBuffer(index, &buffer);
495421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
4966301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    if (buffer == NULL) {
4976301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        handleError(UNKNOWN_ERROR);
4986301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        return false;
4996301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    }
5006301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia
501421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mInputBuffers.size()) {
502421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
503421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBuffers.add();
504421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.add();
505421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.add();
506421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.editItemAt(i) = NULL;
507421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.editItemAt(i) = false;
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
510421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBuffers.editItemAt(index) = buffer;
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
512421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    //CHECK_LT(bufferIx, mInputBuffers.size());
5131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
514421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (mMediaBuffers[index] != NULL) {
515421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers[index]->release();
516421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers.editItemAt(index) = NULL;
517095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
518421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBufferIsDequeued.editItemAt(index) = true;
519095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
52087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    if (!mCSDsToSubmit.isEmpty()) {
5217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
522421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        msg->setSize("buffer-ix", index);
5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
52487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
52587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setBuffer("buffer", buffer);
52787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        mCSDsToSubmit.removeAt(0);
52856097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia        if (!onInputBufferFetched(msg)) {
52956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            handleError(UNKNOWN_ERROR);
53056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            return false;
53156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia        }
5322245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        return true;
5332245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
5342245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
5352245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    while (!mPendingInputMessages.empty()) {
5362245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        sp<AMessage> msg = *mPendingInputMessages.begin();
5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!onInputBufferFetched(msg)) {
5382245fc625910e47d1ba3c339e205c21ab58a47adWei Jia            break;
5392245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        }
5402245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        mPendingInputMessages.erase(mPendingInputMessages.begin());
5412245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
5422245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
543421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mInputBufferIsDequeued.editItemAt(index)) {
54487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        return true;
54587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
54687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
547421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mDequeuedInputBuffers.push_back(index);
5487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    onRequestInputBuffers();
5501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    return true;
5511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
5521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
553421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer(
554421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t index,
555421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t offset,
556421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t size,
557421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t timeUs,
558421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int32_t flags) {
559421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen//    CHECK_LT(bufferIx, mOutputBuffers.size());
560421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<ABuffer> buffer;
561421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getOutputBuffer(index, &buffer);
5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
563421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mOutputBuffers.size()) {
564421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
565421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mOutputBuffers.add();
566095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
567095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
568095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
569421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mOutputBuffers.editItemAt(index) = buffer;
570421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
5717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->setRange(offset, size);
5727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->clear();
5737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->setInt64("timeUs", timeUs);
57466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
57566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
5767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // we do not expect CODECCONFIG or SYNCFRAME for decoder
5777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
579421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    reply->setSize("buffer-ix", index);
5807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setInt32("generation", mBufferGeneration);
5817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
58266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (eos) {
58366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
58466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
58566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        buffer->meta()->setInt32("eos", true);
58666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        reply->setInt32("eos", true);
58766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mSkipRenderingUntilMediaTimeUs >= 0) {
5887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
5897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGV("[%s] dropping buffer at time %lld as requested.",
5907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     mComponentName.c_str(), (long long)timeUs);
5917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->post();
5937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return true;
5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mSkipRenderingUntilMediaTimeUs = -1;
5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
599e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mNumFramesTotal += !mIsAudio;
600e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
601f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // wait until 1st frame comes out to signal resume complete
602f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
603f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
6047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
6057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // send the buffer to renderer.
6067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->queueBuffer(mIsAudio, buffer, reply);
60766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (eos && !isDiscontinuityPending()) {
6087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
6097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return true;
6137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
615421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
616421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mIsAudio) {
617e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
618e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (format->findInt32("width", &width)
619e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && format->findInt32("height", &height)) {
620e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
621e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
622e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
623421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        sp<AMessage> notify = mNotify->dup();
624421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setInt32("what", kWhatVideoSizeChanged);
625421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setMessage("format", format);
626421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->post();
627421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    } else if (mRenderer != NULL) {
628421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        uint32_t flags;
629421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t durationUs;
630421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
631288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung        if (getAudioDeepBufferSetting() // override regardless of source duration
632288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                || (!hasVideo
633288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && mSource->getDuration(&durationUs) == OK
634288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
635421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
636421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        } else {
637421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_NONE;
638421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        }
639421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
640216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        status_t err = mRenderer->openAudioSink(
641421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
642216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        if (err != OK) {
643216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent            handleError(err);
644216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        }
645421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    }
646421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
647421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() {
6497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
6507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mMediaBuffers[i] != NULL) {
6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers[i]->release();
6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers.editItemAt(i) = NULL;
6537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mMediaBuffers.resize(mInputBuffers.size());
6567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
6577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mMediaBuffers.editItemAt(i) = NULL;
6587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.clear();
6607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.resize(mInputBuffers.size());
6617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mInputBufferIsDequeued.editItemAt(i) = false;
6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPendingInputMessages.clear();
6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDequeuedInputBuffers.clear();
6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mSkipRenderingUntilMediaTimeUs = -1;
6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() {
6717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
6721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
6737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        reply->setInt32("generation", mBufferGeneration);
6747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec->requestActivityNotification(reply);
6757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int32_t generation;
6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findInt32("generation", &generation));
6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return generation != mBufferGeneration;
6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> accessUnit;
6867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool dropAccessUnit;
6877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    do {
6887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (err == -EWOULDBLOCK) {
6917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return err;
6927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        } else if (err != OK) {
6937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (err == INFO_DISCONTINUITY) {
6947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t type;
6957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
6967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool formatChange =
6987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    (mIsAudio &&
6997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
7007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    || (!mIsAudio &&
7017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
7027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
7047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                ALOGI("%s discontinuity (format=%d, time=%d)",
7067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mIsAudio ? "audio" : "video", formatChange, timeChange);
7077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool seamlessFormatChange = false;
7097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
7107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange) {
7117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    seamlessFormatChange =
7127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        supportsSeamlessFormatChange(newFormat);
7137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // treat seamless format change separately
7147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    formatChange = !seamlessFormatChange;
7157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
7167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
71766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // For format or time change, return EOS to queue EOS input,
71866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // then wait for EOS on output.
7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange /* not seamless */) {
7207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mFormatChangePending = true;
72166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (timeChange) {
7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
72466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    mTimeChangePending = true;
72566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (seamlessFormatChange) {
7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // reuse existing decoder and don't flush
7287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
72966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    continue;
7307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else {
7317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // This stream is unaffected by the discontinuity
7327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    return -EWOULDBLOCK;
7337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
73666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // reply should only be returned without a buffer set
73766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // when there is an error (including EOS)
73866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            CHECK(err != OK);
73966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->setInt32("err", err);
74166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            return ERROR_END_OF_STREAM;
7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        dropAccessUnit = false;
7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mIsAudio
7467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && !mIsSecure
7477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && mRenderer->getVideoLateByUs() > 100000ll
7487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && mIsVideoAVC
7497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && !IsAVCReferenceFrame(accessUnit)) {
7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            dropAccessUnit = true;
751e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            ++mNumInputFramesDropped;
7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } while (dropAccessUnit);
7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
7567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0
7577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int64_t mediaTimeUs;
7587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
7595abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang    ALOGV("[%s] feeding input buffer at media time %.3f",
7607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mIsAudio ? "audio" : "video",
7617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mediaTimeUs / 1E6);
7627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif
7637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
7657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->decode(accessUnit);
7667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setBuffer("buffer", accessUnit);
7697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return OK;
7717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
7747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t bufferIx;
7757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findSize("buffer-ix", &bufferIx));
7767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK_LT(bufferIx, mInputBuffers.size());
7777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
7787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> buffer;
7807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hasBuffer = msg->findBuffer("buffer", &buffer);
7817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // handle widevine classic source - that fills an arbitrary input buffer
7837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    MediaBuffer *mediaBuffer = NULL;
7847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hasBuffer) {
7857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
7867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mediaBuffer != NULL) {
7877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // likely filled another buffer than we requested: adjust buffer index
7887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            size_t ix;
7897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            for (ix = 0; ix < mInputBuffers.size(); ix++) {
7907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                const sp<ABuffer> &buf = mInputBuffers[ix];
7917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (buf->data() == mediaBuffer->data()) {
7927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // all input buffers are dequeued on start, hence the check
7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    if (!mInputBufferIsDequeued[ix]) {
7947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu",
7957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                mComponentName.c_str(), ix, bufferIx);
7967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mediaBuffer->release();
7977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        return false;
7987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    }
7997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // TRICKY: need buffer for the metadata, so instead, set
8017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // codecBuffer to the same (though incorrect) buffer to
8027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // avoid a memcpy into the codecBuffer
8037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer = buffer;
8047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer->setRange(
8057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_offset(),
8067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_length());
8077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    bufferIx = ix;
8087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    break;
8097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
8107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(ix < mInputBuffers.size());
8127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
8137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
8147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (buffer == NULL /* includes !hasBuffer */) {
8167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int32_t streamErr = ERROR_END_OF_STREAM;
8177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
8187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
81966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        CHECK(streamErr != OK);
8201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
8211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // attempt to queue EOS
8221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
8231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                bufferIx,
8241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
8251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
8261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
8271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                MediaCodec::BUFFER_FLAG_EOS);
828cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        if (err == OK) {
829cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
830cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else if (streamErr == ERROR_END_OF_STREAM) {
8311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            streamErr = err;
8321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            // err will not be ERROR_END_OF_STREAM
8331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
8341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
8351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (streamErr != ERROR_END_OF_STREAM) {
836cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            ALOGE("Stream error for %s (err=%d), EOS %s queued",
837cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    mComponentName.c_str(),
838cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    streamErr,
839cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    err == OK ? "successfully" : "unsuccessfully");
8401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(streamErr);
8411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
8421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
843c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<AMessage> extra;
844c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
845c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            int64_t resumeAtMediaTimeUs;
846c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            if (extra->findInt64(
847c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
848c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                ALOGI("[%s] suppressing rendering until %lld us",
849c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
850c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
851c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            }
852c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        }
853c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
8541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int64_t timeUs = 0;
8551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        uint32_t flags = 0;
8561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
8571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
85887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        int32_t eos, csd;
85987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        // we do not expect SYNCFRAME for decoder
8601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer->meta()->findInt32("eos", &eos) && eos) {
8611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_EOS;
86287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
86387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
8641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
8651cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
8661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // copy into codec buffer
8671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer != codecBuffer) {
86856097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            if (buffer->size() > codecBuffer->capacity()) {
86956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                handleError(ERROR_BUFFER_TOO_SMALL);
87056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                mDequeuedInputBuffers.push_back(bufferIx);
87156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                return false;
87256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            }
8731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            codecBuffer->setRange(0, buffer->size());
8741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            memcpy(codecBuffer->data(), buffer->data(), buffer->size());
8751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
8761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
8771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
8781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        bufferIx,
8791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->offset(),
8801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->size(),
8811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        timeUs,
8821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        flags);
8831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (err != OK) {
884cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
885cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mediaBuffer->release();
886cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
8871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            ALOGE("Failed to queue input buffer for %s (err=%d)",
8881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    mComponentName.c_str(), err);
8891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(err);
890cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else {
891cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
892cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
893cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                CHECK(mMediaBuffers[bufferIx] == NULL);
894cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
895cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
896095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8982245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    return true;
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
9021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    status_t err;
9031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    int32_t render;
9041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    size_t bufferIx;
90566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    int32_t eos;
9061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK(msg->findSize("buffer-ix", &bufferIx));
907c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
9087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!mIsAudio) {
909c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        int64_t timeUs;
910c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<ABuffer> buffer = mOutputBuffers[bufferIx];
911c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        buffer->meta()->findInt64("timeUs", &timeUs);
9127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
9147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mCCDecoder->display(timeUs);
9157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
916c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
917c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
9181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (msg->findInt32("render", &render) && render) {
919dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        int64_t timestampNs;
920dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        CHECK(msg->findInt64("timestampNs", &timestampNs));
921dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
9221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
923e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        mNumOutputFramesDropped += !mIsAudio;
9241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        err = mCodec->releaseOutputBuffer(bufferIx);
9251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
9261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
9271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("failed to release output buffer for %s (err=%d)",
9281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mComponentName.c_str(), err);
9291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
93166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (msg->findInt32("eos", &eos) && eos
93266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            && isDiscontinuityPending()) {
93366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(true /* flushOnTimeChange */);
93466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
93566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
93666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
93766704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const {
93866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    return mFormatChangePending || mTimeChangePending;
93966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
94066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
94166704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
94266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
94366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
94466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
94566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have format change, pause and wait to be killed;
94666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have time change only, flush and restart fetching.
94766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
94866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (mFormatChangePending) {
94966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        mPaused = true;
95066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mTimeChangePending) {
95166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (flushOnTimeChange) {
952421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            doFlush(false /* notifyComplete */);
953421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            signalResume(false /* notifyComplete */);
95466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        }
95566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
95666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
95766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // Notify NuPlayer to either shutdown decoder, or rescan sources
95866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> msg = mNotify->dup();
95966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("what", kWhatInputDiscontinuity);
96066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("formatChange", mFormatChangePending);
96166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->post();
96266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
96366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mFormatChangePending = false;
96466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
9687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &targetFormat) const {
9696d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
9706d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
9716d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString mime;
9746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!targetFormat->findString("mime", &mime)) {
9756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
9766d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9776d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9786d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
9796d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        // field-by-field comparison
9806d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
9816d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
9826d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            int32_t oldVal, newVal;
9837abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
9841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    !targetFormat->findInt32(keys[i], &newVal) ||
9851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    oldVal != newVal) {
9866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
9876d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
9886d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
9896d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9906d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        sp<ABuffer> oldBuf, newBuf;
9917abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
9921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                targetFormat->findBuffer("csd-0", &newBuf)) {
9936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            if (oldBuf->size() != newBuf->size()) {
9946d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
9956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
9966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
9976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
9986d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9996d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return false;
10006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
10016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
10037abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (mInputFormat == NULL) {
10046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
10056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
10086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
10096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10106d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10116d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString oldMime, newMime;
10127abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (!mInputFormat->findString("mime", &oldMime)
10136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !targetFormat->findString("mime", &newMime)
10146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !(oldMime == newMime)) {
10156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
10166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
10196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool seamless;
10206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (audio) {
10216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        seamless = supportsSeamlessAudioFormatChange(targetFormat);
10226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    } else {
10231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int32_t isAdaptive;
10241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        seamless = (mCodec != NULL &&
10251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
10261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                isAdaptive);
10276d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10286d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10296d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
10306d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return seamless;
10316d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
10326d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
10347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (format == NULL) {
1035a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        return;
1036a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
10377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mCSDsForCurrentFormat.clear();
10387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (int32_t i = 0; ; ++i) {
10397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        AString tag = "csd-";
10407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        tag.append(i);
10417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<ABuffer> buffer;
10427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!format->findBuffer(tag.c_str(), &buffer)) {
10437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
10447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
10457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsForCurrentFormat.push(buffer);
1046a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
1047b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang}
1048b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang
1049f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
1050f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (mResumePending) {
1051f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = false;
1052f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1053f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        sp<AMessage> notify = mNotify->dup();
1054f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->setInt32("what", kWhatResumeCompleted);
1055f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->post();
1056f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
1057f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang}
1058f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1061