NuPlayer.cpp revision d5e56231a598b180a1d898bb7dc61b75580e59a4
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>
448ba01021b573889802e67e029225a96f0dfa471aAndy McFadden#include <gui/IGraphicBufferProducer.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
53a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberstruct NuPlayer::Action : public RefBase {
54a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    Action() {}
55a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
56a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    virtual void execute(NuPlayer *player) = 0;
57a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
58a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberprivate:
59a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Action);
60a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber};
61a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
62a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberstruct NuPlayer::SeekAction : public Action {
63a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    SeekAction(int64_t seekTimeUs)
64a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        : mSeekTimeUs(seekTimeUs) {
65a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
66a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
67a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    virtual void execute(NuPlayer *player) {
68a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        player->performSeek(mSeekTimeUs);
69a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
70a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
71a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberprivate:
72a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    int64_t mSeekTimeUs;
73a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
74a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
75a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber};
76a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
7757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huberstruct NuPlayer::SetSurfaceAction : public Action {
7857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
7957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        : mWrapper(wrapper) {
8057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
8157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
8257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    virtual void execute(NuPlayer *player) {
8357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        player->performSetSurface(mWrapper);
8457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
8557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
8657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huberprivate:
8757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    sp<NativeWindowWrapper> mWrapper;
8857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
8957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
9057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber};
9157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
92a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber// Use this if there's no state necessary to save in order to execute
93a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber// the action.
94a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberstruct NuPlayer::SimpleAction : public Action {
95a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    typedef void (NuPlayer::*ActionFunc)();
96a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
97a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    SimpleAction(ActionFunc func)
98a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        : mFunc(func) {
99a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
100a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
101a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    virtual void execute(NuPlayer *player) {
102a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        (player->*mFunc)();
103a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
104a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
105a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberprivate:
106a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ActionFunc mFunc;
107a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
108a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
109a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber};
110a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::NuPlayer()
1149b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    : mUIDValid(false),
1159575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber      mSourceFlags(0),
1163fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mVideoIsAVC(false),
1179b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mAudioEOS(false),
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoEOS(false),
1195bc087c573c70c84c6a39946457590b42d392a33Andreas Huber      mScanSourcesPending(false),
1201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mScanSourcesGeneration(0),
121b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber      mPollDurationGeneration(0),
1226e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber      mTimeDiscontinuityPending(false),
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlushingAudio(NONE),
1241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mFlushingVideo(NONE),
1253fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
1263fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
1273fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mVideoLateByUs(0ll),
1283fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber      mNumFramesTotal(0ll),
1290d268a3cae145afb2720c88ae38fb81550be5584James Dong      mNumFramesDropped(0ll),
13057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
13157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber      mStarted(false) {
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
134f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::~NuPlayer() {
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1379b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid NuPlayer::setUID(uid_t uid) {
1389b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUIDValid = true;
1399b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
1409b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber}
1419b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
14243c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
14343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mDriver = driver;
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1469575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
150b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
151840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    char prop[PROPERTY_VALUE_MAX];
152840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (property_get("media.stagefright.use-mp4source", prop, NULL)
153840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
154b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        msg->setObject("source", new MP4Source(notify, source));
155840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    } else {
156b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        msg->setObject("source", new StreamingSource(notify, source));
157840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
158840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1595bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    msg->post();
1605bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
1615bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
162afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatic bool IsHTTPLiveURL(const char *url) {
163afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!strncasecmp("http://", url, 7)
164afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            || !strncasecmp("https://", url, 8)) {
165afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        size_t len = strlen(url);
166afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
167afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
168afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
169afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
170afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (strstr(url,"m3u8")) {
171afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
172afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
173afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
174afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
175afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return false;
176afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
177afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1789575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(
1795bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        const char *url, const KeyedVector<String8, String8> *headers) {
1805bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
1817a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé    size_t len = strlen(url);
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
184b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
185afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<Source> source;
186afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (IsHTTPLiveURL(url)) {
187b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
188afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    } else if (!strncasecmp(url, "rtsp://", 7)) {
189b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
1907a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé    } else if ((!strncasecmp(url, "http://", 7)
1917a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                || !strncasecmp(url, "https://", 8))
1927a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
1937a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                    || strstr(url, ".sdp?"))) {
1947a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé        source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
1952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    } else {
196b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        source = new GenericSource(notify, url, headers, mUIDValid, mUID);
1972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
199afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
200afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->post();
201afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
202afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
2039575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
204afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
205afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
206b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
207b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
208b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<Source> source = new GenericSource(notify, fd, offset, length);
209afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2139575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::prepareAsync() {
2149575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    (new AMessage(kWhatPrepare, id()))->post();
2159575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
2169575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
21757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Hubervoid NuPlayer::setVideoSurfaceTextureAsync(
2188ba01021b573889802e67e029225a96f0dfa471aAndy McFadden        const sp<IGraphicBufferProducer> &bufferProducer) {
2191173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
22057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
2218ba01021b573889802e67e029225a96f0dfa471aAndy McFadden    if (bufferProducer == NULL) {
22257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        msg->setObject("native-window", NULL);
22357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    } else {
22457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        msg->setObject(
22557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                "native-window",
22657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                new NativeWindowWrapper(
2271a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian                    new Surface(bufferProducer)));
22857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
22957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setObject("sink", sink);
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::start() {
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatStart, id()))->post();
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24343c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::pause() {
244b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatPause, id()))->post();
24543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
24643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
24743c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::resume() {
248b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatResume, id()))->post();
24943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
25043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
2511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::resetAsync() {
2521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (new AMessage(kWhatReset, id()))->post();
2531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
2541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
25543c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::seekToAsync(int64_t seekTimeUs) {
25643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, id());
25743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->setInt64("seekTimeUs", seekTimeUs);
25843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->post();
25943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
26043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
26153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber// static
2621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberbool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
26353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    switch (state) {
26453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        case FLUSHING_DECODER:
2651aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
2661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = false;
26753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
26853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
26953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
2701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case FLUSHING_DECODER_SHUTDOWN:
2711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
2721aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = true;
27353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
27453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
27553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
27653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        default:
27753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return false;
27853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    }
27953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
28053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetDataSource:
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetDataSource");
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(mSource == NULL);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2895bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            sp<RefBase> obj;
2905bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(msg->findObject("source", &obj));
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2925bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource = static_cast<Source *>(obj.get());
293b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
294b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber            looper()->registerHandler(mSource);
2959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
2969575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(mDriver != NULL);
2979575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            sp<NuPlayerDriver> driver = mDriver.promote();
2989575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if (driver != NULL) {
2999575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                driver->notifySetDataSourceCompleted(OK);
3009575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
3019575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
3029575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
3039575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
3049575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case kWhatPrepare:
3059575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
3069575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            mSource->prepareAsync();
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        case kWhatPollDuration:
311b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        {
312b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            int32_t generation;
313b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            CHECK(msg->findInt32("generation", &generation));
314b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
315b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (generation != mPollDurationGeneration) {
316b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                // stale
317b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                break;
318b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
319b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
320b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            int64_t durationUs;
321b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
322b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                sp<NuPlayerDriver> driver = mDriver.promote();
323b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                if (driver != NULL) {
324b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    driver->notifyDuration(durationUs);
325b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                }
326b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
327b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
328b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            msg->post(1000000ll);  // poll again in a second.
329b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            break;
330b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        }
331b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
3321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        case kWhatSetVideoNativeWindow:
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetVideoNativeWindow");
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            mDeferredActions.push_back(
33757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                    new SimpleAction(&NuPlayer::performDecoderShutdown));
33857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
3401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            CHECK(msg->findObject("native-window", &obj));
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            mDeferredActions.push_back(
34357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                    new SetSurfaceAction(
34457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                        static_cast<NativeWindowWrapper *>(obj.get())));
34557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
34657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            if (obj != NULL) {
34757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                // If there is a new surface texture, instantiate decoders
34857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                // again if possible.
34957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                mDeferredActions.push_back(
35057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                        new SimpleAction(&NuPlayer::performScanSources));
35157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            }
3520d268a3cae145afb2720c88ae38fb81550be5584James Dong
35357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            processDeferredActions();
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetAudioSink:
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetAudioSink");
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findObject("sink", &obj));
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatStart:
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatStart");
37143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
3723fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoIsAVC = false;
3731aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mAudioEOS = false;
3741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mVideoEOS = false;
37532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingAudioUntilMediaTimeUs = -1;
37632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingVideoUntilMediaTimeUs = -1;
3773fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoLateByUs = 0;
3783fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesTotal = 0;
3793fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesDropped = 0;
38057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            mStarted = true;
3811aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
3825bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource->start();
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber            uint32_t flags = 0;
385d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
386d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber            if (mSource->isRealTime()) {
387d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber                flags |= Renderer::FLAG_REAL_TIME;
388d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber            }
389d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mRenderer = new Renderer(
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioSink,
392d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber                    new AMessage(kWhatRendererNotify, id()),
393d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber                    flags);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            looper()->registerHandler(mRenderer);
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            postScanSources();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatScanSources:
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            int32_t generation;
4041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            CHECK(msg->findInt32("generation", &generation));
4051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (generation != mScanSourcesGeneration) {
4061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // Drop obsolete msg.
4071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
4081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
4091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4105bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mScanSourcesPending = false;
4115bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
4123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
41343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 mAudioDecoder != NULL, mVideoDecoder != NULL);
41443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
415b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            bool mHadAnySourcesBefore =
416b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
417b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
4185d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            if (mNativeWindow != NULL) {
4195d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George                instantiateDecoder(false, &mVideoDecoder);
4205d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            }
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioSink != NULL) {
4235bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                instantiateDecoder(true, &mAudioDecoder);
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (!mHadAnySourcesBefore
427b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
428b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                // This is the first time we've found anything playable.
429b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
4309575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
431b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    schedulePollDuration();
432b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                }
433b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
434b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
435eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            status_t err;
436eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            if ((err = mSource->feedMoreTSData()) != OK) {
4371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
4381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // We're not currently decoding anything (no audio or
4391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // video tracks found) and we just ran out of input data.
440eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber
441eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (err == ERROR_END_OF_STREAM) {
442eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
443eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    } else {
444eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
445eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    }
4461aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                }
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            if ((mAudioDecoder == NULL && mAudioSink != NULL)
451fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->post(100000ll);
4535bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                mScanSourcesPending = true;
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatVideoNotify:
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatAudioNotify:
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            bool audio = msg->what() == kWhatAudioNotify;
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> codecRequest;
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findMessage("codec-request", &codecRequest));
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(codecRequest->findInt32("what", &what));
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == ACodec::kWhatFillThisBuffer) {
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                status_t err = feedDecoderInputData(
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        audio, codecRequest);
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                if (err == -EWOULDBLOCK) {
474eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (mSource->feedMoreTSData() == OK) {
4751183a4ab06b9fe01fe39a4b8728bfc71789361fcAndreas Huber                        msg->post(10000ll);
4765bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                    }
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatEOS) {
479dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                int32_t err;
480dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                CHECK(codecRequest->findInt32("err", &err));
481dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
482dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err == ERROR_END_OF_STREAM) {
4833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
484dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
4853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS w/ error %d",
486dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         audio ? "audio" : "video",
487dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         err);
488dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
489dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
490dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mRenderer->queueEOS(audio, err);
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatFlushCompleted) {
4921aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                bool needShutdown;
49353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
4951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingAudio = FLUSHED;
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
4981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingVideo = FLUSHED;
5003fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
5013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mVideoLateByUs = 0;
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (needShutdown) {
5073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("initiating %s decoder shutdown",
50853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                         audio ? "audio" : "video");
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    if (audio) {
51353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingAudio = SHUTTING_DOWN_DECODER;
51453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    } else {
51553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingVideo = SHUTTING_DOWN_DECODER;
51653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    }
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
5202c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber            } else if (what == ACodec::kWhatOutputFormatChanged) {
52131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                if (audio) {
52231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t numChannels;
523516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    CHECK(codecRequest->findInt32(
524516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                                "channel-count", &numChannels));
5252c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
52631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t sampleRate;
52731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
5282c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
5293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Audio output format changed to %d Hz, %d channels",
53031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         sampleRate, numChannels);
5312c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
53231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->close();
5331948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
5341948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    audio_output_flags_t flags;
5351948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    int64_t durationUs;
536516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // FIXME: we should handle the case where the video decoder
537516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // is created after we receive the format change indication.
538516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // Current code will just make that we select deep buffer
539516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // with video which should not be a problem as it should
5401948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    // not prevent from keeping A/V sync.
5411948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    if (mVideoDecoder == NULL &&
5421948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                            mSource->getDuration(&durationUs) == OK &&
543516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            durationUs
544516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
5451948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
5461948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    } else {
5471948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                        flags = AUDIO_OUTPUT_FLAG_NONE;
5481948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    }
5491948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
5509806555d3930be43e11106281dee354820ac1c88Andreas Huber                    int32_t channelMask;
5519806555d3930be43e11106281dee354820ac1c88Andreas Huber                    if (!codecRequest->findInt32("channel-mask", &channelMask)) {
5529806555d3930be43e11106281dee354820ac1c88Andreas Huber                        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
5539806555d3930be43e11106281dee354820ac1c88Andreas Huber                    }
5549806555d3930be43e11106281dee354820ac1c88Andreas Huber
555078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                    CHECK_EQ(mAudioSink->open(
556078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                sampleRate,
557078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                numChannels,
5589806555d3930be43e11106281dee354820ac1c88Andreas Huber                                (audio_channel_mask_t)channelMask,
559078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                AUDIO_FORMAT_PCM_16_BIT,
5601948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                8 /* bufferCount */,
5611948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                NULL,
5621948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                NULL,
5631948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                flags),
564078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                             (status_t)OK);
56531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->start();
5663831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
56731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mRenderer->signalAudioSinkChanged();
56831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                } else {
56931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // video
57031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
57131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t width, height;
57231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("width", &width));
57331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("height", &height));
57431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
57531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t cropLeft, cropTop, cropRight, cropBottom;
57631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findRect(
57731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                "crop",
57831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                &cropLeft, &cropTop, &cropRight, &cropBottom));
57931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
580516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    int32_t displayWidth = cropRight - cropLeft + 1;
581516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    int32_t displayHeight = cropBottom - cropTop + 1;
582516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
5833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Video output format changed to %d x %d "
584cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "(crop: %d x %d @ (%d, %d))",
58531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         width, height,
586516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                         displayWidth,
587516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                         displayHeight,
588cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         cropLeft, cropTop);
58931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
590516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    sp<AMessage> videoInputFormat =
591516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        mSource->getFormat(false /* audio */);
592516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
593516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // Take into account sample aspect ratio if necessary:
594516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    int32_t sarWidth, sarHeight;
595516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    if (videoInputFormat->findInt32("sar-width", &sarWidth)
596516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            && videoInputFormat->findInt32(
597516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                                "sar-height", &sarHeight)) {
598516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        ALOGV("Sample aspect ratio %d : %d",
599516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                              sarWidth, sarHeight);
600516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
601516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        displayWidth = (displayWidth * sarWidth) / sarHeight;
602516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
603516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        ALOGV("display dimensions %d x %d",
604516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                              displayWidth, displayHeight);
605516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    }
606516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
60731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    notifyListener(
608516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
60931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                }
6103831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            } else if (what == ACodec::kWhatShutdownCompleted) {
6113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("%s shutdown completed", audio ? "audio" : "video");
6123831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                if (audio) {
6133831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mAudioDecoder.clear();
6143831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6153831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
6163831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingAudio = SHUT_DOWN;
6173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                } else {
6183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mVideoDecoder.clear();
6193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6203831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
6213831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingVideo = SHUT_DOWN;
6223831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                }
6233831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6243831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
625c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            } else if (what == ACodec::kWhatError) {
62629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("Received error from %s decoder, aborting playback.",
627c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                     audio ? "audio" : "video");
628c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
629c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
6305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else if (what == ACodec::kWhatDrainThisBuffer) {
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                renderBuffer(audio, codecRequest);
632a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            } else if (what != ACodec::kWhatComponentAllocated
633a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    && what != ACodec::kWhatComponentConfigured
634a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    && what != ACodec::kWhatBuffersAllocated) {
635a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
636a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what,
637a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what >> 24,
638a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      (what >> 16) & 0xff,
639a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      (what >> 8) & 0xff,
640a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what & 0xff);
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatRendererNotify:
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("what", &what));
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == Renderer::kWhatEOS) {
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
655c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                int32_t finalResult;
656c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                CHECK(msg->findInt32("finalResult", &finalResult));
657c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEOS = true;
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mVideoEOS = true;
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
664c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (finalResult == ERROR_END_OF_STREAM) {
6653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("reached %s EOS", audio ? "audio" : "video");
666c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                } else {
66729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("%s track encountered an error (%d)",
668c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         audio ? "audio" : "video", finalResult);
669c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
670c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    notifyListener(
671c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
672c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if ((mAudioEOS || mAudioDecoder == NULL)
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        && (mVideoEOS || mVideoDecoder == NULL)) {
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
67843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            } else if (what == Renderer::kWhatPosition) {
67943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                int64_t positionUs;
68043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                CHECK(msg->findInt64("positionUs", &positionUs));
68143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
6823fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
6833fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
68443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (mDriver != NULL) {
68543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    sp<NuPlayerDriver> driver = mDriver.promote();
68643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    if (driver != NULL) {
68743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                        driver->notifyPosition(positionUs);
6883fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
6893fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        driver->notifyFrameStats(
6903fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                mNumFramesTotal, mNumFramesDropped);
69143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    }
69243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
6933fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            } else if (what == Renderer::kWhatFlushComplete) {
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
698f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong            } else if (what == Renderer::kWhatVideoRenderingStart) {
699f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatMoreDataQueued:
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case kWhatReset:
7101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        {
7113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatReset");
7121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
713a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
714a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    new SimpleAction(&NuPlayer::performDecoderShutdown));
715b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
716a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
717a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    new SimpleAction(&NuPlayer::performReset));
7181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
719a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            processDeferredActions();
7201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            break;
7211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
7221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
72343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        case kWhatSeek:
72443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        {
72543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            int64_t seekTimeUs;
72643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
72743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
728a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
72943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
730a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
731a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    new SimpleAction(&NuPlayer::performDecoderFlush));
73243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
733a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(new SeekAction(seekTimeUs));
73443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
735a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            processDeferredActions();
73643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            break;
73743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
73843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
739b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatPause:
740b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
741b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
742fba60daf77cc74a13ae3bf4b0e9925dd2ee4470cRoger Jönsson            mSource->pause();
743b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->pause();
744b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
745b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
746b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
747b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatResume:
748b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
749b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
750fba60daf77cc74a13ae3bf4b0e9925dd2ee4470cRoger Jönsson            mSource->resume();
751b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->resume();
752b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
753b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
754b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
755b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        case kWhatSourceNotify:
756b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        {
7579575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            onSourceNotify(msg);
758b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber            break;
759b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        }
760b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7673831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::finishFlushIfPossible() {
7683831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
7693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
7703831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7713831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7723831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
7733831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
7743831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7753831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("both audio and video are flushed now.");
7773831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7786e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (mTimeDiscontinuityPending) {
7796e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mRenderer->signalTimeDiscontinuity();
7806e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mTimeDiscontinuityPending = false;
7816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
7823831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
78322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mAudioDecoder != NULL) {
7843831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mAudioDecoder->signalResume();
7853831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7863831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
78722fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mVideoDecoder != NULL) {
7883831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mVideoDecoder->signalResume();
7893831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7903831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7913831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingAudio = NONE;
7923831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingVideo = NONE;
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    processDeferredActions();
7951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
7961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
7971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::postScanSources() {
7981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mScanSourcesPending) {
7991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return;
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
8031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->setInt32("generation", mScanSourcesGeneration);
8041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->post();
8051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mScanSourcesPending = true;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8095bc087c573c70c84c6a39946457590b42d392a33Andreas Huberstatus_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (*decoder != NULL) {
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
814840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<AMessage> format = mSource->getFormat(audio);
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
816840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (format == NULL) {
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8203fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    if (!audio) {
821840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        AString mime;
822840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        CHECK(format->findString("mime", &mime));
823840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
8243fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    }
8253fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify =
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     id());
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8301173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    *decoder = audio ? new Decoder(notify) :
8311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                       new Decoder(notify, mNativeWindow);
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper()->registerHandler(*decoder);
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
834840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    (*decoder)->configure(format);
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
83643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int64_t durationUs;
83743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
83843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
83943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (driver != NULL) {
84043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            driver->notifyDuration(durationUs);
84143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
84243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
84343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
85153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    if ((audio && IsFlushingState(mFlushingAudio))
85253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            || (!audio && IsFlushingState(mFlushingVideo))) {
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->setInt32("err", INFO_DISCONTINUITY);
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->post();
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> accessUnit;
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8603fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    bool dropAccessUnit;
8613fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    do {
8623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
8635bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
8643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (err == -EWOULDBLOCK) {
8653fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return err;
8663fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        } else if (err != OK) {
8673fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            if (err == INFO_DISCONTINUITY) {
8683fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                int32_t type;
8693fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
87053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
8713fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                bool formatChange =
8726e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    (audio &&
8736e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
8746e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    || (!audio &&
8756e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
87653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
8776e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
8786e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
879df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("%s discontinuity (formatChange=%d, time=%d)",
8806e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                     audio ? "audio" : "video", formatChange, timeChange);
88132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
8823fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                if (audio) {
8833fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingAudioUntilMediaTimeUs = -1;
8843fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                } else {
8853fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingVideoUntilMediaTimeUs = -1;
8863fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                }
88732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
8886e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                if (timeChange) {
8896e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    sp<AMessage> extra;
8906e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    if (accessUnit->meta()->findMessage("extra", &extra)
8916e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            && extra != NULL) {
8926e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        int64_t resumeAtMediaTimeUs;
8936e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        if (extra->findInt64(
8946e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
895df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                            ALOGI("suppressing rendering of %s until %lld us",
8966e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
8976e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
8986e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            if (audio) {
8996e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                mSkipRenderingAudioUntilMediaTimeUs =
9006e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    resumeAtMediaTimeUs;
9016e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            } else {
9026e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                mSkipRenderingVideoUntilMediaTimeUs =
9036e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    resumeAtMediaTimeUs;
9046e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            }
9053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        }
90632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                    }
90732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                }
9083fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
9096e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                mTimeDiscontinuityPending =
9106e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    mTimeDiscontinuityPending || timeChange;
9116e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9126e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                if (formatChange || timeChange) {
913a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
914a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                        // And we'll resume scanning sources once we're done
915a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                        // flushing.
916a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                        mDeferredActions.push_front(
917a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                                new SimpleAction(
918a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                                    &NuPlayer::performScanSources));
919a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    }
920a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
9216e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    flushDecoder(audio, formatChange);
9226e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                } else {
9236e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    // This stream is unaffected by the discontinuity
9246e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9256e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    if (audio) {
9266e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        mFlushingAudio = FLUSHED;
9276e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    } else {
9286e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        mFlushingVideo = FLUSHED;
9296e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    }
9306e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9316e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    finishFlushIfPossible();
9326e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9336e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    return -EWOULDBLOCK;
9346e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                }
93532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            }
93632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
9373fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->setInt32("err", err);
9383fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->post();
9393fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return OK;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9423fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio) {
9433fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesTotal;
9443fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
9453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
9463fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        dropAccessUnit = false;
9473fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio
9483fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoLateByUs > 100000ll
9493fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoIsAVC
9503fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && !IsAVCReferenceFrame(accessUnit)) {
9513fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            dropAccessUnit = true;
9523fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesDropped;
9533fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
9543fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    } while (dropAccessUnit);
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mediaTimeUs;
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
9613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("feeding %s input buffer at media time %.2f secs",
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         audio ? "audio" : "video",
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mediaTimeUs / 1E6);
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9662d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", accessUnit);
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->post();
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
972f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
9733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    // ALOGV("renderBuffer %s", audio ? "audio" : "video");
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
97818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
97918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // We're currently attempting to flush the decoder, in order
98018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // to complete this, the decoder wants all its buffers back,
98118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // so we don't want any output buffers it sent us (from before
98218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // we initiated the flush) to be stuck in the renderer's queue.
98318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
9843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("we're still flushing the %s decoder, sending its output buffer"
98518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber             " right back.", audio ? "audio" : "video");
98618ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
98718ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        reply->post();
98818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        return;
98918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
99018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
9912d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
9922d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    CHECK(msg->findBuffer("buffer", &buffer));
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
99432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    int64_t &skipUntilMediaTimeUs =
99532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        audio
99632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            ? mSkipRenderingAudioUntilMediaTimeUs
99732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            : mSkipRenderingVideoUntilMediaTimeUs;
99832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
99932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    if (skipUntilMediaTimeUs >= 0) {
100032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        int64_t mediaTimeUs;
100132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
100232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
100332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        if (mediaTimeUs < skipUntilMediaTimeUs) {
10043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("dropping %s buffer at time %lld as requested.",
100532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 audio ? "audio" : "video",
100632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 mediaTimeUs);
100732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
100832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            reply->post();
100932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            return;
101032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        }
101132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
101232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        skipUntilMediaTimeUs = -1;
101332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    }
101432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mRenderer->queueBuffer(audio, buffer, reply);
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::notifyListener(int msg, int ext1, int ext2) {
101943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver == NULL) {
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
102343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<NuPlayerDriver> driver = mDriver.promote();
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
102543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (driver == NULL) {
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1029a4af2143ecbd630e946647c1b5f90fda8f61ebb3Andreas Huber    driver->notifyListener(msg, ext1, ext2);
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::flushDecoder(bool audio, bool needShutdown) {
10336e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
1034df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("flushDecoder %s without decoder present",
10356e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber             audio ? "audio" : "video");
10366e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
10376e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
10381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    // Make sure we don't continue to scan sources until we finish flushing.
10391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    ++mScanSourcesGeneration;
104043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mScanSourcesPending = false;
10411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
10431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mRenderer->flush(audio);
10441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    FlushStatus newStatus =
10461aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
10471aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10481aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (audio) {
10491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingAudio == NONE
10501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingAudio == AWAITING_DISCONTINUITY);
10511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingAudio = newStatus;
10531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingVideo == NONE) {
10551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingVideo = (mVideoDecoder != NULL)
10561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
10571aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
10581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
10591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else {
10601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingVideo == NONE
10611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingVideo == AWAITING_DISCONTINUITY);
10621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10631aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingVideo = newStatus;
10641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10651aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingAudio == NONE) {
10661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingAudio = (mAudioDecoder != NULL)
10671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
10681aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
10691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
10701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
10711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
10721aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
1073840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1074840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<MetaData> meta = getFormatMeta(audio);
1075840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1076840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (meta == NULL) {
1077840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        return NULL;
1078840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
1079840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1080840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<AMessage> msg = new AMessage;
1081840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1082840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if(convertMetaDataToMessage(meta, &msg) == OK) {
1083840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        return msg;
1084840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
1085840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    return NULL;
1086840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
1087840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
10880d268a3cae145afb2720c88ae38fb81550be5584James Dongstatus_t NuPlayer::setVideoScalingMode(int32_t mode) {
10890d268a3cae145afb2720c88ae38fb81550be5584James Dong    mVideoScalingMode = mode;
109057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (mNativeWindow != NULL) {
10910d268a3cae145afb2720c88ae38fb81550be5584James Dong        status_t ret = native_window_set_scaling_mode(
10920d268a3cae145afb2720c88ae38fb81550be5584James Dong                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
10930d268a3cae145afb2720c88ae38fb81550be5584James Dong        if (ret != OK) {
10940d268a3cae145afb2720c88ae38fb81550be5584James Dong            ALOGE("Failed to set scaling mode (%d): %s",
10950d268a3cae145afb2720c88ae38fb81550be5584James Dong                -ret, strerror(-ret));
10960d268a3cae145afb2720c88ae38fb81550be5584James Dong            return ret;
10970d268a3cae145afb2720c88ae38fb81550be5584James Dong        }
10980d268a3cae145afb2720c88ae38fb81550be5584James Dong    }
10990d268a3cae145afb2720c88ae38fb81550be5584James Dong    return OK;
11000d268a3cae145afb2720c88ae38fb81550be5584James Dong}
11010d268a3cae145afb2720c88ae38fb81550be5584James Dong
1102b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Hubervoid NuPlayer::schedulePollDuration() {
1103b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1104b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    msg->setInt32("generation", mPollDurationGeneration);
1105b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    msg->post();
1106b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1107b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1108b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Hubervoid NuPlayer::cancelPollDuration() {
1109b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    ++mPollDurationGeneration;
1110b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1111b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1112a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::processDeferredActions() {
1113a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    while (!mDeferredActions.empty()) {
1114a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // We won't execute any deferred actions until we're no longer in
1115a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // an intermediate state, i.e. one more more decoders are currently
1116a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // flushing or shutting down.
1117a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1118a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (mRenderer != NULL) {
1119a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // There's an edge case where the renderer owns all output
1120a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // buffers and is paused, therefore the decoder will not read
1121a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // more input data and will never encounter the matching
1122a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // discontinuity. To avoid this, we resume the renderer.
1123a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1124a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            if (mFlushingAudio == AWAITING_DISCONTINUITY
1125a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    || mFlushingVideo == AWAITING_DISCONTINUITY) {
1126a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                mRenderer->resume();
1127a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            }
1128a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1129a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1130a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1131a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // We're currently flushing, postpone the reset until that's
1132a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // completed.
1133a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1134a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1135a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                  mFlushingAudio, mFlushingVideo);
1136a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1137a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            break;
1138a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1139a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1140a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<Action> action = *mDeferredActions.begin();
1141a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mDeferredActions.erase(mDeferredActions.begin());
1142a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1143a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        action->execute(this);
1144a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1145a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1146a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1147a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performSeek(int64_t seekTimeUs) {
1148a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1149a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber          seekTimeUs,
1150a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber          seekTimeUs / 1E6);
1151a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1152a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mSource->seekTo(seekTimeUs);
1153a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1154a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mDriver != NULL) {
1155a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
1156a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (driver != NULL) {
1157a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            driver->notifyPosition(seekTimeUs);
1158a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            driver->notifySeekComplete();
1159a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1160a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1161a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1162a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    // everything's flushed, continue playback.
1163a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1164a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1165a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performDecoderFlush() {
1166a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performDecoderFlush");
1167a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1168a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1169a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        return;
1170a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1171a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1172a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mTimeDiscontinuityPending = true;
1173a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1174a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder != NULL) {
1175a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(true /* audio */, false /* needShutdown */);
1176a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1177a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1178a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mVideoDecoder != NULL) {
1179a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(false /* audio */, false /* needShutdown */);
1180a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1181a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1182a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1183a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performDecoderShutdown() {
1184a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performDecoderShutdown");
1185a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1186a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder != NULL && mVideoDecoder == NULL) {
1187a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        return;
1188a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1189a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1190a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mTimeDiscontinuityPending = true;
1191a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1192a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder != NULL) {
1193a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(true /* audio */, true /* needShutdown */);
1194a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1195a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1196a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mVideoDecoder != NULL) {
1197a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(false /* audio */, true /* needShutdown */);
1198a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1199a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1200a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1201a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performReset() {
1202a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performReset");
1203a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1204a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    CHECK(mAudioDecoder == NULL);
1205a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    CHECK(mVideoDecoder == NULL);
1206a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1207a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    cancelPollDuration();
1208a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1209a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ++mScanSourcesGeneration;
1210a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mScanSourcesPending = false;
1211a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1212a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mRenderer.clear();
1213a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1214a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mSource != NULL) {
1215a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mSource->stop();
1216b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1217b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        looper()->unregisterHandler(mSource->id());
1218b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1219a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mSource.clear();
1220a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1221a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1222a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mDriver != NULL) {
1223a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
1224a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (driver != NULL) {
1225a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            driver->notifyResetComplete();
1226a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1227a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
122857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
122957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    mStarted = false;
1230a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1231a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1232a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performScanSources() {
1233a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performScanSources");
1234a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
123557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (!mStarted) {
123657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        return;
123757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
123857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
1239a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1240a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        postScanSources();
1241a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1242a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1243a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
124457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Hubervoid NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
124557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    ALOGV("performSetSurface");
124657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
124757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    mNativeWindow = wrapper;
124857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
124957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    // XXX - ignore error from setVideoScalingMode for now
125057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    setVideoScalingMode(mVideoScalingMode);
125157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
125257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (mDriver != NULL) {
125357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
125457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        if (driver != NULL) {
125557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            driver->notifySetSurfaceComplete();
125657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        }
125757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
125857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber}
125957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
12609575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
12619575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    int32_t what;
12629575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    CHECK(msg->findInt32("what", &what));
12639575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12649575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    switch (what) {
12659575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatPrepared:
12669575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
1267ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber            int32_t err;
1268ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber            CHECK(msg->findInt32("err", &err));
1269ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber
12709575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            sp<NuPlayerDriver> driver = mDriver.promote();
12719575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if (driver != NULL) {
1272ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber                driver->notifyPrepareCompleted(err);
12739575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
12749575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
12759575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
12769575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12779575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatFlagsChanged:
12789575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
12799575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            uint32_t flags;
12809575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
12819575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12829575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
12839575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
12849575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                cancelPollDuration();
12859575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
12869575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (flags & Source::FLAG_DYNAMIC_DURATION)
12879575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
12889575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                schedulePollDuration();
12899575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
12909575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12919575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            mSourceFlags = flags;
12929575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
12939575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
12949575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatVideoSizeChanged:
12969575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
12979575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            int32_t width, height;
12989575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(msg->findInt32("width", &width));
12999575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(msg->findInt32("height", &height));
13009575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
13019575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
13029575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
13039575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
13049575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1305b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        case Source::kWhatBufferingStart:
1306b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        {
1307b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1308b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            break;
1309b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        }
1310b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson
1311b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        case Source::kWhatBufferingEnd:
1312b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        {
1313b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1314b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            break;
1315b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        }
1316b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson
13179575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        default:
13189575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            TRESPASS();
13199575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    }
13209575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13219575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1322b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber////////////////////////////////////////////////////////////////////////////////
1323b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
13249575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
13259575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
13269575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatFlagsChanged);
13279575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("flags", flags);
13289575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
13299575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13309575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
13319575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
13329575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
13339575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatVideoSizeChanged);
13349575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("width", width);
13359575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("height", height);
13369575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
13379575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13389575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1339ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Hubervoid NuPlayer::Source::notifyPrepared(status_t err) {
13409575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
13419575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatPrepared);
1342ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber    notify->setInt32("err", err);
13439575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
13449575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13459575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1346b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Hubervoid NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1347b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    TRESPASS();
1348b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber}
1349b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
1351