NuPlayerDecoder.cpp revision e1e5d7a3d3d4d6d644e6c731f977422e004140d5
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/*
27137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * Copyright 2014 The Android Open Source Project
3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License.
6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at
7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software
11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and
14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License.
15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */
16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "NuPlayerDecoder"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h>
201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <inttypes.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerCCDecoder.h"
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h"
24c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h"
25c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h"
26c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
27288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h>
281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h>
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
315bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h>
32095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h>
331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
381de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h"
407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h"
417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() {
45288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung    return property_get_bool("media.stagefright.audio.deep", false /* default_value */);
46288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung}
47288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung
48f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder(
491173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<AMessage> &notify,
50c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Source> &source,
51c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Renderer> &renderer,
521de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        const sp<Surface> &surface,
537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<CCDecoder> &ccDecoder)
54202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    : DecoderBase(notify),
551de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar      mSurface(surface),
56c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSource(source),
57c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mRenderer(renderer),
587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mCCDecoder(ccDecoder),
59c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSkipRenderingUntilMediaTimeUs(-1ll),
607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mNumFramesTotal(0ll),
61e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumInputFramesDropped(0ll),
62e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mNumOutputFramesDropped(0ll),
63e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoWidth(0),
64e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan      mVideoHeight(0),
657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsAudio(true),
667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsVideoAVC(false),
677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsSecure(false),
687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mFormatChangePending(false),
6966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang      mTimeChangePending(false),
70704e72658b1082264a26a83c50046da34f07d1a1Wei Jia      mPaused(true),
71f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang      mResumePending(false),
721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar      mComponentName("decoder") {
731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper = new ALooper;
749e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen    mCodecLooper->setName("NPDecoder-CL");
751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() {
79faeb0f291330134dc4468359a36e099aae508449Ronghua Wu    mCodec->release();
804923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia    releaseAndResetMediaBuffers();
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
83e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const {
84e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-total", mNumFramesTotal);
85e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
86e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
87e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    return mStats;
887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
89095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
92095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatCodecNotify:
957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
963b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            int32_t cbID;
973b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            CHECK(msg->findInt32("callbackID", &cbID));
983b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
993b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
1003b032b3865fd93173aadca0591eeea32853206f9Chong Zhang                    mIsAudio ? "audio" : "video", cbID, mPaused);
1013b032b3865fd93173aadca0591eeea32853206f9Chong Zhang
102421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            if (mPaused) {
103421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                break;
104421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            }
105421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
106421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            switch (cbID) {
107421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_INPUT_AVAILABLE:
108421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
109421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
110421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
111095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
112421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnInputBuffer(index);
113421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
114421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
115421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
116421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_AVAILABLE:
117421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
118421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t index;
119421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t offset;
120421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    size_t size;
121421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int64_t timeUs;
122421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    int32_t flags;
123421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
124421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("index", &index));
125421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("offset", &offset));
126421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findSize("size", &size));
127421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt64("timeUs", &timeUs));
128421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("flags", &flags));
129421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
130421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
131421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
133095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
134421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
135421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
136421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    sp<AMessage> format;
137421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findMessage("format", &format));
138421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleOutputFormatChange(format);
140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                case MediaCodec::CB_ERROR:
144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    status_t err;
146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    CHECK(msg->findInt32("err", &err));
147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    ALOGE("Decoder (%s) reported error : 0x%x",
148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                            mIsAudio ? "audio" : "video", err);
149421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
150421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    handleError(err);
151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
1527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
1537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                default:
155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                {
156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    TRESPASS();
157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                    break;
158421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                }
1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
16187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            break;
16287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        }
1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRenderBuffer:
1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (!isStaleReply(msg)) {
1677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                onRenderBuffer(msg);
1687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            DecoderBase::onMessageReceived(msg);
1747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
17587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
17687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
17787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
1781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mCodec == NULL);
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mFormatChangePending = false;
18266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ++mBufferGeneration;
1851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
186840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    AString mime;
187840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    CHECK(format->findString("mime", &mime));
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
1907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
1917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName = mime;
1931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName.append(" decoder");
1941de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
195840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */);
197095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    int32_t secure = 0;
198095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (format->findInt32("secure", &secure) && secure != 0) {
199095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (mCodec != NULL) {
200095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->getName(&mComponentName);
201095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mComponentName.append(".secure");
202095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->release();
203095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            ALOGI("[%s] creating", mComponentName.c_str());
204095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec = MediaCodec::CreateByComponentName(
205095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                    mCodecLooper, mComponentName.c_str());
206095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
207095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
2081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec == NULL) {
209095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        ALOGE("Failed to create %s%s decoder",
210095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                (secure ? "secure " : ""), mime.c_str());
2111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(UNKNOWN_ERROR);
2121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
213840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
2147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsSecure = secure;
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodec->getName(&mComponentName);
2171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
21814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    status_t err;
2191de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar    if (mSurface != NULL) {
2201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // disconnect from surface as MediaCodec will reconnect
22114986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        err = native_window_api_disconnect(
2221de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar                mSurface.get(), NATIVE_WINDOW_API_MEDIA);
22314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // We treat this as a warning, as this is a preparatory step.
22414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // Codec will try to connect to the surface, which is where
22514986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // any error signaling will occur.
22614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
2271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
22814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    err = mCodec->configure(
2291de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            format, mSurface, NULL /* crypto */, 0 /* flags */);
2301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
2311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
2322abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
2332abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
2341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
2351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
2361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
23787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    rememberCodecSpecificData(format);
23887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
2391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    // the following should work in configured state
2401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
2411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
2421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
243e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("mime", mime.c_str());
244e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mStats->setString("component-name", mComponentName.c_str());
245e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
246e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    if (!mIsAudio) {
247e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
248e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (mOutputFormat->findInt32("width", &width)
249e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && mOutputFormat->findInt32("height", &height)) {
250e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
251e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
252e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
253e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    }
254e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
255421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
256421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->setCallback(reply);
257421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
2581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    err = mCodec->start();
2591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
2601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
2612abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
2622abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
2631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
2641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    releaseAndResetMediaBuffers();
268078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
269704e72658b1082264a26a83c50046da34f07d1a1Wei Jia    mPaused = false;
270f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    mResumePending = false;
2711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
272078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
2738db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> &params) {
2748db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (mCodec == NULL) {
2758db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        ALOGW("onSetParameters called before codec is created.");
2768db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        return;
2778db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
2788db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mCodec->setParameters(params);
2798db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu}
2808db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
2817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
2827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hadNoRenderer = (mRenderer == NULL);
2837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mRenderer = renderer;
2847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hadNoRenderer && mRenderer != NULL) {
285e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar        // this means that the widevine legacy source is ready
286e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar        onRequestInputBuffers();
28781e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia    }
2887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
2897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers(
2917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        Vector<sp<ABuffer> > *dstBuffers) {
292e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers));
2937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
2942245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
295f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) {
2967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPaused = false;
297f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
298f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (notifyComplete) {
299f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = true;
300f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
301421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->start();
302095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
303095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
30466704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) {
3057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
3067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->flush();
3077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
3107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->flush(mIsAudio, notifyComplete);
3117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->signalTimeDiscontinuity();
3127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
3151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec != NULL) {
3167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->flush();
3177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
3187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
319078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber    }
320078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
3217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
3227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
3237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
3247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatFlushCompleted.
3257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // we attempt to release the buffers even if flush fails.
3267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
328421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mPaused = true;
32966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
33266704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() {
33366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    doFlush(true);
33466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
33566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
33666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // This could happen if the client starts seeking/shutdown
33766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // after we queued an EOS for discontinuities.
33866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        // We can consider discontinuity handled.
33966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(false /* flushOnTimeChange */);
3407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
34166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
34266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> notify = mNotify->dup();
34366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->setInt32("what", kWhatFlushCompleted);
34466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    notify->post();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) {
3487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
349f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
350f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // if there is a pending resume request, notify complete now
351f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
352f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
3537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
3547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->release();
3557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec = NULL;
3567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
3571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
3581de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        if (mSurface != NULL) {
3597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // reconnect to surface as MediaCodec disconnected from it
3607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            status_t error =
3611de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar                    native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
3627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGW_IF(error != NO_ERROR,
3637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    "[%s] failed to connect to native window, error=%d",
3647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), error);
3657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
3667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mComponentName = "decoder";
3677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
3707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
3727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
3737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
3747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatShutdownCompleted.
3757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
376c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
3777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (notifyComplete) {
3787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> notify = mNotify->dup();
3797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->setInt32("what", kWhatShutdownCompleted);
3807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->post();
3817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mPaused = true;
3827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
38387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
38487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
3853b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/*
3863b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data
3873b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */
3883b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() {
389e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    // mRenderer is only NULL if we have a legacy widevine source that
390e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    // is not yet ready. In this case we must not fetch input.
391e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    if (isDiscontinuityPending() || mRenderer == NULL) {
3923b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        return false;
3937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
39566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    while (err == OK && !mDequeuedInputBuffers.empty()) {
3967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        size_t bufferIx = *mDequeuedInputBuffers.begin();
3977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
3987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setSize("buffer-ix", bufferIx);
3997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = fetchInputData(msg);
40066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (err != OK && err != ERROR_END_OF_STREAM) {
40166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // if EOS, need to queue EOS buffer
4027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
4037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
4057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mPendingInputMessages.empty()
4077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                || !onInputBufferFetched(msg)) {
4087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mPendingInputMessages.push_back(msg);
4097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
411095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
4123b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    return err == -EWOULDBLOCK
4133b032b3865fd93173aadca0591eeea32853206f9Chong Zhang            && mSource->feedMoreTSData() == OK;
414095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
415095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
416421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err)
417421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{
418421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // We cannot immediately release the codec due to buffers still outstanding
419421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // in the renderer.  We signal to the player the error so it can shutdown/release the
420421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    // decoder after flushing and increment the generation to discard unnecessary messages.
421421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
422421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    ++mBufferGeneration;
423421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
424421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<AMessage> notify = mNotify->dup();
425421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("what", kWhatError);
426421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->setInt32("err", err);
427421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    notify->post();
428421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
429421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
430421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) {
43166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (isDiscontinuityPending()) {
4327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return false;
4337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
434421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
435421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<ABuffer> buffer;
436421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getInputBuffer(index, &buffer);
437421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
4386301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    if (buffer == NULL) {
4396301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        handleError(UNKNOWN_ERROR);
4406301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia        return false;
4416301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia    }
4426301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia
443421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mInputBuffers.size()) {
444421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
445421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBuffers.add();
446421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.add();
447421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.add();
448421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mMediaBuffers.editItemAt(i) = NULL;
449421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mInputBufferIsDequeued.editItemAt(i) = false;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
452421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBuffers.editItemAt(index) = buffer;
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    //CHECK_LT(bufferIx, mInputBuffers.size());
4551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
456421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (mMediaBuffers[index] != NULL) {
457421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers[index]->release();
458421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mMediaBuffers.editItemAt(index) = NULL;
459095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
460421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mInputBufferIsDequeued.editItemAt(index) = true;
461095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
46287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    if (!mCSDsToSubmit.isEmpty()) {
4637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
464421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        msg->setSize("buffer-ix", index);
4657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
46687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
46787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
4687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setBuffer("buffer", buffer);
46987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        mCSDsToSubmit.removeAt(0);
4707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(onInputBufferFetched(msg));
4712245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        return true;
4722245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
4732245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
4742245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    while (!mPendingInputMessages.empty()) {
4752245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        sp<AMessage> msg = *mPendingInputMessages.begin();
4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!onInputBufferFetched(msg)) {
4772245fc625910e47d1ba3c339e205c21ab58a47adWei Jia            break;
4782245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        }
4792245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        mPendingInputMessages.erase(mPendingInputMessages.begin());
4802245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
4812245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
482421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mInputBufferIsDequeued.editItemAt(index)) {
48387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        return true;
48487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
48587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
486421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mDequeuedInputBuffers.push_back(index);
4877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    onRequestInputBuffers();
4891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    return true;
4901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
4911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
492421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer(
493421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t index,
494421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t offset,
495421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        size_t size,
496421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t timeUs,
497421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int32_t flags) {
498421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen//    CHECK_LT(bufferIx, mOutputBuffers.size());
499421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    sp<ABuffer> buffer;
500421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mCodec->getOutputBuffer(index, &buffer);
5017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
502421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (index >= mOutputBuffers.size()) {
503421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
504421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            mOutputBuffers.add();
505095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
506095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
507095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
508421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    mOutputBuffers.editItemAt(index) = buffer;
509421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->setRange(offset, size);
5117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->clear();
5127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->setInt64("timeUs", timeUs);
51366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
51466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
5157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // we do not expect CODECCONFIG or SYNCFRAME for decoder
5167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
518421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    reply->setSize("buffer-ix", index);
5197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setInt32("generation", mBufferGeneration);
5207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
52166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (eos) {
52266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
52366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
52466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        buffer->meta()->setInt32("eos", true);
52566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        reply->setInt32("eos", true);
52666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mSkipRenderingUntilMediaTimeUs >= 0) {
5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGV("[%s] dropping buffer at time %lld as requested.",
5297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     mComponentName.c_str(), (long long)timeUs);
5307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->post();
5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return true;
5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mSkipRenderingUntilMediaTimeUs = -1;
5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
538e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan    mNumFramesTotal += !mIsAudio;
539e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan
540f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // wait until 1st frame comes out to signal resume complete
541f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
542f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
5437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
5447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // send the buffer to renderer.
5457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->queueBuffer(mIsAudio, buffer, reply);
54666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (eos && !isDiscontinuityPending()) {
5477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
5487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return true;
5527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
5537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
554421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
555421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    if (!mIsAudio) {
556e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        int32_t width, height;
557e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        if (format->findInt32("width", &width)
558e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan                && format->findInt32("height", &height)) {
559e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("width", width);
560e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            mStats->setInt32("height", height);
561e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        }
562421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        sp<AMessage> notify = mNotify->dup();
563421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setInt32("what", kWhatVideoSizeChanged);
564421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->setMessage("format", format);
565421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        notify->post();
566421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    } else if (mRenderer != NULL) {
567421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        uint32_t flags;
568421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        int64_t durationUs;
569421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
570288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung        if (getAudioDeepBufferSetting() // override regardless of source duration
571288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                || (!hasVideo
572288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && mSource->getDuration(&durationUs) == OK
573288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
574421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
575421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        } else {
576421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            flags = AUDIO_OUTPUT_FLAG_NONE;
577421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        }
578421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
579421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen        mRenderer->openAudioSink(
580421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen                format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
581421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen    }
582421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen}
583421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
5847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() {
5857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
5867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mMediaBuffers[i] != NULL) {
5877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers[i]->release();
5887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers.editItemAt(i) = NULL;
5897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mMediaBuffers.resize(mInputBuffers.size());
5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
5937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mMediaBuffers.editItemAt(i) = NULL;
5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.clear();
5967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.resize(mInputBuffers.size());
5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
5987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mInputBufferIsDequeued.editItemAt(i) = false;
5997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPendingInputMessages.clear();
6027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDequeuedInputBuffers.clear();
6037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mSkipRenderingUntilMediaTimeUs = -1;
6047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() {
6077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
6081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
6097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        reply->setInt32("generation", mBufferGeneration);
6107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec->requestActivityNotification(reply);
6117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
6157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int32_t generation;
6167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findInt32("generation", &generation));
6177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return generation != mBufferGeneration;
6187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
6217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> accessUnit;
6227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool dropAccessUnit;
6237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    do {
6247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
6257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (err == -EWOULDBLOCK) {
6277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return err;
6287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        } else if (err != OK) {
6297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (err == INFO_DISCONTINUITY) {
6307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t type;
6317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
6327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool formatChange =
6347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    (mIsAudio &&
6357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
6367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    || (!mIsAudio &&
6377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
6387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
6407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                ALOGI("%s discontinuity (format=%d, time=%d)",
6427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mIsAudio ? "audio" : "video", formatChange, timeChange);
6437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool seamlessFormatChange = false;
6457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
6467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange) {
6477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    seamlessFormatChange =
6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        supportsSeamlessFormatChange(newFormat);
6497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // treat seamless format change separately
6507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    formatChange = !seamlessFormatChange;
6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
65366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // For format or time change, return EOS to queue EOS input,
65466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                // then wait for EOS on output.
6557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange /* not seamless */) {
6567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mFormatChangePending = true;
65766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
6587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (timeChange) {
6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
66066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    mTimeChangePending = true;
66166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    err = ERROR_END_OF_STREAM;
6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (seamlessFormatChange) {
6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // reuse existing decoder and don't flush
6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
66566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang                    continue;
6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else {
6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // This stream is unaffected by the discontinuity
6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    return -EWOULDBLOCK;
6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
6707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
6717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
67266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // reply should only be returned without a buffer set
67366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            // when there is an error (including EOS)
67466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            CHECK(err != OK);
67566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->setInt32("err", err);
67766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            return ERROR_END_OF_STREAM;
6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        dropAccessUnit = false;
6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mIsAudio
6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && !mIsSecure
6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && mRenderer->getVideoLateByUs() > 100000ll
6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && mIsVideoAVC
6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && !IsAVCReferenceFrame(accessUnit)) {
6867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            dropAccessUnit = true;
687e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan            ++mNumInputFramesDropped;
6887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } while (dropAccessUnit);
6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
6927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0
6937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int64_t mediaTimeUs;
6947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
6955abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang    ALOGV("[%s] feeding input buffer at media time %.3f",
6967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mIsAudio ? "audio" : "video",
6977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mediaTimeUs / 1E6);
6987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif
6997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
7017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->decode(accessUnit);
7027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setBuffer("buffer", accessUnit);
7057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return OK;
7077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
7087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
7107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t bufferIx;
7117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findSize("buffer-ix", &bufferIx));
7127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK_LT(bufferIx, mInputBuffers.size());
7137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
7147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> buffer;
7167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hasBuffer = msg->findBuffer("buffer", &buffer);
7177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // handle widevine classic source - that fills an arbitrary input buffer
7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    MediaBuffer *mediaBuffer = NULL;
7207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hasBuffer) {
7217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mediaBuffer != NULL) {
7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // likely filled another buffer than we requested: adjust buffer index
7247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            size_t ix;
7257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            for (ix = 0; ix < mInputBuffers.size(); ix++) {
7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                const sp<ABuffer> &buf = mInputBuffers[ix];
7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (buf->data() == mediaBuffer->data()) {
7287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // all input buffers are dequeued on start, hence the check
7297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    if (!mInputBufferIsDequeued[ix]) {
7307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu",
7317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                mComponentName.c_str(), ix, bufferIx);
7327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mediaBuffer->release();
7337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        return false;
7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    }
7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // TRICKY: need buffer for the metadata, so instead, set
7377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // codecBuffer to the same (though incorrect) buffer to
7387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // avoid a memcpy into the codecBuffer
7397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer = buffer;
7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer->setRange(
7417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_offset(),
7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_length());
7437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    bufferIx = ix;
7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    break;
7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
7467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
7477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(ix < mInputBuffers.size());
7487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
7497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (buffer == NULL /* includes !hasBuffer */) {
7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int32_t streamErr = ERROR_END_OF_STREAM;
7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
75566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        CHECK(streamErr != OK);
7561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
7571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // attempt to queue EOS
7581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
7591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                bufferIx,
7601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
7611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
7621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
7631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                MediaCodec::BUFFER_FLAG_EOS);
764cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        if (err == OK) {
765cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
766cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else if (streamErr == ERROR_END_OF_STREAM) {
7671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            streamErr = err;
7681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            // err will not be ERROR_END_OF_STREAM
7691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
7701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
7711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (streamErr != ERROR_END_OF_STREAM) {
772cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            ALOGE("Stream error for %s (err=%d), EOS %s queued",
773cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    mComponentName.c_str(),
774cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    streamErr,
775cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    err == OK ? "successfully" : "unsuccessfully");
7761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(streamErr);
7771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
7781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
779c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<AMessage> extra;
780c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
781c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            int64_t resumeAtMediaTimeUs;
782c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            if (extra->findInt64(
783c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
784c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                ALOGI("[%s] suppressing rendering until %lld us",
785c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
786c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
787c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            }
788c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        }
789c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
7901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int64_t timeUs = 0;
7911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        uint32_t flags = 0;
7921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
7931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
79487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        int32_t eos, csd;
79587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        // we do not expect SYNCFRAME for decoder
7961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer->meta()->findInt32("eos", &eos) && eos) {
7971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_EOS;
79887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
79987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
8001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
8011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
8021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // copy into codec buffer
8031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer != codecBuffer) {
8041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            CHECK_LE(buffer->size(), codecBuffer->capacity());
8051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            codecBuffer->setRange(0, buffer->size());
8061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            memcpy(codecBuffer->data(), buffer->data(), buffer->size());
8071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
8081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
8091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
8101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        bufferIx,
8111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->offset(),
8121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->size(),
8131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        timeUs,
8141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        flags);
8151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (err != OK) {
816cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
817cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mediaBuffer->release();
818cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
8191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            ALOGE("Failed to queue input buffer for %s (err=%d)",
8201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    mComponentName.c_str(), err);
8211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(err);
822cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else {
823cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
824cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
825cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                CHECK(mMediaBuffers[bufferIx] == NULL);
826cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
827cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
828095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8302245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    return true;
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
8341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    status_t err;
8351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    int32_t render;
8361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    size_t bufferIx;
83766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    int32_t eos;
8381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK(msg->findSize("buffer-ix", &bufferIx));
839c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
8407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!mIsAudio) {
841c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        int64_t timeUs;
842c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<ABuffer> buffer = mOutputBuffers[bufferIx];
843c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        buffer->meta()->findInt64("timeUs", &timeUs);
8447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
8457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
8467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mCCDecoder->display(timeUs);
8477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
848c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
849c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
8501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (msg->findInt32("render", &render) && render) {
851dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        int64_t timestampNs;
852dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        CHECK(msg->findInt64("timestampNs", &timestampNs));
853dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
8541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
855e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan        mNumOutputFramesDropped += !mIsAudio;
8561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        err = mCodec->releaseOutputBuffer(bufferIx);
8571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
8581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
8591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("failed to release output buffer for %s (err=%d)",
8601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mComponentName.c_str(), err);
8611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
86366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (msg->findInt32("eos", &eos) && eos
86466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            && isDiscontinuityPending()) {
86566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        finishHandleDiscontinuity(true /* flushOnTimeChange */);
86666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
86766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
86866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
86966704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const {
87066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    return mFormatChangePending || mTimeChangePending;
87166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang}
87266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
87366704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
87466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
87566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
87666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
87766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have format change, pause and wait to be killed;
87866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // If we have time change only, flush and restart fetching.
87966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
88066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    if (mFormatChangePending) {
88166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        mPaused = true;
88266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    } else if (mTimeChangePending) {
88366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        if (flushOnTimeChange) {
884421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            doFlush(false /* notifyComplete */);
885421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen            signalResume(false /* notifyComplete */);
88666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang        }
88766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    }
88866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
88966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    // Notify NuPlayer to either shutdown decoder, or rescan sources
89066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    sp<AMessage> msg = mNotify->dup();
89166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("what", kWhatInputDiscontinuity);
89266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->setInt32("formatChange", mFormatChangePending);
89366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    msg->post();
89466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang
89566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mFormatChangePending = false;
89666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang    mTimeChangePending = false;
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
9007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &targetFormat) const {
9016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
9026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
9036d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString mime;
9066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!targetFormat->findString("mime", &mime)) {
9076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
9086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9106d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
9116d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        // field-by-field comparison
9126d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
9136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
9146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            int32_t oldVal, newVal;
9157abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
9161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    !targetFormat->findInt32(keys[i], &newVal) ||
9171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    oldVal != newVal) {
9186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
9196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
9206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
9216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        sp<ABuffer> oldBuf, newBuf;
9237abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
9241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                targetFormat->findBuffer("csd-0", &newBuf)) {
9256d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            if (oldBuf->size() != newBuf->size()) {
9266d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
9276d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
9286d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
9296d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
9306d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9316d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return false;
9326d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
9336d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9346d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
9357abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (mInputFormat == NULL) {
9366d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
9376d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9386d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9396d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
9406d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
9416d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9426d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9436d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString oldMime, newMime;
9447abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (!mInputFormat->findString("mime", &oldMime)
9456d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !targetFormat->findString("mime", &newMime)
9466d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !(oldMime == newMime)) {
9476d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
9486d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9496d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9506d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
9516d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool seamless;
9526d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (audio) {
9536d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        seamless = supportsSeamlessAudioFormatChange(targetFormat);
9546d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    } else {
9551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int32_t isAdaptive;
9561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        seamless = (mCodec != NULL &&
9571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
9581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                isAdaptive);
9596d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
9606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
9626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return seamless;
9636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
9646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
9657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
9667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (format == NULL) {
967a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        return;
968a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
9697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mCSDsForCurrentFormat.clear();
9707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (int32_t i = 0; ; ++i) {
9717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        AString tag = "csd-";
9727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        tag.append(i);
9737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<ABuffer> buffer;
9747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!format->findBuffer(tag.c_str(), &buffer)) {
9757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
9767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
9777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsForCurrentFormat.push(buffer);
978a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
979b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang}
980b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang
981f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
982f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (mResumePending) {
983f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = false;
984f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
985f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        sp<AMessage> notify = mNotify->dup();
986f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->setInt32("what", kWhatResumeCompleted);
987f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->post();
988f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
989f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang}
990f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993