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"
31840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include "mp4/MP4Source.h"
325bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
335bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "ATSParser.h"
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <cutils/properties.h> // for property_get
363831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#include <media/stagefright/foundation/hexdump.h>
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
413fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include <media/stagefright/MediaDefs.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaErrors.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h>
441173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/ISurfaceTexture.h>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
463fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include "avc_utils.h"
473fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
48840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include "ESDS.h"
49840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/Utils.h>
50840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
51f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::NuPlayer()
569b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    : mUIDValid(false),
573fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mVideoIsAVC(false),
589b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mAudioEOS(false),
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoEOS(false),
605bc087c573c70c84c6a39946457590b42d392a33Andreas Huber      mScanSourcesPending(false),
611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mScanSourcesGeneration(0),
626e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber      mTimeDiscontinuityPending(false),
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlushingAudio(NONE),
641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mFlushingVideo(NONE),
651aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mResetInProgress(false),
663fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mResetPostponed(false),
673fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
683fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
693fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mVideoLateByUs(0ll),
703fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mNumFramesTotal(0ll),
710d268a3cae145afb2720c88ae38fb81550be5584James Dong      mNumFramesDropped(0ll),
720d268a3cae145afb2720c88ae38fb81550be5584James Dong      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW) {
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::~NuPlayer() {
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid NuPlayer::setUID(uid_t uid) {
799b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUIDValid = true;
809b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
819b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber}
829b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
8343c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
8443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mDriver = driver;
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
87f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setDataSource(const sp<IStreamSource> &source) {
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
90840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    char prop[PROPERTY_VALUE_MAX];
91840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (property_get("media.stagefright.use-mp4source", prop, NULL)
92840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
93840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        msg->setObject("source", new MP4Source(source));
94840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    } else {
95840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        msg->setObject("source", new StreamingSource(source));
96840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
97840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
985bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    msg->post();
995bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
1005bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
101afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatic bool IsHTTPLiveURL(const char *url) {
102afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!strncasecmp("http://", url, 7)
103afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            || !strncasecmp("https://", url, 8)) {
104afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        size_t len = strlen(url);
105afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
106afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
107afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
108afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
109afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (strstr(url,"m3u8")) {
110afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
111afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
112afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
113afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
114afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return false;
115afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
116afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1175bc087c573c70c84c6a39946457590b42d392a33Andreas Hubervoid NuPlayer::setDataSource(
1185bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        const char *url, const KeyedVector<String8, String8> *headers) {
1195bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<Source> source;
122afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (IsHTTPLiveURL(url)) {
123afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        source = new HTTPLiveSource(url, headers, mUIDValid, mUID);
124afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    } else if (!strncasecmp(url, "rtsp://", 7)) {
125afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        source = new RTSPSource(url, headers, mUIDValid, mUID);
1262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    } else {
127afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        source = new GenericSource(url, headers, mUIDValid, mUID);
1282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
130afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
131afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->post();
132afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
133afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
134afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
135afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
136afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
137afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<Source> source = new GenericSource(fd, offset, length);
138afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1421173118eace0e9e347cb007f0da817cee87579edGlenn Kastenvoid NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
1431173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
1441173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
1451173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                new SurfaceTextureClient(surfaceTexture) : NULL);
1461173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
150f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setObject("sink", sink);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::start() {
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatStart, id()))->post();
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16043c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::pause() {
161b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatPause, id()))->post();
16243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
16343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
16443c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::resume() {
165b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatResume, id()))->post();
16643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
16743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
1681aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::resetAsync() {
1691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (new AMessage(kWhatReset, id()))->post();
1701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
1711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
17243c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::seekToAsync(int64_t seekTimeUs) {
17343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, id());
17443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->setInt64("seekTimeUs", seekTimeUs);
17543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->post();
17643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
17743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
17853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber// static
1791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberbool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
18053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    switch (state) {
18153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        case FLUSHING_DECODER:
1821aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
1831aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = false;
18453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
18553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
18653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
1871aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case FLUSHING_DECODER_SHUTDOWN:
1881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
1891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = true;
19053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
19153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
19253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
19353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        default:
19453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return false;
19553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    }
19653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
19753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
198f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetDataSource:
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetDataSource");
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(mSource == NULL);
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2065bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            sp<RefBase> obj;
2075bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(msg->findObject("source", &obj));
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2095bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource = static_cast<Source *>(obj.get());
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2131173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        case kWhatSetVideoNativeWindow:
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetVideoNativeWindow");
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
2181173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            CHECK(msg->findObject("native-window", &obj));
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2201173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
2210d268a3cae145afb2720c88ae38fb81550be5584James Dong
2220d268a3cae145afb2720c88ae38fb81550be5584James Dong            // XXX - ignore error from setVideoScalingMode for now
2230d268a3cae145afb2720c88ae38fb81550be5584James Dong            setVideoScalingMode(mVideoScalingMode);
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetAudioSink:
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetAudioSink");
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findObject("sink", &obj));
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatStart:
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatStart");
24143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
2423fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoIsAVC = false;
2431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mAudioEOS = false;
2441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mVideoEOS = false;
24532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingAudioUntilMediaTimeUs = -1;
24632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingVideoUntilMediaTimeUs = -1;
2473fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoLateByUs = 0;
2483fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesTotal = 0;
2493fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesDropped = 0;
2501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2515bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource->start();
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mRenderer = new Renderer(
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioSink,
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    new AMessage(kWhatRendererNotify, id()));
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            looper()->registerHandler(mRenderer);
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            postScanSources();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatScanSources:
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2651aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            int32_t generation;
2661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            CHECK(msg->findInt32("generation", &generation));
2671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (generation != mScanSourcesGeneration) {
2681aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // Drop obsolete msg.
2691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
2701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
2711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2725bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mScanSourcesPending = false;
2735bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
2743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
27543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 mAudioDecoder != NULL, mVideoDecoder != NULL);
27643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
2775d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            if (mNativeWindow != NULL) {
2785d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George                instantiateDecoder(false, &mVideoDecoder);
2795d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            }
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioSink != NULL) {
2825bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                instantiateDecoder(true, &mAudioDecoder);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            status_t err;
286eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            if ((err = mSource->feedMoreTSData()) != OK) {
2871aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
2881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // We're not currently decoding anything (no audio or
2891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // video tracks found) and we just ran out of input data.
290eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber
291eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (err == ERROR_END_OF_STREAM) {
292eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
293eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    } else {
294eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
295eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    }
2961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                }
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            if ((mAudioDecoder == NULL && mAudioSink != NULL)
301fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->post(100000ll);
3035bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                mScanSourcesPending = true;
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatVideoNotify:
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatAudioNotify:
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            bool audio = msg->what() == kWhatAudioNotify;
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> codecRequest;
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findMessage("codec-request", &codecRequest));
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(codecRequest->findInt32("what", &what));
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == ACodec::kWhatFillThisBuffer) {
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                status_t err = feedDecoderInputData(
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        audio, codecRequest);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3235bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                if (err == -EWOULDBLOCK) {
324eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (mSource->feedMoreTSData() == OK) {
3251183a4ab06b9fe01fe39a4b8728bfc71789361fcAndreas Huber                        msg->post(10000ll);
3265bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                    }
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatEOS) {
329dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                int32_t err;
330dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                CHECK(codecRequest->findInt32("err", &err));
331dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
332dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err == ERROR_END_OF_STREAM) {
3333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
334dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS w/ error %d",
336dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         audio ? "audio" : "video",
337dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         err);
338dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
339dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
340dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mRenderer->queueEOS(audio, err);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatFlushCompleted) {
3421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                bool needShutdown;
34353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
3451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingAudio = FLUSHED;
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
3481aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingVideo = FLUSHED;
3503fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
3513fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mVideoLateByUs = 0;
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (needShutdown) {
3573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("initiating %s decoder shutdown",
35853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                         audio ? "audio" : "video");
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    if (audio) {
36353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingAudio = SHUTTING_DOWN_DECODER;
36453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    } else {
36553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingVideo = SHUTTING_DOWN_DECODER;
36653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    }
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3683831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
3693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
3702c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber            } else if (what == ACodec::kWhatOutputFormatChanged) {
37131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                if (audio) {
37231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t numChannels;
37331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("channel-count", &numChannels));
3742c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
37531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t sampleRate;
37631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
3772c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
3783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Audio output format changed to %d Hz, %d channels",
37931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         sampleRate, numChannels);
3802c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
38131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->close();
3821948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
3831948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    audio_output_flags_t flags;
3841948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    int64_t durationUs;
3851948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    // FIXME: we should handle the case where the video decoder is created after
3861948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    // we receive the format change indication. Current code will just make that
3871948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    // we select deep buffer with video which should not be a problem as it should
3881948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    // not prevent from keeping A/V sync.
3891948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    if (mVideoDecoder == NULL &&
3901948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                            mSource->getDuration(&durationUs) == OK &&
3911948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                            durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
3921948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
3931948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    } else {
3941948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                        flags = AUDIO_OUTPUT_FLAG_NONE;
3951948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    }
3961948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
3979806555d3930be43e11106281dee354820ac1c88Andreas Huber                    int32_t channelMask;
3989806555d3930be43e11106281dee354820ac1c88Andreas Huber                    if (!codecRequest->findInt32("channel-mask", &channelMask)) {
3999806555d3930be43e11106281dee354820ac1c88Andreas Huber                        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
4009806555d3930be43e11106281dee354820ac1c88Andreas Huber                    }
4019806555d3930be43e11106281dee354820ac1c88Andreas Huber
402078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                    CHECK_EQ(mAudioSink->open(
403078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                sampleRate,
404078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                numChannels,
4059806555d3930be43e11106281dee354820ac1c88Andreas Huber                                (audio_channel_mask_t)channelMask,
406078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                AUDIO_FORMAT_PCM_16_BIT,
4071948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                8 /* bufferCount */,
4081948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                NULL,
4091948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                NULL,
4101948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                flags),
411078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                             (status_t)OK);
41231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->start();
4133831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
41431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mRenderer->signalAudioSinkChanged();
41531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                } else {
41631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // video
41731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
41831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t width, height;
41931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("width", &width));
42031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("height", &height));
42131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
42231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t cropLeft, cropTop, cropRight, cropBottom;
42331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findRect(
42431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                "crop",
42531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                &cropLeft, &cropTop, &cropRight, &cropBottom));
42631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Video output format changed to %d x %d "
428cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "(crop: %d x %d @ (%d, %d))",
42931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         width, height,
430cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         (cropRight - cropLeft + 1),
431cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         (cropBottom - cropTop + 1),
432cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         cropLeft, cropTop);
43331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    notifyListener(
43531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            MEDIA_SET_VIDEO_SIZE,
43631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            cropRight - cropLeft + 1,
43731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            cropBottom - cropTop + 1);
43831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                }
4393831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            } else if (what == ACodec::kWhatShutdownCompleted) {
4403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("%s shutdown completed", audio ? "audio" : "video");
4413831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                if (audio) {
4423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mAudioDecoder.clear();
4433831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4443831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
4453831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingAudio = SHUT_DOWN;
4463831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                } else {
4473831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mVideoDecoder.clear();
4483831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4493831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
4503831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingVideo = SHUT_DOWN;
4513831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                }
4523831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4533831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
454c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            } else if (what == ACodec::kWhatError) {
45529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("Received error from %s decoder, aborting playback.",
456c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                     audio ? "audio" : "video");
457c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
458c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else if (what == ACodec::kWhatDrainThisBuffer) {
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                renderBuffer(audio, codecRequest);
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("Unhandled codec notification %d.", what);
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatRendererNotify:
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("what", &what));
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == Renderer::kWhatEOS) {
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                int32_t finalResult;
478c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                CHECK(msg->findInt32("finalResult", &finalResult));
479c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEOS = true;
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mVideoEOS = true;
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
486c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (finalResult == ERROR_END_OF_STREAM) {
4873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("reached %s EOS", audio ? "audio" : "video");
488c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                } else {
48929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("%s track encountered an error (%d)",
490c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         audio ? "audio" : "video", finalResult);
491c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
492c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    notifyListener(
493c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
494c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if ((mAudioEOS || mAudioDecoder == NULL)
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        && (mVideoEOS || mVideoDecoder == NULL)) {
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
50043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            } else if (what == Renderer::kWhatPosition) {
50143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                int64_t positionUs;
50243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                CHECK(msg->findInt64("positionUs", &positionUs));
50343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
5043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
5053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
50643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (mDriver != NULL) {
50743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    sp<NuPlayerDriver> driver = mDriver.promote();
50843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    if (driver != NULL) {
50943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                        driver->notifyPosition(positionUs);
5103fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
5113fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        driver->notifyFrameStats(
5123fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                mNumFramesTotal, mNumFramesDropped);
51343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    }
51443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
5153fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            } else if (what == Renderer::kWhatFlushComplete) {
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
522f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong            } else if (what == Renderer::kWhatVideoRenderingStart) {
523f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatMoreDataQueued:
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5331aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case kWhatReset:
5341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        {
5353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatReset");
5361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
537b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber            if (mRenderer != NULL) {
538b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // There's an edge case where the renderer owns all output
539b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // buffers and is paused, therefore the decoder will not read
540b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // more input data and will never encounter the matching
541b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                // discontinuity. To avoid this, we resume the renderer.
542b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
543b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                if (mFlushingAudio == AWAITING_DISCONTINUITY
544b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                        || mFlushingVideo == AWAITING_DISCONTINUITY) {
545b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                    mRenderer->resume();
546b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber                }
547b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber            }
548b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
5491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
5501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // We're currently flushing, postpone the reset until that's
5511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // completed.
5521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
553ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber                ALOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
554ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber                      mFlushingAudio, mFlushingVideo);
5551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                mResetPostponed = true;
5571aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
5581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
5611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                finishReset();
5621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
5631aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5656e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            mTimeDiscontinuityPending = true;
5666e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
5671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mAudioDecoder != NULL) {
5681aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                flushDecoder(true /* audio */, true /* needShutdown */);
5691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (mVideoDecoder != NULL) {
5721aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                flushDecoder(false /* audio */, true /* needShutdown */);
5731aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
5741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mResetInProgress = true;
5761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            break;
5771aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
5781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
57943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        case kWhatSeek:
58043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        {
58143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            int64_t seekTimeUs;
58243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
58343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
5843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
58543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 seekTimeUs, seekTimeUs / 1E6);
58643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
58743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            mSource->seekTo(seekTimeUs);
58843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
58943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            if (mDriver != NULL) {
59043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                sp<NuPlayerDriver> driver = mDriver.promote();
59143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (driver != NULL) {
59243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    driver->notifySeekComplete();
59343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
59443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            }
59543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
59643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            break;
59743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
59843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
599b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatPause:
600b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
601b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
602b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->pause();
603b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
604b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
605b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
606b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatResume:
607b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
608b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
609b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->resume();
610b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
611b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
612b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::finishFlushIfPossible() {
6203831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
6213831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
6223831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
6233831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6243831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
6253831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
6263831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
6273831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("both audio and video are flushed now.");
6293831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6306e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (mTimeDiscontinuityPending) {
6316e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mRenderer->signalTimeDiscontinuity();
6326e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mTimeDiscontinuityPending = false;
6336e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
6343831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
63522fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mAudioDecoder != NULL) {
6363831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mAudioDecoder->signalResume();
6373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
6383831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
63922fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mVideoDecoder != NULL) {
6403831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mVideoDecoder->signalResume();
6413831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
6423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6433831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingAudio = NONE;
6443831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingVideo = NONE;
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6461aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mResetInProgress) {
6473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("reset completed");
6481aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mResetInProgress = false;
6501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        finishReset();
6511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else if (mResetPostponed) {
6521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        (new AMessage(kWhatReset, id()))->post();
6531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mResetPostponed = false;
65422fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
6551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        postScanSources();
6561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
6571aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
6581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::finishReset() {
6601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    CHECK(mAudioDecoder == NULL);
6611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    CHECK(mVideoDecoder == NULL);
6621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    ++mScanSourcesGeneration;
6642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mScanSourcesPending = false;
6652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mRenderer.clear();
6672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mSource != NULL) {
6692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mSource->stop();
6702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mSource.clear();
6712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6721aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
67343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver != NULL) {
67443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
67543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (driver != NULL) {
67643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            driver->notifyResetComplete();
67743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
67843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
6791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
6801aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6811aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::postScanSources() {
6821aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mScanSourcesPending) {
6831aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return;
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6851aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6861aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
6871aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->setInt32("generation", mScanSourcesGeneration);
6881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->post();
6891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6901aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mScanSourcesPending = true;
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6935bc087c573c70c84c6a39946457590b42d392a33Andreas Huberstatus_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (*decoder != NULL) {
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
698840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<AMessage> format = mSource->getFormat(audio);
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (format == NULL) {
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    if (!audio) {
705840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        AString mime;
706840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        CHECK(format->findString("mime", &mime));
707840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
7083fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    }
7093fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify =
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     id());
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7141173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    *decoder = audio ? new Decoder(notify) :
7151173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                       new Decoder(notify, mNativeWindow);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper()->registerHandler(*decoder);
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
718840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    (*decoder)->configure(format);
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int64_t durationUs;
72143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
72243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
72343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (driver != NULL) {
72443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            driver->notifyDuration(durationUs);
72543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
726