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
271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
305bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h>
31095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h>
321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h"
377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h"
387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
39f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder(
421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<AMessage> &notify,
43c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Source> &source,
44c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        const sp<Renderer> &renderer,
457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<NativeWindowWrapper> &nativeWindow,
467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<CCDecoder> &ccDecoder)
47202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    : DecoderBase(notify),
481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar      mNativeWindow(nativeWindow),
49c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSource(source),
50c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mRenderer(renderer),
517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mCCDecoder(ccDecoder),
52c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia      mSkipRenderingUntilMediaTimeUs(-1ll),
537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mNumFramesTotal(0ll),
547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mNumFramesDropped(0ll),
557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsAudio(true),
567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsVideoAVC(false),
577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mIsSecure(false),
587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang      mFormatChangePending(false),
59704e72658b1082264a26a83c50046da34f07d1a1Wei Jia      mPaused(true),
60f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang      mResumePending(false),
611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar      mComponentName("decoder") {
621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper = new ALooper;
639e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen    mCodecLooper->setName("NPDecoder-CL");
641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() {
684923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia    releaseAndResetMediaBuffers();
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::getStats(
727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int64_t *numFramesTotal,
737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int64_t *numFramesDropped) const {
747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    *numFramesTotal = mNumFramesTotal;
757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    *numFramesDropped = mNumFramesDropped;
767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
77095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
80095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatCodecNotify:
837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (!isStaleReply(msg)) {
857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t numInput, numOutput;
86095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (!msg->findInt32("input-buffers", &numInput)) {
887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    numInput = INT32_MAX;
897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
90095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (!msg->findInt32("output-buffers", &numOutput)) {
927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    numOutput = INT32_MAX;
937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (!mPaused) {
967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    while (numInput-- > 0 && handleAnInputBuffer()) {}
977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                while (numOutput-- > 0 && handleAnOutputBuffer()) {}
1007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
1017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            requestCodecNotification();
10387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            break;
10487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        }
1057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRenderBuffer:
1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (!isStaleReply(msg)) {
1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                onRenderBuffer(msg);
1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
1157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            DecoderBase::onMessageReceived(msg);
1167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
11787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
11887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
11987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
1201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mCodec == NULL);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mFormatChangePending = false;
1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ++mBufferGeneration;
1261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
127840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    AString mime;
128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    CHECK(format->findString("mime", &mime));
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    sp<Surface> surface = NULL;
1341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mNativeWindow != NULL) {
1351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        surface = mNativeWindow->getSurfaceTextureClient();
1361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName = mime;
1391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mComponentName.append(" decoder");
1401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), surface.get());
141840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */);
143095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    int32_t secure = 0;
144095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (format->findInt32("secure", &secure) && secure != 0) {
145095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (mCodec != NULL) {
146095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->getName(&mComponentName);
147095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mComponentName.append(".secure");
148095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec->release();
149095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            ALOGI("[%s] creating", mComponentName.c_str());
150095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mCodec = MediaCodec::CreateByComponentName(
151095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                    mCodecLooper, mComponentName.c_str());
152095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
153095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
1541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec == NULL) {
155095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        ALOGE("Failed to create %s%s decoder",
156095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                (secure ? "secure " : ""), mime.c_str());
1571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(UNKNOWN_ERROR);
1581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
159840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mIsSecure = secure;
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    mCodec->getName(&mComponentName);
1631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
16414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    status_t err;
1651173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (mNativeWindow != NULL) {
1661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // disconnect from surface as MediaCodec will reconnect
16714986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        err = native_window_api_disconnect(
16814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar                surface.get(), NATIVE_WINDOW_API_MEDIA);
16914986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // We treat this as a warning, as this is a preparatory step.
17014986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // Codec will try to connect to the surface, which is where
17114986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        // any error signaling will occur.
17214986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
1731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
17414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar    err = mCodec->configure(
1751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            format, surface, NULL /* crypto */, 0 /* flags */);
1761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
1771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
1782abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
1792abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
1801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
1811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
1821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
18387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    rememberCodecSpecificData(format);
18487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
1851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    // the following should work in configured state
1861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
1871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
1881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
1891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    err = mCodec->start();
1901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
1911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
1922abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec->release();
1932abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        mCodec.clear();
1941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
1951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return;
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    // the following should work after start
1991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers));
200095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    releaseAndResetMediaBuffers();
2011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers));
2021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ALOGV("[%s] got %zu input and %zu output buffers",
2031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            mComponentName.c_str(),
2041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            mInputBuffers.size(),
2051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            mOutputBuffers.size());
206078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
207c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    if (mRenderer != NULL) {
208c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        requestCodecNotification();
209c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
210704e72658b1082264a26a83c50046da34f07d1a1Wei Jia    mPaused = false;
211f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    mResumePending = false;
2121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
213078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
2147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
2157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hadNoRenderer = (mRenderer == NULL);
2167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mRenderer = renderer;
2177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hadNoRenderer && mRenderer != NULL) {
2187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        requestCodecNotification();
21981e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia    }
2207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
2217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers(
2237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        Vector<sp<ABuffer> > *dstBuffers) {
2247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    dstBuffers->clear();
2257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mInputBuffers.size(); i++) {
2267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        dstBuffers->push(mInputBuffers[i]);
22781e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia    }
2287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
2292245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
230f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) {
2317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPaused = false;
232f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
233f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (notifyComplete) {
234f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = true;
235f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
236095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
237095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
2387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onFlush(bool notifyComplete) {
2397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
2407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->flush();
2417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
2427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
2447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->flush(mIsAudio, notifyComplete);
2457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->signalTimeDiscontinuity();
2467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
2477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
2491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (mCodec != NULL) {
2507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->flush();
2517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
2527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
253078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber    }
254078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
2557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
2567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err);
2577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
2587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatFlushCompleted.
2597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // we attempt to release the buffers even if flush fails.
2607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
2617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (notifyComplete) {
2647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> notify = mNotify->dup();
2657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->setInt32("what", kWhatFlushCompleted);
2667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->post();
2677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mPaused = true;
2687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) {
2727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
273f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
274f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // if there is a pending resume request, notify complete now
275f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
276f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
2777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
2787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = mCodec->release();
2797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec = NULL;
2807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ++mBufferGeneration;
2811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
2827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mNativeWindow != NULL) {
2837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // reconnect to surface as MediaCodec disconnected from it
2847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            status_t error =
2857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    native_window_api_connect(
2867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mNativeWindow->getNativeWindow().get(),
2877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            NATIVE_WINDOW_API_MEDIA);
2887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGW_IF(error != NO_ERROR,
2897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    "[%s] failed to connect to native window, error=%d",
2907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), error);
2917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
2927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mComponentName = "decoder";
2937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
2947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    releaseAndResetMediaBuffers();
2967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
2977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
2987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err);
2997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        handleError(err);
3007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // finish with posting kWhatShutdownCompleted.
3017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
302c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
3037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (notifyComplete) {
3047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> notify = mNotify->dup();
3057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->setInt32("what", kWhatShutdownCompleted);
3067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        notify->post();
3077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mPaused = true;
3087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
30987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
31087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
3117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::doRequestBuffers() {
3127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mFormatChangePending) {
3137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
3147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = OK;
3167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    while (!mDequeuedInputBuffers.empty()) {
3177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        size_t bufferIx = *mDequeuedInputBuffers.begin();
3187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
3197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setSize("buffer-ix", bufferIx);
3207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = fetchInputData(msg);
3217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (err != OK) {
3227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
3237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
3247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
3257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mPendingInputMessages.empty()
3277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                || !onInputBufferFetched(msg)) {
3287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mPendingInputMessages.push_back(msg);
3297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
3307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
331095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
3327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err == -EWOULDBLOCK
3337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            && mSource->feedMoreTSData() == OK) {
3347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        scheduleRequestBuffers();
3357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
336095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar}
337095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
3381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarbool NuPlayer::Decoder::handleAnInputBuffer() {
3397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mFormatChangePending) {
3407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return false;
3417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    size_t bufferIx = -1;
3431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    status_t res = mCodec->dequeueInputBuffer(&bufferIx);
3441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    ALOGV("[%s] dequeued input: %d",
3451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            mComponentName.c_str(), res == OK ? (int)bufferIx : res);
3461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (res != OK) {
3471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (res != -EAGAIN) {
348cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            ALOGE("Failed to dequeue input buffer for %s (err=%d)",
349cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    mComponentName.c_str(), res);
3501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(res);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        return false;
3531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK_LT(bufferIx, mInputBuffers.size());
3561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
357095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (mMediaBuffers[bufferIx] != NULL) {
358095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        mMediaBuffers[bufferIx]->release();
359095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        mMediaBuffers.editItemAt(bufferIx) = NULL;
360095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
361095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    mInputBufferIsDequeued.editItemAt(bufferIx) = true;
362095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
36387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    if (!mCSDsToSubmit.isEmpty()) {
3647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> msg = new AMessage();
3657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setSize("buffer-ix", bufferIx);
3667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
36787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
36887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
3697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        msg->setBuffer("buffer", buffer);
37087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        mCSDsToSubmit.removeAt(0);
3717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(onInputBufferFetched(msg));
3722245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        return true;
3732245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
3742245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
3752245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    while (!mPendingInputMessages.empty()) {
3762245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        sp<AMessage> msg = *mPendingInputMessages.begin();
3777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!onInputBufferFetched(msg)) {
3782245fc625910e47d1ba3c339e205c21ab58a47adWei Jia            break;
3792245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        }
3802245fc625910e47d1ba3c339e205c21ab58a47adWei Jia        mPendingInputMessages.erase(mPendingInputMessages.begin());
3812245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    }
3822245fc625910e47d1ba3c339e205c21ab58a47adWei Jia
3832245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    if (!mInputBufferIsDequeued.editItemAt(bufferIx)) {
38487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        return true;
38587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
38687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
3877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDequeuedInputBuffers.push_back(bufferIx);
3887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
3897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    onRequestInputBuffers();
3901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    return true;
3911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar}
3921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
3937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::handleAnOutputBuffer() {
3947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mFormatChangePending) {
3957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return false;
3967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
3977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t bufferIx = -1;
3987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t offset;
3997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t size;
4007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int64_t timeUs;
4017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    uint32_t flags;
4027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t res = mCodec->dequeueOutputBuffer(
4037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            &bufferIx, &offset, &size, &timeUs, &flags);
4041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
4057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (res != OK) {
4067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGV("[%s] dequeued output: %d", mComponentName.c_str(), res);
4077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } else {
4087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        ALOGV("[%s] dequeued output: %d (time=%lld flags=%" PRIu32 ")",
4097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                mComponentName.c_str(), (int)bufferIx, timeUs, flags);
4107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
411095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
4127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
4137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        res = mCodec->getOutputBuffers(&mOutputBuffers);
4147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (res != OK) {
4157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGE("Failed to get output buffers for %s after INFO event (err=%d)",
4167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), res);
4177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            handleError(res);
4187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return false;
4197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // NuPlayer ignores this
4217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return true;
4227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } else if (res == INFO_FORMAT_CHANGED) {
4237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> format = new AMessage();
4247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        res = mCodec->getOutputFormat(&format);
4257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (res != OK) {
4267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGE("Failed to get output format for %s after INFO event (err=%d)",
4277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), res);
4287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            handleError(res);
4297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return false;
4307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
431095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
4327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mIsAudio) {
4337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<AMessage> notify = mNotify->dup();
4347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            notify->setInt32("what", kWhatVideoSizeChanged);
4357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            notify->setMessage("format", format);
4367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            notify->post();
4377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        } else if (mRenderer != NULL) {
4387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            uint32_t flags;
4397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            int64_t durationUs;
4407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
4417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (!hasVideo &&
4427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mSource->getDuration(&durationUs) == OK &&
4437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    durationUs
4447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
4457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
4467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            } else {
4477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                flags = AUDIO_OUTPUT_FLAG_NONE;
448095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            }
4497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
450202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            res = mRenderer->openAudioSink(
451202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                    format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaded */);
452202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            if (res != OK) {
453202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                ALOGE("Failed to open AudioSink on format change for %s (err=%d)",
454202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                        mComponentName.c_str(), res);
455202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                handleError(res);
456202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                return false;
457202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            }
4587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return true;
4607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } else if (res == INFO_DISCONTINUITY) {
4617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // nothing to do
4627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return true;
4637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } else if (res != OK) {
4647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (res != -EAGAIN) {
4657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGE("Failed to dequeue output buffer for %s (err=%d)",
4667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mComponentName.c_str(), res);
4677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            handleError(res);
468095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
4697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return false;
470095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
471095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
4727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK_LT(bufferIx, mOutputBuffers.size());
4737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> buffer = mOutputBuffers[bufferIx];
4747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->setRange(offset, size);
4757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->clear();
4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    buffer->meta()->setInt64("timeUs", timeUs);
4777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (flags & MediaCodec::BUFFER_FLAG_EOS) {
4787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        buffer->meta()->setInt32("eos", true);
479474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        notifyResumeCompleteIfNecessary();
4807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // we do not expect CODECCONFIG or SYNCFRAME for decoder
4827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id());
4847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setSize("buffer-ix", bufferIx);
4857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setInt32("generation", mBufferGeneration);
4867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mSkipRenderingUntilMediaTimeUs >= 0) {
4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
4897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ALOGV("[%s] dropping buffer at time %lld as requested.",
4907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     mComponentName.c_str(), (long long)timeUs);
4917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->post();
4937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return true;
4947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
4957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
4967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mSkipRenderingUntilMediaTimeUs = -1;
4977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
4987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
499f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    // wait until 1st frame comes out to signal resume complete
500f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    notifyResumeCompleteIfNecessary();
501f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
5027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRenderer != NULL) {
5037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        // send the buffer to renderer.
5047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mRenderer->queueBuffer(mIsAudio, buffer, reply);
5057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
5067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
5077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return true;
5117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
5127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() {
5147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
5157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mMediaBuffers[i] != NULL) {
5167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers[i]->release();
5177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mMediaBuffers.editItemAt(i) = NULL;
5187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
5197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mMediaBuffers.resize(mInputBuffers.size());
5217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
5227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mMediaBuffers.editItemAt(i) = NULL;
5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.clear();
5257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mInputBufferIsDequeued.resize(mInputBuffers.size());
5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mInputBufferIsDequeued.editItemAt(i) = false;
5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mPendingInputMessages.clear();
5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDequeuedInputBuffers.clear();
5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mSkipRenderingUntilMediaTimeUs = -1;
5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() {
5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mFormatChangePending) {
5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
5387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCodec != NULL) {
5407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<AMessage> reply = new AMessage(kWhatCodecNotify, id());
5417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        reply->setInt32("generation", mBufferGeneration);
5427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCodec->requestActivityNotification(reply);
5437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
5447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
5457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
5477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int32_t generation;
5487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findInt32("generation", &generation));
5497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return generation != mBufferGeneration;
5507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
5517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) {
5537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> accessUnit;
5547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool dropAccessUnit;
5557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    do {
5567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
5577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (err == -EWOULDBLOCK) {
5597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return err;
5607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        } else if (err != OK) {
5617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (err == INFO_DISCONTINUITY) {
5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t type;
5637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
5647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool formatChange =
5667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    (mIsAudio &&
5677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
5687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    || (!mIsAudio &&
5697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
5707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
5727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                ALOGI("%s discontinuity (format=%d, time=%d)",
5747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mIsAudio ? "audio" : "video", formatChange, timeChange);
5757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                bool seamlessFormatChange = false;
5777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
5787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange) {
5797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    seamlessFormatChange =
5807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        supportsSeamlessFormatChange(newFormat);
5817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // treat seamless format change separately
5827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    formatChange = !seamlessFormatChange;
5837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
5847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange || timeChange) {
5867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    sp<AMessage> msg = mNotify->dup();
5877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    msg->setInt32("what", kWhatInputDiscontinuity);
5887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    msg->setInt32("formatChange", formatChange);
5897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    msg->post();
5907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
5917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange /* not seamless */) {
5937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // must change decoder
5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // return EOS and wait to be killed
5957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mFormatChangePending = true;
5967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    return ERROR_END_OF_STREAM;
5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (timeChange) {
5987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // need to flush
5997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // TODO: Ideally we shouldn't need a flush upon time
6007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // discontinuity, flushing will cause loss of frames.
6017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // We probably should queue a time change marker to the
6027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // output queue, and handles it in renderer instead.
6037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
6047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    onFlush(false /* notifyComplete */);
6057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    err = OK;
6067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else if (seamlessFormatChange) {
6077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // reuse existing decoder and don't flush
6087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    rememberCodecSpecificData(newFormat);
6097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    err = OK;
6107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                } else {
6117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // This stream is unaffected by the discontinuity
6127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    return -EWOULDBLOCK;
6137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
6147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
6157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            reply->setInt32("err", err);
6177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            return OK;
6187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mIsAudio) {
6217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ++mNumFramesTotal;
6227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        dropAccessUnit = false;
6257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!mIsAudio
6267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && !mIsSecure
6277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && mRenderer->getVideoLateByUs() > 100000ll
6287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && mIsVideoAVC
6297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                && !IsAVCReferenceFrame(accessUnit)) {
6307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            dropAccessUnit = true;
6317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            ++mNumFramesDropped;
6327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } while (dropAccessUnit);
6347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
6367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0
6377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    int64_t mediaTimeUs;
6387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
6397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    ALOGV("feeding %s input buffer at media time %.2f secs",
6407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mIsAudio ? "audio" : "video",
6417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         mediaTimeUs / 1E6);
6427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif
6437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mCCDecoder != NULL) {
6457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCCDecoder->decode(accessUnit);
6467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    reply->setBuffer("buffer", accessUnit);
6497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return OK;
6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
6547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    size_t bufferIx;
6557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK(msg->findSize("buffer-ix", &bufferIx));
6567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    CHECK_LT(bufferIx, mInputBuffers.size());
6577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
6587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<ABuffer> buffer;
6607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    bool hasBuffer = msg->findBuffer("buffer", &buffer);
6617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // handle widevine classic source - that fills an arbitrary input buffer
6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    MediaBuffer *mediaBuffer = NULL;
6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (hasBuffer) {
6657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mediaBuffer != NULL) {
6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // likely filled another buffer than we requested: adjust buffer index
6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            size_t ix;
6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            for (ix = 0; ix < mInputBuffers.size(); ix++) {
6707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                const sp<ABuffer> &buf = mInputBuffers[ix];
6717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (buf->data() == mediaBuffer->data()) {
6727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // all input buffers are dequeued on start, hence the check
6737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    if (!mInputBufferIsDequeued[ix]) {
6747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu",
6757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                mComponentName.c_str(), ix, bufferIx);
6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        mediaBuffer->release();
6777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        return false;
6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    }
6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // TRICKY: need buffer for the metadata, so instead, set
6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // codecBuffer to the same (though incorrect) buffer to
6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    // avoid a memcpy into the codecBuffer
6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer = buffer;
6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    codecBuffer->setRange(
6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_offset(),
6867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            mediaBuffer->range_length());
6877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    bufferIx = ix;
6887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    break;
6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                }
6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            }
6917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(ix < mInputBuffers.size());
6927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
6937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
6947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (buffer == NULL /* includes !hasBuffer */) {
6967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        int32_t streamErr = ERROR_END_OF_STREAM;
6977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
6987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
6997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (streamErr == OK) {
7007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            /* buffers are returned to hold on to */
7012245fc625910e47d1ba3c339e205c21ab58a47adWei Jia            return true;
7021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
7031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
7041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // attempt to queue EOS
7051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
7061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                bufferIx,
7071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
7081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
7091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                0,
7101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                MediaCodec::BUFFER_FLAG_EOS);
711cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        if (err == OK) {
712cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
713cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else if (streamErr == ERROR_END_OF_STREAM) {
7141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            streamErr = err;
7151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            // err will not be ERROR_END_OF_STREAM
7161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
7171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
7181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (streamErr != ERROR_END_OF_STREAM) {
719cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            ALOGE("Stream error for %s (err=%d), EOS %s queued",
720cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    mComponentName.c_str(),
721cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    streamErr,
722cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                    err == OK ? "successfully" : "unsuccessfully");
7231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(streamErr);
7241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
7251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
726c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<AMessage> extra;
727c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
728c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            int64_t resumeAtMediaTimeUs;
729c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            if (extra->findInt64(
730c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
731c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                ALOGI("[%s] suppressing rendering until %lld us",
732c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
733c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
734c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            }
735c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        }
736c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
7371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int64_t timeUs = 0;
7381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        uint32_t flags = 0;
7391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
7401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
74187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        int32_t eos, csd;
74287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        // we do not expect SYNCFRAME for decoder
7431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer->meta()->findInt32("eos", &eos) && eos) {
7441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_EOS;
74587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
74687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar            flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
7471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
7481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
7491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        // copy into codec buffer
7501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (buffer != codecBuffer) {
7511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            CHECK_LE(buffer->size(), codecBuffer->capacity());
7521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            codecBuffer->setRange(0, buffer->size());
7531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            memcpy(codecBuffer->data(), buffer->data(), buffer->size());
7541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        }
7551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
7561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        status_t err = mCodec->queueInputBuffer(
7571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        bufferIx,
7581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->offset(),
7591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        codecBuffer->size(),
7601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        timeUs,
7611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                        flags);
7621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        if (err != OK) {
763cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
764cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mediaBuffer->release();
765cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
7661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            ALOGE("Failed to queue input buffer for %s (err=%d)",
7671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    mComponentName.c_str(), err);
7681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            handleError(err);
769cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung        } else {
770cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
771cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            if (mediaBuffer != NULL) {
772cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                CHECK(mMediaBuffers[bufferIx] == NULL);
773cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung                mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
774cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung            }
775095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7772245fc625910e47d1ba3c339e205c21ab58a47adWei Jia    return true;
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
7811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    status_t err;
7821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    int32_t render;
7831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    size_t bufferIx;
7841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    CHECK(msg->findSize("buffer-ix", &bufferIx));
785c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
7867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!mIsAudio) {
787c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        int64_t timeUs;
788c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        sp<ABuffer> buffer = mOutputBuffers[bufferIx];
789c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        buffer->meta()->findInt64("timeUs", &timeUs);
7907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
7927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mCCDecoder->display(timeUs);
7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
794c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
795c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
7961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (msg->findInt32("render", &render) && render) {
797dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        int64_t timestampNs;
798dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        CHECK(msg->findInt64("timestampNs", &timestampNs));
799dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs);
8001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    } else {
8011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        err = mCodec->releaseOutputBuffer(bufferIx);
8021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    }
8031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    if (err != OK) {
8041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        ALOGE("failed to release output buffer for %s (err=%d)",
8051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mComponentName.c_str(), err);
8061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        handleError(err);
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(
8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &targetFormat) const {
8126d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
8136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
8146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
8156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString mime;
8176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!targetFormat->findString("mime", &mime)) {
8186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
8196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
8206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
8226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        // field-by-field comparison
8236d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
8246d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
8256d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            int32_t oldVal, newVal;
8267abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson            if (!mInputFormat->findInt32(keys[i], &oldVal) ||
8271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    !targetFormat->findInt32(keys[i], &newVal) ||
8281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                    oldVal != newVal) {
8296d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
8306d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
8316d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
8326d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8336d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        sp<ABuffer> oldBuf, newBuf;
8347abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&
8351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                targetFormat->findBuffer("csd-0", &newBuf)) {
8366d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            if (oldBuf->size() != newBuf->size()) {
8376d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih                return false;
8386d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            }
8396d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
8406d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        }
8416d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
8426d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return false;
8436d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
8446d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8456d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
8467abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (mInputFormat == NULL) {
8476d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
8486d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
8496d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8506d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (targetFormat == NULL) {
8516d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return true;
8526d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
8536d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8546d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    AString oldMime, newMime;
8557abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson    if (!mInputFormat->findString("mime", &oldMime)
8566d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !targetFormat->findString("mime", &newMime)
8576d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih            || !(oldMime == newMime)) {
8586d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        return false;
8596d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
8606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
8626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    bool seamless;
8636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    if (audio) {
8646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih        seamless = supportsSeamlessAudioFormatChange(targetFormat);
8656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    } else {
8661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        int32_t isAdaptive;
8671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar        seamless = (mCodec != NULL &&
8681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                mInputFormat->findInt32("adaptive-playback", &isAdaptive) &&
8691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                isAdaptive);
8706d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    }
8716d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
8736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih    return seamless;
8746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih}
8756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih
8767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
8777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (format == NULL) {
878a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        return;
879a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
8807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mCSDsForCurrentFormat.clear();
8817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    for (int32_t i = 0; ; ++i) {
8827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        AString tag = "csd-";
8837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        tag.append(i);
8847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        sp<ABuffer> buffer;
8857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        if (!format->findBuffer(tag.c_str(), &buffer)) {
8867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
8877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
8887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        mCSDsForCurrentFormat.push(buffer);
889a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
890b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang}
891b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang
892f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
893f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (mResumePending) {
894f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = false;
895f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
896f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        sp<AMessage> notify = mNotify->dup();
897f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->setInt32("what", kWhatResumeCompleted);
898f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        notify->post();
899f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
900f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang}
901f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
904