NuPlayer.cpp revision b58ce9f5e8d0696f9571a94ba5fc05f4500f663f
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/*
2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2010 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 "NuPlayer"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h>
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayer.h"
225bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
235bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "HTTPLiveSource.h"
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h"
2543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber#include "NuPlayerDriver.h"
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerRenderer.h"
275bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "NuPlayerSource.h"
282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include "RTSPSource.h"
295bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "StreamingSource.h"
305bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
315bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "ATSParser.h"
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
383fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include <media/stagefright/MediaDefs.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaErrors.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <surfaceflinger/Surface.h>
421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/ISurfaceTexture.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include "avc_utils.h"
453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::NuPlayer()
519b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    : mUIDValid(false),
523fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mVideoIsAVC(false),
539b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mAudioEOS(false),
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoEOS(false),
555bc087c573c70c84c6a39946457590b42d392a33Andreas Huber      mScanSourcesPending(false),
561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mScanSourcesGeneration(0),
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlushingAudio(NONE),
581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mFlushingVideo(NONE),
591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mResetInProgress(false),
603fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mResetPostponed(false),
613fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
633fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mVideoLateByUs(0ll),
643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mNumFramesTotal(0ll),
653fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mNumFramesDropped(0ll) {
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::~NuPlayer() {
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid NuPlayer::setUID(uid_t uid) {
729b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUIDValid = true;
739b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
749b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber}
759b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
7643c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
7743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mDriver = driver;
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
80f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setDataSource(const sp<IStreamSource> &source) {
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    msg->setObject("source", new StreamingSource(source));
845bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    msg->post();
855bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
865bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
875bc087c573c70c84c6a39946457590b42d392a33Andreas Hubervoid NuPlayer::setDataSource(
885bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        const char *url, const KeyedVector<String8, String8> *headers) {
895bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!strncasecmp(url, "rtsp://", 7)) {
922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        msg->setObject(
932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                "source", new RTSPSource(url, headers, mUIDValid, mUID));
942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    } else {
952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        msg->setObject(
962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                "source", new HTTPLiveSource(url, headers, mUIDValid, mUID));
972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1021173118eace0e9e347cb007f0da817cee87579edGlenn Kastenvoid NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
1031173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
1041173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
1051173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                new SurfaceTextureClient(surfaceTexture) : NULL);
1061173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
110f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setObject("sink", sink);
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
116f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::start() {
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatStart, id()))->post();
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12043c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::pause() {
121b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatPause, id()))->post();
12243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
12343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
12443c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::resume() {
125b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatResume, id()))->post();
12643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
12743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
1281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::resetAsync() {
1291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (new AMessage(kWhatReset, id()))->post();
1301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
1311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
13243c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::seekToAsync(int64_t seekTimeUs) {
13343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, id());
13443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->setInt64("seekTimeUs", seekTimeUs);
13543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->post();
13643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
13743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
13853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber// static
1391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberbool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
14053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    switch (state) {
14153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        case FLUSHING_DECODER:
1421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
1431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = false;
14453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
14553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
14653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
1471aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case FLUSHING_DECODER_SHUTDOWN:
1481aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
1491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = true;
15053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
15153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
15253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
15353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        default:
15453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return false;
15553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    }
15653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
15753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
158f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetDataSource:
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            LOGV("kWhatSetDataSource");
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(mSource == NULL);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1665bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            sp<RefBase> obj;
1675bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(msg->findObject("source", &obj));
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1695bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource = static_cast<Source *>(obj.get());
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1731173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        case kWhatSetVideoNativeWindow:
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1751173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            LOGV("kWhatSetVideoNativeWindow");
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
1781173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            CHECK(msg->findObject("native-window", &obj));
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1801173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetAudioSink:
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1861aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            LOGV("kWhatSetAudioSink");
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findObject("sink", &obj));
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatStart:
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
19743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            LOGV("kWhatStart");
19843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
1993fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoIsAVC = false;
2001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mAudioEOS = false;
2011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mVideoEOS = false;
20232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingAudioUntilMediaTimeUs = -1;
20332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingVideoUntilMediaTimeUs = -1;
2043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoLateByUs = 0;
2053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesTotal = 0;
2063fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesDropped = 0;
2071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2085bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource->start();
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mRenderer = new Renderer(
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioSink,
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    new AMessage(kWhatRendererNotify, id()));
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            looper()->registerHandler(mRenderer);
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            postScanSources();
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatScanSources:
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            int32_t generation;
2231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            CHECK(msg->findInt32("generation", &generation));
2241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (generation != mScanSourcesGeneration) {
2251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // Drop obsolete msg.
2261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
2271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
2281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2295bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mScanSourcesPending = false;
2305bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
23143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            LOGV("scanning sources haveAudio=%d, haveVideo=%d",
23243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 mAudioDecoder != NULL, mVideoDecoder != NULL);
23343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
2345bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            instantiateDecoder(false, &mVideoDecoder);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioSink != NULL) {
2375bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                instantiateDecoder(true, &mAudioDecoder);
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            status_t err;
241eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            if ((err = mSource->feedMoreTSData()) != OK) {
2421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
2431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // We're not currently decoding anything (no audio or
2441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // video tracks found) and we just ran out of input data.
245eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber
246eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (err == ERROR_END_OF_STREAM) {
247eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
248eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    } else {
249eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
250eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    }
2511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                }
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->post(100000ll);
2575bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                mScanSourcesPending = true;
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatVideoNotify:
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatAudioNotify:
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            bool audio = msg->what() == kWhatAudioNotify;
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> codecRequest;
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findMessage("codec-request", &codecRequest));
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(codecRequest->findInt32("what", &what));
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == ACodec::kWhatFillThisBuffer) {
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                status_t err = feedDecoderInputData(
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        audio, codecRequest);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2775bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                if (err == -EWOULDBLOCK) {
278eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (mSource->feedMoreTSData() == OK) {
2791183a4ab06b9fe01fe39a4b8728bfc71789361fcAndreas Huber                        msg->post(10000ll);
2805bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                    }
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatEOS) {
283dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                int32_t err;
284dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                CHECK(codecRequest->findInt32("err", &err));
285dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
286dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err == ERROR_END_OF_STREAM) {
287dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    LOGV("got %s decoder EOS", audio ? "audio" : "video");
288dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
289dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    LOGV("got %s decoder EOS w/ error %d",
290dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         audio ? "audio" : "video",
291dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         err);
292dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
293dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
294dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mRenderer->queueEOS(audio, err);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatFlushCompleted) {
2961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                bool needShutdown;
29753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
2991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingAudio = FLUSHED;
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
3021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingVideo = FLUSHED;
3043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
3053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mVideoLateByUs = 0;
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                LOGV("decoder %s flush completed", audio ? "audio" : "video");
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (needShutdown) {
3111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    LOGV("initiating %s decoder shutdown",
31253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                         audio ? "audio" : "video");
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    if (audio) {
31753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingAudio = SHUTTING_DOWN_DECODER;
31853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    } else {
31953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingVideo = SHUTTING_DOWN_DECODER;
32053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    }
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3223831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
3233831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
3242c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber            } else if (what == ACodec::kWhatOutputFormatChanged) {
32531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                if (audio) {
32631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t numChannels;
32731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("channel-count", &numChannels));
3282c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
32931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t sampleRate;
33031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
3312c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
33231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    LOGV("Audio output format changed to %d Hz, %d channels",
33331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         sampleRate, numChannels);
3342c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
33531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->close();
336078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                    CHECK_EQ(mAudioSink->open(
337078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                sampleRate,
338078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                numChannels,
339078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                AUDIO_FORMAT_PCM_16_BIT,
340078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                8 /* bufferCount */),
341078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                             (status_t)OK);
34231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->start();
3433831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
34431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mRenderer->signalAudioSinkChanged();
34531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                } else {
34631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // video
34731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
34831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t width, height;
34931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("width", &width));
35031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("height", &height));
35131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t cropLeft, cropTop, cropRight, cropBottom;
35331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findRect(
35431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                "crop",
35531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                &cropLeft, &cropTop, &cropRight, &cropBottom));
35631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    LOGV("Video output format changed to %d x %d "
358cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "(crop: %d x %d @ (%d, %d))",
35931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         width, height,
360cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         (cropRight - cropLeft + 1),
361cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         (cropBottom - cropTop + 1),
362cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         cropLeft, cropTop);
36331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
36431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    notifyListener(
36531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            MEDIA_SET_VIDEO_SIZE,
36631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            cropRight - cropLeft + 1,
36731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            cropBottom - cropTop + 1);
36831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                }
3693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            } else if (what == ACodec::kWhatShutdownCompleted) {
3701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                LOGV("%s shutdown completed", audio ? "audio" : "video");
3713831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                if (audio) {
3723831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mAudioDecoder.clear();
3733831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
3743831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
3753831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingAudio = SHUT_DOWN;
3763831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                } else {
3773831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mVideoDecoder.clear();
3783831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
3793831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
3803831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingVideo = SHUT_DOWN;
3813831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                }
3823831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
3833831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
384c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            } else if (what == ACodec::kWhatError) {
385c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                LOGE("Received error from %s decoder, aborting playback.",
386c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                     audio ? "audio" : "video");
387c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
388c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                renderBuffer(audio, codecRequest);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatRendererNotify:
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("what", &what));
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == Renderer::kWhatEOS) {
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                int32_t finalResult;
408c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                CHECK(msg->findInt32("finalResult", &finalResult));
409c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEOS = true;
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mVideoEOS = true;
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
416c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (finalResult == ERROR_END_OF_STREAM) {
417c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    LOGV("reached %s EOS", audio ? "audio" : "video");
418c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                } else {
419dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    LOGE("%s track encountered an error (%d)",
420c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         audio ? "audio" : "video", finalResult);
421c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
422c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    notifyListener(
423c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
424c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if ((mAudioEOS || mAudioDecoder == NULL)
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        && (mVideoEOS || mVideoDecoder == NULL)) {
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
43043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            } else if (what == Renderer::kWhatPosition) {
43143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                int64_t positionUs;
43243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                CHECK(msg->findInt64("positionUs", &positionUs));
43343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
4343fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
4353fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
43643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (mDriver != NULL) {
43743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    sp<NuPlayerDriver> driver = mDriver.promote();
43843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    if (driver != NULL) {
43943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                        driver->notifyPosition(positionUs);
4403fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
4413fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        driver->notifyFrameStats(
4423fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                mNumFramesTotal, mNumFramesDropped);
44343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    }
44443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
4453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            } else if (what == Renderer::kWhatFlushComplete) {
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                LOGV("renderer %s flush completed.", audio ? "audio" : "video");
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatMoreDataQueued:
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case kWhatReset:
4621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        {
4631aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            LOGV("kWhatReset");
4641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
465b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber            if (mRenderer != NULL) {
466b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // There's an edge case where the renderer owns all output
467b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // buffers and is paused, therefore the decoder will not read
468b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // more input data and will never encounter the matching
469b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // discontinuity. To avoid this, we resume the renderer.
470b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
471b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                if (mFlushingAudio == AWAITING_DISCONTINUITY
472b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                        || mFlushingVideo == AWAITING_DISCONTINUITY) {
473b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                    mRenderer->resume();
474b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                }
475b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber            }
476b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
4771aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
4781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // We're currently flushing, postpone the reset until that's
4791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // completed.
4801aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
481b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                LOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
482b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                        mFlushingAudio, mFlushingVideo);
4831aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4841aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                mResetPostponed = true;
4851aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
4861aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
4871aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
4891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                finishReset();
4901aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
4911aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
4921aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4931aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mAudioDecoder != NULL) {
4941aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                flushDecoder(true /* audio */, true /* needShutdown */);
4951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
4961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mVideoDecoder != NULL) {
4981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                flushDecoder(false /* audio */, true /* needShutdown */);
4991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mResetInProgress = true;
5021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            break;
5031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
5041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
50543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        case kWhatSeek:
50643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        {
50743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            int64_t seekTimeUs;
50843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
50943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
51022fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber            LOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
51143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 seekTimeUs, seekTimeUs / 1E6);
51243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
51343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            mSource->seekTo(seekTimeUs);
51443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
51543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            if (mDriver != NULL) {
51643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                sp<NuPlayerDriver> driver = mDriver.promote();
51743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (driver != NULL) {
51843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    driver->notifySeekComplete();
51943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
52043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            }
52143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
52243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            break;
52343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
52443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
525b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatPause:
526b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
527b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
528b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->pause();
529b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
530b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
531b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
532b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatResume:
533b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
534b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
535b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->resume();
536b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
537b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
538b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5453831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::finishFlushIfPossible() {
5463831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
5473831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
5483831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5493831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5503831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
5513831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
5523831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5533831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    LOGV("both audio and video are flushed now.");
5553831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5563831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mRenderer->signalTimeDiscontinuity();
5573831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
55822fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mAudioDecoder != NULL) {
5593831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mAudioDecoder->signalResume();
5603831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5613831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
56222fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mVideoDecoder != NULL) {
5633831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mVideoDecoder->signalResume();
5643831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5653831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5663831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingAudio = NONE;
5673831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingVideo = NONE;
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mResetInProgress) {
5701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        LOGV("reset completed");
5711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5721aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mResetInProgress = false;
5731aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        finishReset();
5741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else if (mResetPostponed) {
5751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        (new AMessage(kWhatReset, id()))->post();
5761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mResetPostponed = false;
57722fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
5781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        postScanSources();
5791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
5801aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
5811aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5821aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::finishReset() {
5831aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    CHECK(mAudioDecoder == NULL);
5841aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    CHECK(mVideoDecoder == NULL);
5851aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    ++mScanSourcesGeneration;
5872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mScanSourcesPending = false;
5882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mRenderer.clear();
5902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mSource != NULL) {
5922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mSource->stop();
5932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mSource.clear();
5942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
59643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver != NULL) {
59743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
59843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (driver != NULL) {
59943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            driver->notifyResetComplete();
60043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
60143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
6021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
6031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::postScanSources() {
6051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mScanSourcesPending) {
6061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return;
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
6101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->setInt32("generation", mScanSourcesGeneration);
6111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->post();
6121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mScanSourcesPending = true;
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6165bc087c573c70c84c6a39946457590b42d392a33Andreas Huberstatus_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (*decoder != NULL) {
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6215bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<MetaData> meta = mSource->getFormat(audio);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6235bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    if (meta == NULL) {
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6273fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    if (!audio) {
6283fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        const char *mime;
6293fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
6303fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime);
6313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    }
6323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify =
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     id());
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    *decoder = audio ? new Decoder(notify) :
6381173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                       new Decoder(notify, mNativeWindow);
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper()->registerHandler(*decoder);
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6415bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    (*decoder)->configure(meta);
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int64_t durationUs;
64443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
64543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
64643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (driver != NULL) {
64743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            driver->notifyDuration(durationUs);
64843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
64943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
65043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    if ((audio && IsFlushingState(mFlushingAudio))
65953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            || (!audio && IsFlushingState(mFlushingVideo))) {
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->setInt32("err", INFO_DISCONTINUITY);
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->post();
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> accessUnit;
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6673fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    bool dropAccessUnit;
6683fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    do {
6693fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
6705bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
6713fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (err == -EWOULDBLOCK) {
6723fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return err;
6733fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        } else if (err != OK) {
6743fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            if (err == INFO_DISCONTINUITY) {
6753fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                int32_t type;
6763fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
67753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
6783fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                bool formatChange =
6793fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    type == ATSParser::DISCONTINUITY_FORMATCHANGE;
68053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
6813fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                LOGV("%s discontinuity (formatChange=%d)",
6823fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                     audio ? "audio" : "video", formatChange);
68332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
6843fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                if (audio) {
6853fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingAudioUntilMediaTimeUs = -1;
6863fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                } else {
6873fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingVideoUntilMediaTimeUs = -1;
6883fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                }
68932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
6903fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                sp<AMessage> extra;
6913fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                if (accessUnit->meta()->findMessage("extra", &extra)
6923fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        && extra != NULL) {
6933fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    int64_t resumeAtMediaTimeUs;
6943fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    if (extra->findInt64(
6953fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
6963fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        LOGI("suppressing rendering of %s until %lld us",
6973fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                audio ? "audio" : "video", resumeAtMediaTimeUs);
6983fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
6993fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        if (audio) {
7003fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                            mSkipRenderingAudioUntilMediaTimeUs =
7013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                resumeAtMediaTimeUs;
7023fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        } else {
7033fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                            mSkipRenderingVideoUntilMediaTimeUs =
7043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                resumeAtMediaTimeUs;
7053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        }
70632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                    }
70732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                }
7083fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
7093fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                flushDecoder(audio, formatChange);
71032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            }
71132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
7123fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->setInt32("err", err);
7133fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->post();
7143fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return OK;
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7173fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio) {
7183fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesTotal;
7193fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
7203fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
7213fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        dropAccessUnit = false;
7223fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio
7233fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoLateByUs > 100000ll
7243fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoIsAVC
7253fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && !IsAVCReferenceFrame(accessUnit)) {
7263fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            dropAccessUnit = true;
7273fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesDropped;
7283fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
7293fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    } while (dropAccessUnit);
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    // LOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mediaTimeUs;
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
7361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    LOGV("feeding %s input buffer at media time %.2f secs",
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         audio ? "audio" : "video",
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mediaTimeUs / 1E6);
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setObject("buffer", accessUnit);
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->post();
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
747f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
74843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    // LOGV("renderBuffer %s", audio ? "audio" : "video");
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
75418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // We're currently attempting to flush the decoder, in order
75518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // to complete this, the decoder wants all its buffers back,
75618ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // so we don't want any output buffers it sent us (from before
75718ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // we initiated the flush) to be stuck in the renderer's queue.
75818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
75918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        LOGV("we're still flushing the %s decoder, sending its output buffer"
76018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber             " right back.", audio ? "audio" : "video");
76118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
76218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        reply->post();
76318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        return;
76418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
76518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findObject("buffer", &obj));
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    int64_t &skipUntilMediaTimeUs =
77232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        audio
77332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            ? mSkipRenderingAudioUntilMediaTimeUs
77432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            : mSkipRenderingVideoUntilMediaTimeUs;
77532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
77632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    if (skipUntilMediaTimeUs >= 0) {
77732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        int64_t mediaTimeUs;
77832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
77932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
78032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        if (mediaTimeUs < skipUntilMediaTimeUs) {
78132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            LOGV("dropping %s buffer at time %lld as requested.",
78232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 audio ? "audio" : "video",
78332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 mediaTimeUs);
78432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
78532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            reply->post();
78632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            return;
78732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        }
78832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
78932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        skipUntilMediaTimeUs = -1;
79032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    }
79132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mRenderer->queueBuffer(audio, buffer, reply);
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
795f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::notifyListener(int msg, int ext1, int ext2) {
79643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver == NULL) {
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
80043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<NuPlayerDriver> driver = mDriver.promote();
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
80243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (driver == NULL) {
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806a4af2143ecbd630e946647c1b5f90fda8f61ebb3Andreas Huber    driver->notifyListener(msg, ext1, ext2);
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::flushDecoder(bool audio, bool needShutdown) {
8101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    // Make sure we don't continue to scan sources until we finish flushing.
8111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    ++mScanSourcesGeneration;
81243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mScanSourcesPending = false;
8131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
8151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mRenderer->flush(audio);
8161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    FlushStatus newStatus =
8181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
8191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (audio) {
8211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingAudio == NONE
8221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingAudio == AWAITING_DISCONTINUITY);
8231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingAudio = newStatus;
8251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingVideo == NONE) {
8271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingVideo = (mVideoDecoder != NULL)
8281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
8291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
8301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
8311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else {
8321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingVideo == NONE
8331aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingVideo == AWAITING_DISCONTINUITY);
8341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8351aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingVideo = newStatus;
8361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingAudio == NONE) {
8381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingAudio = (mAudioDecoder != NULL)
8391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
8401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
8411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
8421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
8431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
8441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
846