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
229fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar#include <algorithm>
239fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar
247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerCCDecoder.h"
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h"
26c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h"
27c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h"
28c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
29288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h>
301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
335bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h>
34095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h>
351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
401de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h"
427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h"
437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
469fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnarstatic float kDisplayRefreshingRate = 60.f; // TODO: get this from the display
47bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
48bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// The default total video frame rate of a stream when that info is not available from
49bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// the source.
50bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavanstatic float kDefaultVideoFrameRateTotal = 30.f;
51bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
52288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() {
53288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung    return property_get_bool("media.stagefright.audio.deep", false /* default_value */);
54288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung}
55288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung
56f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder(
571173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<AMessage> &notify,
58c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Source> &source,
5968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        pid_t pid,
60c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Renderer> &renderer,
611de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        const sp<Surface> &surface,
627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<CCDecoder> &ccDecoder)
63202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    : DecoderBase(notify),
641de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar      mSurface(surface),
65c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSource(source),
66c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mRenderer(renderer),
677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mCCDecoder(ccDecoder),
6868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu      mPid(pid),
69c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSkipRenderingUntilMediaTimeUs(-1ll),
707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mNumFramesTotal(0ll),
71e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumInputFramesDropped(0ll),
72e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumOutputFramesDropped(0ll),
73e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoWidth(0),
74e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoHeight(0),
757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsAudio(true),
767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsVideoAVC(false),
777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsSecure(false),
787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mFormatChangePending(false),
7966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang      mTimeChangePending(false),
80bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mFrameRateTotal(kDefaultVideoFrameRateTotal),
81bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mPlaybackSpeed(1.0f),
829fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar      mNumVideoTemporalLayerTotal(1), // decode all layers
83bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mNumVideoTemporalLayerAllowed(1),
84bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mCurrentMaxVideoTemporalLayerId(0),
85f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang      mResumePending(false),
861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar      mComponentName("decoder") {
871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper = new ALooper;
889e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen    mCodecLooper->setName("NPDecoder-CL");
891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
90bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    mVideoTemporalLayerAggregateFps[0] = mFrameRateTotal;
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
93f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() {
94faeb0f291330134dc4468359a36e099aae508449Ronghua Wu    mCodec->release();
954923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia    releaseAndResetMediaBuffers();
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
98e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const {
99e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-total", mNumFramesTotal);
100e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
101e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
102e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    return mStats;
1037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
104095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
105a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnarstatus_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) {
106a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) {
107a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        return BAD_VALUE;
108a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    }
109a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
110a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
111a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
112a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    msg->setObject("surface", surface);
113a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    sp<AMessage> response;
114a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
115a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    if (err == OK && response != NULL) {
116a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        CHECK(response->findInt32("err", &err));
117a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    }
118a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    return err;
119a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar}
120a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
1217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
1227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
123095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
1257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatCodecNotify:
1267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1273b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            int32_t cbID;
1283b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            CHECK(msg->findInt32("callbackID", &cbID));
1293b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
1303b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
1313b032b3865fd93173aadca0591eeea32853206f9Chong Zhang                    mIsAudio ? "audio" : "video", cbID, mPaused);
1323b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
133421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            if (mPaused) {
134421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                break;
135421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            }
136421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
137421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            switch (cbID) {
138421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_INPUT_AVAILABLE:
139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
141421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
142095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnInputBuffer(index);
144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_AVAILABLE:
148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
149421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
150421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t offset;
151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t size;
152421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int64_t timeUs;
153421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t flags;
154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("offset", &offset));
157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("size", &size));
158421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt64("timeUs", &timeUs));
159421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("flags", &flags));
160421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
161421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
162421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
164095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
165421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
166421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
167421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    sp<AMessage> format;
168421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findMessage("format", &format));
169421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
170421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleOutputFormatChange(format);
171421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
174421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_ERROR:
175421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
176421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    status_t err;
177421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("err", &err));
178421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    ALOGE("Decoder (%s) reported error : 0x%x",
179421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                            mIsAudio ? "audio" : "video", err);
180421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
181421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleError(err);
182421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
185421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                default:
186421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
187421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    TRESPASS();
188421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
189421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
1907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
1917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
19287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            break;
19387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        }
1947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRenderBuffer:
1967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (!isStaleReply(msg)) {
1987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                onRenderBuffer(msg);
1997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
2007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
2017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
2027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
203a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        case kWhatSetVideoSurface:
204a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        {
205a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<AReplyToken> replyID;
206a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
207a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
208a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<RefBase> obj;
209a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            CHECK(msg->findObject("surface", &obj));
210a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null
211a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            int32_t err = INVALID_OPERATION;
212a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            // NOTE: in practice mSurface is always non-null, but checking here for completeness
213a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            if (mCodec != NULL && mSurface != NULL) {
214a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // TODO: once AwesomePlayer is removed, remove this automatic connecting
215a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // to the surface by MediaPlayerService.
216a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                //
217a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // at this point MediaPlayerService::client has already connected to the
218a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // surface, which MediaCodec does not expect
219a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                err = native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
220a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                if (err == OK) {
221a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    err = mCodec->setSurface(surface);
222a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    ALOGI_IF(err, "codec setSurface returned: %d", err);
223a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    if (err == OK) {
224a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        // reconnect to the old surface as MPS::Client will expect to
225a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        // be able to disconnect from it.
226a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        (void)native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
227a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        mSurface = surface;
228a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    }
229a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                }
230a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                if (err != OK) {
231a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    // reconnect to the new surface on error as MPS::Client will expect to
232a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    // be able to disconnect from it.
233a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    (void)native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
234a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                }
235a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            }
236a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
237a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<AMessage> response = new AMessage;
238a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            response->setInt32("err", err);
239a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            response->postReply(replyID);
240a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            break;
241a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        }
242a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
2437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
2447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            DecoderBase::onMessageReceived(msg);
2457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
24687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
24787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
24887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
2491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mCodec == NULL);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mFormatChangePending = false;
25366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
2547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ++mBufferGeneration;
2561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
257840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    AString mime;
258840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    CHECK(format->findString("mime", &mime));
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
2617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
2627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName = mime;
2641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName.append(" decoder");
2651de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
266840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
26768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    mCodec = MediaCodec::CreateByType(
26868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu            mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid);
269095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    int32_t secure = 0;
270095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (format->findInt32("secure", &secure) && secure != 0) {
271095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (mCodec != NULL) {
272095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->getName(&mComponentName);
273095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mComponentName.append(".secure");
274095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->release();
275095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            ALOGI("[%s] creating", mComponentName.c_str());
276095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec = MediaCodec::CreateByComponentName(
27768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu                    mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid);
278095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
279095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
2801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec == NULL) {
281095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        ALOGE("Failed to create %s%s decoder",
282095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                (secure ? "secure " : ""), mime.c_str());
2831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(UNKNOWN_ERROR);
2841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
285840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
2867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsSecure = secure;
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodec->getName(&mComponentName);
2891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
29014986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    status_t err;
2911de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    if (mSurface != NULL) {
2921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // disconnect from surface as MediaCodec will reconnect
29314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        err = native_window_api_disconnect(
2941de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar                mSurface.get(), NATIVE_WINDOW_API_MEDIA);
29514986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // We treat this as a warning, as this is a preparatory step.
29614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // Codec will try to connect to the surface, which is where
29714986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // any error signaling will occur.
29814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
2991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
30014986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    err = mCodec->configure(
3011de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            format, mSurface, NULL /* crypto */, 0 /* flags */);
3021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
3031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
3042abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
3052abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
3061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
3071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
3081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
30987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    rememberCodecSpecificData(format);
31087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
3111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    // the following should work in configured state
3121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
3131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
3141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
315e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("mime", mime.c_str());
316e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("component-name", mComponentName.c_str());
317e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
318e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    if (!mIsAudio) {
319e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
320e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (mOutputFormat->findInt32("width", &width)
321e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && mOutputFormat->findInt32("height", &height)) {
322e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
323e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
324e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
325e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    }
326e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
327421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
328421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->setCallback(reply);
329421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
3301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    err = mCodec->start();
3311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
3321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
3332abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
3342abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
3351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
3361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    releaseAndResetMediaBuffers();
340078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
341704e72658b1082264a26a83c50046da34f07d1a1Wei Jia    mPaused = false;
342f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    mResumePending = false;
3431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
344078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
3458db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> &params) {
346bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    bool needAdjustLayers = false;
347bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    float frameRateTotal;
348bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (params->findFloat("frame-rate-total", &frameRateTotal)
349bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && mFrameRateTotal != frameRateTotal) {
350bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        needAdjustLayers = true;
351bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mFrameRateTotal = frameRateTotal;
352bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
353bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
354bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    int32_t numVideoTemporalLayerTotal;
355bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (params->findInt32("temporal-layer-count", &numVideoTemporalLayerTotal)
3569fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            && numVideoTemporalLayerTotal >= 0
357bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && numVideoTemporalLayerTotal <= kMaxNumVideoTemporalLayers
358bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && mNumVideoTemporalLayerTotal != numVideoTemporalLayerTotal) {
359bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        needAdjustLayers = true;
3609fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        mNumVideoTemporalLayerTotal = std::max(numVideoTemporalLayerTotal, 1);
361bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
362bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
3639fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar    if (needAdjustLayers && mNumVideoTemporalLayerTotal > 1) {
364bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        // TODO: For now, layer fps is calculated for some specific architectures.
365bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        // But it really should be extracted from the stream.
366bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mVideoTemporalLayerAggregateFps[0] =
367bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - 1));
368bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) {
369bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            mVideoTemporalLayerAggregateFps[i] =
370bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - i))
371bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                + mVideoTemporalLayerAggregateFps[i - 1];
372bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        }
373bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
374bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
375bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    float playbackSpeed;
376bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (params->findFloat("playback-speed", &playbackSpeed)
377bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && mPlaybackSpeed != playbackSpeed) {
378bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        needAdjustLayers = true;
379bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mPlaybackSpeed = playbackSpeed;
380bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
381bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
382bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (needAdjustLayers) {
3839fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        float decodeFrameRate = mFrameRateTotal;
3849fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        // enable temporal layering optimization only if we know the layering depth
3859fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        if (mNumVideoTemporalLayerTotal > 1) {
3869fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            int32_t layerId;
3879fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            for (layerId = 0; layerId < mNumVideoTemporalLayerTotal - 1; ++layerId) {
3889fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                if (mVideoTemporalLayerAggregateFps[layerId] * mPlaybackSpeed
3899fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                        >= kDisplayRefreshingRate * 0.9) {
3909fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    break;
3919fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                }
392bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
3939fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            mNumVideoTemporalLayerAllowed = layerId + 1;
3949fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            decodeFrameRate = mVideoTemporalLayerAggregateFps[layerId];
395bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        }
3969fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        ALOGV("onSetParameters: allowed layers=%d, decodeFps=%g",
3979fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                mNumVideoTemporalLayerAllowed, decodeFrameRate);
398bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
399bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        if (mCodec == NULL) {
400bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            ALOGW("onSetParameters called before codec is created.");
401bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            return;
402bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        }
403bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
404bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        sp<AMessage> codecParams = new AMessage();
4059fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed);
406bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mCodec->setParameters(codecParams);
4078db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
4088db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu}
4098db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
4107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
4117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hadNoRenderer = (mRenderer == NULL);
4127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mRenderer = renderer;
4137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hadNoRenderer && mRenderer != NULL) {
414e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar        // this means that the widevine legacy source is ready
415e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar        onRequestInputBuffers();
41681e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia    }
4177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
4187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers(
4207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        Vector<sp<ABuffer> > *dstBuffers) {
421e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers));
4227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
4232245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
424f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) {
4257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPaused = false;
426f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
427f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (notifyComplete) {
428f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = true;
429f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
430421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->start();
431095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
432095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
43366704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) {
4347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
4357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->flush();
4367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
4397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->flush(mIsAudio, notifyComplete);
4407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->signalTimeDiscontinuity();
4417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
4441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec != NULL) {
4457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->flush();
4467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
4477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
448078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber    }
449078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
4507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
4517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
4527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
4537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatFlushCompleted.
4547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // we attempt to release the buffers even if flush fails.
4557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
457421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mPaused = true;
45866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
460421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
46166704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() {
46266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    doFlush(true);
46366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
46466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
46566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // This could happen if the client starts seeking/shutdown
46666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // after we queued an EOS for discontinuities.
46766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // We can consider discontinuity handled.
46866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(false /* flushOnTimeChange */);
4697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
47066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
47166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> notify = mNotify->dup();
47266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->setInt32("what", kWhatFlushCompleted);
47366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->post();
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) {
4777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
478f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
479f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // if there is a pending resume request, notify complete now
480f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
481f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
4827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
4837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->release();
4847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec = NULL;
4857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
4861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
4871de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        if (mSurface != NULL) {
4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // reconnect to surface as MediaCodec disconnected from it
4897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            status_t error =
4901de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar                    native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
4917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGW_IF(error != NO_ERROR,
4927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    "[%s] failed to connect to native window, error=%d",
4937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), error);
4947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mComponentName = "decoder";
4967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
4997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
5017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
5027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
5037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatShutdownCompleted.
5047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
505c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
5067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (notifyComplete) {
5077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> notify = mNotify->dup();
5087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->setInt32("what", kWhatShutdownCompleted);
5097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->post();
5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mPaused = true;
5117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
51287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
51387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
5143b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/*
5153b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data
5163b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */
5173b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() {
518e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    // mRenderer is only NULL if we have a legacy widevine source that
519e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    // is not yet ready. In this case we must not fetch input.
520e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    if (isDiscontinuityPending() || mRenderer == NULL) {
5213b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        return false;
5227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
52466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    while (err == OK && !mDequeuedInputBuffers.empty()) {
5257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        size_t bufferIx = *mDequeuedInputBuffers.begin();
5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setSize("buffer-ix", bufferIx);
5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = fetchInputData(msg);
52966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (err != OK && err != ERROR_END_OF_STREAM) {
53066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // if EOS, need to queue EOS buffer
5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mPendingInputMessages.empty()
5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                || !onInputBufferFetched(msg)) {
5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mPendingInputMessages.push_back(msg);
5387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
540095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
5413b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    return err == -EWOULDBLOCK
5423b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            && mSource->feedMoreTSData() == OK;
543095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
544095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
545421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err)
546421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{
547421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // We cannot immediately release the codec due to buffers still outstanding
548421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // in the renderer.  We signal to the player the error so it can shutdown/release the
549421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // decoder after flushing and increment the generation to discard unnecessary messages.
550421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
551421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    ++mBufferGeneration;
552421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
553421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> notify = mNotify->dup();
554421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("what", kWhatError);
555421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("err", err);
556421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->post();
557421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
558421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
559421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) {
56066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
5617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return false;
5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
563421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
564421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<ABuffer> buffer;
565421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getInputBuffer(index, &buffer);
566421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
5676301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    if (buffer == NULL) {
5686301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        handleError(UNKNOWN_ERROR);
5696301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        return false;
5706301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    }
5716301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia
572421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mInputBuffers.size()) {
573421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
574421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBuffers.add();
575421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.add();
576421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.add();
577421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.editItemAt(i) = NULL;
578421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.editItemAt(i) = false;
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
581421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBuffers.editItemAt(index) = buffer;
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
583421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    //CHECK_LT(bufferIx, mInputBuffers.size());
5841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
585421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (mMediaBuffers[index] != NULL) {
586421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers[index]->release();
587421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers.editItemAt(index) = NULL;
588095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
589421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBufferIsDequeued.editItemAt(index) = true;
590095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
59187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    if (!mCSDsToSubmit.isEmpty()) {
5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
593421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        msg->setSize("buffer-ix", index);
5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
59587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
59687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setBuffer("buffer", buffer);
59887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        mCSDsToSubmit.removeAt(0);
59956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia        if (!onInputBufferFetched(msg)) {
60056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            handleError(UNKNOWN_ERROR);
60156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            return false;
60256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia        }
6032245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        return true;
6042245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
6052245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
6062245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    while (!mPendingInputMessages.empty()) {
6072245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        sp<AMessage> msg = *mPendingInputMessages.begin();
6087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!onInputBufferFetched(msg)) {
6092245fc625910e47d1ba3c339e205c21ab58a47adWei Jia            break;
6102245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        }
6112245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        mPendingInputMessages.erase(mPendingInputMessages.begin());
6122245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
6132245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
614421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mInputBufferIsDequeued.editItemAt(index)) {
61587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        return true;
61687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
61787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
618421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mDequeuedInputBuffers.push_back(index);
6197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    onRequestInputBuffers();
6211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    return true;
6221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
6231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
624421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer(
625421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t index,
626421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t offset,
627421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t size,
628421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t timeUs,
629421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int32_t flags) {
630421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen//    CHECK_LT(bufferIx, mOutputBuffers.size());
631421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<ABuffer> buffer;
632421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getOutputBuffer(index, &buffer);
6337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6344448ac702a70b18da283ce29c21fa6db207974bbSanthosh Behara    if (buffer == NULL) {
6354448ac702a70b18da283ce29c21fa6db207974bbSanthosh Behara        handleError(UNKNOWN_ERROR);
6364448ac702a70b18da283ce29c21fa6db207974bbSanthosh Behara        return false;
6374448ac702a70b18da283ce29c21fa6db207974bbSanthosh Behara    }
6384448ac702a70b18da283ce29c21fa6db207974bbSanthosh Behara
639421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mOutputBuffers.size()) {
640421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
641421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mOutputBuffers.add();
642095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
643095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
644095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
645421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mOutputBuffers.editItemAt(index) = buffer;
646421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
6477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->setRange(offset, size);
6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->clear();
6497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->setInt64("timeUs", timeUs);
65066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
65166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // we do not expect CODECCONFIG or SYNCFRAME for decoder
6537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
655421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    reply->setSize("buffer-ix", index);
6567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setInt32("generation", mBufferGeneration);
6577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
65866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (eos) {
65966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
66066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
66166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        buffer->meta()->setInt32("eos", true);
66266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        reply->setInt32("eos", true);
66366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mSkipRenderingUntilMediaTimeUs >= 0) {
6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
6657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGV("[%s] dropping buffer at time %lld as requested.",
6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     mComponentName.c_str(), (long long)timeUs);
6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->post();
6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return true;
6707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mSkipRenderingUntilMediaTimeUs = -1;
6737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
675e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mNumFramesTotal += !mIsAudio;
676e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
677f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // wait until 1st frame comes out to signal resume complete
678f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
679f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // send the buffer to renderer.
6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->queueBuffer(mIsAudio, buffer, reply);
68366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (eos && !isDiscontinuityPending()) {
6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return true;
6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
691421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
692421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mIsAudio) {
693e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
694e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (format->findInt32("width", &width)
695e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && format->findInt32("height", &height)) {
696e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
697e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
698e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
699421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        sp<AMessage> notify = mNotify->dup();
700421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setInt32("what", kWhatVideoSizeChanged);
701421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setMessage("format", format);
702421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->post();
703421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    } else if (mRenderer != NULL) {
704421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        uint32_t flags;
705421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t durationUs;
706421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
707288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung        if (getAudioDeepBufferSetting() // override regardless of source duration
708288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                || (!hasVideo
709288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && mSource->getDuration(&durationUs) == OK
710288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
711421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
712421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        } else {
713421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_NONE;
714421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        }
715421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
716216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        status_t err = mRenderer->openAudioSink(
717421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
718216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        if (err != OK) {
719216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent            handleError(err);
720216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        }
721421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    }
722421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
723421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
7247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() {
7257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mMediaBuffers[i] != NULL) {
7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers[i]->release();
7287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers.editItemAt(i) = NULL;
7297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mMediaBuffers.resize(mInputBuffers.size());
7327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
7337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mMediaBuffers.editItemAt(i) = NULL;
7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.clear();
7367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.resize(mInputBuffers.size());
7377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
7387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mInputBufferIsDequeued.editItemAt(i) = false;
7397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPendingInputMessages.clear();
7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDequeuedInputBuffers.clear();
7437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mSkipRenderingUntilMediaTimeUs = -1;
7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() {
7477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
7481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
7497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        reply->setInt32("generation", mBufferGeneration);
7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec->requestActivityNotification(reply);
7517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
7557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int32_t generation;
7567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findInt32("generation", &generation));
7577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return generation != mBufferGeneration;
7587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
7617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> accessUnit;
76259e9ca734f4d33fa1698466cdb2b66ab4ea1b82bRobert Shih    bool dropAccessUnit = true;
7637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    do {
7647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
7657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (err == -EWOULDBLOCK) {
7677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return err;
7687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        } else if (err != OK) {
7697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (err == INFO_DISCONTINUITY) {
7707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t type;
7717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
7727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool formatChange =
7747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    (mIsAudio &&
7757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
7767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    || (!mIsAudio &&
7777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
7787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
7807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                ALOGI("%s discontinuity (format=%d, time=%d)",
7827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mIsAudio ? "audio" : "video", formatChange, timeChange);
7837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool seamlessFormatChange = false;
7857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
7867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange) {
7877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    seamlessFormatChange =
7887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        supportsSeamlessFormatChange(newFormat);
7897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // treat seamless format change separately
7907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    formatChange = !seamlessFormatChange;
7917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
7927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
79366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // For format or time change, return EOS to queue EOS input,
79466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // then wait for EOS on output.
7957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange /* not seamless */) {
7967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mFormatChangePending = true;
79766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
7987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (timeChange) {
7997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
80066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    mTimeChangePending = true;
80166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
8027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (seamlessFormatChange) {
8037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // reuse existing decoder and don't flush
8047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
80566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    continue;
8067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else {
8077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // This stream is unaffected by the discontinuity
8087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    return -EWOULDBLOCK;
8097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
8107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
81266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // reply should only be returned without a buffer set
81366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // when there is an error (including EOS)
81466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            CHECK(err != OK);
81566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
8167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->setInt32("err", err);
81766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            return ERROR_END_OF_STREAM;
8187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
8197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        dropAccessUnit = false;
821bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        if (!mIsAudio && !mIsSecure) {
822bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            int32_t layerId = 0;
8239fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
824bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            if (mRenderer->getVideoLateByUs() > 100000ll
825bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    && mIsVideoAVC
826bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    && !IsAVCReferenceFrame(accessUnit)) {
827bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                dropAccessUnit = true;
8289fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) {
829bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                // Add only one layer each time.
830bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                if (layerId > mCurrentMaxVideoTemporalLayerId + 1
831bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                        || layerId >= mNumVideoTemporalLayerAllowed) {
832bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    dropAccessUnit = true;
833bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d",
834bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                            layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed,
835bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                            mCurrentMaxVideoTemporalLayerId);
836bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                } else if (layerId > mCurrentMaxVideoTemporalLayerId) {
837bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    mCurrentMaxVideoTemporalLayerId = layerId;
8389fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1 && IsIDR(accessUnit)) {
8399fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1;
840bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                }
841bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
842bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            if (dropAccessUnit) {
8439fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) {
8449fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    mCurrentMaxVideoTemporalLayerId = layerId - 1;
8459fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                }
846bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                ++mNumInputFramesDropped;
847bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
8487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
8497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } while (dropAccessUnit);
8507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
8527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0
8537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int64_t mediaTimeUs;
8547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
8555abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang    ALOGV("[%s] feeding input buffer at media time %.3f",
8567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mIsAudio ? "audio" : "video",
8577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mediaTimeUs / 1E6);
8587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif
8597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
8617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->decode(accessUnit);
8627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
8637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setBuffer("buffer", accessUnit);
8657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return OK;
8677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
8687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
8707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t bufferIx;
8717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findSize("buffer-ix", &bufferIx));
8727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK_LT(bufferIx, mInputBuffers.size());
8737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
8747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> buffer;
8767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hasBuffer = msg->findBuffer("buffer", &buffer);
8777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // handle widevine classic source - that fills an arbitrary input buffer
8797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    MediaBuffer *mediaBuffer = NULL;
8807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hasBuffer) {
8817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
8827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mediaBuffer != NULL) {
8837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // likely filled another buffer than we requested: adjust buffer index
8847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            size_t ix;
8857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            for (ix = 0; ix < mInputBuffers.size(); ix++) {
8867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                const sp<ABuffer> &buf = mInputBuffers[ix];
8877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (buf->data() == mediaBuffer->data()) {
8887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // all input buffers are dequeued on start, hence the check
8897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    if (!mInputBufferIsDequeued[ix]) {
8907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu",
8917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                mComponentName.c_str(), ix, bufferIx);
8927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mediaBuffer->release();
8937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        return false;
8947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    }
8957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // TRICKY: need buffer for the metadata, so instead, set
8977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // codecBuffer to the same (though incorrect) buffer to
8987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // avoid a memcpy into the codecBuffer
8997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer = buffer;
9007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer->setRange(
9017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_offset(),
9027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_length());
9037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    bufferIx = ix;
9047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    break;
9057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
9067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
9077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(ix < mInputBuffers.size());
9087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
9097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
9107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (buffer == NULL /* includes !hasBuffer */) {
9127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int32_t streamErr = ERROR_END_OF_STREAM;
9137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
9147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
91566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        CHECK(streamErr != OK);
9161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // attempt to queue EOS
9181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
9191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                bufferIx,
9201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                MediaCodec::BUFFER_FLAG_EOS);
924cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        if (err == OK) {
925cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
926cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else if (streamErr == ERROR_END_OF_STREAM) {
9271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            streamErr = err;
9281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            // err will not be ERROR_END_OF_STREAM
9291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (streamErr != ERROR_END_OF_STREAM) {
932cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            ALOGE("Stream error for %s (err=%d), EOS %s queued",
933cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    mComponentName.c_str(),
934cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    streamErr,
935cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    err == OK ? "successfully" : "unsuccessfully");
9361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(streamErr);
9371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
939c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<AMessage> extra;
940c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
941c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            int64_t resumeAtMediaTimeUs;
942c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            if (extra->findInt64(
943c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
944c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                ALOGI("[%s] suppressing rendering until %lld us",
945c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
946c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
947c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            }
948c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        }
949c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
9501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int64_t timeUs = 0;
9511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        uint32_t flags = 0;
9521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
9531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
95487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        int32_t eos, csd;
95587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        // we do not expect SYNCFRAME for decoder
9561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer->meta()->findInt32("eos", &eos) && eos) {
9571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_EOS;
95887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
95987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
9601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // copy into codec buffer
9631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer != codecBuffer) {
96456097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            if (buffer->size() > codecBuffer->capacity()) {
96556097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                handleError(ERROR_BUFFER_TOO_SMALL);
96656097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                mDequeuedInputBuffers.push_back(bufferIx);
96756097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                return false;
96856097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            }
9691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            codecBuffer->setRange(0, buffer->size());
9701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            memcpy(codecBuffer->data(), buffer->data(), buffer->size());
9711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
9741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        bufferIx,
9751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->offset(),
9761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->size(),
9771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        timeUs,
9781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        flags);
9791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (err != OK) {
980cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
981cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mediaBuffer->release();
982cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
9831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            ALOGE("Failed to queue input buffer for %s (err=%d)",
9841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    mComponentName.c_str(), err);
9851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(err);
986cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else {
987cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
988cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
989cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                CHECK(mMediaBuffers[bufferIx] == NULL);
990cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
991cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
992095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
9942245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    return true;
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
9981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    status_t err;
9991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    int32_t render;
10001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    size_t bufferIx;
100166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    int32_t eos;
10021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK(msg->findSize("buffer-ix", &bufferIx));
1003c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
10047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!mIsAudio) {
1005c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        int64_t timeUs;
1006c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<ABuffer> buffer = mOutputBuffers[bufferIx];
1007c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        buffer->meta()->findInt64("timeUs", &timeUs);
10087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
10097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
10107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mCCDecoder->display(timeUs);
10117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1012c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
1013c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
10141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (msg->findInt32("render", &render) && render) {
1015dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        int64_t timestampNs;
1016dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        CHECK(msg->findInt64("timestampNs", &timestampNs));
1017dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
10181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
1019e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        mNumOutputFramesDropped += !mIsAudio;
10201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        err = mCodec->releaseOutputBuffer(bufferIx);
10211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
10221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
10231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("failed to release output buffer for %s (err=%d)",
10241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mComponentName.c_str(), err);
10251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
102766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (msg->findInt32("eos", &eos) && eos
102866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            && isDiscontinuityPending()) {
102966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(true /* flushOnTimeChange */);
103066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
103166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
103266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
103366704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const {
103466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    return mFormatChangePending || mTimeChangePending;
103566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
103666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
103766704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
103866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
103966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
104066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
104166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have format change, pause and wait to be killed;
104266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have time change only, flush and restart fetching.
104366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
104466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (mFormatChangePending) {
104566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        mPaused = true;
104666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mTimeChangePending) {
104766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (flushOnTimeChange) {
1048421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            doFlush(false /* notifyComplete */);
1049421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            signalResume(false /* notifyComplete */);
105066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        }
105166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
105266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
105366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // Notify NuPlayer to either shutdown decoder, or rescan sources
105466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> msg = mNotify->dup();
105566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("what", kWhatInputDiscontinuity);
105666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("formatChange", mFormatChangePending);
105766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->post();
105866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
105966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mFormatChangePending = false;
106066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
10647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &targetFormat) const {
10656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
10666d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
10676d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10686d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10696d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString mime;
10706d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!targetFormat->findString("mime", &mime)) {
10716d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
10726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
10756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        // field-by-field comparison
10766d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
10776d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
10786d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            int32_t oldVal, newVal;
10797abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
10801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    !targetFormat->findInt32(keys[i], &newVal) ||
10811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    oldVal != newVal) {
10826d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
10836d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
10846d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
10856d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        sp<ABuffer> oldBuf, newBuf;
10877abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
10881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                targetFormat->findBuffer("csd-0", &newBuf)) {
10896d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            if (oldBuf->size() != newBuf->size()) {
10906d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
10916d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
10926d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
10936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
10946d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return false;
10966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
10976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10986d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
10997abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (mInputFormat == NULL) {
11006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
11016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11036d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
11046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
11056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString oldMime, newMime;
11087abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (!mInputFormat->findString("mime", &oldMime)
11096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !targetFormat->findString("mime", &newMime)
11106d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !(oldMime == newMime)) {
11116d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
11126d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
11156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool seamless;
11166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (audio) {
11176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        seamless = supportsSeamlessAudioFormatChange(targetFormat);
11186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    } else {
11191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int32_t isAdaptive;
11201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        seamless = (mCodec != NULL &&
11211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
11221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                isAdaptive);
11236d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11246d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11256d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
11266d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return seamless;
11276d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
11286d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
11307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (format == NULL) {
1131a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        return;
1132a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
11337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mCSDsForCurrentFormat.clear();
11347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (int32_t i = 0; ; ++i) {
11357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        AString tag = "csd-";
11367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        tag.append(i);
11377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<ABuffer> buffer;
11387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!format->findBuffer(tag.c_str(), &buffer)) {
11397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
11407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
11417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsForCurrentFormat.push(buffer);
1142a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
1143b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang}
1144b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang
1145f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
1146f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (mResumePending) {
1147f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = false;
1148f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1149f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        sp<AMessage> notify = mNotify->dup();
1150f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->setInt32("what", kWhatResumeCompleted);
1151f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->post();
1152f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
1153f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang}
1154f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157