NuPlayer.cpp revision da9740e63a835e610519bd235be9137d74b6d409
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)
164997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            || !strncasecmp("https://", url, 8)
165997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            || !strncasecmp("file://", url, 7)) {
166afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        size_t len = strlen(url);
167afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
168afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
169afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
170afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
171afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (strstr(url,"m3u8")) {
172afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
173afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
174afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
175afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
176afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return false;
177afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
178afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1799575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(
1805bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        const char *url, const KeyedVector<String8, String8> *headers) {
1815bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
1827a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé    size_t len = strlen(url);
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
185b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
186afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<Source> source;
187afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (IsHTTPLiveURL(url)) {
188b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
189afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    } else if (!strncasecmp(url, "rtsp://", 7)) {
190b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
1917a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé    } else if ((!strncasecmp(url, "http://", 7)
1927a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                || !strncasecmp(url, "https://", 8))
1937a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
1947a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                    || strstr(url, ".sdp?"))) {
1957a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé        source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
1962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    } else {
197b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        source = new GenericSource(notify, url, headers, mUIDValid, mUID);
1982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
200afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
201afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->post();
202afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
203afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
2049575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
205afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
206afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
207b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
208b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
209b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<Source> source = new GenericSource(notify, fd, offset, length);
210afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2149575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::prepareAsync() {
2159575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    (new AMessage(kWhatPrepare, id()))->post();
2169575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
2179575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
21857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Hubervoid NuPlayer::setVideoSurfaceTextureAsync(
2198ba01021b573889802e67e029225a96f0dfa471aAndy McFadden        const sp<IGraphicBufferProducer> &bufferProducer) {
2201173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
22157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
2228ba01021b573889802e67e029225a96f0dfa471aAndy McFadden    if (bufferProducer == NULL) {
22357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        msg->setObject("native-window", NULL);
22457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    } else {
22557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        msg->setObject(
22657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                "native-window",
22757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                new NativeWindowWrapper(
2281a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian                    new Surface(bufferProducer)));
22957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
23057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setObject("sink", sink);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::start() {
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatStart, id()))->post();
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24443c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::pause() {
245b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatPause, id()))->post();
24643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
24743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
24843c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::resume() {
249b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatResume, id()))->post();
25043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
25143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
2521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::resetAsync() {
2531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (new AMessage(kWhatReset, id()))->post();
2541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
2551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
25643c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::seekToAsync(int64_t seekTimeUs) {
25743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, id());
25843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->setInt64("seekTimeUs", seekTimeUs);
25943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->post();
26043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
26143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
26253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber// static
2631aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberbool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
26453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    switch (state) {
26553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        case FLUSHING_DECODER:
2661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
2671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = false;
26853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
26953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
27053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
2711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case FLUSHING_DECODER_SHUTDOWN:
2721aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (needShutdown != NULL) {
2731aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                *needShutdown = true;
27453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            }
27553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return true;
27653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
27753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        default:
27853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            return false;
27953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    }
28053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
28153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetDataSource:
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetDataSource");
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(mSource == NULL);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2905bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            sp<RefBase> obj;
2915bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(msg->findObject("source", &obj));
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2935bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource = static_cast<Source *>(obj.get());
294b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
295b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber            looper()->registerHandler(mSource);
2969575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
2979575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(mDriver != NULL);
2989575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            sp<NuPlayerDriver> driver = mDriver.promote();
2999575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if (driver != NULL) {
3009575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                driver->notifySetDataSourceCompleted(OK);
3019575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
3029575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
3039575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
3049575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
3059575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case kWhatPrepare:
3069575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
3079575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            mSource->prepareAsync();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        case kWhatPollDuration:
312b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        {
313b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            int32_t generation;
314b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            CHECK(msg->findInt32("generation", &generation));
315b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
316b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (generation != mPollDurationGeneration) {
317b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                // stale
318b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                break;
319b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
320b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
321b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            int64_t durationUs;
322b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
323b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                sp<NuPlayerDriver> driver = mDriver.promote();
324b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                if (driver != NULL) {
325b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    driver->notifyDuration(durationUs);
326b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                }
327b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
328b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
329b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            msg->post(1000000ll);  // poll again in a second.
330b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            break;
331b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        }
332b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
3331173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        case kWhatSetVideoNativeWindow:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetVideoNativeWindow");
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            mDeferredActions.push_back(
33857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                    new SimpleAction(&NuPlayer::performDecoderShutdown));
33957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
3411173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            CHECK(msg->findObject("native-window", &obj));
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            mDeferredActions.push_back(
34457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                    new SetSurfaceAction(
34557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                        static_cast<NativeWindowWrapper *>(obj.get())));
34657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
34757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            if (obj != NULL) {
34857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                // If there is a new surface texture, instantiate decoders
34957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                // again if possible.
35057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                mDeferredActions.push_back(
35157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                        new SimpleAction(&NuPlayer::performScanSources));
35257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            }
3530d268a3cae145afb2720c88ae38fb81550be5584James Dong
35457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            processDeferredActions();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetAudioSink:
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetAudioSink");
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findObject("sink", &obj));
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatStart:
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatStart");
37243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
3733fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoIsAVC = false;
3741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mAudioEOS = false;
3751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mVideoEOS = false;
37632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingAudioUntilMediaTimeUs = -1;
37732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            mSkipRenderingVideoUntilMediaTimeUs = -1;
3783fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mVideoLateByUs = 0;
3793fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesTotal = 0;
3803fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mNumFramesDropped = 0;
38157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            mStarted = true;
3821aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
3835bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mSource->start();
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber            uint32_t flags = 0;
386d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
387d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber            if (mSource->isRealTime()) {
388d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber                flags |= Renderer::FLAG_REAL_TIME;
389d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber            }
390d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mRenderer = new Renderer(
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioSink,
393d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber                    new AMessage(kWhatRendererNotify, id()),
394d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber                    flags);
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            looper()->registerHandler(mRenderer);
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            postScanSources();
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatScanSources:
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            int32_t generation;
4051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            CHECK(msg->findInt32("generation", &generation));
4061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (generation != mScanSourcesGeneration) {
4071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // Drop obsolete msg.
4081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
4091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
4101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4115bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mScanSourcesPending = false;
4125bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
4133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
41443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 mAudioDecoder != NULL, mVideoDecoder != NULL);
41543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
416b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            bool mHadAnySourcesBefore =
417b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
418b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
4195d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            if (mNativeWindow != NULL) {
4205d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George                instantiateDecoder(false, &mVideoDecoder);
4215d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            }
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioSink != NULL) {
4245bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                instantiateDecoder(true, &mAudioDecoder);
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (!mHadAnySourcesBefore
428b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
429b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                // This is the first time we've found anything playable.
430b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
4319575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
432b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    schedulePollDuration();
433b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                }
434b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
435b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
436eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            status_t err;
437eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            if ((err = mSource->feedMoreTSData()) != OK) {
4381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
4391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // We're not currently decoding anything (no audio or
4401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // video tracks found) and we just ran out of input data.
441eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber
442eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (err == ERROR_END_OF_STREAM) {
443eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
444eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    } else {
445eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
446eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    }
4471aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                }
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            if ((mAudioDecoder == NULL && mAudioSink != NULL)
452fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->post(100000ll);
4545bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                mScanSourcesPending = true;
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatVideoNotify:
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatAudioNotify:
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            bool audio = msg->what() == kWhatAudioNotify;
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> codecRequest;
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findMessage("codec-request", &codecRequest));
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(codecRequest->findInt32("what", &what));
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == ACodec::kWhatFillThisBuffer) {
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                status_t err = feedDecoderInputData(
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        audio, codecRequest);
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4745bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                if (err == -EWOULDBLOCK) {
475eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (mSource->feedMoreTSData() == OK) {
4761183a4ab06b9fe01fe39a4b8728bfc71789361fcAndreas Huber                        msg->post(10000ll);
4775bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                    }
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatEOS) {
480dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                int32_t err;
481dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                CHECK(codecRequest->findInt32("err", &err));
482dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
483dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err == ERROR_END_OF_STREAM) {
4843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
485dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
4863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS w/ error %d",
487dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         audio ? "audio" : "video",
488dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         err);
489dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
490dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
491dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mRenderer->queueEOS(audio, err);
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (what == ACodec::kWhatFlushCompleted) {
4931aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                bool needShutdown;
49453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
4961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingAudio = FLUSHED;
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
4991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mFlushingVideo = FLUSHED;
5013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
5023fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mVideoLateByUs = 0;
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (needShutdown) {
5083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("initiating %s decoder shutdown",
50953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                         audio ? "audio" : "video");
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    if (audio) {
51453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingAudio = SHUTTING_DOWN_DECODER;
51553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    } else {
51653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                        mFlushingVideo = SHUTTING_DOWN_DECODER;
51753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber                    }
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5203831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
5212c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber            } else if (what == ACodec::kWhatOutputFormatChanged) {
52231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                if (audio) {
52331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t numChannels;
524516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    CHECK(codecRequest->findInt32(
525516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                                "channel-count", &numChannels));
5262c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
52731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t sampleRate;
52831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
5292c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
5303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Audio output format changed to %d Hz, %d channels",
53131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         sampleRate, numChannels);
5322c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber
53331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->close();
5341948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
5351948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    audio_output_flags_t flags;
5361948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    int64_t durationUs;
537516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // FIXME: we should handle the case where the video decoder
538516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // is created after we receive the format change indication.
539516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // Current code will just make that we select deep buffer
540516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // with video which should not be a problem as it should
5411948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    // not prevent from keeping A/V sync.
5421948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    if (mVideoDecoder == NULL &&
5431948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                            mSource->getDuration(&durationUs) == OK &&
544516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            durationUs
545516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
5461948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
5471948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    } else {
5481948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                        flags = AUDIO_OUTPUT_FLAG_NONE;
5491948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                    }
5501948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
5519806555d3930be43e11106281dee354820ac1c88Andreas Huber                    int32_t channelMask;
5529806555d3930be43e11106281dee354820ac1c88Andreas Huber                    if (!codecRequest->findInt32("channel-mask", &channelMask)) {
5539806555d3930be43e11106281dee354820ac1c88Andreas Huber                        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
5549806555d3930be43e11106281dee354820ac1c88Andreas Huber                    }
5559806555d3930be43e11106281dee354820ac1c88Andreas Huber
556078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                    CHECK_EQ(mAudioSink->open(
557078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                sampleRate,
558078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                numChannels,
5599806555d3930be43e11106281dee354820ac1c88Andreas Huber                                (audio_channel_mask_t)channelMask,
560078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                                AUDIO_FORMAT_PCM_16_BIT,
5611948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                8 /* bufferCount */,
5621948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                NULL,
5631948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                NULL,
5641948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                                flags),
565078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                             (status_t)OK);
56631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mAudioSink->start();
5673831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
56831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mRenderer->signalAudioSinkChanged();
56931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                } else {
57031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    // video
57131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
57231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t width, height;
57331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("width", &width));
57431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findInt32("height", &height));
57531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
57631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    int32_t cropLeft, cropTop, cropRight, cropBottom;
57731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    CHECK(codecRequest->findRect(
57831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                "crop",
57931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                                &cropLeft, &cropTop, &cropRight, &cropBottom));
58031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
581516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    int32_t displayWidth = cropRight - cropLeft + 1;
582516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    int32_t displayHeight = cropBottom - cropTop + 1;
583516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
5843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("Video output format changed to %d x %d "
585cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "(crop: %d x %d @ (%d, %d))",
58631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                         width, height,
587516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                         displayWidth,
588516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                         displayHeight,
589cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         cropLeft, cropTop);
59031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
591516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    sp<AMessage> videoInputFormat =
592516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        mSource->getFormat(false /* audio */);
593516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
594516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    // Take into account sample aspect ratio if necessary:
595516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    int32_t sarWidth, sarHeight;
596516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    if (videoInputFormat->findInt32("sar-width", &sarWidth)
597516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            && videoInputFormat->findInt32(
598516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                                "sar-height", &sarHeight)) {
599516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        ALOGV("Sample aspect ratio %d : %d",
600516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                              sarWidth, sarHeight);
601516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
602516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        displayWidth = (displayWidth * sarWidth) / sarHeight;
603516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
604516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                        ALOGV("display dimensions %d x %d",
605516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                              displayWidth, displayHeight);
606516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    }
607516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
60831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    notifyListener(
609516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
61031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                }
6113831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            } else if (what == ACodec::kWhatShutdownCompleted) {
6123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("%s shutdown completed", audio ? "audio" : "video");
6133831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                if (audio) {
6143831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mAudioDecoder.clear();
6153831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6163831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
6173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingAudio = SHUT_DOWN;
6183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                } else {
6193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mVideoDecoder.clear();
6203831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6213831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
6223831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingVideo = SHUT_DOWN;
6233831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                }
6243831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
6253831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
626c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            } else if (what == ACodec::kWhatError) {
62729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("Received error from %s decoder, aborting playback.",
628c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                     audio ? "audio" : "video");
629c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
630c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
6315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else if (what == ACodec::kWhatDrainThisBuffer) {
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                renderBuffer(audio, codecRequest);
633a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            } else if (what != ACodec::kWhatComponentAllocated
634a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    && what != ACodec::kWhatComponentConfigured
635a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    && what != ACodec::kWhatBuffersAllocated) {
636a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
637a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what,
638a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what >> 24,
639a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      (what >> 16) & 0xff,
640a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      (what >> 8) & 0xff,
641a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what & 0xff);
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatRendererNotify:
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("what", &what));
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == Renderer::kWhatEOS) {
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
656c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                int32_t finalResult;
657c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                CHECK(msg->findInt32("finalResult", &finalResult));
658c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEOS = true;
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mVideoEOS = true;
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
665c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (finalResult == ERROR_END_OF_STREAM) {
6663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("reached %s EOS", audio ? "audio" : "video");
667c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                } else {
66829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("%s track encountered an error (%d)",
669c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         audio ? "audio" : "video", finalResult);
670c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
671c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    notifyListener(
672c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
673c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if ((mAudioEOS || mAudioDecoder == NULL)
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        && (mVideoEOS || mVideoDecoder == NULL)) {
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
67943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            } else if (what == Renderer::kWhatPosition) {
68043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                int64_t positionUs;
68143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                CHECK(msg->findInt64("positionUs", &positionUs));
68243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
6833fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
6843fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
68543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (mDriver != NULL) {
68643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    sp<NuPlayerDriver> driver = mDriver.promote();
68743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    if (driver != NULL) {
68843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                        driver->notifyPosition(positionUs);
6893fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
6903fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        driver->notifyFrameStats(
6913fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                                mNumFramesTotal, mNumFramesDropped);
69243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    }
69343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
6943fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            } else if (what == Renderer::kWhatFlushComplete) {
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
699f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong            } else if (what == Renderer::kWhatVideoRenderingStart) {
700f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatMoreDataQueued:
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case kWhatReset:
7111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        {
7123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatReset");
7131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
714a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
715a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    new SimpleAction(&NuPlayer::performDecoderShutdown));
716b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
717a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
718a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    new SimpleAction(&NuPlayer::performReset));
7191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
720a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            processDeferredActions();
7211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            break;
7221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
7231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
72443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        case kWhatSeek:
72543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        {
72643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            int64_t seekTimeUs;
72743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
72843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
729a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
73043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
731a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
732a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    new SimpleAction(&NuPlayer::performDecoderFlush));
73343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
734a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(new SeekAction(seekTimeUs));
73543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
736a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            processDeferredActions();
73743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            break;
73843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
73943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
740b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatPause:
741b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
742b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
743fba60daf77cc74a13ae3bf4b0e9925dd2ee4470cRoger Jönsson            mSource->pause();
744b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->pause();
745b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
746b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
747b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
748b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatResume:
749b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
750b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            CHECK(mRenderer != NULL);
751fba60daf77cc74a13ae3bf4b0e9925dd2ee4470cRoger Jönsson            mSource->resume();
752b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            mRenderer->resume();
753b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
754b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
755b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
756b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        case kWhatSourceNotify:
757b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        {
7589575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            onSourceNotify(msg);
759b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber            break;
760b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        }
761b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7683831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::finishFlushIfPossible() {
7693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
7703831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
7713831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7723831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7733831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
7743831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
7753831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7763831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("both audio and video are flushed now.");
7783831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7796e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (mTimeDiscontinuityPending) {
7806e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mRenderer->signalTimeDiscontinuity();
7816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        mTimeDiscontinuityPending = false;
7826e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
7833831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
78422fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mAudioDecoder != NULL) {
7853831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mAudioDecoder->signalResume();
7863831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7873831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
78822fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (mVideoDecoder != NULL) {
7893831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        mVideoDecoder->signalResume();
7903831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
7913831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7923831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingAudio = NONE;
7933831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingVideo = NONE;
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
795a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    processDeferredActions();
7961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
7971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
7981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::postScanSources() {
7991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mScanSourcesPending) {
8001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return;
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
8041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->setInt32("generation", mScanSourcesGeneration);
8051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->post();
8061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
8071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mScanSourcesPending = true;
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8105bc087c573c70c84c6a39946457590b42d392a33Andreas Huberstatus_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (*decoder != NULL) {
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
815840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<AMessage> format = mSource->getFormat(audio);
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
817840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (format == NULL) {
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8213fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    if (!audio) {
822840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        AString mime;
823840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        CHECK(format->findString("mime", &mime));
824840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
8253fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    }
8263fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify =
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     id());
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    *decoder = audio ? new Decoder(notify) :
8321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                       new Decoder(notify, mNativeWindow);
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper()->registerHandler(*decoder);
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    (*decoder)->configure(format);
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    if ((audio && IsFlushingState(mFlushingAudio))
84553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            || (!audio && IsFlushingState(mFlushingVideo))) {
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->setInt32("err", INFO_DISCONTINUITY);
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->post();
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> accessUnit;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8533fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    bool dropAccessUnit;
8543fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    do {
8553fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
8565bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
8573fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (err == -EWOULDBLOCK) {
8583fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return err;
8593fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        } else if (err != OK) {
8603fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            if (err == INFO_DISCONTINUITY) {
8613fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                int32_t type;
8623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
86353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
8643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                bool formatChange =
8656e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    (audio &&
8666e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
8676e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    || (!audio &&
8686e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
86953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
8706e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
8716e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
872df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("%s discontinuity (formatChange=%d, time=%d)",
8736e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                     audio ? "audio" : "video", formatChange, timeChange);
87432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
8753fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                if (audio) {
8763fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingAudioUntilMediaTimeUs = -1;
8773fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                } else {
8783fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                    mSkipRenderingVideoUntilMediaTimeUs = -1;
8793fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                }
88032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
8816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                if (timeChange) {
8826e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    sp<AMessage> extra;
8836e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    if (accessUnit->meta()->findMessage("extra", &extra)
8846e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            && extra != NULL) {
8856e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        int64_t resumeAtMediaTimeUs;
8866e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        if (extra->findInt64(
8876e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
888df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                            ALOGI("suppressing rendering of %s until %lld us",
8896e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
8906e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
8916e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            if (audio) {
8926e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                mSkipRenderingAudioUntilMediaTimeUs =
8936e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    resumeAtMediaTimeUs;
8946e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            } else {
8956e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                mSkipRenderingVideoUntilMediaTimeUs =
8966e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                                    resumeAtMediaTimeUs;
8976e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                            }
8983fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                        }
89932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                    }
90032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                }
9013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
9026e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                mTimeDiscontinuityPending =
9036e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    mTimeDiscontinuityPending || timeChange;
9046e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9056e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                if (formatChange || timeChange) {
906a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
907a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                        // And we'll resume scanning sources once we're done
908a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                        // flushing.
909a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                        mDeferredActions.push_front(
910a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                                new SimpleAction(
911a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                                    &NuPlayer::performScanSources));
912a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    }
913a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
9146e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    flushDecoder(audio, formatChange);
9156e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                } else {
9166e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    // This stream is unaffected by the discontinuity
9176e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9186e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    if (audio) {
9196e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        mFlushingAudio = FLUSHED;
9206e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    } else {
9216e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                        mFlushingVideo = FLUSHED;
9226e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    }
9236e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9246e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    finishFlushIfPossible();
9256e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9266e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    return -EWOULDBLOCK;
9276e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                }
92832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            }
92932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
9303fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->setInt32("err", err);
9313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            reply->post();
9323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            return OK;
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9353fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio) {
9363fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesTotal;
9373fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
9383fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
9393fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        dropAccessUnit = false;
9403fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (!audio
9413fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoLateByUs > 100000ll
9423fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && mVideoIsAVC
9433fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber                && !IsAVCReferenceFrame(accessUnit)) {
9443fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            dropAccessUnit = true;
9453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            ++mNumFramesDropped;
9463fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        }
9473fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    } while (dropAccessUnit);
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mediaTimeUs;
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
9543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("feeding %s input buffer at media time %.2f secs",
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         audio ? "audio" : "video",
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mediaTimeUs / 1E6);
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9592d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", accessUnit);
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->post();
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
965f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
9663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    // ALOGV("renderBuffer %s", audio ? "audio" : "video");
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply;
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findMessage("reply", &reply));
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
97118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
97218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // We're currently attempting to flush the decoder, in order
97318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // to complete this, the decoder wants all its buffers back,
97418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // so we don't want any output buffers it sent us (from before
97518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        // we initiated the flush) to be stuck in the renderer's queue.
97618ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
9773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("we're still flushing the %s decoder, sending its output buffer"
97818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber             " right back.", audio ? "audio" : "video");
97918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
98018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        reply->post();
98118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        return;
98218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
98318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
9842d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
9852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    CHECK(msg->findBuffer("buffer", &buffer));
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
98732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    int64_t &skipUntilMediaTimeUs =
98832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        audio
98932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            ? mSkipRenderingAudioUntilMediaTimeUs
99032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            : mSkipRenderingVideoUntilMediaTimeUs;
99132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
99232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    if (skipUntilMediaTimeUs >= 0) {
99332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        int64_t mediaTimeUs;
99432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
99532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
99632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        if (mediaTimeUs < skipUntilMediaTimeUs) {
9973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("dropping %s buffer at time %lld as requested.",
99832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 audio ? "audio" : "video",
99932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                 mediaTimeUs);
100032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
100132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            reply->post();
100232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            return;
100332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        }
100432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
100532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        skipUntilMediaTimeUs = -1;
100632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    }
100732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mRenderer->queueBuffer(audio, buffer, reply);
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::notifyListener(int msg, int ext1, int ext2) {
101243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver == NULL) {
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
101643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<NuPlayerDriver> driver = mDriver.promote();
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
101843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (driver == NULL) {
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022a4af2143ecbd630e946647c1b5f90fda8f61ebb3Andreas Huber    driver->notifyListener(msg, ext1, ext2);
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::flushDecoder(bool audio, bool needShutdown) {
10266e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
1027df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("flushDecoder %s without decoder present",
10286e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber             audio ? "audio" : "video");
10296e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
10306e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
10311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    // Make sure we don't continue to scan sources until we finish flushing.
10321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    ++mScanSourcesGeneration;
103343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mScanSourcesPending = false;
10341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10351aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
10361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mRenderer->flush(audio);
10371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    FlushStatus newStatus =
10391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
10401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (audio) {
10421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingAudio == NONE
10431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingAudio == AWAITING_DISCONTINUITY);
10441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingAudio = newStatus;
10461aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10471aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingVideo == NONE) {
10481aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingVideo = (mVideoDecoder != NULL)
10491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
10501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
10511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
10521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else {
10531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        CHECK(mFlushingVideo == NONE
10541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                || mFlushingVideo == AWAITING_DISCONTINUITY);
10551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingVideo = newStatus;
10571aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
10581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mFlushingAudio == NONE) {
10591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mFlushingAudio = (mAudioDecoder != NULL)
10601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                ? AWAITING_DISCONTINUITY
10611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                : FLUSHED;
10621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
10631aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
10641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
10651aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
1066840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1067840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<MetaData> meta = getFormatMeta(audio);
1068840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1069840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (meta == NULL) {
1070840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        return NULL;
1071840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
1072840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1073840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<AMessage> msg = new AMessage;
1074840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1075840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if(convertMetaDataToMessage(meta, &msg) == OK) {
1076840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        return msg;
1077840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
1078840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    return NULL;
1079840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
1080840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
10810d268a3cae145afb2720c88ae38fb81550be5584James Dongstatus_t NuPlayer::setVideoScalingMode(int32_t mode) {
10820d268a3cae145afb2720c88ae38fb81550be5584James Dong    mVideoScalingMode = mode;
108357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (mNativeWindow != NULL) {
10840d268a3cae145afb2720c88ae38fb81550be5584James Dong        status_t ret = native_window_set_scaling_mode(
10850d268a3cae145afb2720c88ae38fb81550be5584James Dong                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
10860d268a3cae145afb2720c88ae38fb81550be5584James Dong        if (ret != OK) {
10870d268a3cae145afb2720c88ae38fb81550be5584James Dong            ALOGE("Failed to set scaling mode (%d): %s",
10880d268a3cae145afb2720c88ae38fb81550be5584James Dong                -ret, strerror(-ret));
10890d268a3cae145afb2720c88ae38fb81550be5584James Dong            return ret;
10900d268a3cae145afb2720c88ae38fb81550be5584James Dong        }
10910d268a3cae145afb2720c88ae38fb81550be5584James Dong    }
10920d268a3cae145afb2720c88ae38fb81550be5584James Dong    return OK;
10930d268a3cae145afb2720c88ae38fb81550be5584James Dong}
10940d268a3cae145afb2720c88ae38fb81550be5584James Dong
1095b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Hubervoid NuPlayer::schedulePollDuration() {
1096b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1097b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    msg->setInt32("generation", mPollDurationGeneration);
1098b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    msg->post();
1099b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1100b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1101b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Hubervoid NuPlayer::cancelPollDuration() {
1102b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    ++mPollDurationGeneration;
1103b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1104b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1105a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::processDeferredActions() {
1106a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    while (!mDeferredActions.empty()) {
1107a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // We won't execute any deferred actions until we're no longer in
1108a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // an intermediate state, i.e. one more more decoders are currently
1109a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // flushing or shutting down.
1110a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1111a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (mRenderer != NULL) {
1112a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // There's an edge case where the renderer owns all output
1113a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // buffers and is paused, therefore the decoder will not read
1114a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // more input data and will never encounter the matching
1115a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // discontinuity. To avoid this, we resume the renderer.
1116a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1117a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            if (mFlushingAudio == AWAITING_DISCONTINUITY
1118a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    || mFlushingVideo == AWAITING_DISCONTINUITY) {
1119a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                mRenderer->resume();
1120a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            }
1121a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1122a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1123a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1124a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // We're currently flushing, postpone the reset until that's
1125a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // completed.
1126a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1127a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1128a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                  mFlushingAudio, mFlushingVideo);
1129a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1130a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            break;
1131a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1132a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1133a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<Action> action = *mDeferredActions.begin();
1134a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mDeferredActions.erase(mDeferredActions.begin());
1135a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1136a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        action->execute(this);
1137a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1138a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1139a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1140a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performSeek(int64_t seekTimeUs) {
1141a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1142a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber          seekTimeUs,
1143a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber          seekTimeUs / 1E6);
1144a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1145a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mSource->seekTo(seekTimeUs);
1146a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1147a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mDriver != NULL) {
1148a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
1149a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (driver != NULL) {
1150a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            driver->notifyPosition(seekTimeUs);
1151a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            driver->notifySeekComplete();
1152a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1153a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1154a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1155a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    // everything's flushed, continue playback.
1156a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1157a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1158a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performDecoderFlush() {
1159a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performDecoderFlush");
1160a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1161da9740e63a835e610519bd235be9137d74b6d409Andreas Huber    if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1162a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        return;
1163a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1164a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1165a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mTimeDiscontinuityPending = true;
1166a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1167a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder != NULL) {
1168a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(true /* audio */, false /* needShutdown */);
1169a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1170a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1171a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mVideoDecoder != NULL) {
1172a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(false /* audio */, false /* needShutdown */);
1173a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1174a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1175a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1176a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performDecoderShutdown() {
1177a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performDecoderShutdown");
1178a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1179da9740e63a835e610519bd235be9137d74b6d409Andreas Huber    if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1180a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        return;
1181a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1182a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1183a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mTimeDiscontinuityPending = true;
1184a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1185a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder != NULL) {
1186a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(true /* audio */, true /* needShutdown */);
1187a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1188a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1189a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mVideoDecoder != NULL) {
1190a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        flushDecoder(false /* audio */, true /* needShutdown */);
1191a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1192a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1193a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1194a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performReset() {
1195a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performReset");
1196a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1197a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    CHECK(mAudioDecoder == NULL);
1198a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    CHECK(mVideoDecoder == NULL);
1199a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1200a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    cancelPollDuration();
1201a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1202a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ++mScanSourcesGeneration;
1203a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mScanSourcesPending = false;
1204a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1205a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mRenderer.clear();
1206a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1207a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mSource != NULL) {
1208a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mSource->stop();
1209b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1210b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        looper()->unregisterHandler(mSource->id());
1211b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1212a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mSource.clear();
1213a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1214a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1215a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mDriver != NULL) {
1216a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
1217a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (driver != NULL) {
1218a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            driver->notifyResetComplete();
1219a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1220a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
122157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
122257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    mStarted = false;
1223a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1224a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1225a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performScanSources() {
1226a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performScanSources");
1227a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
122857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (!mStarted) {
122957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        return;
123057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
123157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
1232a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1233a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        postScanSources();
1234a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1235a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1236a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
123757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Hubervoid NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
123857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    ALOGV("performSetSurface");
123957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
124057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    mNativeWindow = wrapper;
124157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
124257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    // XXX - ignore error from setVideoScalingMode for now
124357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    setVideoScalingMode(mVideoScalingMode);
124457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
124557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (mDriver != NULL) {
124657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
124757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        if (driver != NULL) {
124857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            driver->notifySetSurfaceComplete();
124957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        }
125057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
125157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber}
125257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
12539575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
12549575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    int32_t what;
12559575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    CHECK(msg->findInt32("what", &what));
12569575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12579575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    switch (what) {
12589575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatPrepared:
12599575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
1260ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber            int32_t err;
1261ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber            CHECK(msg->findInt32("err", &err));
1262ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber
12639575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            sp<NuPlayerDriver> driver = mDriver.promote();
12649575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if (driver != NULL) {
1265ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber                driver->notifyPrepareCompleted(err);
12669575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
1267997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber
1268997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            int64_t durationUs;
1269997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
1270997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber                sp<NuPlayerDriver> driver = mDriver.promote();
1271997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber                if (driver != NULL) {
1272997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber                    driver->notifyDuration(durationUs);
1273997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber                }
1274997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            }
12759575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
12769575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
12779575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12789575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatFlagsChanged:
12799575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
12809575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            uint32_t flags;
12819575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
12829575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12839575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
12849575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
12859575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                cancelPollDuration();
12869575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
12879575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (flags & Source::FLAG_DYNAMIC_DURATION)
12889575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
12899575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                schedulePollDuration();
12909575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
12919575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12929575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            mSourceFlags = flags;
12939575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
12949575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
12959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
12969575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatVideoSizeChanged:
12979575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
12989575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            int32_t width, height;
12999575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(msg->findInt32("width", &width));
13009575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(msg->findInt32("height", &height));
13019575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
13029575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
13039575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
13049575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
13059575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1306b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        case Source::kWhatBufferingStart:
1307b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        {
1308b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1309b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            break;
1310b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        }
1311b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson
1312b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        case Source::kWhatBufferingEnd:
1313b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        {
1314b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1315b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            break;
1316b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        }
1317b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson
13189575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        default:
13199575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            TRESPASS();
13209575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    }
13219575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13229575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1323b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber////////////////////////////////////////////////////////////////////////////////
1324b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
13259575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
13269575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
13279575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatFlagsChanged);
13289575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("flags", flags);
13299575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
13309575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13319575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
13329575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
13339575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
13349575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatVideoSizeChanged);
13359575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("width", width);
13369575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("height", height);
13379575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
13389575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13399575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1340ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Hubervoid NuPlayer::Source::notifyPrepared(status_t err) {
13419575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
13429575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatPrepared);
1343ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber    notify->setInt32("err", err);
13449575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
13459575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
13469575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1347b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Hubervoid NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1348b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    TRESPASS();
1349b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber}
1350b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
1352