NuPlayerDecoder.cpp revision 1de1e25cba872bd4c077c2e394f8ca9c70b65856
116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/*
216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Copyright 2014 The Android Open Source Project
316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * you may not use this file except in compliance with the License.
616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * You may obtain a copy of the License at
716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
1016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Unless required by applicable law or agreed to in writing, software
1116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
1216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * See the License for the specific language governing permissions and
1416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * limitations under the License.
1516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */
1616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
17b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood//#define LOG_NDEBUG 0
18b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#define LOG_TAG "NuPlayerDecoder"
1916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <utils/Log.h>
2016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <inttypes.h>
2116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
2216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "NuPlayerCCDecoder.h"
230cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include "NuPlayerDecoder.h"
240cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include "NuPlayerRenderer.h"
2516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "NuPlayerSource.h"
2616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/ICrypto.h>
287850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood#include <media/stagefright/foundation/ABuffer.h>
297850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood#include <media/stagefright/foundation/ADebug.h>
3016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/foundation/AMessage.h>
3144c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood#include <media/stagefright/MediaBuffer.h>
3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/MediaCodec.h>
3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/MediaDefs.h>
3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/MediaErrors.h>
3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <gui/Surface.h>
3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "avc_utils.h"
3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "ATSParser.h"
4016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodnamespace android {
4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4316864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodNuPlayer::Decoder::Decoder(
4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        const sp<AMessage> &notify,
4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        const sp<Source> &source,
4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        const sp<Renderer> &renderer,
4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        const sp<Surface> &surface,
4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        const sp<CCDecoder> &ccDecoder)
4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    : DecoderBase(notify),
5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood      mSurface(surface),
5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood      mSource(source),
52ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mRenderer(renderer),
53ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mCCDecoder(ccDecoder),
54ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mSkipRenderingUntilMediaTimeUs(-1ll),
55ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mNumFramesTotal(0ll),
56ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mNumFramesDropped(0ll),
57ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mIsAudio(true),
58ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mIsVideoAVC(false),
59ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mIsSecure(false),
60ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mFormatChangePending(false),
61ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mTimeChangePending(false),
6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood      mPaused(true),
63ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mResumePending(false),
64ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood      mComponentName("decoder") {
65ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mCodecLooper = new ALooper;
6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mCodecLooper->setName("NPDecoder-CL");
6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
68ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood}
69ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
70ab063847e6e893740749029a04cce1f6b7345ed5Mike LockwoodNuPlayer::Decoder::~Decoder() {
7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    releaseAndResetMediaBuffers();
72ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood}
7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
74ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodvoid NuPlayer::Decoder::getStats(
75ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        int64_t *numFramesTotal,
7616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        int64_t *numFramesDropped) const {
7716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    *numFramesTotal = mNumFramesTotal;
78ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    *numFramesDropped = mNumFramesDropped;
79ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood}
80ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
8116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
82ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
8416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    switch (msg->what()) {
8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        case kWhatCodecNotify:
86ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        {
87ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            int32_t cbID;
8816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            CHECK(msg->findInt32("callbackID", &cbID));
8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
90ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
91ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    mIsAudio ? "audio" : "video", cbID, mPaused);
92a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
93a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood            if (mPaused) {
94ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                break;
9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            }
96ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            switch (cbID) {
9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood                case MediaCodec::CB_INPUT_AVAILABLE:
99335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                {
100ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    int32_t index;
101ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    CHECK(msg->findInt32("index", &index));
102ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
103335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    handleAnInputBuffer(index);
104ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    break;
105ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                }
106ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
107ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                case MediaCodec::CB_OUTPUT_AVAILABLE:
108ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                {
109ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    int32_t index;
110ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    size_t offset;
111ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    size_t size;
112335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    int64_t timeUs;
113335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    int32_t flags;
114335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
115335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    CHECK(msg->findInt32("index", &index));
116ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    CHECK(msg->findSize("offset", &offset));
117ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    CHECK(msg->findSize("size", &size));
118ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    CHECK(msg->findInt64("timeUs", &timeUs));
119335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    CHECK(msg->findInt32("flags", &flags));
120ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
121ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
122ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    break;
123ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                }
124ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
125ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
126ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                {
127ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    sp<AMessage> format;
128335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    CHECK(msg->findMessage("format", &format));
129335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
130335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    handleOutputFormatChange(format);
131335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    break;
132ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                }
133ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
134ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                case MediaCodec::CB_ERROR:
135335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                {
136ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    status_t err;
137ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    CHECK(msg->findInt32("err", &err));
138ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    ALOGE("Decoder (%s) reported error : 0x%x",
139ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                            mIsAudio ? "audio" : "video", err);
140ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
141ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    handleError(err);
142ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    break;
143ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                }
144335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
145335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                default:
146335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                {
147335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood                    TRESPASS();
148ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    break;
149ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                }
150ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            }
151335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
152ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            break;
153ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
154ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
155ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        case kWhatRenderBuffer:
156ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        {
157ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            if (!isStaleReply(msg)) {
158ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                onRenderBuffer(msg);
159ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            }
160335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood            break;
161335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        }
162335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
163335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        default:
164ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            DecoderBase::onMessageReceived(msg);
165ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            break;
166ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
167335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
168ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
169ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
170ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    CHECK(mCodec == NULL);
171ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
172ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mFormatChangePending = false;
173ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mTimeChangePending = false;
174ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
175ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    ++mBufferGeneration;
176335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
177335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    AString mime;
178335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    CHECK(format->findString("mime", &mime));
179335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
180ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
181ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
182ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
183335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    mComponentName = mime;
184ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mComponentName.append(" decoder");
185ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
186ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
187ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */);
188ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    int32_t secure = 0;
189ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (format->findInt32("secure", &secure) && secure != 0) {
190ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (mCodec != NULL) {
191ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            mCodec->getName(&mComponentName);
192335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood            mComponentName.append(".secure");
193335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood            mCodec->release();
194335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood            ALOGI("[%s] creating", mComponentName.c_str());
195335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood            mCodec = MediaCodec::CreateByComponentName(
196ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                    mCodecLooper, mComponentName.c_str());
197ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
198ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
199335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    if (mCodec == NULL) {
200ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        ALOGE("Failed to create %s%s decoder",
201ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                (secure ? "secure " : ""), mime.c_str());
202ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        handleError(UNKNOWN_ERROR);
203ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return;
204ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
205ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mIsSecure = secure;
206ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
207ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mCodec->getName(&mComponentName);
208335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
209335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    status_t err;
210335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    if (mSurface != NULL) {
211335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        // disconnect from surface as MediaCodec will reconnect
212ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        err = native_window_api_disconnect(
213ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood                mSurface.get(), NATIVE_WINDOW_API_MEDIA);
214ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        // We treat this as a warning, as this is a preparatory step.
215335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        // Codec will try to connect to the surface, which is where
216ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        // any error signaling will occur.
217ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
218ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
219ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    err = mCodec->configure(
220ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            format, mSurface, NULL /* crypto */, 0 /* flags */);
221ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (err != OK) {
222ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
223ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        mCodec->release();
224335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        mCodec.clear();
225335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        handleError(err);
226335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        return;
22716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
22816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    rememberCodecSpecificData(format);
22916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
23016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // the following should work in configured state
23116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
23216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
23316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
23416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
23516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mCodec->setCallback(reply);
23616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
23716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    err = mCodec->start();
23816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (err != OK) {
23916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
24016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mCodec->release();
24116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mCodec.clear();
24216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        handleError(err);
24316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return;
24416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
24516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
24616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    releaseAndResetMediaBuffers();
24716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
24816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mPaused = false;
24916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mResumePending = false;
25016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
25116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
25216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> &params) {
25316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mCodec == NULL) {
25416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        ALOGW("onSetParameters called before codec is created.");
25516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return;
25616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mCodec->setParameters(params);
25816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
25916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
26016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
26116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    bool hadNoRenderer = (mRenderer == NULL);
26216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mRenderer = renderer;
26316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (hadNoRenderer && mRenderer != NULL) {
26416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        // this means that the widevine legacy source is ready
26516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        onRequestInputBuffers();
26616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
26716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
26816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
26916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onGetInputBuffers(
27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        Vector<sp<ABuffer> > *dstBuffers) {
27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers));
27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
27316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
27416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onResume(bool notifyComplete) {
27516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mPaused = false;
27616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
27716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (notifyComplete) {
27816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mResumePending = true;
27916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
28016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mCodec->start();
28116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
28216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
28316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::doFlush(bool notifyComplete) {
28416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mCCDecoder != NULL) {
28516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mCCDecoder->flush();
28616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
28716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mRenderer != NULL) {
28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mRenderer->flush(mIsAudio, notifyComplete);
29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mRenderer->signalTimeDiscontinuity();
29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
29316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    status_t err = OK;
29416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mCodec != NULL) {
29516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        err = mCodec->flush();
29616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        ++mBufferGeneration;
29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
29916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (err != OK) {
30116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        handleError(err);
30316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        // finish with posting kWhatFlushCompleted.
30416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        // we attempt to release the buffers even if flush fails.
305a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    }
306a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    releaseAndResetMediaBuffers();
307a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    mPaused = true;
308a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
309a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
310a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
311a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid NuPlayer::Decoder::onFlush() {
312a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    doFlush(true);
313a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
314a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    if (isDiscontinuityPending()) {
315a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        // This could happen if the client starts seeking/shutdown
316a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        // after we queued an EOS for discontinuities.
317a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        // We can consider discontinuity handled.
318a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        finishHandleDiscontinuity(false /* flushOnTimeChange */);
3198277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    }
3208277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood
3215959988b63ace3fba2fc78b135a4f5ef25dcf860Mike Lockwood    sp<AMessage> notify = mNotify->dup();
3228277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    notify->setInt32("what", kWhatFlushCompleted);
3238277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    notify->post();
3248277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood}
3258277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood
3268277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) {
3278277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    status_t err = OK;
3288277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood
32916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // if there is a pending resume request, notify complete now
33016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    notifyResumeCompleteIfNecessary();
33116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
33216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mCodec != NULL) {
33316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        err = mCodec->release();
33416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mCodec = NULL;
33516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        ++mBufferGeneration;
33616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
33716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        if (mSurface != NULL) {
33816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            // reconnect to surface as MediaCodec disconnected from it
33916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            status_t error =
34016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood                    native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
34116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            ALOGW_IF(error != NO_ERROR,
34216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood                    "[%s] failed to connect to native window, error=%d",
34316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood                    mComponentName.c_str(), error);
34416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        }
34516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mComponentName = "decoder";
34616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
34716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
34816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    releaseAndResetMediaBuffers();
34916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
35016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (err != OK) {
35116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
35216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        handleError(err);
353782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood        // finish with posting kWhatShutdownCompleted.
354782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    }
355782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood
356782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    if (notifyComplete) {
357782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood        sp<AMessage> notify = mNotify->dup();
358782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood        notify->setInt32("what", kWhatShutdownCompleted);
359782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood        notify->post();
36016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPaused = true;
36116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
36216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
36316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
36416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/*
36516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * returns true if we should request more data
36616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */
36716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodbool NuPlayer::Decoder::doRequestBuffers() {
36816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // mRenderer is only NULL if we have a legacy widevine source that
36916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // is not yet ready. In this case we must not fetch input.
37016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (isDiscontinuityPending() || mRenderer == NULL) {
37116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return false;
37216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
37316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    status_t err = OK;
37416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    while (err == OK && !mDequeuedInputBuffers.empty()) {
37516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        size_t bufferIx = *mDequeuedInputBuffers.begin();
37616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        sp<AMessage> msg = new AMessage();
37716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        msg->setSize("buffer-ix", bufferIx);
37816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        err = fetchInputData(msg);
37916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        if (err != OK && err != ERROR_END_OF_STREAM) {
38016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            // if EOS, need to queue EOS buffer
38116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            break;
38216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        }
38316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
38416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
38516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        if (!mPendingInputMessages.empty()
38616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood                || !onInputBufferFetched(msg)) {
38716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            mPendingInputMessages.push_back(msg);
38816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        }
38916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
39016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
39116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return err == -EWOULDBLOCK
39216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            && mSource->feedMoreTSData() == OK;
39316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
39416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
3951865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid NuPlayer::Decoder::handleError(int32_t err)
39616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{
39716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // We cannot immediately release the codec due to buffers still outstanding
39816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // in the renderer.  We signal to the player the error so it can shutdown/release the
3991865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    // decoder after flushing and increment the generation to discard unnecessary messages.
40016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
40116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    ++mBufferGeneration;
40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    sp<AMessage> notify = mNotify->dup();
4041865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    notify->setInt32("what", kWhatError);
4051865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    notify->setInt32("err", err);
406014897f5aece2c6212418934bd4618326979f17aYin Liu    notify->post();
4071865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood}
4081865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood
4091865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) {
4101865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    if (isDiscontinuityPending()) {
4111865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        return false;
412de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    }
4131865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood
4141865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    sp<ABuffer> buffer;
415de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    mCodec->getInputBuffer(index, &buffer);
416de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood
417de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    if (index >= mInputBuffers.size()) {
4181865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
4191865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood            mInputBuffers.add();
42016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            mMediaBuffers.add();
42116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            mInputBufferIsDequeued.add();
42244c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood            mMediaBuffers.editItemAt(i) = NULL;
423ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood            mInputBufferIsDequeued.editItemAt(i) = false;
42416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        }
425ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    }
42616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mInputBuffers.editItemAt(index) = buffer;
42716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
42816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    //CHECK_LT(bufferIx, mInputBuffers.size());
42916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
43016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mMediaBuffers[index] != NULL) {
43116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mMediaBuffers[index]->release();
43216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mMediaBuffers.editItemAt(index) = NULL;
433ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    }
43416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mInputBufferIsDequeued.editItemAt(index) = true;
43516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
43664000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood    if (!mCSDsToSubmit.isEmpty()) {
43764000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood        sp<AMessage> msg = new AMessage();
438ebb1081a624a773a67c49b279c775e18e693c4fcMarco Nelissen        msg->setSize("buffer-ix", index);
439ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood
440ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
441ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
44264000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood        msg->setBuffer("buffer", buffer);
443ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood        mCSDsToSubmit.removeAt(0);
44464000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood        CHECK(onInputBufferFetched(msg));
44564000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood        return true;
44664000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood    }
44716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
44816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    while (!mPendingInputMessages.empty()) {
44916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        sp<AMessage> msg = *mPendingInputMessages.begin();
45042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        if (!onInputBufferFetched(msg)) {
45116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            break;
45242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        }
45342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        mPendingInputMessages.erase(mPendingInputMessages.begin());
45442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    }
455437e945013318de54746422c8b44306e6d5319caMike Lockwood
4563e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    if (!mInputBufferIsDequeued.editItemAt(index)) {
4573e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        return true;
45833bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood    }
459b3be006498f28f2630264135e88d266b540bcec3Daichi Hirono
46042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    mDequeuedInputBuffers.push_back(index);
46133bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood
46242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    onRequestInputBuffers();
4633e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    return true;
4643e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood}
4653e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
4663e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodbool NuPlayer::Decoder::handleAnOutputBuffer(
4673e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        size_t index,
4683e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        size_t offset,
4693e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        size_t size,
4703e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        int64_t timeUs,
4713e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        int32_t flags) {
4723e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood//    CHECK_LT(bufferIx, mOutputBuffers.size());
4733e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    sp<ABuffer> buffer;
47416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mCodec->getOutputBuffer(index, &buffer);
47516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
47642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    if (index >= mOutputBuffers.size()) {
4770cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
4780cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood            mOutputBuffers.add();
47942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        }
48042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    }
48142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood
4820cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    mOutputBuffers.editItemAt(index) = buffer;
4830cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
4840cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    buffer->setRange(offset, size);
4850cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    buffer->meta()->clear();
4860cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    buffer->meta()->setInt64("timeUs", timeUs);
4870cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
4880cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
4890cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    // we do not expect CODECCONFIG or SYNCFRAME for decoder
490b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
49142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
49242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    reply->setSize("buffer-ix", index);
49329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    reply->setInt32("generation", mBufferGeneration);
494b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
495b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood    if (eos) {
496b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
497b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
498b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood        buffer->meta()->setInt32("eos", true);
499b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood        reply->setInt32("eos", true);
50042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    } else if (mSkipRenderingUntilMediaTimeUs >= 0) {
50142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
50242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            ALOGV("[%s] dropping buffer at time %lld as requested.",
503b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood                     mComponentName.c_str(), (long long)timeUs);
504b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
50542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            reply->post();
50642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            return true;
50742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        }
50842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood
5090cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        mSkipRenderingUntilMediaTimeUs = -1;
5100cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    }
5110cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
5120cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    // wait until 1st frame comes out to signal resume complete
5130cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    notifyResumeCompleteIfNecessary();
51442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood
5150cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    if (mRenderer != NULL) {
5160cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        // send the buffer to renderer.
51742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        mRenderer->queueBuffer(mIsAudio, buffer, reply);
51842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        if (eos && !isDiscontinuityPending()) {
51942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
5200cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        }
5210cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    }
5220cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
52342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    return true;
52416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
52516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
52642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
52764c948bf5041fdfe391553315c9d028e1ee56382Tomasz Mikolajewski    if (!mIsAudio) {
52842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        sp<AMessage> notify = mNotify->dup();
52916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        notify->setInt32("what", kWhatVideoSizeChanged);
53016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        notify->setMessage("format", format);
53116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        notify->post();
53242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    } else if (mRenderer != NULL) {
53342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        uint32_t flags;
53442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        int64_t durationUs;
53542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
5360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        if (!hasVideo &&
5370cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood                mSource->getDuration(&durationUs) == OK &&
5380cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood                durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
53916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
5407850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood        } else {
5414fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono            flags = AUDIO_OUTPUT_FLAG_NONE;
5423e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
5433e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
5443e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        mRenderer->openAudioSink(
5453e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood                format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
5463e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    }
5474fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono}
5483e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
5493e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() {
5503e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
5514fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono        if (mMediaBuffers[i] != NULL) {
5523e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            mMediaBuffers[i]->release();
5533e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            mMediaBuffers.editItemAt(i) = NULL;
5543e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
5557850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood    }
556    mMediaBuffers.resize(mInputBuffers.size());
557    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
558        mMediaBuffers.editItemAt(i) = NULL;
559    }
560    mInputBufferIsDequeued.clear();
561    mInputBufferIsDequeued.resize(mInputBuffers.size());
562    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
563        mInputBufferIsDequeued.editItemAt(i) = false;
564    }
565
566    mPendingInputMessages.clear();
567    mDequeuedInputBuffers.clear();
568    mSkipRenderingUntilMediaTimeUs = -1;
569}
570
571void NuPlayer::Decoder::requestCodecNotification() {
572    if (mCodec != NULL) {
573        sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
574        reply->setInt32("generation", mBufferGeneration);
575        mCodec->requestActivityNotification(reply);
576    }
577}
578
579bool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
580    int32_t generation;
581    CHECK(msg->findInt32("generation", &generation));
582    return generation != mBufferGeneration;
583}
584
585status_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
586    sp<ABuffer> accessUnit;
587    bool dropAccessUnit;
588    do {
589        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
590
591        if (err == -EWOULDBLOCK) {
592            return err;
593        } else if (err != OK) {
594            if (err == INFO_DISCONTINUITY) {
595                int32_t type;
596                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
597
598                bool formatChange =
599                    (mIsAudio &&
600                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
601                    || (!mIsAudio &&
602                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
603
604                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
605
606                ALOGI("%s discontinuity (format=%d, time=%d)",
607                        mIsAudio ? "audio" : "video", formatChange, timeChange);
608
609                bool seamlessFormatChange = false;
610                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
611                if (formatChange) {
612                    seamlessFormatChange =
613                        supportsSeamlessFormatChange(newFormat);
614                    // treat seamless format change separately
615                    formatChange = !seamlessFormatChange;
616                }
617
618                // For format or time change, return EOS to queue EOS input,
619                // then wait for EOS on output.
620                if (formatChange /* not seamless */) {
621                    mFormatChangePending = true;
622                    err = ERROR_END_OF_STREAM;
623                } else if (timeChange) {
624                    rememberCodecSpecificData(newFormat);
625                    mTimeChangePending = true;
626                    err = ERROR_END_OF_STREAM;
627                } else if (seamlessFormatChange) {
628                    // reuse existing decoder and don't flush
629                    rememberCodecSpecificData(newFormat);
630                    continue;
631                } else {
632                    // This stream is unaffected by the discontinuity
633                    return -EWOULDBLOCK;
634                }
635            }
636
637            // reply should only be returned without a buffer set
638            // when there is an error (including EOS)
639            CHECK(err != OK);
640
641            reply->setInt32("err", err);
642            return ERROR_END_OF_STREAM;
643        }
644
645        if (!mIsAudio) {
646            ++mNumFramesTotal;
647        }
648
649        dropAccessUnit = false;
650        if (!mIsAudio
651                && !mIsSecure
652                && mRenderer->getVideoLateByUs() > 100000ll
653                && mIsVideoAVC
654                && !IsAVCReferenceFrame(accessUnit)) {
655            dropAccessUnit = true;
656            ++mNumFramesDropped;
657        }
658    } while (dropAccessUnit);
659
660    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
661#if 0
662    int64_t mediaTimeUs;
663    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
664    ALOGV("[%s] feeding input buffer at media time %.3f",
665         mIsAudio ? "audio" : "video",
666         mediaTimeUs / 1E6);
667#endif
668
669    if (mCCDecoder != NULL) {
670        mCCDecoder->decode(accessUnit);
671    }
672
673    reply->setBuffer("buffer", accessUnit);
674
675    return OK;
676}
677
678bool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
679    size_t bufferIx;
680    CHECK(msg->findSize("buffer-ix", &bufferIx));
681    CHECK_LT(bufferIx, mInputBuffers.size());
682    sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
683
684    sp<ABuffer> buffer;
685    bool hasBuffer = msg->findBuffer("buffer", &buffer);
686
687    // handle widevine classic source - that fills an arbitrary input buffer
688    MediaBuffer *mediaBuffer = NULL;
689    if (hasBuffer) {
690        mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
691        if (mediaBuffer != NULL) {
692            // likely filled another buffer than we requested: adjust buffer index
693            size_t ix;
694            for (ix = 0; ix < mInputBuffers.size(); ix++) {
695                const sp<ABuffer> &buf = mInputBuffers[ix];
696                if (buf->data() == mediaBuffer->data()) {
697                    // all input buffers are dequeued on start, hence the check
698                    if (!mInputBufferIsDequeued[ix]) {
699                        ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu",
700                                mComponentName.c_str(), ix, bufferIx);
701                        mediaBuffer->release();
702                        return false;
703                    }
704
705                    // TRICKY: need buffer for the metadata, so instead, set
706                    // codecBuffer to the same (though incorrect) buffer to
707                    // avoid a memcpy into the codecBuffer
708                    codecBuffer = buffer;
709                    codecBuffer->setRange(
710                            mediaBuffer->range_offset(),
711                            mediaBuffer->range_length());
712                    bufferIx = ix;
713                    break;
714                }
715            }
716            CHECK(ix < mInputBuffers.size());
717        }
718    }
719
720    if (buffer == NULL /* includes !hasBuffer */) {
721        int32_t streamErr = ERROR_END_OF_STREAM;
722        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
723
724        CHECK(streamErr != OK);
725
726        // attempt to queue EOS
727        status_t err = mCodec->queueInputBuffer(
728                bufferIx,
729                0,
730                0,
731                0,
732                MediaCodec::BUFFER_FLAG_EOS);
733        if (err == OK) {
734            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
735        } else if (streamErr == ERROR_END_OF_STREAM) {
736            streamErr = err;
737            // err will not be ERROR_END_OF_STREAM
738        }
739
740        if (streamErr != ERROR_END_OF_STREAM) {
741            ALOGE("Stream error for %s (err=%d), EOS %s queued",
742                    mComponentName.c_str(),
743                    streamErr,
744                    err == OK ? "successfully" : "unsuccessfully");
745            handleError(streamErr);
746        }
747    } else {
748        sp<AMessage> extra;
749        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
750            int64_t resumeAtMediaTimeUs;
751            if (extra->findInt64(
752                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
753                ALOGI("[%s] suppressing rendering until %lld us",
754                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
755                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
756            }
757        }
758
759        int64_t timeUs = 0;
760        uint32_t flags = 0;
761        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
762
763        int32_t eos, csd;
764        // we do not expect SYNCFRAME for decoder
765        if (buffer->meta()->findInt32("eos", &eos) && eos) {
766            flags |= MediaCodec::BUFFER_FLAG_EOS;
767        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
768            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
769        }
770
771        // copy into codec buffer
772        if (buffer != codecBuffer) {
773            CHECK_LE(buffer->size(), codecBuffer->capacity());
774            codecBuffer->setRange(0, buffer->size());
775            memcpy(codecBuffer->data(), buffer->data(), buffer->size());
776        }
777
778        status_t err = mCodec->queueInputBuffer(
779                        bufferIx,
780                        codecBuffer->offset(),
781                        codecBuffer->size(),
782                        timeUs,
783                        flags);
784        if (err != OK) {
785            if (mediaBuffer != NULL) {
786                mediaBuffer->release();
787            }
788            ALOGE("Failed to queue input buffer for %s (err=%d)",
789                    mComponentName.c_str(), err);
790            handleError(err);
791        } else {
792            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
793            if (mediaBuffer != NULL) {
794                CHECK(mMediaBuffers[bufferIx] == NULL);
795                mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
796            }
797        }
798    }
799    return true;
800}
801
802void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
803    status_t err;
804    int32_t render;
805    size_t bufferIx;
806    int32_t eos;
807    CHECK(msg->findSize("buffer-ix", &bufferIx));
808
809    if (!mIsAudio) {
810        int64_t timeUs;
811        sp<ABuffer> buffer = mOutputBuffers[bufferIx];
812        buffer->meta()->findInt64("timeUs", &timeUs);
813
814        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
815            mCCDecoder->display(timeUs);
816        }
817    }
818
819    if (msg->findInt32("render", &render) && render) {
820        int64_t timestampNs;
821        CHECK(msg->findInt64("timestampNs", &timestampNs));
822        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
823    } else {
824        err = mCodec->releaseOutputBuffer(bufferIx);
825    }
826    if (err != OK) {
827        ALOGE("failed to release output buffer for %s (err=%d)",
828                mComponentName.c_str(), err);
829        handleError(err);
830    }
831    if (msg->findInt32("eos", &eos) && eos
832            && isDiscontinuityPending()) {
833        finishHandleDiscontinuity(true /* flushOnTimeChange */);
834    }
835}
836
837bool NuPlayer::Decoder::isDiscontinuityPending() const {
838    return mFormatChangePending || mTimeChangePending;
839}
840
841void NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
842    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
843            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
844
845    // If we have format change, pause and wait to be killed;
846    // If we have time change only, flush and restart fetching.
847
848    if (mFormatChangePending) {
849        mPaused = true;
850    } else if (mTimeChangePending) {
851        if (flushOnTimeChange) {
852            doFlush(false /* notifyComplete */);
853            signalResume(false /* notifyComplete */);
854        }
855    }
856
857    // Notify NuPlayer to either shutdown decoder, or rescan sources
858    sp<AMessage> msg = mNotify->dup();
859    msg->setInt32("what", kWhatInputDiscontinuity);
860    msg->setInt32("formatChange", mFormatChangePending);
861    msg->post();
862
863    mFormatChangePending = false;
864    mTimeChangePending = false;
865}
866
867bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
868        const sp<AMessage> &targetFormat) const {
869    if (targetFormat == NULL) {
870        return true;
871    }
872
873    AString mime;
874    if (!targetFormat->findString("mime", &mime)) {
875        return false;
876    }
877
878    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
879        // field-by-field comparison
880        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
881        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
882            int32_t oldVal, newVal;
883            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
884                    !targetFormat->findInt32(keys[i], &newVal) ||
885                    oldVal != newVal) {
886                return false;
887            }
888        }
889
890        sp<ABuffer> oldBuf, newBuf;
891        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
892                targetFormat->findBuffer("csd-0", &newBuf)) {
893            if (oldBuf->size() != newBuf->size()) {
894                return false;
895            }
896            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
897        }
898    }
899    return false;
900}
901
902bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
903    if (mInputFormat == NULL) {
904        return false;
905    }
906
907    if (targetFormat == NULL) {
908        return true;
909    }
910
911    AString oldMime, newMime;
912    if (!mInputFormat->findString("mime", &oldMime)
913            || !targetFormat->findString("mime", &newMime)
914            || !(oldMime == newMime)) {
915        return false;
916    }
917
918    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
919    bool seamless;
920    if (audio) {
921        seamless = supportsSeamlessAudioFormatChange(targetFormat);
922    } else {
923        int32_t isAdaptive;
924        seamless = (mCodec != NULL &&
925                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
926                isAdaptive);
927    }
928
929    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
930    return seamless;
931}
932
933void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
934    if (format == NULL) {
935        return;
936    }
937    mCSDsForCurrentFormat.clear();
938    for (int32_t i = 0; ; ++i) {
939        AString tag = "csd-";
940        tag.append(i);
941        sp<ABuffer> buffer;
942        if (!format->findBuffer(tag.c_str(), &buffer)) {
943            break;
944        }
945        mCSDsForCurrentFormat.push(buffer);
946    }
947}
948
949void NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
950    if (mResumePending) {
951        mResumePending = false;
952
953        sp<AMessage> notify = mNotify->dup();
954        notify->setInt32("what", kWhatResumeCompleted);
955        notify->post();
956    }
957}
958
959}  // namespace android
960
961