NuPlayerDecoder.cpp revision 9fb815244cc33927e14ce0fe70539786a611daf9
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
634421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mOutputBuffers.size()) {
635421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
636421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mOutputBuffers.add();
637095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
638095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
639095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
640421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mOutputBuffers.editItemAt(index) = buffer;
641421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
6427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->setRange(offset, size);
6437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->clear();
6447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->setInt64("timeUs", timeUs);
64566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
64666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
6477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // we do not expect CODECCONFIG or SYNCFRAME for decoder
6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
650421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    reply->setSize("buffer-ix", index);
6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setInt32("generation", mBufferGeneration);
6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
65366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (eos) {
65466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
65566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
65666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        buffer->meta()->setInt32("eos", true);
65766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        reply->setInt32("eos", true);
65866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mSkipRenderingUntilMediaTimeUs >= 0) {
6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
6607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGV("[%s] dropping buffer at time %lld as requested.",
6617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     mComponentName.c_str(), (long long)timeUs);
6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->post();
6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return true;
6657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mSkipRenderingUntilMediaTimeUs = -1;
6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
670e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mNumFramesTotal += !mIsAudio;
671e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
672f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // wait until 1st frame comes out to signal resume complete
673f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
674f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
6757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // send the buffer to renderer.
6777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->queueBuffer(mIsAudio, buffer, reply);
67866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (eos && !isDiscontinuityPending()) {
6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return true;
6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
686421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
687421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mIsAudio) {
688e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
689e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (format->findInt32("width", &width)
690e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && format->findInt32("height", &height)) {
691e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
692e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
693e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
694421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        sp<AMessage> notify = mNotify->dup();
695421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setInt32("what", kWhatVideoSizeChanged);
696421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setMessage("format", format);
697421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->post();
698421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    } else if (mRenderer != NULL) {
699421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        uint32_t flags;
700421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t durationUs;
701421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
702288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung        if (getAudioDeepBufferSetting() // override regardless of source duration
703288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                || (!hasVideo
704288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && mSource->getDuration(&durationUs) == OK
705288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
706421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
707421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        } else {
708421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_NONE;
709421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        }
710421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
711216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        status_t err = mRenderer->openAudioSink(
712421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
713216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        if (err != OK) {
714216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent            handleError(err);
715216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent        }
716421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    }
717421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
718421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() {
7207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
7217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mMediaBuffers[i] != NULL) {
7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers[i]->release();
7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers.editItemAt(i) = NULL;
7247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mMediaBuffers.resize(mInputBuffers.size());
7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
7287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mMediaBuffers.editItemAt(i) = NULL;
7297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.clear();
7317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.resize(mInputBuffers.size());
7327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
7337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mInputBufferIsDequeued.editItemAt(i) = false;
7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPendingInputMessages.clear();
7377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDequeuedInputBuffers.clear();
7387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mSkipRenderingUntilMediaTimeUs = -1;
7397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() {
7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
7431d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        reply->setInt32("generation", mBufferGeneration);
7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec->requestActivityNotification(reply);
7467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int32_t generation;
7517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findInt32("generation", &generation));
7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return generation != mBufferGeneration;
7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
7567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> accessUnit;
7577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool dropAccessUnit;
7587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    do {
7597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
7607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (err == -EWOULDBLOCK) {
7627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return err;
7637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        } else if (err != OK) {
7647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (err == INFO_DISCONTINUITY) {
7657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t type;
7667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
7677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool formatChange =
7697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    (mIsAudio &&
7707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
7717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    || (!mIsAudio &&
7727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
7737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
7757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                ALOGI("%s discontinuity (format=%d, time=%d)",
7777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mIsAudio ? "audio" : "video", formatChange, timeChange);
7787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool seamlessFormatChange = false;
7807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
7817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange) {
7827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    seamlessFormatChange =
7837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        supportsSeamlessFormatChange(newFormat);
7847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // treat seamless format change separately
7857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    formatChange = !seamlessFormatChange;
7867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
7877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
78866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // For format or time change, return EOS to queue EOS input,
78966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // then wait for EOS on output.
7907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange /* not seamless */) {
7917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mFormatChangePending = true;
79266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (timeChange) {
7947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
79566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    mTimeChangePending = true;
79666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
7977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (seamlessFormatChange) {
7987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // reuse existing decoder and don't flush
7997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
80066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    continue;
8017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else {
8027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // This stream is unaffected by the discontinuity
8037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    return -EWOULDBLOCK;
8047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
8057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
8067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
80766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // reply should only be returned without a buffer set
80866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // when there is an error (including EOS)
80966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            CHECK(err != OK);
81066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->setInt32("err", err);
81266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            return ERROR_END_OF_STREAM;
8137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
8147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        dropAccessUnit = false;
816bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        if (!mIsAudio && !mIsSecure) {
817bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            int32_t layerId = 0;
8189fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
819bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            if (mRenderer->getVideoLateByUs() > 100000ll
820bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    && mIsVideoAVC
821bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    && !IsAVCReferenceFrame(accessUnit)) {
822bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                dropAccessUnit = true;
8239fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) {
824bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                // Add only one layer each time.
825bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                if (layerId > mCurrentMaxVideoTemporalLayerId + 1
826bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                        || layerId >= mNumVideoTemporalLayerAllowed) {
827bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    dropAccessUnit = true;
828bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d",
829bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                            layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed,
830bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                            mCurrentMaxVideoTemporalLayerId);
831bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                } else if (layerId > mCurrentMaxVideoTemporalLayerId) {
832bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    mCurrentMaxVideoTemporalLayerId = layerId;
8339fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1 && IsIDR(accessUnit)) {
8349fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1;
835bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                }
836bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
837bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            if (dropAccessUnit) {
8389fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) {
8399fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    mCurrentMaxVideoTemporalLayerId = layerId - 1;
8409fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                }
841bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                ++mNumInputFramesDropped;
842bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
8437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
8447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } while (dropAccessUnit);
8457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
8477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0
8487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int64_t mediaTimeUs;
8497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
8505abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang    ALOGV("[%s] feeding input buffer at media time %.3f",
8517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mIsAudio ? "audio" : "video",
8527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mediaTimeUs / 1E6);
8537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif
8547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
8567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->decode(accessUnit);
8577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
8587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setBuffer("buffer", accessUnit);
8607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return OK;
8627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
8637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
8657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t bufferIx;
8667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findSize("buffer-ix", &bufferIx));
8677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK_LT(bufferIx, mInputBuffers.size());
8687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
8697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> buffer;
8717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hasBuffer = msg->findBuffer("buffer", &buffer);
8727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // handle widevine classic source - that fills an arbitrary input buffer
8747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    MediaBuffer *mediaBuffer = NULL;
8757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hasBuffer) {
8767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
8777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mediaBuffer != NULL) {
8787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // likely filled another buffer than we requested: adjust buffer index
8797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            size_t ix;
8807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            for (ix = 0; ix < mInputBuffers.size(); ix++) {
8817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                const sp<ABuffer> &buf = mInputBuffers[ix];
8827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (buf->data() == mediaBuffer->data()) {
8837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // all input buffers are dequeued on start, hence the check
8847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    if (!mInputBufferIsDequeued[ix]) {
8857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu",
8867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                mComponentName.c_str(), ix, bufferIx);
8877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mediaBuffer->release();
8887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        return false;
8897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    }
8907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // TRICKY: need buffer for the metadata, so instead, set
8927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // codecBuffer to the same (though incorrect) buffer to
8937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // avoid a memcpy into the codecBuffer
8947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer = buffer;
8957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer->setRange(
8967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_offset(),
8977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_length());
8987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    bufferIx = ix;
8997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    break;
9007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
9017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
9027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(ix < mInputBuffers.size());
9037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
9047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
9057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (buffer == NULL /* includes !hasBuffer */) {
9077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int32_t streamErr = ERROR_END_OF_STREAM;
9087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
9097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
91066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        CHECK(streamErr != OK);
9111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // attempt to queue EOS
9131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
9141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                bufferIx,
9151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                MediaCodec::BUFFER_FLAG_EOS);
919cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        if (err == OK) {
920cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
921cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else if (streamErr == ERROR_END_OF_STREAM) {
9221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            streamErr = err;
9231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            // err will not be ERROR_END_OF_STREAM
9241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (streamErr != ERROR_END_OF_STREAM) {
927cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            ALOGE("Stream error for %s (err=%d), EOS %s queued",
928cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    mComponentName.c_str(),
929cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    streamErr,
930cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    err == OK ? "successfully" : "unsuccessfully");
9311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(streamErr);
9321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
934c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<AMessage> extra;
935c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
936c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            int64_t resumeAtMediaTimeUs;
937c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            if (extra->findInt64(
938c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
939c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                ALOGI("[%s] suppressing rendering until %lld us",
940c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
941c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
942c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            }
943c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        }
944c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
9451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int64_t timeUs = 0;
9461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        uint32_t flags = 0;
9471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
9481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
94987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        int32_t eos, csd;
95087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        // we do not expect SYNCFRAME for decoder
9511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer->meta()->findInt32("eos", &eos) && eos) {
9521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_EOS;
95387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
95487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
9551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // copy into codec buffer
9581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer != codecBuffer) {
95956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            if (buffer->size() > codecBuffer->capacity()) {
96056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                handleError(ERROR_BUFFER_TOO_SMALL);
96156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                mDequeuedInputBuffers.push_back(bufferIx);
96256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                return false;
96356097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            }
9641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            codecBuffer->setRange(0, buffer->size());
9651cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            memcpy(codecBuffer->data(), buffer->data(), buffer->size());
9661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
9691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        bufferIx,
9701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->offset(),
9711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->size(),
9721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        timeUs,
9731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        flags);
9741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (err != OK) {
975cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
976cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mediaBuffer->release();
977cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
9781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            ALOGE("Failed to queue input buffer for %s (err=%d)",
9791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    mComponentName.c_str(), err);
9801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(err);
981cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else {
982cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
983cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
984cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                CHECK(mMediaBuffers[bufferIx] == NULL);
985cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
986cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
987095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
9892245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    return true;
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
9931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    status_t err;
9941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    int32_t render;
9951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    size_t bufferIx;
99666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    int32_t eos;
9971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK(msg->findSize("buffer-ix", &bufferIx));
998c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
9997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!mIsAudio) {
1000c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        int64_t timeUs;
1001c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<ABuffer> buffer = mOutputBuffers[bufferIx];
1002c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        buffer->meta()->findInt64("timeUs", &timeUs);
10037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
10047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
10057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mCCDecoder->display(timeUs);
10067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1007c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
1008c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
10091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (msg->findInt32("render", &render) && render) {
1010dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        int64_t timestampNs;
1011dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        CHECK(msg->findInt64("timestampNs", &timestampNs));
1012dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
10131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
1014e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        mNumOutputFramesDropped += !mIsAudio;
10151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        err = mCodec->releaseOutputBuffer(bufferIx);
10161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
10171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
10181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("failed to release output buffer for %s (err=%d)",
10191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mComponentName.c_str(), err);
10201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
102266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (msg->findInt32("eos", &eos) && eos
102366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            && isDiscontinuityPending()) {
102466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(true /* flushOnTimeChange */);
102566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
102666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
102766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
102866704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const {
102966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    return mFormatChangePending || mTimeChangePending;
103066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
103166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
103266704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
103366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
103466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
103566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
103666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have format change, pause and wait to be killed;
103766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have time change only, flush and restart fetching.
103866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
103966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (mFormatChangePending) {
104066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        mPaused = true;
104166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mTimeChangePending) {
104266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (flushOnTimeChange) {
1043421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            doFlush(false /* notifyComplete */);
1044421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            signalResume(false /* notifyComplete */);
104566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        }
104666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
104766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
104866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // Notify NuPlayer to either shutdown decoder, or rescan sources
104966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> msg = mNotify->dup();
105066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("what", kWhatInputDiscontinuity);
105166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("formatChange", mFormatChangePending);
105266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->post();
105366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
105466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mFormatChangePending = false;
105566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
10597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &targetFormat) const {
10606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
10616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
10626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString mime;
10656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!targetFormat->findString("mime", &mime)) {
10666d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
10676d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10686d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10696d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
10706d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        // field-by-field comparison
10716d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
10726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
10736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            int32_t oldVal, newVal;
10747abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
10751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    !targetFormat->findInt32(keys[i], &newVal) ||
10761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    oldVal != newVal) {
10776d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
10786d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
10796d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
10806d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10816d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        sp<ABuffer> oldBuf, newBuf;
10827abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
10831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                targetFormat->findBuffer("csd-0", &newBuf)) {
10846d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            if (oldBuf->size() != newBuf->size()) {
10856d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
10866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
10876d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
10886d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
10896d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10906d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return false;
10916d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
10926d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
10947abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (mInputFormat == NULL) {
10956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
10966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
10976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
10986d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
10996d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
11006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString oldMime, newMime;
11037abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (!mInputFormat->findString("mime", &oldMime)
11046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !targetFormat->findString("mime", &newMime)
11056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !(oldMime == newMime)) {
11066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
11076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
11106d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool seamless;
11116d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (audio) {
11126d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        seamless = supportsSeamlessAudioFormatChange(targetFormat);
11136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    } else {
11141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int32_t isAdaptive;
11151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        seamless = (mCodec != NULL &&
11161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
11171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                isAdaptive);
11186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
11216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return seamless;
11226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
11236d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
11257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (format == NULL) {
1126a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        return;
1127a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
11287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mCSDsForCurrentFormat.clear();
11297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (int32_t i = 0; ; ++i) {
11307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        AString tag = "csd-";
11317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        tag.append(i);
11327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<ABuffer> buffer;
11337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!format->findBuffer(tag.c_str(), &buffer)) {
11347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
11357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
11367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsForCurrentFormat.push(buffer);
1137a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
1138b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang}
1139b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang
1140f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
1141f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (mResumePending) {
1142f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = false;
1143f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1144f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        sp<AMessage> notify = mNotify->dup();
1145f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->setInt32("what", kWhatResumeCompleted);
1146f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->post();
1147f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
1148f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang}
1149f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1152