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"
26cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania#include "NuPlayerDrm.h"
27c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h"
28c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h"
29c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
30288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h>
311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h>
327e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
355bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h>
36095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h>
371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h>
40181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang#include <media/stagefright/SurfaceUtils.h>
411de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
421de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h"
447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h"
457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
489fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnarstatic float kDisplayRefreshingRate = 60.f; // TODO: get this from the display
49bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
50bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// The default total video frame rate of a stream when that info is not available from
51bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// the source.
52bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavanstatic float kDefaultVideoFrameRateTotal = 30.f;
53bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
54288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() {
55288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung    return property_get_bool("media.stagefright.audio.deep", false /* default_value */);
56288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung}
57288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung
58f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder(
591173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<AMessage> &notify,
60c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Source> &source,
6168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        pid_t pid,
62f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        uid_t uid,
63c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Renderer> &renderer,
641de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        const sp<Surface> &surface,
657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<CCDecoder> &ccDecoder)
66202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    : DecoderBase(notify),
671de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar      mSurface(surface),
68c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSource(source),
69c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mRenderer(renderer),
707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mCCDecoder(ccDecoder),
7168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu      mPid(pid),
72f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia      mUid(uid),
73c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSkipRenderingUntilMediaTimeUs(-1ll),
747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mNumFramesTotal(0ll),
75e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumInputFramesDropped(0ll),
76e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumOutputFramesDropped(0ll),
77e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoWidth(0),
78e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoHeight(0),
797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsAudio(true),
807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsVideoAVC(false),
817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsSecure(false),
8262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania      mIsEncrypted(false),
8362dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania      mIsEncryptedObservedEarlier(false),
847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mFormatChangePending(false),
8566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang      mTimeChangePending(false),
86bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mFrameRateTotal(kDefaultVideoFrameRateTotal),
87bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mPlaybackSpeed(1.0f),
889fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar      mNumVideoTemporalLayerTotal(1), // decode all layers
89bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mNumVideoTemporalLayerAllowed(1),
90bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan      mCurrentMaxVideoTemporalLayerId(0),
91f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang      mResumePending(false),
921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar      mComponentName("decoder") {
931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper = new ALooper;
949e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen    mCodecLooper->setName("NPDecoder-CL");
951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
96bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    mVideoTemporalLayerAggregateFps[0] = mFrameRateTotal;
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
99f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() {
10037ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia    // Need to stop looper first since mCodec could be accessed on the mDecoderLooper.
10137ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia    stopLooper();
10237ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia    if (mCodec != NULL) {
10337ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia        mCodec->release();
10437ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia    }
1054923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia    releaseAndResetMediaBuffers();
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
108e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const {
109e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-total", mNumFramesTotal);
110e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
111e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
112e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    return mStats;
1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
114095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
115a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnarstatus_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) {
116a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) {
117a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        return BAD_VALUE;
118a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    }
119a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
120a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
121a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
122a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    msg->setObject("surface", surface);
123a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    sp<AMessage> response;
124a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
125a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    if (err == OK && response != NULL) {
126a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        CHECK(response->findInt32("err", &err));
127a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    }
128a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar    return err;
129a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar}
130a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
133095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
1347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
1357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatCodecNotify:
1367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1373b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            int32_t cbID;
1383b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            CHECK(msg->findInt32("callbackID", &cbID));
1393b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
1403b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
1413b032b3865fd93173aadca0591eeea32853206f9Chong Zhang                    mIsAudio ? "audio" : "video", cbID, mPaused);
1423b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            if (mPaused) {
144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                break;
145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            }
146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            switch (cbID) {
148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_INPUT_AVAILABLE:
149421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
150421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
152095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
153421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnInputBuffer(index);
154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_AVAILABLE:
158421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
159421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
160421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t offset;
161421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t size;
162421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int64_t timeUs;
163421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t flags;
164421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
165421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
166421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("offset", &offset));
167421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("size", &size));
168421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt64("timeUs", &timeUs));
169421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("flags", &flags));
170421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
171421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
172421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
174095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
175421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
176421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
177421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    sp<AMessage> format;
178421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findMessage("format", &format));
179421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
180421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleOutputFormatChange(format);
181421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
184421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_ERROR:
185421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
186421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    status_t err;
187421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("err", &err));
188421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    ALOGE("Decoder (%s) reported error : 0x%x",
189421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                            mIsAudio ? "audio" : "video", err);
190421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
191421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleError(err);
192421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
195421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                default:
196421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
197421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    TRESPASS();
198421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
199421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
2007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
2017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
20287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            break;
20387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        }
2047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRenderBuffer:
2067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
2077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (!isStaleReply(msg)) {
2087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                onRenderBuffer(msg);
2097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
2107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
2117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
2127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2139a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia        case kWhatAudioOutputFormatChanged:
2149a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia        {
2159a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia            if (!isStaleReply(msg)) {
2169a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia                status_t err;
2179a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia                if (msg->findInt32("err", &err) && err != OK) {
2189a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia                    ALOGE("Renderer reported 0x%x when changing audio output format", err);
2199a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia                    handleError(err);
2209a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia                }
2219a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia            }
2229a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia            break;
2239a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia        }
2249a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia
225a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        case kWhatSetVideoSurface:
226a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        {
227a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<AReplyToken> replyID;
228a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
229a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
230a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<RefBase> obj;
231a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            CHECK(msg->findObject("surface", &obj));
232a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null
233a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            int32_t err = INVALID_OPERATION;
234a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            // NOTE: in practice mSurface is always non-null, but checking here for completeness
235a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            if (mCodec != NULL && mSurface != NULL) {
236a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // TODO: once AwesomePlayer is removed, remove this automatic connecting
237a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // to the surface by MediaPlayerService.
238a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                //
239a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // at this point MediaPlayerService::client has already connected to the
240a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                // surface, which MediaCodec does not expect
241181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang                err = nativeWindowDisconnect(surface.get(), "kWhatSetVideoSurface(surface)");
242a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                if (err == OK) {
243a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    err = mCodec->setSurface(surface);
244a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    ALOGI_IF(err, "codec setSurface returned: %d", err);
245a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    if (err == OK) {
246a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        // reconnect to the old surface as MPS::Client will expect to
247a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        // be able to disconnect from it.
248181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang                        (void)nativeWindowConnect(mSurface.get(), "kWhatSetVideoSurface(mSurface)");
249a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                        mSurface = surface;
250a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    }
251a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                }
252a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                if (err != OK) {
253a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    // reconnect to the new surface on error as MPS::Client will expect to
254a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                    // be able to disconnect from it.
255181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang                    (void)nativeWindowConnect(surface.get(), "kWhatSetVideoSurface(err)");
256a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar                }
257a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            }
258a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
259a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            sp<AMessage> response = new AMessage;
260a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            response->setInt32("err", err);
261a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            response->postReply(replyID);
262a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            break;
263a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar        }
264a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar
265cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        case kWhatDrmReleaseCrypto:
266cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        {
267cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            ALOGV("kWhatDrmReleaseCrypto");
268cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            onReleaseCrypto(msg);
269cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            break;
270cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        }
271cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
2727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
2737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            DecoderBase::onMessageReceived(msg);
2747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
27587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
27687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
27787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
2781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mCodec == NULL);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mFormatChangePending = false;
28266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
2837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ++mBufferGeneration;
2851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
286840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    AString mime;
287840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    CHECK(format->findString("mime", &mime));
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
2907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
2917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName = mime;
2931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName.append(" decoder");
2941de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
295840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
29668845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    mCodec = MediaCodec::CreateByType(
297f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia            mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid, mUid);
298095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    int32_t secure = 0;
299095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (format->findInt32("secure", &secure) && secure != 0) {
300095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (mCodec != NULL) {
301095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->getName(&mComponentName);
302095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mComponentName.append(".secure");
303095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->release();
304095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            ALOGI("[%s] creating", mComponentName.c_str());
305095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec = MediaCodec::CreateByComponentName(
306f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia                    mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid, mUid);
307095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
308095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
3091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec == NULL) {
310095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        ALOGE("Failed to create %s%s decoder",
311095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                (secure ? "secure " : ""), mime.c_str());
3121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(UNKNOWN_ERROR);
3131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
314840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
3157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsSecure = secure;
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodec->getName(&mComponentName);
3181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
31914986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    status_t err;
3201de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    if (mSurface != NULL) {
3211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // disconnect from surface as MediaCodec will reconnect
322181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang        err = nativeWindowDisconnect(mSurface.get(), "onConfigure");
32314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // We treat this as a warning, as this is a preparatory step.
32414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // Codec will try to connect to the surface, which is where
32514986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // any error signaling will occur.
32614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
3271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
328cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
329cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    // Modular DRM
330cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    void *pCrypto;
331cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    if (!format->findPointer("crypto", &pCrypto)) {
332cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        pCrypto = NULL;
333cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }
334cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    sp<ICrypto> crypto = (ICrypto*)pCrypto;
33562dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania    // non-encrypted source won't have a crypto
33662dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania    mIsEncrypted = (crypto != NULL);
33762dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania    // configure is called once; still using OR in case the behavior changes.
33862dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania    mIsEncryptedObservedEarlier = mIsEncryptedObservedEarlier || mIsEncrypted;
339cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    ALOGV("onConfigure mCrypto: %p (%d)  mIsSecure: %d",
340cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            crypto.get(), (crypto != NULL ? crypto->getStrongCount() : 0), mIsSecure);
341cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
34214986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    err = mCodec->configure(
343cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            format, mSurface, crypto, 0 /* flags */);
344cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
3451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
3461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
3472abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
3482abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
3491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
3501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
3511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
35287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    rememberCodecSpecificData(format);
35387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
3541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    // the following should work in configured state
3551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
3561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
3571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
358e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("mime", mime.c_str());
359e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("component-name", mComponentName.c_str());
360e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
361e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    if (!mIsAudio) {
362e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
363e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (mOutputFormat->findInt32("width", &width)
364e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && mOutputFormat->findInt32("height", &height)) {
365e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
366e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
367e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
368e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    }
369e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
370421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
371421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->setCallback(reply);
372421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
3731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    err = mCodec->start();
3741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
3751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
3762abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
3772abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
3781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
3791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    releaseAndResetMediaBuffers();
383078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
384704e72658b1082264a26a83c50046da34f07d1a1Wei Jia    mPaused = false;
385f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    mResumePending = false;
3861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
387078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
3888db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> &params) {
389bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    bool needAdjustLayers = false;
390bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    float frameRateTotal;
391bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (params->findFloat("frame-rate-total", &frameRateTotal)
392bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && mFrameRateTotal != frameRateTotal) {
393bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        needAdjustLayers = true;
394bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mFrameRateTotal = frameRateTotal;
395bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
396bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
397bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    int32_t numVideoTemporalLayerTotal;
398bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (params->findInt32("temporal-layer-count", &numVideoTemporalLayerTotal)
3999fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            && numVideoTemporalLayerTotal >= 0
400bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && numVideoTemporalLayerTotal <= kMaxNumVideoTemporalLayers
401bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && mNumVideoTemporalLayerTotal != numVideoTemporalLayerTotal) {
402bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        needAdjustLayers = true;
4039fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        mNumVideoTemporalLayerTotal = std::max(numVideoTemporalLayerTotal, 1);
404bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
405bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
4069fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar    if (needAdjustLayers && mNumVideoTemporalLayerTotal > 1) {
407bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        // TODO: For now, layer fps is calculated for some specific architectures.
408bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        // But it really should be extracted from the stream.
409bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mVideoTemporalLayerAggregateFps[0] =
410bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - 1));
411bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) {
412bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            mVideoTemporalLayerAggregateFps[i] =
413bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - i))
414bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                + mVideoTemporalLayerAggregateFps[i - 1];
415bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        }
416bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
417bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
418bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    float playbackSpeed;
419bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (params->findFloat("playback-speed", &playbackSpeed)
420bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            && mPlaybackSpeed != playbackSpeed) {
421bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        needAdjustLayers = true;
422bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mPlaybackSpeed = playbackSpeed;
423bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    }
424bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
425bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan    if (needAdjustLayers) {
4269fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        float decodeFrameRate = mFrameRateTotal;
4279fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        // enable temporal layering optimization only if we know the layering depth
4289fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        if (mNumVideoTemporalLayerTotal > 1) {
4299fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            int32_t layerId;
4309fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            for (layerId = 0; layerId < mNumVideoTemporalLayerTotal - 1; ++layerId) {
4319fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                if (mVideoTemporalLayerAggregateFps[layerId] * mPlaybackSpeed
4329fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                        >= kDisplayRefreshingRate * 0.9) {
4339fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    break;
4349fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                }
435bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
4369fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            mNumVideoTemporalLayerAllowed = layerId + 1;
4379fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            decodeFrameRate = mVideoTemporalLayerAggregateFps[layerId];
438bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        }
4399fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        ALOGV("onSetParameters: allowed layers=%d, decodeFps=%g",
4409fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                mNumVideoTemporalLayerAllowed, decodeFrameRate);
441bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
442bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        if (mCodec == NULL) {
443bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            ALOGW("onSetParameters called before codec is created.");
444bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            return;
445bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        }
446bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan
447bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        sp<AMessage> codecParams = new AMessage();
4489fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar        codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed);
449bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan        mCodec->setParameters(codecParams);
4508db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
4518db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu}
4528db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
4537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
4547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mRenderer = renderer;
4557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
4562245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
457f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) {
4587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPaused = false;
459f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
460f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (notifyComplete) {
461f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = true;
462f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
463421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->start();
464095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
465095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
46666704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) {
4677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
4687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->flush();
4697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
4727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->flush(mIsAudio, notifyComplete);
4737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->signalTimeDiscontinuity();
4747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
4771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec != NULL) {
4787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->flush();
4797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
4807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
481078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber    }
482078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
4837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
4847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
4857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
4867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatFlushCompleted.
4877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // we attempt to release the buffers even if flush fails.
4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
490421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mPaused = true;
49166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
49466704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() {
49566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    doFlush(true);
49666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
49766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
49866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // This could happen if the client starts seeking/shutdown
49966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // after we queued an EOS for discontinuities.
50066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // We can consider discontinuity handled.
50166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(false /* flushOnTimeChange */);
5027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
50366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
50466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> notify = mNotify->dup();
50566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->setInt32("what", kWhatFlushCompleted);
50666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->post();
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) {
5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
511f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
512f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // if there is a pending resume request, notify complete now
513f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
514f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
5157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
5167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->release();
5177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec = NULL;
5187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
5191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
5201de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        if (mSurface != NULL) {
5217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // reconnect to surface as MediaCodec disconnected from it
522181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang            status_t error = nativeWindowConnect(mSurface.get(), "onShutdown");
5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGW_IF(error != NO_ERROR,
5247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    "[%s] failed to connect to native window, error=%d",
5257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), error);
5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mComponentName = "decoder";
5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatShutdownCompleted.
5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
537c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
5387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (notifyComplete) {
5397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> notify = mNotify->dup();
5407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->setInt32("what", kWhatShutdownCompleted);
5417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->post();
5427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mPaused = true;
5437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
54487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
54587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
5463b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/*
5473b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data
5483b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */
5493b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() {
55029b7dcf6d3cdb97103467dc8106151c6260c239aJeff Tinker    if (isDiscontinuityPending()) {
5513b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        return false;
5527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
55466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    while (err == OK && !mDequeuedInputBuffers.empty()) {
5557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        size_t bufferIx = *mDequeuedInputBuffers.begin();
5567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
5577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setSize("buffer-ix", bufferIx);
5587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = fetchInputData(msg);
55966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (err != OK && err != ERROR_END_OF_STREAM) {
56066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // if EOS, need to queue EOS buffer
5617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
5647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mPendingInputMessages.empty()
5667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                || !onInputBufferFetched(msg)) {
5677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mPendingInputMessages.push_back(msg);
5687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
570095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
5713b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    return err == -EWOULDBLOCK
5723b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            && mSource->feedMoreTSData() == OK;
573095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
574095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
575421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err)
576421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{
577421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // We cannot immediately release the codec due to buffers still outstanding
578421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // in the renderer.  We signal to the player the error so it can shutdown/release the
579421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // decoder after flushing and increment the generation to discard unnecessary messages.
580421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
581421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    ++mBufferGeneration;
582421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
583421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> notify = mNotify->dup();
584421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("what", kWhatError);
585421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("err", err);
586421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->post();
587421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
588421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
589cefac14261a32fb856b0d1ab31541787112e306eHassan Shojaniastatus_t NuPlayer::Decoder::releaseCrypto()
590cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania{
591cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    ALOGV("releaseCrypto");
592cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
593cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this);
594cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
595cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    sp<AMessage> response;
596cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    status_t status = msg->postAndAwaitResponse(&response);
597cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    if (status == OK && response != NULL) {
598cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        CHECK(response->findInt32("status", &status));
599cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGV("releaseCrypto ret: %d ", status);
600cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    } else {
601cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGE("releaseCrypto err: %d", status);
602cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }
603cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
604cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    return status;
605cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania}
606cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
607cefac14261a32fb856b0d1ab31541787112e306eHassan Shojaniavoid NuPlayer::Decoder::onReleaseCrypto(const sp<AMessage>& msg)
608cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania{
609cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    status_t status = INVALID_OPERATION;
610cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    if (mCodec != NULL) {
611cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        status = mCodec->releaseCrypto();
612cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    } else {
613cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        // returning OK if the codec has been already released
614cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        status = OK;
615cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGE("onReleaseCrypto No mCodec. err: %d", status);
616cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }
617cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
618cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    sp<AMessage> response = new AMessage;
619cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    response->setInt32("status", status);
62062dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania    // Clearing the state as it's tied to crypto. mIsEncryptedObservedEarlier is sticky though
62162dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania    // and lasts for the lifetime of this codec. See its use in fetchInputData.
62262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania    mIsEncrypted = false;
623cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
624cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    sp<AReplyToken> replyID;
625cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    CHECK(msg->senderAwaitsResponse(&replyID));
626cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    response->postReply(replyID);
627cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania}
628cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
629421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) {
63066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
6317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return false;
6327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
633421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
6347e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
635421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getInputBuffer(index, &buffer);
636421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
6376301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    if (buffer == NULL) {
6386301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        handleError(UNKNOWN_ERROR);
6396301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        return false;
6406301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    }
6416301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia
642421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mInputBuffers.size()) {
643421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
644421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBuffers.add();
645421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.add();
646421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.add();
647421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.editItemAt(i) = NULL;
648421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.editItemAt(i) = false;
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
651421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBuffers.editItemAt(index) = buffer;
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
653421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    //CHECK_LT(bufferIx, mInputBuffers.size());
6541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
655421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (mMediaBuffers[index] != NULL) {
656421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers[index]->release();
657421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers.editItemAt(index) = NULL;
658095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
659421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBufferIsDequeued.editItemAt(index) = true;
660095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
66187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    if (!mCSDsToSubmit.isEmpty()) {
6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
663421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        msg->setSize("buffer-ix", index);
6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
66587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
66687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setBuffer("buffer", buffer);
66887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        mCSDsToSubmit.removeAt(0);
66956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia        if (!onInputBufferFetched(msg)) {
67056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            handleError(UNKNOWN_ERROR);
67156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            return false;
67256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia        }
6732245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        return true;
6742245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
6752245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
6762245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    while (!mPendingInputMessages.empty()) {
6772245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        sp<AMessage> msg = *mPendingInputMessages.begin();
6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!onInputBufferFetched(msg)) {
6792245fc625910e47d1ba3c339e205c21ab58a47adWei Jia            break;
6802245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        }
6812245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        mPendingInputMessages.erase(mPendingInputMessages.begin());
6822245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
6832245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
684421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mInputBufferIsDequeued.editItemAt(index)) {
68587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        return true;
68687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
68787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
688421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mDequeuedInputBuffers.push_back(index);
6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    onRequestInputBuffers();
6911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    return true;
6921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
6931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
694421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer(
695421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t index,
696421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t offset,
697421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t size,
698421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t timeUs,
699421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int32_t flags) {
700421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen//    CHECK_LT(bufferIx, mOutputBuffers.size());
7017e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
702421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getOutputBuffer(index, &buffer);
7037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7043539defd032864d33eed6add4820552f6fc4349bSanthosh Behara    if (buffer == NULL) {
7053539defd032864d33eed6add4820552f6fc4349bSanthosh Behara        handleError(UNKNOWN_ERROR);
7063539defd032864d33eed6add4820552f6fc4349bSanthosh Behara        return false;
7073539defd032864d33eed6add4820552f6fc4349bSanthosh Behara    }
7083539defd032864d33eed6add4820552f6fc4349bSanthosh Behara
709421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mOutputBuffers.size()) {
710421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
711421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mOutputBuffers.add();
712095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
713095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
714095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
715421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mOutputBuffers.editItemAt(index) = buffer;
716421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
7177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->setRange(offset, size);
7187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->clear();
7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->setInt64("timeUs", timeUs);
72066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
72166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // we do not expect CODECCONFIG or SYNCFRAME for decoder
7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
725421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    reply->setSize("buffer-ix", index);
7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setInt32("generation", mBufferGeneration);
7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
72866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (eos) {
72966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
73066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
73166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        buffer->meta()->setInt32("eos", true);
73266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        reply->setInt32("eos", true);
73366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mSkipRenderingUntilMediaTimeUs >= 0) {
7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGV("[%s] dropping buffer at time %lld as requested.",
7367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     mComponentName.c_str(), (long long)timeUs);
7377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->post();
7397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return true;
7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mSkipRenderingUntilMediaTimeUs = -1;
7437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
745e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mNumFramesTotal += !mIsAudio;
746e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
747f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // wait until 1st frame comes out to signal resume complete
748f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
749f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
7517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // send the buffer to renderer.
7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->queueBuffer(mIsAudio, buffer, reply);
75366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (eos && !isDiscontinuityPending()) {
7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
7557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return true;
7597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
761421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
762421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mIsAudio) {
763e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
764e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (format->findInt32("width", &width)
765e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && format->findInt32("height", &height)) {
766e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
767e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
768e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
769421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        sp<AMessage> notify = mNotify->dup();
770421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setInt32("what", kWhatVideoSizeChanged);
771421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setMessage("format", format);
772421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->post();
773421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    } else if (mRenderer != NULL) {
774421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        uint32_t flags;
775421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t durationUs;
776421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
777288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung        if (getAudioDeepBufferSetting() // override regardless of source duration
77871c8e5c9565af4745cfd7ff0e327da1a27d77bf7Andy Hung                || (mSource->getDuration(&durationUs) == OK
779288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
780421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
781421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        } else {
782421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_NONE;
783421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        }
784421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
7859a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia        sp<AMessage> reply = new AMessage(kWhatAudioOutputFormatChanged, this);
7869a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia        reply->setInt32("generation", mBufferGeneration);
7879a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia        mRenderer->changeAudioFormat(
788c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar                format, false /* offloadOnly */, hasVideo,
789c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar                flags, mSource->isStreaming(), reply);
790421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    }
791421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
792421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() {
7947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
7957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mMediaBuffers[i] != NULL) {
7967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers[i]->release();
7977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers.editItemAt(i) = NULL;
7987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
8007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mMediaBuffers.resize(mInputBuffers.size());
8017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
8027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mMediaBuffers.editItemAt(i) = NULL;
8037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
8047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.clear();
8057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.resize(mInputBuffers.size());
8067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
8077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mInputBufferIsDequeued.editItemAt(i) = false;
8087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
8097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPendingInputMessages.clear();
8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDequeuedInputBuffers.clear();
8127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mSkipRenderingUntilMediaTimeUs = -1;
8137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
8147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() {
8167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
8171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
8187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        reply->setInt32("generation", mBufferGeneration);
8197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec->requestActivityNotification(reply);
8207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
8217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
8227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
8247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int32_t generation;
8257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findInt32("generation", &generation));
8267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return generation != mBufferGeneration;
8277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
8287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
8307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> accessUnit;
83159e9ca734f4d33fa1698466cdb2b66ab4ea1b82bRobert Shih    bool dropAccessUnit = true;
8327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    do {
8337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
8347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (err == -EWOULDBLOCK) {
8367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return err;
8377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        } else if (err != OK) {
8387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (err == INFO_DISCONTINUITY) {
8397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t type;
8407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
8417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool formatChange =
8437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    (mIsAudio &&
8447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
8457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    || (!mIsAudio &&
8467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
8477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
8497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                ALOGI("%s discontinuity (format=%d, time=%d)",
8517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mIsAudio ? "audio" : "video", formatChange, timeChange);
8527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool seamlessFormatChange = false;
8547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
8557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange) {
8567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    seamlessFormatChange =
8577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        supportsSeamlessFormatChange(newFormat);
8587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // treat seamless format change separately
8597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    formatChange = !seamlessFormatChange;
8607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
8617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
86266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // For format or time change, return EOS to queue EOS input,
86366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // then wait for EOS on output.
8647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange /* not seamless */) {
8657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mFormatChangePending = true;
86666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
8677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (timeChange) {
8687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
86966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    mTimeChangePending = true;
87066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
8717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (seamlessFormatChange) {
8727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // reuse existing decoder and don't flush
8737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
87466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    continue;
8757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else {
8767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // This stream is unaffected by the discontinuity
8777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    return -EWOULDBLOCK;
8787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
8797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
8807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
88166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // reply should only be returned without a buffer set
88266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // when there is an error (including EOS)
88366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            CHECK(err != OK);
88466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
8857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->setInt32("err", err);
88666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            return ERROR_END_OF_STREAM;
8877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
8887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        dropAccessUnit = false;
89062dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania        if (!mIsAudio && !mIsEncrypted) {
89162dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            // Extra safeguard if higher-level behavior changes. Otherwise, not required now.
89262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            // Preventing the buffer from being processed (and sent to codec) if this is a later
89362dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            // round of playback but this time without prepareDrm. Or if there is a race between
89462dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            // stop (which is not blocking) and releaseDrm allowing buffers being processed after
89562dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            // Crypto has been released (GenericSource currently prevents this race though).
89662dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            // Particularly doing this check before IsAVCReferenceFrame call to prevent parsing
89762dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            // of encrypted data.
89862dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            if (mIsEncryptedObservedEarlier) {
89962dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania                ALOGE("fetchInputData: mismatched mIsEncrypted/mIsEncryptedObservedEarlier (0/1)");
90062dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania
90162dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania                return INVALID_OPERATION;
90262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania            }
90362dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania
904bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            int32_t layerId = 0;
9059fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
906bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            if (mRenderer->getVideoLateByUs() > 100000ll
907bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    && mIsVideoAVC
908bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    && !IsAVCReferenceFrame(accessUnit)) {
909bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                dropAccessUnit = true;
9109fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar            } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) {
911bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                // Add only one layer each time.
912bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                if (layerId > mCurrentMaxVideoTemporalLayerId + 1
913bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                        || layerId >= mNumVideoTemporalLayerAllowed) {
914bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    dropAccessUnit = true;
915bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d",
916bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                            layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed,
917bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                            mCurrentMaxVideoTemporalLayerId);
918bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                } else if (layerId > mCurrentMaxVideoTemporalLayerId) {
919bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                    mCurrentMaxVideoTemporalLayerId = layerId;
9209fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1 && IsIDR(accessUnit)) {
9219fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1;
922bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                }
923bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
924bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            if (dropAccessUnit) {
9259fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) {
9269fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                    mCurrentMaxVideoTemporalLayerId = layerId - 1;
9279fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar                }
928bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan                ++mNumInputFramesDropped;
929bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan            }
9307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
9317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } while (dropAccessUnit);
9327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
9347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0
9357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int64_t mediaTimeUs;
9367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
9375abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang    ALOGV("[%s] feeding input buffer at media time %.3f",
9387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mIsAudio ? "audio" : "video",
9397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mediaTimeUs / 1E6);
9407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif
9417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
9437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->decode(accessUnit);
9447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
9457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setBuffer("buffer", accessUnit);
9477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return OK;
9497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
9507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
9527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t bufferIx;
9537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findSize("buffer-ix", &bufferIx));
9547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK_LT(bufferIx, mInputBuffers.size());
9557e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> codecBuffer = mInputBuffers[bufferIx];
9567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> buffer;
9587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hasBuffer = msg->findBuffer("buffer", &buffer);
9597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    bool needsCopy = true;
9607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
9617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (buffer == NULL /* includes !hasBuffer */) {
9627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int32_t streamErr = ERROR_END_OF_STREAM;
9637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
9647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
96566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        CHECK(streamErr != OK);
9661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // attempt to queue EOS
9681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
9691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                bufferIx,
9701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
9731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                MediaCodec::BUFFER_FLAG_EOS);
974cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        if (err == OK) {
975cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
976cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else if (streamErr == ERROR_END_OF_STREAM) {
9771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            streamErr = err;
9781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            // err will not be ERROR_END_OF_STREAM
9791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
9811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (streamErr != ERROR_END_OF_STREAM) {
982cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            ALOGE("Stream error for %s (err=%d), EOS %s queued",
983cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    mComponentName.c_str(),
984cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    streamErr,
985cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    err == OK ? "successfully" : "unsuccessfully");
9861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(streamErr);
9871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
9881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
989c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<AMessage> extra;
990c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
991c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            int64_t resumeAtMediaTimeUs;
992c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            if (extra->findInt64(
993c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
994c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                ALOGI("[%s] suppressing rendering until %lld us",
995c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
996c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
997c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            }
998c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        }
999c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
10001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int64_t timeUs = 0;
10011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        uint32_t flags = 0;
10021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
10031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
100487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        int32_t eos, csd;
100587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        // we do not expect SYNCFRAME for decoder
10061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer->meta()->findInt32("eos", &eos) && eos) {
10071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_EOS;
100887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
100987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
10101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
10111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
1012cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        // Modular DRM
1013cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        MediaBuffer *mediaBuf = NULL;
1014cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        NuPlayerDrm::CryptoInfo *cryptInfo = NULL;
1015cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
10161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // copy into codec buffer
10177e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        if (needsCopy) {
101856097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            if (buffer->size() > codecBuffer->capacity()) {
101956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                handleError(ERROR_BUFFER_TOO_SMALL);
102056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                mDequeuedInputBuffers.push_back(bufferIx);
102156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia                return false;
102256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia            }
10231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
1024cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            if (buffer->data() != NULL) {
1025cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                codecBuffer->setRange(0, buffer->size());
1026cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                memcpy(codecBuffer->data(), buffer->data(), buffer->size());
1027cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            } else { // No buffer->data()
1028cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                //Modular DRM
1029cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                mediaBuf = (MediaBuffer*)buffer->getMediaBufferBase();
1030cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                if (mediaBuf != NULL) {
1031cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    codecBuffer->setRange(0, mediaBuf->size());
1032cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
1033cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
1034cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    sp<MetaData> meta_data = mediaBuf->meta_data();
1035cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    cryptInfo = NuPlayerDrm::getSampleCryptoInfo(meta_data);
1036cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
1037cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    // since getMediaBuffer() has incremented the refCount
1038cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    mediaBuf->release();
1039cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                } else { // No mediaBuf
1040cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p",
1041cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                            buffer.get());
1042cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    handleError(UNKNOWN_ERROR);
1043cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    return false;
1044cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                }
1045cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            } // buffer->data()
1046cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        } // needsCopy
1047cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
1048cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        status_t err;
1049cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        AString errorDetailMsg;
1050cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        if (cryptInfo != NULL) {
1051cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            err = mCodec->queueSecureInputBuffer(
1052cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    bufferIx,
1053cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    codecBuffer->offset(),
1054cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    cryptInfo->subSamples,
1055cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    cryptInfo->numSubSamples,
1056cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    cryptInfo->key,
1057cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    cryptInfo->iv,
1058cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    cryptInfo->mode,
1059cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    cryptInfo->pattern,
1060cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    timeUs,
1061cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    flags,
1062cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    &errorDetailMsg);
1063cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            // synchronous call so done with cryptInfo here
1064cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            free(cryptInfo);
1065cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        } else {
1066cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            err = mCodec->queueInputBuffer(
1067cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    bufferIx,
1068cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    codecBuffer->offset(),
1069cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    codecBuffer->size(),
1070cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    timeUs,
1071cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    flags,
1072cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    &errorDetailMsg);
1073cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        } // no cryptInfo
1074cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
10751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (err != OK) {
1076cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania            ALOGE("onInputBufferFetched: queue%sInputBuffer failed for %s (err=%d, %s)",
1077cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    (cryptInfo != NULL ? "Secure" : ""),
1078cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                    mComponentName.c_str(), err, errorDetailMsg.c_str());
10791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(err);
1080cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else {
1081cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
1082095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
1083cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
1084cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }   // buffer != NULL
10852245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    return true;
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
10891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    status_t err;
10901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    int32_t render;
10911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    size_t bufferIx;
109266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    int32_t eos;
10931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK(msg->findSize("buffer-ix", &bufferIx));
1094c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
10957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!mIsAudio) {
1096c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        int64_t timeUs;
10977e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        sp<MediaCodecBuffer> buffer = mOutputBuffers[bufferIx];
1098c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        buffer->meta()->findInt64("timeUs", &timeUs);
10997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
11007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
11017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mCCDecoder->display(timeUs);
11027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1103c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
1104c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
11051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (msg->findInt32("render", &render) && render) {
1106dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        int64_t timestampNs;
1107dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        CHECK(msg->findInt64("timestampNs", &timestampNs));
1108dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
11091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
1110e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        mNumOutputFramesDropped += !mIsAudio;
11111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        err = mCodec->releaseOutputBuffer(bufferIx);
11121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
11131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
11141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("failed to release output buffer for %s (err=%d)",
11151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mComponentName.c_str(), err);
11161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
111866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (msg->findInt32("eos", &eos) && eos
111966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            && isDiscontinuityPending()) {
112066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(true /* flushOnTimeChange */);
112166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
112266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
112366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
112466704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const {
112566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    return mFormatChangePending || mTimeChangePending;
112666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
112766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
112866704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
112966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
113066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
113166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
113266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have format change, pause and wait to be killed;
113366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have time change only, flush and restart fetching.
113466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
113566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (mFormatChangePending) {
113666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        mPaused = true;
113766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mTimeChangePending) {
113866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (flushOnTimeChange) {
1139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            doFlush(false /* notifyComplete */);
1140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            signalResume(false /* notifyComplete */);
114166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        }
114266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
114366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
114466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // Notify NuPlayer to either shutdown decoder, or rescan sources
114566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> msg = mNotify->dup();
114666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("what", kWhatInputDiscontinuity);
114766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("formatChange", mFormatChangePending);
114866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->post();
114966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
115066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mFormatChangePending = false;
115166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
11557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &targetFormat) const {
11566d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
11576d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
11586d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11596d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString mime;
11616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!targetFormat->findString("mime", &mime)) {
11626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
11636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
11666d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        // field-by-field comparison
11676d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
11686d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
11696d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            int32_t oldVal, newVal;
11707abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
11711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    !targetFormat->findInt32(keys[i], &newVal) ||
11721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    oldVal != newVal) {
11736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
11746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
11756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
11766d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11776d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        sp<ABuffer> oldBuf, newBuf;
11787abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
11791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                targetFormat->findBuffer("csd-0", &newBuf)) {
11806d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            if (oldBuf->size() != newBuf->size()) {
11816d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
11826d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
11836d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
11846d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
11856d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return false;
11876d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
11886d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11896d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
11907abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (mInputFormat == NULL) {
11916d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
11926d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11946d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
11956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
11966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
11976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
11986d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString oldMime, newMime;
11997abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (!mInputFormat->findString("mime", &oldMime)
12006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !targetFormat->findString("mime", &newMime)
12016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !(oldMime == newMime)) {
12026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
12036d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
12046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
12056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
12066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool seamless;
12076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (audio) {
12086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        seamless = supportsSeamlessAudioFormatChange(targetFormat);
12096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    } else {
12101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int32_t isAdaptive;
12111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        seamless = (mCodec != NULL &&
12121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
12131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                isAdaptive);
12146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
12156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
12166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
12176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return seamless;
12186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
12196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
12207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
12217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (format == NULL) {
1222a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        return;
1223a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
12247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mCSDsForCurrentFormat.clear();
12257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (int32_t i = 0; ; ++i) {
12267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        AString tag = "csd-";
12277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        tag.append(i);
12287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<ABuffer> buffer;
12297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!format->findBuffer(tag.c_str(), &buffer)) {
12307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
12317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
12327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsForCurrentFormat.push(buffer);
1233a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
1234b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang}
1235b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang
1236f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
1237f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (mResumePending) {
1238f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = false;
1239f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1240f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        sp<AMessage> notify = mNotify->dup();
1241f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->setInt32("what", kWhatResumeCompleted);
1242f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->post();
1243f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
1244f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang}
1245f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1248