NuPlayer.cpp revision afed0e1fa37473a4cd30018577b560acc79d9a3f
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"
30afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "GenericSource.h"
315bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
325bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "ATSParser.h"
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#include <media/stagefright/foundation/hexdump.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
393fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include <media/stagefright/MediaDefs.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaErrors.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.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),
576e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber      mTimeDiscontinuityPending(false),
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlushingAudio(NONE),
591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mFlushingVideo(NONE),
601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mResetInProgress(false),
613fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mResetPostponed(false),
623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
633fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mVideoLateByUs(0ll),
653fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mNumFramesTotal(0ll),
663fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mNumFramesDropped(0ll) {
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::~NuPlayer() {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
729b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid NuPlayer::setUID(uid_t uid) {
739b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUIDValid = true;
749b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
759b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber}
769b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
7743c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
7843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mDriver = driver;
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setDataSource(const sp<IStreamSource> &source) {
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
845bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    msg->setObject("source", new StreamingSource(source));
855bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    msg->post();
865bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
875bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
88afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatic bool IsHTTPLiveURL(const char *url) {
89afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!strncasecmp("http://", url, 7)
90afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            || !strncasecmp("https://", url, 8)) {
91afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        size_t len = strlen(url);
92afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
93afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
94afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
95afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
96afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (strstr(url,"m3u8")) {
97afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
98afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
99afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
100afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
101afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return false;
102afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
103afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1045bc087c573c70c84c6a39946457590b42d392a33Andreas Hubervoid NuPlayer::setDataSource(
1055bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        const char *url, const KeyedVector<String8, String8> *headers) {
1065bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
108afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<Source> source;
109afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (IsHTTPLiveURL(url)) {
110afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        source = new HTTPLiveSource(url, headers, mUIDValid, mUID);
111afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    } else if (!strncasecmp(url, "rtsp://", 7)) {
112afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        source = new RTSPSource(url, headers, mUIDValid, mUID);
1132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    } else {
114afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        source = new GenericSource(url, headers, mUIDValid, mUID);
1152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
117afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
118afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->post();
119afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
120afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
121afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
122afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
123afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
124afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<Source> source = new GenericSource(fd, offset, length);
125afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1291173118eace0e9e347cb007f0da817cee87579edGlenn Kastenvoid NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
1301173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
1311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
1321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                new SurfaceTextureClient(surfaceTexture) : NULL);
1331173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setObject("sink", sink);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
143f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::start() {
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatStart, id()))->post();
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14743c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::pause() {
148b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatPause, id()))->post();
14943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
15043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
15143c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::resume() {
152b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatResume, id()))->post();
15343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
15443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
1551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::resetAsync() {
1561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (new AMessage(kWhatReset, id()))->post();
1571aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
1581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
15943c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::seekToAsync(int64_t seekTimeUs) {
16043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, id());
16143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->setInt64("seekTimeUs", seekTimeUs);
16243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->post();
16343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
16443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
16553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber// static
1661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberbool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
16753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    switch (state) {
16853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        case FLUSHING_DECODER:
1691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
1701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = false;
17153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
17253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
17353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
1741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case FLUSHING_DECODER_SHUTDOWN:
1751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
1761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = true;
17753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
17853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
17953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
18053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        default:
18153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return false;
18253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    }
18353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
18453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
185f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetDataSource:
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetDataSource");
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(mSource == NULL);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1935bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            sp<RefBase> obj;
1945bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(msg->findObject("source", &obj));
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1965bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource = static_cast<Source *>(obj.get());
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2001173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        case kWhatSetVideoNativeWindow:
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetVideoNativeWindow");
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
2051173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            CHECK(msg->findObject("native-window", &obj));
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2071173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetAudioSink:
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetAudioSink");
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findObject("sink", &obj));
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatStart:
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatStart");
22543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
2263fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoIsAVC = false;
2271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mAudioEOS = false;
2281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mVideoEOS = false;
22932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingAudioUntilMediaTimeUs = -1;
23032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingVideoUntilMediaTimeUs = -1;
2313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoLateByUs = 0;
2323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesTotal = 0;
2333fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesDropped = 0;
2341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2355bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource->start();
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mRenderer = new Renderer(
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioSink,
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    new AMessage(kWhatRendererNotify, id()));
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            looper()->registerHandler(mRenderer);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            postScanSources();
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatScanSources:
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            int32_t generation;
2501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            CHECK(msg->findInt32("generation", &generation));
2511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (generation != mScanSourcesGeneration) {
2521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // Drop obsolete msg.
2531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
2541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
2551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2565bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mScanSourcesPending = false;
2575bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
2583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
25943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 mAudioDecoder != NULL, mVideoDecoder != NULL);
26043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
2615bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            instantiateDecoder(false, &mVideoDecoder);
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioSink != NULL) {
2645bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                instantiateDecoder(true, &mAudioDecoder);
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            status_t err;
268eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            if ((err = mSource->feedMoreTSData()) != OK) {
2691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
2701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // We're not currently decoding anything (no audio or
2711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // video tracks found) and we just ran out of input data.
272eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber
273eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (err == ERROR_END_OF_STREAM) {
274eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
275eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    } else {
276eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
277eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    }
2781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                }
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->post(100000ll);
2845bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                mScanSourcesPending = true;
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatVideoNotify:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatAudioNotify:
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            bool audio = msg->what() == kWhatAudioNotify;
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> codecRequest;
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findMessage("codec-request", &codecRequest));
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(codecRequest->findInt32("what", &what));
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == ACodec::kWhatFillThisBuffer) {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                status_t err = feedDecoderInputData(
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        audio, codecRequest);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3045bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                if (err == -EWOULDBLOCK) {
305eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (mSource->feedMoreTSData() == OK) {
3061183a4ab06b9fe01fe39a4b8728bfc71789361fcAndreas Huber                        msg->post(10000ll);
3075bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                    }
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatEOS) {
310dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                int32_t err;
311dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                CHECK(codecRequest->findInt32("err", &err));
312dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
313dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err == ERROR_END_OF_STREAM) {
3143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
315dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
3163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS w/ error %d",
317dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         audio ? "audio" : "video",
318dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         err);
319dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
320dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
321dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mRenderer->queueEOS(audio, err);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatFlushCompleted) {
3231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                bool needShutdown;
32453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
3261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingAudio = FLUSHED;
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
3291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingVideo = FLUSHED;
3313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
3323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mVideoLateByUs = 0;
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (needShutdown) {
3383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("initiating %s decoder shutdown",
33953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                         audio ? "audio" : "video");
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    if (audio) {
34453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingAudio = SHUTTING_DOWN_DECODER;
34553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    } else {
34653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingVideo = SHUTTING_DOWN_DECODER;
34753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    }
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3493831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
3503831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
3512c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber            } else if (what == ACodec::kWhatOutputFormatChanged) {
35231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                if (audio) {
35331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t numChannels;
35431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("channel-count", &numChannels));
3552c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
35631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t sampleRate;
35731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
3582c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
3593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Audio output format changed to %d Hz, %d channels",
36031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         sampleRate, numChannels);
3612c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
36231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->close();
363078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                    CHECK_EQ(mAudioSink->open(
364078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                sampleRate,
365078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                numChannels,
366786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi                                CHANNEL_MASK_USE_CHANNEL_ORDER,
367078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                AUDIO_FORMAT_PCM_16_BIT,
368078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                8 /* bufferCount */),
369078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                             (status_t)OK);
37031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->start();
3713831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
37231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mRenderer->signalAudioSinkChanged();
37331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                } else {
37431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // video
37531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
37631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t width, height;
37731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("width", &width));
37831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("height", &height));
37931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
38031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t cropLeft, cropTop, cropRight, cropBottom;
38131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findRect(
38231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                "crop",
38331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                &cropLeft, &cropTop, &cropRight, &cropBottom));
38431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Video output format changed to %d x %d "
386cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "(crop: %d x %d @ (%d, %d))",
38731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         width, height,
388cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         (cropRight - cropLeft + 1),
389cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         (cropBottom - cropTop + 1),
390cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         cropLeft, cropTop);
39131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
39231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    notifyListener(
39331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            MEDIA_SET_VIDEO_SIZE,
39431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            cropRight - cropLeft + 1,
39531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            cropBottom - cropTop + 1);
39631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                }
3973831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            } else if (what == ACodec::kWhatShutdownCompleted) {
3983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("%s shutdown completed", audio ? "audio" : "video");
3993831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                if (audio) {
4003831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mAudioDecoder.clear();
4013831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4023831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
4033831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingAudio = SHUT_DOWN;
4043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                } else {
4053831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mVideoDecoder.clear();
4063831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4073831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
4083831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingVideo = SHUT_DOWN;
4093831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                }
4103831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4113831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
412c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            } else if (what == ACodec::kWhatError) {
41329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("Received error from %s decoder, aborting playback.",
414c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                     audio ? "audio" : "video");
415c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
416c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else if (what == ACodec::kWhatDrainThisBuffer) {
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                renderBuffer(audio, codecRequest);
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("Unhandled codec notification %d.", what);
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatRendererNotify:
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("what", &what));
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == Renderer::kWhatEOS) {
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                int32_t finalResult;
436c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                CHECK(msg->findInt32("finalResult", &finalResult));
437c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEOS = true;
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mVideoEOS = true;
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (finalResult == ERROR_END_OF_STREAM) {
4453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("reached %s EOS", audio ? "audio" : "video");
446c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                } else {
44729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("%s track encountered an error (%d)",
448c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         audio ? "audio" : "video", finalResult);
449c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
450c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    notifyListener(
451c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
452c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if ((mAudioEOS || mAudioDecoder == NULL)
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        && (mVideoEOS || mVideoDecoder == NULL)) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
45843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            } else if (what == Renderer::kWhatPosition) {
45943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                int64_t positionUs;
46043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                CHECK(msg->findInt64("positionUs", &positionUs));
46143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
4623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
4633fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
46443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (mDriver != NULL) {
46543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    sp<NuPlayerDriver> driver = mDriver.promote();
46643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    if (driver != NULL) {
46743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                        driver->notifyPosition(positionUs);
4683fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
4693fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        driver->notifyFrameStats(
4703fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                mNumFramesTotal, mNumFramesDropped);
47143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    }
47243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
4733fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            } else if (what == Renderer::kWhatFlushComplete) {
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatMoreDataQueued:
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case kWhatReset:
4901aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        {
4913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatReset");
4921aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
493b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber            if (mRenderer != NULL) {
494b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // There's an edge case where the renderer owns all output
495b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // buffers and is paused, therefore the decoder will not read
496b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // more input data and will never encounter the matching
497b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // discontinuity. To avoid this, we resume the renderer.
498b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
499b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                if (mFlushingAudio == AWAITING_DISCONTINUITY
500b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                        || mFlushingVideo == AWAITING_DISCONTINUITY) {
501b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                    mRenderer->resume();
502b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                }
503b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber            }
504b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
5051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
5061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // We're currently flushing, postpone the reset until that's
5071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // completed.
5081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
509ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber                ALOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
510ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber                      mFlushingAudio, mFlushingVideo);
5111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                mResetPostponed = true;
5131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
5141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
5171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                finishReset();
5181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
5191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5216e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            mTimeDiscontinuityPending = true;
5226e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
5231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mAudioDecoder != NULL) {
5241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                flushDecoder(true /* audio */, true /* needShutdown */);
5251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mVideoDecoder != NULL) {
5281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                flushDecoder(false /* audio */, true /* needShutdown */);
5291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mResetInProgress = true;
5321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            break;
5331aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
5341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
53543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        case kWhatSeek:
53643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        {
53743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            int64_t seekTimeUs;
53843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
53943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
5403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
54143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 seekTimeUs, seekTimeUs / 1E6);
54243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
54343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            mSource->seekTo(seekTimeUs);
54443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
54543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            if (mDriver != NULL) {
54643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                sp<NuPlayerDriver> driver = mDriver.promote();
54743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (driver != NULL) {
54843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    driver->notifySeekComplete();
54943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
55043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            }
55143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
55243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            break;
55343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
55443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
555b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatPause:
556b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
557b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
558b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->pause();
559b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
560b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
561b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
562b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatResume:
563b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
564b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
565b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->resume();
566b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
567b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
568b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5753831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::finishFlushIfPossible() {
5763831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
5773831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
5783831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5793831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5803831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
5813831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
5823831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5833831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("both audio and video are flushed now.");
5853831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5866e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (mTimeDiscontinuityPending) {
5876e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mRenderer->signalTimeDiscontinuity();
5886e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mTimeDiscontinuityPending = false;
5896e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
5903831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
59122fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mAudioDecoder != NULL) {
5923831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mAudioDecoder->signalResume();
5933831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5943831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
59522fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mVideoDecoder != NULL) {
5963831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mVideoDecoder->signalResume();
5973831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5983831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5993831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingAudio = NONE;
6003831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingVideo = NONE;
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mResetInProgress) {
6033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("reset completed");
6041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mResetInProgress = false;
6061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        finishReset();
6071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else if (mResetPostponed) {
6081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        (new AMessage(kWhatReset, id()))->post();
6091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mResetPostponed = false;
61022fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
6111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        postScanSources();
6121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
6131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
6141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::finishReset() {
6161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    CHECK(mAudioDecoder == NULL);
6171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    CHECK(mVideoDecoder == NULL);
6181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    ++mScanSourcesGeneration;
6202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mScanSourcesPending = false;
6212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mRenderer.clear();
6232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mSource != NULL) {
6252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mSource->stop();
6262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mSource.clear();
6272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
62943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver != NULL) {
63043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
63143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (driver != NULL) {
63243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            driver->notifyResetComplete();
63343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
63443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
6351aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
6361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::postScanSources() {
6381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mScanSourcesPending) {
6391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return;
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
6431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->setInt32("generation", mScanSourcesGeneration);
6441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->post();
6451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6461aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mScanSourcesPending = true;
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6495bc087c573c70c84c6a39946457590b42d392a33Andreas Huberstatus_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (*decoder != NULL) {
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6545bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<MetaData> meta = mSource->getFormat(audio);
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6565bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    if (meta == NULL) {
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6603fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    if (!audio) {
6613fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        const char *mime;
6623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
6633fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime);
6643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    }
6653fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify =
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     id());
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6701173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    *decoder = audio ? new Decoder(notify) :
6711173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                       new Decoder(notify, mNativeWindow);
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper()->registerHandler(*decoder);
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6745bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    (*decoder)->configure(meta);
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int64_t durationUs;
67743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
67843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
67943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (driver != NULL) {
68043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            driver->notifyDuration(durationUs);
68143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
68243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
68343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    if ((audio && IsFlushingState(mFlushingAudio))
69253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            || (!audio && IsFlushingState(mFlushingVideo))) {
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->setInt32("err", INFO_DISCONTINUITY);
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->post();
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> accessUnit;
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7003fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    bool dropAccessUnit;
7013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    do {
7023fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
7035bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
7043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (err == -EWOULDBLOCK) {
7053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return err;
7063fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        } else if (err != OK) {
7073fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            if (err == INFO_DISCONTINUITY) {
7083fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                int32_t type;
7093fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
71053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
7113fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                bool formatChange =
7126e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    (audio &&
7136e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
7146e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    || (!audio &&
7156e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
71653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
7176e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
7186e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
719df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("%s discontinuity (formatChange=%d, time=%d)",
7206e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                     audio ? "audio" : "video", formatChange, timeChange);
72132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
7223fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                if (audio) {
7233fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingAudioUntilMediaTimeUs = -1;
7243fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                } else {
7253fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingVideoUntilMediaTimeUs = -1;
7263fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                }
72732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
7286e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                if (timeChange) {
7296e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    sp<AMessage> extra;
7306e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    if (accessUnit->meta()->findMessage("extra", &extra)
7316e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            && extra != NULL) {
7326e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        int64_t resumeAtMediaTimeUs;
7336e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        if (extra->findInt64(
7346e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
735df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                            ALOGI("suppressing rendering of %s until %lld us",
7366e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
7376e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
7386e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            if (audio) {
7396e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                mSkipRenderingAudioUntilMediaTimeUs =
7406e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    resumeAtMediaTimeUs;
7416e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            } else {
7426e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                mSkipRenderingVideoUntilMediaTimeUs =
7436e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    resumeAtMediaTimeUs;
7446e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            }
7453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        }
74632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                    }
74732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                }
7483fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
7496e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                mTimeDiscontinuityPending =
7506e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    mTimeDiscontinuityPending || timeChange;
7516e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
7526e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                if (formatChange || timeChange) {
7536e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    flushDecoder(audio, formatChange);
7546e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                } else {
7556e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    // This stream is unaffected by the discontinuity
7566e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
7576e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    if (audio) {
7586e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        mFlushingAudio = FLUSHED;
7596e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    } else {
7606e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        mFlushingVideo = FLUSHED;
7616e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    }
7626e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
7636e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    finishFlushIfPossible();
7646e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
7656e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    return -EWOULDBLOCK;
7666e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                }
76732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            }
76832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
7693fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->setInt32("err", err);
7703fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->post();
7713fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return OK;
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7743fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio) {
7753fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesTotal;
7763fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
7773fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
7783fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        dropAccessUnit = false;
7793fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio
7803fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoLateByUs > 100000ll
7813fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoIsAVC
7823fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && !IsAVCReferenceFrame(accessUnit)) {
7833fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            dropAccessUnit = true;
7843fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesDropped;
7853fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
7863fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    } while (dropAccessUnit);
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mediaTimeUs;
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
7933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("feeding %s input buffer at media time %.2f secs",
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         audio ? "audio" : "video",
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mediaTimeUs / 1E6);
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7982d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", accessUnit);
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->post();
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
804f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
8053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    // ALOGV("renderBuffer %s", audio ? "audio" : "video");
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
81118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // We're currently attempting to flush the decoder, in order
81218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // to complete this, the decoder wants all its buffers back,
81318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // so we don't want any output buffers it sent us (from before
81418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // we initiated the flush) to be stuck in the renderer's queue.
81518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
8163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("we're still flushing the %s decoder, sending its output buffer"
81718ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber             " right back.", audio ? "audio" : "video");
81818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
81918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        reply->post();
82018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        return;
82118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
82218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
8232d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
8242d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    CHECK(msg->findBuffer("buffer", &buffer));
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    int64_t &skipUntilMediaTimeUs =
82732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        audio
82832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            ? mSkipRenderingAudioUntilMediaTimeUs
82932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            : mSkipRenderingVideoUntilMediaTimeUs;
83032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
83132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    if (skipUntilMediaTimeUs >= 0) {
83232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        int64_t mediaTimeUs;
83332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
83432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
83532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        if (mediaTimeUs < skipUntilMediaTimeUs) {
8363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("dropping %s buffer at time %lld as requested.",
83732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 audio ? "audio" : "video",
83832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 mediaTimeUs);
83932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
84032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            reply->post();
84132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            return;
84232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        }
84332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
84432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        skipUntilMediaTimeUs = -1;
84532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    }
84632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mRenderer->queueBuffer(audio, buffer, reply);
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
850f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::notifyListener(int msg, int ext1, int ext2) {
85143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver == NULL) {
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
85543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<NuPlayerDriver> driver = mDriver.promote();
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
85743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (driver == NULL) {
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
861a4af2143ecbd630e946647c1b5f90fda8f61ebb3Andreas Huber    driver->notifyListener(msg, ext1, ext2);
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::flushDecoder(bool audio, bool needShutdown) {
8656e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
866df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("flushDecoder %s without decoder present",
8676e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber             audio ? "audio" : "video");
8686e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
8696e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
8701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    // Make sure we don't continue to scan sources until we finish flushing.
8711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    ++mScanSourcesGeneration;
87243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mScanSourcesPending = false;
8731aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
8751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mRenderer->flush(audio);
8761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8771aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    FlushStatus newStatus =
8781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
8791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8801aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (audio) {
8811aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingAudio == NONE
8821aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingAudio == AWAITING_DISCONTINUITY);
8831aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8841aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingAudio = newStatus;
8851aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8861aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingVideo == NONE) {
8871aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingVideo = (mVideoDecoder != NULL)
8881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
8891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
8901aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
8911aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else {
8921aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingVideo == NONE
8931aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingVideo == AWAITING_DISCONTINUITY);
8941aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingVideo = newStatus;
8961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingAudio == NONE) {
8981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingAudio = (mAudioDecoder != NULL)
8991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
9001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
9011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
9021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
9031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
9041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
906