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"
247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerCCDecoder.h"
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h"
267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerDecoderBase.h"
27bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia#include "NuPlayerDecoderPassThrough.h"
2843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber#include "NuPlayerDriver.h"
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerRenderer.h"
305bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "NuPlayerSource.h"
312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include "RTSPSource.h"
325bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "StreamingSource.h"
33afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "GenericSource.h"
34d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih#include "TextDescriptions.h"
355bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
365bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "ATSParser.h"
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar#include <cutils/properties.h>
39d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar
403831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#include <media/stagefright/foundation/hexdump.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
44095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h>
453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include <media/stagefright/MediaDefs.h>
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaErrors.h>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h>
488ba01021b573889802e67e029225a96f0dfa471aAndy McFadden#include <gui/IGraphicBufferProducer.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include "avc_utils.h"
513fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
52840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include "ESDS.h"
53840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/Utils.h>
54840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberstruct NuPlayer::Action : public RefBase {
58a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    Action() {}
59a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
60a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    virtual void execute(NuPlayer *player) = 0;
61a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
62a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberprivate:
63a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Action);
64a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber};
65a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
66a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberstruct NuPlayer::SeekAction : public Action {
67e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia    SeekAction(int64_t seekTimeUs, bool needNotify)
68e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia        : mSeekTimeUs(seekTimeUs),
69e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia          mNeedNotify(needNotify) {
70a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
71a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
72a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    virtual void execute(NuPlayer *player) {
73e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia        player->performSeek(mSeekTimeUs, mNeedNotify);
74a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
75a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
76a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberprivate:
77a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    int64_t mSeekTimeUs;
78e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia    bool mNeedNotify;
79a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
80a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
81a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber};
82a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
83f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangstruct NuPlayer::ResumeDecoderAction : public Action {
84f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    ResumeDecoderAction(bool needNotify)
85f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        : mNeedNotify(needNotify) {
86f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
87f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
88f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    virtual void execute(NuPlayer *player) {
89f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        player->performResumeDecoders(mNeedNotify);
90f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
91f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
92f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangprivate:
93f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    bool mNeedNotify;
94f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
95f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
96f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang};
97f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
9857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huberstruct NuPlayer::SetSurfaceAction : public Action {
9957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
10057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        : mWrapper(wrapper) {
10157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
10257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
10357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    virtual void execute(NuPlayer *player) {
10457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        player->performSetSurface(mWrapper);
10557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
10657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
10757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huberprivate:
10857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    sp<NativeWindowWrapper> mWrapper;
10957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
11057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
11157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber};
11257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
113fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jiastruct NuPlayer::FlushDecoderAction : public Action {
114fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    FlushDecoderAction(FlushCommand audio, FlushCommand video)
11514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        : mAudio(audio),
11614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber          mVideo(video) {
11714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
11814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
11914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    virtual void execute(NuPlayer *player) {
120fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia        player->performDecoderFlush(mAudio, mVideo);
12114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
12214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
12314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberprivate:
124fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    FlushCommand mAudio;
125fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    FlushCommand mVideo;
12614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
127fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
12814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber};
12914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
13014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct NuPlayer::PostMessageAction : public Action {
13114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    PostMessageAction(const sp<AMessage> &msg)
13214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        : mMessage(msg) {
13314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
13414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
13514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    virtual void execute(NuPlayer *) {
13614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        mMessage->post();
13714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
13814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
13914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberprivate:
14014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> mMessage;
14114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
14214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
14314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber};
14414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
145a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber// Use this if there's no state necessary to save in order to execute
146a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber// the action.
147a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberstruct NuPlayer::SimpleAction : public Action {
148a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    typedef void (NuPlayer::*ActionFunc)();
149a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
150a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    SimpleAction(ActionFunc func)
151a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        : mFunc(func) {
152a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
153a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
154a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    virtual void execute(NuPlayer *player) {
155a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        (player->*mFunc)();
156a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
157a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
158a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huberprivate:
159a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ActionFunc mFunc;
160a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
161a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
162a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber};
163a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::NuPlayer()
1679b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    : mUIDValid(false),
1689575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber      mSourceFlags(0),
169bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia      mOffloadAudio(false),
17088703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia      mAudioDecoderGeneration(0),
17188703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia      mVideoDecoderGeneration(0),
17257568df014f8629ebc5ca8bce9da796dd187401bWei Jia      mRendererGeneration(0),
1739b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mAudioEOS(false),
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoEOS(false),
1755bc087c573c70c84c6a39946457590b42d392a33Andreas Huber      mScanSourcesPending(false),
1761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mScanSourcesGeneration(0),
177b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber      mPollDurationGeneration(0),
178d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih      mTimedTextGeneration(0),
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlushingAudio(NONE),
1801aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber      mFlushingVideo(NONE),
181f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang      mResumePending(false),
18257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
183efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mStarted(false),
184efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mPaused(false),
185efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mPausedByClient(false) {
1868d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    clearFlushComplete();
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::~NuPlayer() {
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1929b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid NuPlayer::setUID(uid_t uid) {
1939b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUIDValid = true;
1949b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
1959b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber}
1969b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
19743c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
19843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mDriver = driver;
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2019575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
205b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
206240abcc4bf661a10ffca24859945796acc76ac6eAndreas Huber    msg->setObject("source", new StreamingSource(notify, source));
2075bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    msg->post();
2085bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
2095bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
210afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatic bool IsHTTPLiveURL(const char *url) {
211afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!strncasecmp("http://", url, 7)
212997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            || !strncasecmp("https://", url, 8)
213997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            || !strncasecmp("file://", url, 7)) {
214afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        size_t len = strlen(url);
215afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
216afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
217afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
218afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
219afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (strstr(url,"m3u8")) {
220afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            return true;
221afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
222afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
223afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
224afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return false;
225afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
226afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
2279575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(
2281b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const sp<IMediaHTTPService> &httpService,
2291b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const char *url,
2301b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const KeyedVector<String8, String8> *headers) {
2313de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2325bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
2337a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé    size_t len = strlen(url);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
236b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
237afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<Source> source;
238afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (IsHTTPLiveURL(url)) {
23981e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber        source = new HTTPLiveSource(notify, httpService, url, headers);
240afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    } else if (!strncasecmp(url, "rtsp://", 7)) {
2411b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        source = new RTSPSource(
2421b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                notify, httpService, url, headers, mUIDValid, mUID);
2437a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé    } else if ((!strncasecmp(url, "http://", 7)
2447a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                || !strncasecmp(url, "https://", 8))
2457a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
2467a33b7740412accf6a1cc912686c8d0acfb2a883Oscar Rydhé                    || strstr(url, ".sdp?"))) {
2471b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        source = new RTSPSource(
2481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                notify, httpService, url, headers, mUIDValid, mUID, true);
2492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    } else {
2503de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        sp<GenericSource> genericSource =
2513de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                new GenericSource(notify, mUIDValid, mUID);
2523de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        // Don't set FLAG_SECURE on mSourceFlags here for widevine.
2533de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        // The correct flags will be updated in Source::kWhatFlagsChanged
2543de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        // handler when  GenericSource is prepared.
2553de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
256a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        status_t err = genericSource->setDataSource(httpService, url, headers);
2573de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2583de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        if (err == OK) {
2593de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            source = genericSource;
2603de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        } else {
261a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang            ALOGE("Failed to set data source!");
2623de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        }
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
264afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
265afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->post();
266afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
267afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
2689575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
269afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
270afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
271b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
272b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
2733de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    sp<GenericSource> source =
2743de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            new GenericSource(notify, mUIDValid, mUID);
2753de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
276a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    status_t err = source->setDataSource(fd, offset, length);
2773de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2783de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    if (err != OK) {
279a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        ALOGE("Failed to set data source!");
2803de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        source = NULL;
2813de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    }
2823de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
283afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    msg->setObject("source", source);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2879575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::prepareAsync() {
2889575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    (new AMessage(kWhatPrepare, id()))->post();
2899575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
2909575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
29157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Hubervoid NuPlayer::setVideoSurfaceTextureAsync(
2928ba01021b573889802e67e029225a96f0dfa471aAndy McFadden        const sp<IGraphicBufferProducer> &bufferProducer) {
2931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
29457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
2958ba01021b573889802e67e029225a96f0dfa471aAndy McFadden    if (bufferProducer == NULL) {
29657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        msg->setObject("native-window", NULL);
29757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    } else {
29857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        msg->setObject(
29957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                "native-window",
30057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                new NativeWindowWrapper(
3019c03a40367c149526c31ddf14a518ba2036195a5Wei Jia                    new Surface(bufferProducer, true /* controlledByApp */)));
30257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
30357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setObject("sink", sink);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::start() {
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatStart, id()))->post();
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31743c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::pause() {
318b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    (new AMessage(kWhatPause, id()))->post();
31943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
32043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
3211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::resetAsync() {
32248296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    if (mSource != NULL) {
32348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // During a reset, the data source might be unresponsive already, we need to
32448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // disconnect explicitly so that reads exit promptly.
32548296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // We can't queue the disconnect request to the looper, as it might be
32648296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // queued behind a stuck read and never gets processed.
32748296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // Doing a disconnect outside the looper to allows the pending reads to exit
32848296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // (either successfully or with error).
32948296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        mSource->disconnect();
33048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    }
33148296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang
3321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    (new AMessage(kWhatReset, id()))->post();
3331aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
3341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
335e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jiavoid NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
33643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, id());
33743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->setInt64("seekTimeUs", seekTimeUs);
338e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia    msg->setInt32("needNotify", needNotify);
33943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    msg->post();
34043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
34143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
34253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
343404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangvoid NuPlayer::writeTrackInfo(
344404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        Parcel* reply, const sp<AMessage> format) const {
345404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    int32_t trackType;
346404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    CHECK(format->findInt32("type", &trackType));
347404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
348404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    AString lang;
349404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    CHECK(format->findString("language", &lang));
350404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
351404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    reply->writeInt32(2); // write something non-zero
352404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    reply->writeInt32(trackType);
353404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    reply->writeString16(String16(lang.c_str()));
354404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
355404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
356404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        AString mime;
357404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        CHECK(format->findString("mime", &mime));
358404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
359404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        int32_t isAuto, isDefault, isForced;
360404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        CHECK(format->findInt32("auto", &isAuto));
361404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        CHECK(format->findInt32("default", &isDefault));
362404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        CHECK(format->findInt32("forced", &isForced));
363404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
364404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        reply->writeString16(String16(mime.c_str()));
365404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        reply->writeInt32(isAuto);
366404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        reply->writeInt32(isDefault);
367404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        reply->writeInt32(isForced);
368404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    }
369404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang}
370404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
371f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetDataSource:
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetDataSource");
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(mSource == NULL);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3793de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            status_t err = OK;
3805bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            sp<RefBase> obj;
3815bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(msg->findObject("source", &obj));
3823de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            if (obj != NULL) {
3833de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                mSource = static_cast<Source *>(obj.get());
3843de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            } else {
3853de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                err = UNKNOWN_ERROR;
3863de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            }
3879575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
3889575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(mDriver != NULL);
3899575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            sp<NuPlayerDriver> driver = mDriver.promote();
3909575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if (driver != NULL) {
3913de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                driver->notifySetDataSourceCompleted(err);
3929575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
3939575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
3949575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
3959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
3969575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case kWhatPrepare:
3979575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
3989575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            mSource->prepareAsync();
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402dcb89b3b505522efde173c105a851c412f947178Chong Zhang        case kWhatGetTrackInfo:
403dcb89b3b505522efde173c105a851c412f947178Chong Zhang        {
404dcb89b3b505522efde173c105a851c412f947178Chong Zhang            uint32_t replyID;
405dcb89b3b505522efde173c105a851c412f947178Chong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
406dcb89b3b505522efde173c105a851c412f947178Chong Zhang
407404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            Parcel* reply;
408404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            CHECK(msg->findPointer("reply", (void**)&reply));
409404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
410404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            size_t inbandTracks = 0;
411dcb89b3b505522efde173c105a851c412f947178Chong Zhang            if (mSource != NULL) {
412404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang                inbandTracks = mSource->getTrackCount();
413dcb89b3b505522efde173c105a851c412f947178Chong Zhang            }
414dcb89b3b505522efde173c105a851c412f947178Chong Zhang
415a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            size_t ccTracks = 0;
416a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            if (mCCDecoder != NULL) {
417a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                ccTracks = mCCDecoder->getTrackCount();
418a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            }
419a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
420404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            // total track count
421a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            reply->writeInt32(inbandTracks + ccTracks);
422404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
423404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            // write inband tracks
424404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            for (size_t i = 0; i < inbandTracks; ++i) {
425404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang                writeTrackInfo(reply, mSource->getTrackInfo(i));
426404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            }
427dcb89b3b505522efde173c105a851c412f947178Chong Zhang
428a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            // write CC track
429a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            for (size_t i = 0; i < ccTracks; ++i) {
430a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
431a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            }
432a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
433404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            sp<AMessage> response = new AMessage;
434dcb89b3b505522efde173c105a851c412f947178Chong Zhang            response->postReply(replyID);
435dcb89b3b505522efde173c105a851c412f947178Chong Zhang            break;
436dcb89b3b505522efde173c105a851c412f947178Chong Zhang        }
437dcb89b3b505522efde173c105a851c412f947178Chong Zhang
4387c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih        case kWhatGetSelectedTrack:
4397c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih        {
4407c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            status_t err = INVALID_OPERATION;
4417c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            if (mSource != NULL) {
4427c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                err = OK;
4437c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih
4447c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                int32_t type32;
4457c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                CHECK(msg->findInt32("type", (int32_t*)&type32));
4467c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                media_track_type type = (media_track_type)type32;
4477c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                ssize_t selectedTrack = mSource->getSelectedTrack(type);
4487c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih
4497c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                Parcel* reply;
4507c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                CHECK(msg->findPointer("reply", (void**)&reply));
4517c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih                reply->writeInt32(selectedTrack);
4527c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            }
4537c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih
4547c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            sp<AMessage> response = new AMessage;
4557c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            response->setInt32("err", err);
4567c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih
4577c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            uint32_t replyID;
4587c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            CHECK(msg->senderAwaitsResponse(&replyID));
4597c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            response->postReply(replyID);
4607c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih            break;
4617c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih        }
4627c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih
463dcb89b3b505522efde173c105a851c412f947178Chong Zhang        case kWhatSelectTrack:
464dcb89b3b505522efde173c105a851c412f947178Chong Zhang        {
465dcb89b3b505522efde173c105a851c412f947178Chong Zhang            uint32_t replyID;
466dcb89b3b505522efde173c105a851c412f947178Chong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
467dcb89b3b505522efde173c105a851c412f947178Chong Zhang
468404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            size_t trackIndex;
469404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            int32_t select;
4706ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            int64_t timeUs;
471404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            CHECK(msg->findSize("trackIndex", &trackIndex));
472404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            CHECK(msg->findInt32("select", &select));
4736ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            CHECK(msg->findInt64("timeUs", &timeUs));
474404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
475dcb89b3b505522efde173c105a851c412f947178Chong Zhang            status_t err = INVALID_OPERATION;
476404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
477404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            size_t inbandTracks = 0;
478dcb89b3b505522efde173c105a851c412f947178Chong Zhang            if (mSource != NULL) {
479404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang                inbandTracks = mSource->getTrackCount();
480404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            }
481a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            size_t ccTracks = 0;
482a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            if (mCCDecoder != NULL) {
483a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                ccTracks = mCCDecoder->getTrackCount();
484a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            }
485404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
486404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            if (trackIndex < inbandTracks) {
4876ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih                err = mSource->selectTrack(trackIndex, select, timeUs);
488d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
489d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                if (!select && err == OK) {
490d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                    int32_t type;
491d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                    sp<AMessage> info = mSource->getTrackInfo(trackIndex);
492d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                    if (info != NULL
493d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                            && info->findInt32("type", &type)
494d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                            && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
495d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                        ++mTimedTextGeneration;
496d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                    }
497d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                }
498a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            } else {
499a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                trackIndex -= inbandTracks;
500a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
501a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                if (trackIndex < ccTracks) {
502a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                    err = mCCDecoder->selectTrack(trackIndex, select);
503a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                }
504dcb89b3b505522efde173c105a851c412f947178Chong Zhang            }
505dcb89b3b505522efde173c105a851c412f947178Chong Zhang
506dcb89b3b505522efde173c105a851c412f947178Chong Zhang            sp<AMessage> response = new AMessage;
507dcb89b3b505522efde173c105a851c412f947178Chong Zhang            response->setInt32("err", err);
508dcb89b3b505522efde173c105a851c412f947178Chong Zhang
509dcb89b3b505522efde173c105a851c412f947178Chong Zhang            response->postReply(replyID);
510dcb89b3b505522efde173c105a851c412f947178Chong Zhang            break;
511dcb89b3b505522efde173c105a851c412f947178Chong Zhang        }
512dcb89b3b505522efde173c105a851c412f947178Chong Zhang
513b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        case kWhatPollDuration:
514b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        {
515b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            int32_t generation;
516b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            CHECK(msg->findInt32("generation", &generation));
517b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
518b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (generation != mPollDurationGeneration) {
519b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                // stale
520b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                break;
521b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
522b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
523b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            int64_t durationUs;
524b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
525b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                sp<NuPlayerDriver> driver = mDriver.promote();
526b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                if (driver != NULL) {
527b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    driver->notifyDuration(durationUs);
528b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                }
529b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
530b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
531b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            msg->post(1000000ll);  // poll again in a second.
532b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            break;
533b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        }
534b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
5351173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        case kWhatSetVideoNativeWindow:
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetVideoNativeWindow");
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
5401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            CHECK(msg->findObject("native-window", &obj));
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
542f484952edd94c1b7ee82d7b108edc1ce08671cc4Lajos Molnar            if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) {
543fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                performSetSurface(static_cast<NativeWindowWrapper *>(obj.get()));
544fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                break;
545fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia            }
546fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia
547fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia            mDeferredActions.push_back(
548fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
549fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                                           FLUSH_CMD_SHUTDOWN /* video */));
550fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia
55157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            mDeferredActions.push_back(
55257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                    new SetSurfaceAction(
55357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                        static_cast<NativeWindowWrapper *>(obj.get())));
55457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
55557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            if (obj != NULL) {
556fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                if (mStarted) {
5577353585789513466d5887986620e8734a325b3ebAndy Hung                    // Issue a seek to refresh the video screen only if started otherwise
5587353585789513466d5887986620e8734a325b3ebAndy Hung                    // the extractor may not yet be started and will assert.
5597353585789513466d5887986620e8734a325b3ebAndy Hung                    // If the video decoder is not set (perhaps audio only in this case)
5607353585789513466d5887986620e8734a325b3ebAndy Hung                    // do not perform a seek as it is not needed.
561a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    int64_t currentPositionUs = 0;
562a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    if (getCurrentPosition(&currentPositionUs) == OK) {
563a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        mDeferredActions.push_back(
564a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                                new SeekAction(currentPositionUs, false /* needNotify */));
565a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    }
5667353585789513466d5887986620e8734a325b3ebAndy Hung                }
567ac428aa54d2489705091dd38372bbaade281a92eWei Jia
56857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                // If there is a new surface texture, instantiate decoders
56957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                // again if possible.
57057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                mDeferredActions.push_back(
57157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber                        new SimpleAction(&NuPlayer::performScanSources));
57257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            }
5730d268a3cae145afb2720c88ae38fb81550be5584James Dong
574f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            // After a flush without shutdown, decoder is paused.
575f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            // Don't resume it until source seek is done, otherwise it could
5767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // start pulling stale data too soon.
5777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mDeferredActions.push_back(
578f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang                    new ResumeDecoderAction(false /* needNotify */));
5797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
58057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber            processDeferredActions();
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatSetAudioSink:
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatSetAudioSink");
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<RefBase> obj;
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findObject("sink", &obj));
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatStart:
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatStart");
5989421174a2f002fef31b330fb04e00105a905dca4Wei Jia            if (mStarted) {
5999421174a2f002fef31b330fb04e00105a905dca4Wei Jia                onResume();
6009421174a2f002fef31b330fb04e00105a905dca4Wei Jia            } else {
6019421174a2f002fef31b330fb04e00105a905dca4Wei Jia                onStart();
602c851b5de495169d7e9528644c2592746021bd968Lajos Molnar            }
603efbb61950db36a5eb789be83f077246172507c67Chong Zhang            mPausedByClient = false;
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatScanSources:
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            int32_t generation;
6101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            CHECK(msg->findInt32("generation", &generation));
6111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (generation != mScanSourcesGeneration) {
6121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                // Drop obsolete msg.
6131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                break;
6141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
6151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
6165bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            mScanSourcesPending = false;
6175bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
6183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
61943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 mAudioDecoder != NULL, mVideoDecoder != NULL);
62043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
621b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            bool mHadAnySourcesBefore =
622b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
623b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
624282a7e31681840253a4cb6fab3f6725d35798699Andy Hung            // initialize video before audio because successful initialization of
625282a7e31681840253a4cb6fab3f6725d35798699Andy Hung            // video may change deep buffer mode of audio.
6265d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            if (mNativeWindow != NULL) {
6275d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George                instantiateDecoder(false, &mVideoDecoder);
6285d246efa220a7c7b22e490576c488b3853c664ddHaynes Mathew George            }
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu            // Don't try to re-open audio sink if there's an existing decoder.
631a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu            if (mAudioSink != NULL && mAudioDecoder == NULL) {
632a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
633a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
634a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
635202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                const bool hasVideo = (videoFormat != NULL);
636202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                const bool canOffload = canOffloadStream(
637202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                        audioMeta, hasVideo, true /* is_streaming */, streamType);
638a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                if (canOffload) {
639a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                    if (!mOffloadAudio) {
640a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                        mRenderer->signalEnableOffloadAudio();
641a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                    }
642282a7e31681840253a4cb6fab3f6725d35798699Andy Hung                    // open audio sink early under offload mode.
643282a7e31681840253a4cb6fab3f6725d35798699Andy Hung                    sp<AMessage> format = mSource->getFormat(true /*audio*/);
644202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                    tryOpenAudioSinkForOffload(format, hasVideo);
645282a7e31681840253a4cb6fab3f6725d35798699Andy Hung                }
6465bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                instantiateDecoder(true, &mAudioDecoder);
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            if (!mHadAnySourcesBefore
650b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
651b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                // This is the first time we've found anything playable.
652b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
6539575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
654b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                    schedulePollDuration();
655b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                }
656b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            }
657b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
658eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            status_t err;
659eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber            if ((err = mSource->feedMoreTSData()) != OK) {
6601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
6611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // We're not currently decoding anything (no audio or
6621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    // video tracks found) and we just ran out of input data.
663eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber
664eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    if (err == ERROR_END_OF_STREAM) {
665eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
666eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    } else {
667eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
668eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber                    }
6691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                }
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
673fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            if ((mAudioDecoder == NULL && mAudioSink != NULL)
674fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->post(100000ll);
6765bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                mScanSourcesPending = true;
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatVideoNotify:
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatAudioNotify:
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            bool audio = msg->what() == kWhatAudioNotify;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68688703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia            int32_t currentDecoderGeneration =
68788703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
68888703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia            int32_t requesterGeneration = currentDecoderGeneration - 1;
68988703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia            CHECK(msg->findInt32("generation", &requesterGeneration));
69088703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia
69188703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia            if (requesterGeneration != currentDecoderGeneration) {
69288703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                ALOGV("got message from old %s decoder, generation(%d:%d)",
69388703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                        audio ? "audio" : "video", requesterGeneration,
69488703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                        currentDecoderGeneration);
69588703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                sp<AMessage> reply;
69688703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                if (!(msg->findMessage("reply", &reply))) {
69788703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                    return;
69888703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                }
69988703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia
70088703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                reply->setInt32("err", INFO_DISCONTINUITY);
70188703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                reply->post();
70288703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia                return;
70388703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia            }
70488703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
7061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            CHECK(msg->findInt32("what", &what));
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            if (what == DecoderBase::kWhatInputDiscontinuity) {
7097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                int32_t formatChange;
7107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                CHECK(msg->findInt32("formatChange", &formatChange));
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                ALOGV("%s discontinuity: formatChange %d",
7137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        audio ? "audio" : "video", formatChange);
7147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                if (formatChange) {
7167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mDeferredActions.push_back(
7177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            new FlushDecoderAction(
7187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
7217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                mDeferredActions.push_back(
7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        new SimpleAction(
7247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                                &NuPlayer::performScanSources));
7257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                processDeferredActions();
7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            } else if (what == DecoderBase::kWhatEOS) {
728dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                int32_t err;
7291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                CHECK(msg->findInt32("err", &err));
730dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
731dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err == ERROR_END_OF_STREAM) {
7323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
733dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
7343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("got %s decoder EOS w/ error %d",
735dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         audio ? "audio" : "video",
736dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         err);
737dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
738dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
739dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mRenderer->queueEOS(audio, err);
7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            } else if (what == DecoderBase::kWhatFlushCompleted) {
7413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7438d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung                handleFlushComplete(audio, true /* isDecoder */);
7443831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            } else if (what == DecoderBase::kWhatVideoSizeChanged) {
7461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                sp<AMessage> format;
7471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                CHECK(msg->findMessage("format", &format));
7481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar
749c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                sp<AMessage> inputFormat =
750c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                        mSource->getFormat(false /* audio */);
75131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
752c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia                updateVideoSize(inputFormat, format);
7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            } else if (what == DecoderBase::kWhatShutdownCompleted) {
7543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("%s shutdown completed", audio ? "audio" : "video");
7553831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                if (audio) {
7563831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mAudioDecoder.clear();
75757568df014f8629ebc5ca8bce9da796dd187401bWei Jia                    ++mAudioDecoderGeneration;
7583831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7593831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
7603831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingAudio = SHUT_DOWN;
7613831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                } else {
7623831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mVideoDecoder.clear();
76357568df014f8629ebc5ca8bce9da796dd187401bWei Jia                    ++mVideoDecoderGeneration;
7643831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7653831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
7663831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                    mFlushingVideo = SHUT_DOWN;
7673831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                }
7683831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
7693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber                finishFlushIfPossible();
770f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            } else if (what == DecoderBase::kWhatResumeCompleted) {
771f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang                finishResume();
7727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            } else if (what == DecoderBase::kWhatError) {
773f4c0a94ab32541611f5ed6d407fc25b394c1988bChong Zhang                status_t err;
7742abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                if (!msg->findInt32("err", &err) || err == OK) {
775f4c0a94ab32541611f5ed6d407fc25b394c1988bChong Zhang                    err = UNKNOWN_ERROR;
776f4c0a94ab32541611f5ed6d407fc25b394c1988bChong Zhang                }
777cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung
7782abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // Decoder errors can be due to Source (e.g. from streaming),
7792abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // or from decoding corrupted bitstreams, or from other decoder
7802abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // MediaCodec operations (e.g. from an ongoing reset or seek).
781202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                // They may also be due to openAudioSink failure at
782202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                // decoder start or after a format change.
7832abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                //
7842abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // We try to gracefully shut down the affected decoder if possible,
7852abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // rather than trying to force the shutdown with something
7862abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // similar to performReset(). This method can lead to a hang
7872abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // if MediaCodec functions block after an error, but they should
7882abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                // typically return INVALID_OPERATION instead of blocking.
7892abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung
7902abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
7912abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
7922abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        err, audio ? "audio" : "video", *flushing);
7932abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung
7942abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                switch (*flushing) {
7952abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                    case NONE:
7962abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        mDeferredActions.push_back(
797fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                                new FlushDecoderAction(
798fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                                    audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
799fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                                    audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
8002abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        processDeferredActions();
8012abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        break;
8022abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                    case FLUSHING_DECODER:
8032abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
8042abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        break; // Wait for flush to complete.
8052abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                    case FLUSHING_DECODER_SHUTDOWN:
8062abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        break; // Wait for flush to complete.
8072abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                    case SHUTTING_DOWN_DECODER:
8082abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        break; // Wait for shutdown to complete.
8092abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                    case FLUSHED:
8102abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        // Widevine source reads must stop before releasing the video decoder.
8112abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        if (!audio && mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
8122abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                            mSource->stop();
8132abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        }
8142abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
8152abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        *flushing = SHUTTING_DOWN_DECODER;     // Shut down.
8162abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        break;
8172abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                    case SHUT_DOWN:
8182abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        finishFlushIfPossible();  // Should not occur.
8192abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                        break;                    // Finish anyways.
8209e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                }
8212abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung                notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
8221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar            } else {
8231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar                ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
824a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what,
825a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what >> 24,
826a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      (what >> 16) & 0xff,
827a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      (what >> 8) & 0xff,
828a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                      what & 0xff);
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatRendererNotify:
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
83657568df014f8629ebc5ca8bce9da796dd187401bWei Jia            int32_t requesterGeneration = mRendererGeneration - 1;
83757568df014f8629ebc5ca8bce9da796dd187401bWei Jia            CHECK(msg->findInt32("generation", &requesterGeneration));
83857568df014f8629ebc5ca8bce9da796dd187401bWei Jia            if (requesterGeneration != mRendererGeneration) {
83957568df014f8629ebc5ca8bce9da796dd187401bWei Jia                ALOGV("got message from old renderer, generation(%d:%d)",
84057568df014f8629ebc5ca8bce9da796dd187401bWei Jia                        requesterGeneration, mRendererGeneration);
84157568df014f8629ebc5ca8bce9da796dd187401bWei Jia                return;
84257568df014f8629ebc5ca8bce9da796dd187401bWei Jia            }
84357568df014f8629ebc5ca8bce9da796dd187401bWei Jia
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t what;
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("what", &what));
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (what == Renderer::kWhatEOS) {
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                int32_t finalResult;
852c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                CHECK(msg->findInt32("finalResult", &finalResult));
853c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (audio) {
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEOS = true;
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mVideoEOS = true;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
860c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (finalResult == ERROR_END_OF_STREAM) {
8613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("reached %s EOS", audio ? "audio" : "video");
862c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                } else {
86329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("%s track encountered an error (%d)",
864c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         audio ? "audio" : "video", finalResult);
865c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
866c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    notifyListener(
867c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
868c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if ((mAudioEOS || mAudioDecoder == NULL)
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        && (mVideoEOS || mVideoDecoder == NULL)) {
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
8743fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            } else if (what == Renderer::kWhatFlushComplete) {
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t audio;
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("audio", &audio));
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
8798d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung                handleFlushComplete(audio, false /* isDecoder */);
8808d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung                finishFlushIfPossible();
881f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong            } else if (what == Renderer::kWhatVideoRenderingStart) {
882f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
883cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar            } else if (what == Renderer::kWhatMediaRenderingStart) {
884cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar                ALOGV("media rendering started");
885cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar                notifyListener(MEDIA_STARTED, 0, 0);
8863a2956d148d81194e297408179e84a47a309ef48Wei Jia            } else if (what == Renderer::kWhatAudioOffloadTearDown) {
887a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                ALOGV("Tear down audio offload, fall back to s/w path if due to error.");
8883a2956d148d81194e297408179e84a47a309ef48Wei Jia                int64_t positionUs;
8893a2956d148d81194e297408179e84a47a309ef48Wei Jia                CHECK(msg->findInt64("positionUs", &positionUs));
8900852917279f79a94907e9906d0533ae409a30f6aRonghua Wu                int32_t reason;
8910852917279f79a94907e9906d0533ae409a30f6aRonghua Wu                CHECK(msg->findInt32("reason", &reason));
892282a7e31681840253a4cb6fab3f6725d35798699Andy Hung                closeAudioSink();
8933a2956d148d81194e297408179e84a47a309ef48Wei Jia                mAudioDecoder.clear();
89457568df014f8629ebc5ca8bce9da796dd187401bWei Jia                ++mAudioDecoderGeneration;
8957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                mRenderer->flush(
8967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                        true /* audio */, false /* notifyComplete */);
8973a2956d148d81194e297408179e84a47a309ef48Wei Jia                if (mVideoDecoder != NULL) {
8987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                    mRenderer->flush(
8997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                            false /* audio */, false /* notifyComplete */);
9003a2956d148d81194e297408179e84a47a309ef48Wei Jia                }
9013a2956d148d81194e297408179e84a47a309ef48Wei Jia
902e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia                performSeek(positionUs, false /* needNotify */);
9030852917279f79a94907e9906d0533ae409a30f6aRonghua Wu                if (reason == Renderer::kDueToError) {
904a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                    mRenderer->signalDisableOffloadAudio();
905a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu                    mOffloadAudio = false;
9060852917279f79a94907e9906d0533ae409a30f6aRonghua Wu                    instantiateDecoder(true /* audio */, &mAudioDecoder);
9070852917279f79a94907e9906d0533ae409a30f6aRonghua Wu                }
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatMoreDataQueued:
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        case kWhatReset:
9181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        {
9193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("kWhatReset");
9201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
921a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
922fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                    new FlushDecoderAction(
923fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        FLUSH_CMD_SHUTDOWN /* audio */,
924fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        FLUSH_CMD_SHUTDOWN /* video */));
925b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber
926a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
927a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                    new SimpleAction(&NuPlayer::performReset));
9281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
929a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            processDeferredActions();
9301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            break;
9311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
9321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
93343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        case kWhatSeek:
93443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        {
93543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            int64_t seekTimeUs;
936e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia            int32_t needNotify;
93743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
938e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia            CHECK(msg->findInt32("needNotify", &needNotify));
93943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
940e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia            ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d",
941e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia                    seekTimeUs, needNotify);
94243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
943a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            mDeferredActions.push_back(
944fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
945fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                                           FLUSH_CMD_FLUSH /* video */));
94643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
947e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia            mDeferredActions.push_back(
948e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia                    new SeekAction(seekTimeUs, needNotify));
94943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
950f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            // After a flush without shutdown, decoder is paused.
951f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            // Don't resume it until source seek is done, otherwise it could
9527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            // start pulling stale data too soon.
9537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mDeferredActions.push_back(
954f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang                    new ResumeDecoderAction(needNotify));
9557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
956a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            processDeferredActions();
95743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            break;
95843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
95943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
960b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        case kWhatPause:
961b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        {
962efbb61950db36a5eb789be83f077246172507c67Chong Zhang            onPause();
963efbb61950db36a5eb789be83f077246172507c67Chong Zhang            mPausedByClient = true;
964b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            break;
965b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
966b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
967b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        case kWhatSourceNotify:
968b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        {
9699575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            onSourceNotify(msg);
970b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber            break;
971b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        }
972b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
973a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        case kWhatClosedCaptionNotify:
974a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        {
975a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            onClosedCaptionNotify(msg);
976a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            break;
977a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        }
978a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9859421174a2f002fef31b330fb04e00105a905dca4Wei Jiavoid NuPlayer::onResume() {
986efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (!mPaused) {
987efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return;
988efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
989efbb61950db36a5eb789be83f077246172507c67Chong Zhang    mPaused = false;
9909421174a2f002fef31b330fb04e00105a905dca4Wei Jia    if (mSource != NULL) {
9919421174a2f002fef31b330fb04e00105a905dca4Wei Jia        mSource->resume();
9929421174a2f002fef31b330fb04e00105a905dca4Wei Jia    } else {
9939421174a2f002fef31b330fb04e00105a905dca4Wei Jia        ALOGW("resume called when source is gone or not set");
9949421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
9959421174a2f002fef31b330fb04e00105a905dca4Wei Jia    // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
9969421174a2f002fef31b330fb04e00105a905dca4Wei Jia    // needed.
9979421174a2f002fef31b330fb04e00105a905dca4Wei Jia    if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
9989421174a2f002fef31b330fb04e00105a905dca4Wei Jia        instantiateDecoder(true /* audio */, &mAudioDecoder);
9999421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
10009421174a2f002fef31b330fb04e00105a905dca4Wei Jia    if (mRenderer != NULL) {
10019421174a2f002fef31b330fb04e00105a905dca4Wei Jia        mRenderer->resume();
10029421174a2f002fef31b330fb04e00105a905dca4Wei Jia    } else {
10039421174a2f002fef31b330fb04e00105a905dca4Wei Jia        ALOGW("resume called when renderer is gone or not set");
10049421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
10059421174a2f002fef31b330fb04e00105a905dca4Wei Jia}
10069421174a2f002fef31b330fb04e00105a905dca4Wei Jia
100722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnarstatus_t NuPlayer::onInstantiateSecureDecoders() {
100822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    status_t err;
100922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    if (!(mSourceFlags & Source::FLAG_SECURE)) {
101022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        return BAD_TYPE;
101122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    }
10129421174a2f002fef31b330fb04e00105a905dca4Wei Jia
101322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    if (mRenderer != NULL) {
101422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        ALOGE("renderer should not be set when instantiating secure decoders");
101522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        return UNKNOWN_ERROR;
101622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    }
101722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
101822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
101922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    // data on instantiation.
102022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    if (mNativeWindow != NULL) {
102122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        err = instantiateDecoder(false, &mVideoDecoder);
102222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        if (err != OK) {
102322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            return err;
10249421174a2f002fef31b330fb04e00105a905dca4Wei Jia        }
102522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    }
10269421174a2f002fef31b330fb04e00105a905dca4Wei Jia
102722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    if (mAudioSink != NULL) {
102822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        err = instantiateDecoder(true, &mAudioDecoder);
102922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        if (err != OK) {
103022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            return err;
10319421174a2f002fef31b330fb04e00105a905dca4Wei Jia        }
10329421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
103322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    return OK;
103422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar}
103522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
103622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnarvoid NuPlayer::onStart() {
103722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    mOffloadAudio = false;
103822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    mAudioEOS = false;
103922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    mVideoEOS = false;
104022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    mStarted = true;
10419421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10429421174a2f002fef31b330fb04e00105a905dca4Wei Jia    mSource->start();
10439421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10449421174a2f002fef31b330fb04e00105a905dca4Wei Jia    uint32_t flags = 0;
10459421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10469421174a2f002fef31b330fb04e00105a905dca4Wei Jia    if (mSource->isRealTime()) {
10479421174a2f002fef31b330fb04e00105a905dca4Wei Jia        flags |= Renderer::FLAG_REAL_TIME;
10489421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
10499421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10509421174a2f002fef31b330fb04e00105a905dca4Wei Jia    sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
10519421174a2f002fef31b330fb04e00105a905dca4Wei Jia    audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
10529421174a2f002fef31b330fb04e00105a905dca4Wei Jia    if (mAudioSink != NULL) {
10539421174a2f002fef31b330fb04e00105a905dca4Wei Jia        streamType = mAudioSink->getAudioStreamType();
10549421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
10559421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10569421174a2f002fef31b330fb04e00105a905dca4Wei Jia    sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
10579421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10589421174a2f002fef31b330fb04e00105a905dca4Wei Jia    mOffloadAudio =
10599421174a2f002fef31b330fb04e00105a905dca4Wei Jia        canOffloadStream(audioMeta, (videoFormat != NULL),
10609421174a2f002fef31b330fb04e00105a905dca4Wei Jia                         true /* is_streaming */, streamType);
10619421174a2f002fef31b330fb04e00105a905dca4Wei Jia    if (mOffloadAudio) {
10629421174a2f002fef31b330fb04e00105a905dca4Wei Jia        flags |= Renderer::FLAG_OFFLOAD_AUDIO;
10639421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
10649421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10659421174a2f002fef31b330fb04e00105a905dca4Wei Jia    sp<AMessage> notify = new AMessage(kWhatRendererNotify, id());
10669421174a2f002fef31b330fb04e00105a905dca4Wei Jia    ++mRendererGeneration;
10679421174a2f002fef31b330fb04e00105a905dca4Wei Jia    notify->setInt32("generation", mRendererGeneration);
10689421174a2f002fef31b330fb04e00105a905dca4Wei Jia    mRenderer = new Renderer(mAudioSink, notify, flags);
10699421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10709421174a2f002fef31b330fb04e00105a905dca4Wei Jia    mRendererLooper = new ALooper;
10719421174a2f002fef31b330fb04e00105a905dca4Wei Jia    mRendererLooper->setName("NuPlayerRenderer");
10729421174a2f002fef31b330fb04e00105a905dca4Wei Jia    mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
10739421174a2f002fef31b330fb04e00105a905dca4Wei Jia    mRendererLooper->registerHandler(mRenderer);
10749421174a2f002fef31b330fb04e00105a905dca4Wei Jia
10759421174a2f002fef31b330fb04e00105a905dca4Wei Jia    sp<MetaData> meta = getFileMeta();
10769421174a2f002fef31b330fb04e00105a905dca4Wei Jia    int32_t rate;
10779421174a2f002fef31b330fb04e00105a905dca4Wei Jia    if (meta != NULL
10789421174a2f002fef31b330fb04e00105a905dca4Wei Jia            && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
10799421174a2f002fef31b330fb04e00105a905dca4Wei Jia        mRenderer->setVideoFrameRate(rate);
10809421174a2f002fef31b330fb04e00105a905dca4Wei Jia    }
10819421174a2f002fef31b330fb04e00105a905dca4Wei Jia
1082c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    if (mVideoDecoder != NULL) {
1083c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        mVideoDecoder->setRenderer(mRenderer);
1084c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
1085c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    if (mAudioDecoder != NULL) {
1086c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia        mAudioDecoder->setRenderer(mRenderer);
1087c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia    }
1088c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia
10899421174a2f002fef31b330fb04e00105a905dca4Wei Jia    postScanSources();
10909421174a2f002fef31b330fb04e00105a905dca4Wei Jia}
10919421174a2f002fef31b330fb04e00105a905dca4Wei Jia
1092efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::onPause() {
1093efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mPaused) {
1094efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return;
1095efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
1096efbb61950db36a5eb789be83f077246172507c67Chong Zhang    mPaused = true;
1097efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mSource != NULL) {
1098efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mSource->pause();
1099efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else {
1100efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGW("pause called when source is gone or not set");
1101efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
1102efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mRenderer != NULL) {
1103efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mRenderer->pause();
1104efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else {
1105efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGW("pause called when renderer is gone or not set");
1106efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
1107efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
1108efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1109d7988b1a7b32e39e671f7d4e2b2d8027a1f99639Ronghua Wubool NuPlayer::audioDecoderStillNeeded() {
1110d7988b1a7b32e39e671f7d4e2b2d8027a1f99639Ronghua Wu    // Audio decoder is no longer needed if it's in shut/shutting down status.
1111d7988b1a7b32e39e671f7d4e2b2d8027a1f99639Ronghua Wu    return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1112d7988b1a7b32e39e671f7d4e2b2d8027a1f99639Ronghua Wu}
1113d7988b1a7b32e39e671f7d4e2b2d8027a1f99639Ronghua Wu
11148d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hungvoid NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
11158d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    // We wait for both the decoder flush and the renderer flush to complete
11168d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
11178d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung
11188d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    mFlushComplete[audio][isDecoder] = true;
11198d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    if (!mFlushComplete[audio][!isDecoder]) {
11208d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        return;
11218d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    }
11228d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung
11238d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
11248d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    switch (*state) {
11258d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        case FLUSHING_DECODER:
11268d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        {
11278d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            *state = FLUSHED;
11288d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            break;
11298d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        }
11308d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung
11318d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        case FLUSHING_DECODER_SHUTDOWN:
11328d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        {
11338d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            *state = SHUTTING_DOWN_DECODER;
11348d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung
11358d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
11368d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            if (!audio) {
11378d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung                // Widevine source reads must stop before releasing the video decoder.
11388d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung                if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
11398d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung                    mSource->stop();
11408d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung                }
11418d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            }
11428d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            getDecoder(audio)->initiateShutdown();
11438d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            break;
11448d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        }
11458d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung
11468d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung        default:
11478d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            // decoder flush completes only occur in a flushing state.
11488d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
11498d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung            break;
11508d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    }
11518d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung}
11528d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung
11533831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::finishFlushIfPossible() {
115453904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia    if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
115553904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia            && mFlushingAudio != SHUT_DOWN) {
11563831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
11573831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
11583831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
115953904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia    if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
116053904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia            && mFlushingVideo != SHUT_DOWN) {
11613831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return;
11623831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
11633831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
11643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("both audio and video are flushed now.");
11653831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
11663831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingAudio = NONE;
11673831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    mFlushingVideo = NONE;
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11698d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    clearFlushComplete();
11708d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung
1171a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    processDeferredActions();
11721aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
11731aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
11741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::postScanSources() {
11751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (mScanSourcesPending) {
11761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return;
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
11791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
11801aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->setInt32("generation", mScanSourcesGeneration);
11811aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    msg->post();
11821aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
11831aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mScanSourcesPending = true;
1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1186202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungvoid NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) {
1187202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // Note: This is called early in NuPlayer to determine whether offloading
1188202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // is possible; otherwise the decoders call the renderer openAudioSink directly.
1189282a7e31681840253a4cb6fab3f6725d35798699Andy Hung
1190202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    status_t err = mRenderer->openAudioSink(
1191202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio);
1192202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    if (err != OK) {
1193202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung        // Any failure we turn off mOffloadAudio.
1194202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung        mOffloadAudio = false;
1195202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    } else if (mOffloadAudio) {
11963b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        sp<MetaData> audioMeta =
11973b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                mSource->getFormatMeta(true /* audio */);
11983b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        sendMetaDataToHal(mAudioSink, audioMeta);
1199282a7e31681840253a4cb6fab3f6725d35798699Andy Hung    }
1200282a7e31681840253a4cb6fab3f6725d35798699Andy Hung}
1201282a7e31681840253a4cb6fab3f6725d35798699Andy Hung
1202282a7e31681840253a4cb6fab3f6725d35798699Andy Hungvoid NuPlayer::closeAudioSink() {
12033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang    mRenderer->closeAudioSink();
1204282a7e31681840253a4cb6fab3f6725d35798699Andy Hung}
1205282a7e31681840253a4cb6fab3f6725d35798699Andy Hung
12067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (*decoder != NULL) {
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1211840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<AMessage> format = mSource->getFormat(audio);
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1213840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if (format == NULL) {
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
1215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12173fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    if (!audio) {
1218840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        AString mime;
1219840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        CHECK(format->findString("mime", &mime));
1220a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1221a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
1222341ab6eebb6a992ec7bdf095420cf82bcab1c6b3Chong Zhang        if (mCCDecoder == NULL) {
1223341ab6eebb6a992ec7bdf095420cf82bcab1c6b3Chong Zhang            mCCDecoder = new CCDecoder(ccNotify);
1224341ab6eebb6a992ec7bdf095420cf82bcab1c6b3Chong Zhang        }
1225095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
1226095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (mSourceFlags & Source::FLAG_SECURE) {
1227095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            format->setInt32("secure", true);
1228095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
12291713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
12301713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (mSourceFlags & Source::FLAG_PROTECTED) {
12311713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            format->setInt32("protected", true);
12321713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
12333fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber    }
12343fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber
1235bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    if (audio) {
123688703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia        sp<AMessage> notify = new AMessage(kWhatAudioNotify, id());
123788703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia        ++mAudioDecoderGeneration;
123888703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia        notify->setInt32("generation", mAudioDecoderGeneration);
123988703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia
1240bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        if (mOffloadAudio) {
1241c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
1242bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        } else {
1243c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            *decoder = new Decoder(notify, mSource, mRenderer);
1244bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        }
1245bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    } else {
124688703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia        sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());
124788703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia        ++mVideoDecoderGeneration;
124888703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia        notify->setInt32("generation", mVideoDecoderGeneration);
124988703c34fb4a9db1ff51495879f9775474c8ce89Wei Jia
12507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        *decoder = new Decoder(
12517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang                notify, mSource, mRenderer, mNativeWindow, mCCDecoder);
1252d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar
1253d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar        // enable FRC if high-quality AV sync is requested, even if not
1254d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar        // queuing to native window, as this will even improve textureview
1255d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar        // playback.
1256d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar        {
1257d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar            char value[PROPERTY_VALUE_MAX];
1258d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar            if (property_get("persist.sys.media.avsync", value, NULL) &&
1259d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar                    (!strcmp("1", value) || !strcasecmp("true", value))) {
1260d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar                format->setInt32("auto-frc", 1);
1261d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar            }
1262d9fd6317913c74e1c955eb31978c41e70d5810bcLajos Molnar        }
1263bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
12641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar    (*decoder)->init();
1265840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    (*decoder)->configure(format);
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1267095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    // allocate buffers to decrypt widevine source buffers
1268095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1269095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        Vector<sp<ABuffer> > inputBufs;
1270095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1271095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
1272095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        Vector<MediaBuffer *> mediaBufs;
1273095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        for (size_t i = 0; i < inputBufs.size(); i++) {
1274095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            const sp<ABuffer> &buffer = inputBufs[i];
1275095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1276095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mediaBufs.push(mbuf);
1277095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
1278095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
1279095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        status_t err = mSource->setBuffers(audio, mediaBufs);
1280095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (err != OK) {
1281095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            for (size_t i = 0; i < mediaBufs.size(); ++i) {
1282095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar                mediaBufs[i]->release();
1283095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            }
1284095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mediaBufs.clear();
1285095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            ALOGE("Secure source didn't support secure mediaBufs.");
1286095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            return err;
1287095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
1288095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1292ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhangvoid NuPlayer::updateVideoSize(
1293ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        const sp<AMessage> &inputFormat,
1294ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        const sp<AMessage> &outputFormat) {
1295ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    if (inputFormat == NULL) {
1296ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        ALOGW("Unknown video size, reporting 0x0!");
1297ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1298ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        return;
1299ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    }
1300ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1301ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    int32_t displayWidth, displayHeight;
1302ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    int32_t cropLeft, cropTop, cropRight, cropBottom;
1303ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1304ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    if (outputFormat != NULL) {
1305ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        int32_t width, height;
1306ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        CHECK(outputFormat->findInt32("width", &width));
1307ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        CHECK(outputFormat->findInt32("height", &height));
1308ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1309ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        int32_t cropLeft, cropTop, cropRight, cropBottom;
1310ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        CHECK(outputFormat->findRect(
1311ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang                    "crop",
1312ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang                    &cropLeft, &cropTop, &cropRight, &cropBottom));
1313ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1314ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        displayWidth = cropRight - cropLeft + 1;
1315ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        displayHeight = cropBottom - cropTop + 1;
1316ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1317ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        ALOGV("Video output format changed to %d x %d "
1318ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang             "(crop: %d x %d @ (%d, %d))",
1319ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang             width, height,
1320ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang             displayWidth,
1321ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang             displayHeight,
1322ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang             cropLeft, cropTop);
1323ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    } else {
1324ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        CHECK(inputFormat->findInt32("width", &displayWidth));
1325ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        CHECK(inputFormat->findInt32("height", &displayHeight));
1326ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1327ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1328ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    }
1329ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1330ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    // Take into account sample aspect ratio if necessary:
1331ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    int32_t sarWidth, sarHeight;
1332ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    if (inputFormat->findInt32("sar-width", &sarWidth)
1333ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            && inputFormat->findInt32("sar-height", &sarHeight)) {
1334ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1335ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1336ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        displayWidth = (displayWidth * sarWidth) / sarHeight;
1337ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1338ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
1339ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    }
1340ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1341ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    int32_t rotationDegrees;
1342ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1343ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        rotationDegrees = 0;
1344ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    }
1345ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1346ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    if (rotationDegrees == 90 || rotationDegrees == 270) {
1347ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        int32_t tmp = displayWidth;
1348ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        displayWidth = displayHeight;
1349ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        displayHeight = tmp;
1350ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    }
1351ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1352ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    notifyListener(
1353ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            MEDIA_SET_VIDEO_SIZE,
1354ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            displayWidth,
1355ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            displayHeight);
1356ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang}
1357ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1358dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
135943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mDriver == NULL) {
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    sp<NuPlayerDriver> driver = mDriver.promote();
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (driver == NULL) {
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1369dcb89b3b505522efde173c105a851c412f947178Chong Zhang    driver->notifyListener(msg, ext1, ext2, in);
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::flushDecoder(bool audio, bool needShutdown) {
137314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    ALOGV("[%s] flushDecoder needShutdown=%d",
137414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber          audio ? "audio" : "video", needShutdown);
137514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
13767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    const sp<DecoderBase> &decoder = getDecoder(audio);
137787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    if (decoder == NULL) {
1378df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("flushDecoder %s without decoder present",
13796e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber             audio ? "audio" : "video");
138087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar        return;
13816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
13826e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
13831aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    // Make sure we don't continue to scan sources until we finish flushing.
13841aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    ++mScanSourcesGeneration;
138543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    mScanSourcesPending = false;
13861aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
13877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    decoder->signalFlush();
13881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
13891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    FlushStatus newStatus =
13901aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
13911aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
139222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
13938d121d41f5355b78b687f44e8d4aae4de2aa0359Andy Hung    mFlushComplete[audio][true /* isDecoder */] = false;
13941aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (audio) {
139553904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia        ALOGE_IF(mFlushingAudio != NONE,
139653904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia                "audio flushDecoder() is called in state %d", mFlushingAudio);
13971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingAudio = newStatus;
13981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else {
139953904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia        ALOGE_IF(mFlushingVideo != NONE,
140053904f372b9c4a5ea7f839012b52b3d564e41207Wei Jia                "video flushDecoder() is called in state %d", mFlushingVideo);
14011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        mFlushingVideo = newStatus;
140287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar    }
140387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar}
140487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar
1405ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhangvoid NuPlayer::queueDecoderShutdown(
1406ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        bool audio, bool video, const sp<AMessage> &reply) {
1407ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
1408840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1409ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    mDeferredActions.push_back(
1410fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia            new FlushDecoderAction(
1411fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1412fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
1413840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1414ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    mDeferredActions.push_back(
1415ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            new SimpleAction(&NuPlayer::performScanSources));
1416840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
1417ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    mDeferredActions.push_back(new PostMessageAction(reply));
1418ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1419ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    processDeferredActions();
1420840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
1421840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
14220d268a3cae145afb2720c88ae38fb81550be5584James Dongstatus_t NuPlayer::setVideoScalingMode(int32_t mode) {
14230d268a3cae145afb2720c88ae38fb81550be5584James Dong    mVideoScalingMode = mode;
142457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (mNativeWindow != NULL) {
14250d268a3cae145afb2720c88ae38fb81550be5584James Dong        status_t ret = native_window_set_scaling_mode(
14260d268a3cae145afb2720c88ae38fb81550be5584James Dong                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
14270d268a3cae145afb2720c88ae38fb81550be5584James Dong        if (ret != OK) {
14280d268a3cae145afb2720c88ae38fb81550be5584James Dong            ALOGE("Failed to set scaling mode (%d): %s",
14290d268a3cae145afb2720c88ae38fb81550be5584James Dong                -ret, strerror(-ret));
14300d268a3cae145afb2720c88ae38fb81550be5584James Dong            return ret;
14310d268a3cae145afb2720c88ae38fb81550be5584James Dong        }
14320d268a3cae145afb2720c88ae38fb81550be5584James Dong    }
14330d268a3cae145afb2720c88ae38fb81550be5584James Dong    return OK;
14340d268a3cae145afb2720c88ae38fb81550be5584James Dong}
14350d268a3cae145afb2720c88ae38fb81550be5584James Dong
1436dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t NuPlayer::getTrackInfo(Parcel* reply) const {
1437dcb89b3b505522efde173c105a851c412f947178Chong Zhang    sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
1438dcb89b3b505522efde173c105a851c412f947178Chong Zhang    msg->setPointer("reply", reply);
1439dcb89b3b505522efde173c105a851c412f947178Chong Zhang
1440dcb89b3b505522efde173c105a851c412f947178Chong Zhang    sp<AMessage> response;
1441dcb89b3b505522efde173c105a851c412f947178Chong Zhang    status_t err = msg->postAndAwaitResponse(&response);
1442dcb89b3b505522efde173c105a851c412f947178Chong Zhang    return err;
1443dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
1444dcb89b3b505522efde173c105a851c412f947178Chong Zhang
14457c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shihstatus_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
14467c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
14477c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    msg->setPointer("reply", reply);
14487c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    msg->setInt32("type", type);
14497c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih
14507c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    sp<AMessage> response;
14517c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
14527c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    if (err == OK && response != NULL) {
14537c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih        CHECK(response->findInt32("err", &err));
14547c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    }
14557c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih    return err;
14567c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih}
14577c4f0d757bfeedaab4b7ef4ccf5b0a72ec8f4306Robert Shih
14586ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
1459dcb89b3b505522efde173c105a851c412f947178Chong Zhang    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
1460dcb89b3b505522efde173c105a851c412f947178Chong Zhang    msg->setSize("trackIndex", trackIndex);
1461dcb89b3b505522efde173c105a851c412f947178Chong Zhang    msg->setInt32("select", select);
14626ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    msg->setInt64("timeUs", timeUs);
1463dcb89b3b505522efde173c105a851c412f947178Chong Zhang
1464dcb89b3b505522efde173c105a851c412f947178Chong Zhang    sp<AMessage> response;
1465dcb89b3b505522efde173c105a851c412f947178Chong Zhang    status_t err = msg->postAndAwaitResponse(&response);
1466dcb89b3b505522efde173c105a851c412f947178Chong Zhang
1467404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    if (err != OK) {
1468404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        return err;
1469404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    }
1470404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
1471404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    if (!response->findInt32("err", &err)) {
1472404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang        err = OK;
1473404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    }
1474404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
1475dcb89b3b505522efde173c105a851c412f947178Chong Zhang    return err;
1476dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
1477dcb89b3b505522efde173c105a851c412f947178Chong Zhang
1478a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wustatus_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
1479a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu    sp<Renderer> renderer = mRenderer;
1480a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu    if (renderer == NULL) {
1481a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu        return NO_INIT;
1482a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu    }
1483a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu
1484a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu    return renderer->getCurrentPosition(mediaUs);
1485a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu}
1486a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu
1487a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuvoid NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) {
14887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<DecoderBase> decoder = getDecoder(false /* audio */);
14897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (decoder != NULL) {
14907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        decoder->getStats(numFramesTotal, numFramesDropped);
14917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    } else {
14927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        *numFramesTotal = 0;
14937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        *numFramesDropped = 0;
14947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1495a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu}
1496a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu
1497f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissensp<MetaData> NuPlayer::getFileMeta() {
1498f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen    return mSource->getFileFormatMeta();
1499f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen}
1500f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen
1501b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Hubervoid NuPlayer::schedulePollDuration() {
1502b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1503b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    msg->setInt32("generation", mPollDurationGeneration);
1504b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    msg->post();
1505b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1506b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1507b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Hubervoid NuPlayer::cancelPollDuration() {
1508b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    ++mPollDurationGeneration;
1509b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1510b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1511a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::processDeferredActions() {
1512a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    while (!mDeferredActions.empty()) {
1513a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // We won't execute any deferred actions until we're no longer in
1514a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // an intermediate state, i.e. one more more decoders are currently
1515a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        // flushing or shutting down.
1516a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1517a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1518a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // We're currently flushing, postpone the reset until that's
1519a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            // completed.
1520a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1521a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1522a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber                  mFlushingAudio, mFlushingVideo);
1523a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1524a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            break;
1525a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1526a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1527a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<Action> action = *mDeferredActions.begin();
1528a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mDeferredActions.erase(mDeferredActions.begin());
1529a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1530a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        action->execute(this);
1531a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1532a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1533a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1534e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jiavoid NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
1535e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), needNotify(%d)",
1536a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber          seekTimeUs,
1537e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia          seekTimeUs / 1E6,
1538e427abf1ea252ff305fc33aacdd2e83cf34891b5Wei Jia          needNotify);
1539a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1540adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung    if (mSource == NULL) {
1541adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung        // This happens when reset occurs right before the loop mode
1542adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung        // asynchronously seeks to the start of the stream.
1543adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung        LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
1544adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung                "mSource is NULL and decoders not NULL audio(%p) video(%p)",
1545adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung                mAudioDecoder.get(), mVideoDecoder.get());
1546adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung        return;
1547adf34bf9b7925f990259b1b6f4c69b8668f76eadAndy Hung    }
1548a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mSource->seekTo(seekTimeUs);
1549d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    ++mTimedTextGeneration;
1550a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1551a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    // everything's flushed, continue playback.
1552a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1553a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1554fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jiavoid NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
1555fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
1556a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1557fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
1558fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia            && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
1559a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        return;
1560a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1561a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1562fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
1563fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia        flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
1564a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1565a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1566fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia    if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
1567fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia        flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
1568a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1569a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1570a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1571a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performReset() {
1572a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performReset");
1573a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1574a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    CHECK(mAudioDecoder == NULL);
1575a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    CHECK(mVideoDecoder == NULL);
1576a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1577a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    cancelPollDuration();
1578a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1579a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ++mScanSourcesGeneration;
1580a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mScanSourcesPending = false;
1581a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1582095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    if (mRendererLooper != NULL) {
1583095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        if (mRenderer != NULL) {
1584095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar            mRendererLooper->unregisterHandler(mRenderer->id());
1585095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
1586095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        mRendererLooper->stop();
1587095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        mRendererLooper.clear();
1588095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar    }
1589a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    mRenderer.clear();
159057568df014f8629ebc5ca8bce9da796dd187401bWei Jia    ++mRendererGeneration;
1591a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1592a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mSource != NULL) {
1593a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mSource->stop();
1594b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1595a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        mSource.clear();
1596a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1597a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1598a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mDriver != NULL) {
1599a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        sp<NuPlayerDriver> driver = mDriver.promote();
1600a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        if (driver != NULL) {
1601a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber            driver->notifyResetComplete();
1602a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        }
1603a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
160457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
160557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    mStarted = false;
1606a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1607a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
1608a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Hubervoid NuPlayer::performScanSources() {
1609a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    ALOGV("performScanSources");
1610a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
161157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    if (!mStarted) {
161257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber        return;
161357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    }
161457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
1615a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1616a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber        postScanSources();
1617a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber    }
1618a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber}
1619a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber
162057a339cdb7524f883de3ceb364c0b5606df0c610Andreas Hubervoid NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
162157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    ALOGV("performSetSurface");
162257a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
162357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    mNativeWindow = wrapper;
162457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
162557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    // XXX - ignore error from setVideoScalingMode for now
162657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber    setVideoScalingMode(mVideoScalingMode);
162713d6faa02087ce3bb0d4a02b8495f1822f211433Chong Zhang
162813d6faa02087ce3bb0d4a02b8495f1822f211433Chong Zhang    if (mDriver != NULL) {
162913d6faa02087ce3bb0d4a02b8495f1822f211433Chong Zhang        sp<NuPlayerDriver> driver = mDriver.promote();
163013d6faa02087ce3bb0d4a02b8495f1822f211433Chong Zhang        if (driver != NULL) {
163113d6faa02087ce3bb0d4a02b8495f1822f211433Chong Zhang            driver->notifySetSurfaceComplete();
163213d6faa02087ce3bb0d4a02b8495f1822f211433Chong Zhang        }
163313d6faa02087ce3bb0d4a02b8495f1822f211433Chong Zhang    }
163457a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber}
163557a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber
1636f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::performResumeDecoders(bool needNotify) {
1637f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (needNotify) {
1638f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = true;
1639f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        if (mVideoDecoder == NULL) {
1640f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            // if audio-only, we can notify seek complete now,
1641f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            // as the resume operation will be relatively fast.
1642f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            finishResume();
1643f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        }
1644f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
1645f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
16467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mVideoDecoder != NULL) {
1647f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        // When there is continuous seek, MediaPlayer will cache the seek
1648f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        // position, and send down new seek request when previous seek is
1649f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        // complete. Let's wait for at least one video output frame before
1650f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        // notifying seek complete, so that the video thumbnail gets updated
1651f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        // when seekbar is dragged.
1652f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mVideoDecoder->signalResume(needNotify);
16537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
16547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
16557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mAudioDecoder != NULL) {
1656f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mAudioDecoder->signalResume(false /* needNotify */);
1657f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    }
1658f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang}
1659f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
1660f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::finishResume() {
1661f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    if (mResumePending) {
1662f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        mResumePending = false;
1663f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        if (mDriver != NULL) {
1664f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            sp<NuPlayerDriver> driver = mDriver.promote();
1665f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            if (driver != NULL) {
1666f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang                driver->notifySeekComplete();
1667f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            }
1668f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang        }
16697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
16707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
16717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
16729575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
16739575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    int32_t what;
16749575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    CHECK(msg->findInt32("what", &what));
16759575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
16769575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    switch (what) {
167722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        case Source::kWhatInstantiateSecureDecoders:
167822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        {
167922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            if (mSource == NULL) {
168022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                // This is a stale notification from a source that was
168122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                // asynchronously preparing when the client called reset().
168222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                // We handled the reset, the source is gone.
168322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                break;
168422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            }
168522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
168622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            sp<AMessage> reply;
168722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            CHECK(msg->findMessage("reply", &reply));
168822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            status_t err = onInstantiateSecureDecoders();
168922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            reply->setInt32("err", err);
169022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            reply->post();
169122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            break;
169222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        }
169322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
16949575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatPrepared:
16959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
1696b5f28d4749b898d92fe5e56236b417e37b6fe84fAndreas Huber            if (mSource == NULL) {
1697b5f28d4749b898d92fe5e56236b417e37b6fe84fAndreas Huber                // This is a stale notification from a source that was
1698b5f28d4749b898d92fe5e56236b417e37b6fe84fAndreas Huber                // asynchronously preparing when the client called reset().
1699b5f28d4749b898d92fe5e56236b417e37b6fe84fAndreas Huber                // We handled the reset, the source is gone.
1700b5f28d4749b898d92fe5e56236b417e37b6fe84fAndreas Huber                break;
1701b5f28d4749b898d92fe5e56236b417e37b6fe84fAndreas Huber            }
1702b5f28d4749b898d92fe5e56236b417e37b6fe84fAndreas Huber
1703ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber            int32_t err;
1704ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber            CHECK(msg->findInt32("err", &err));
1705ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber
170622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            if (err != OK) {
170722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                // shut down potential secure codecs in case client never calls reset
170822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                mDeferredActions.push_back(
170922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                        new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
171022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                                               FLUSH_CMD_SHUTDOWN /* video */));
171122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar                processDeferredActions();
171222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar            }
171322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
17149575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            sp<NuPlayerDriver> driver = mDriver.promote();
17159575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if (driver != NULL) {
1716dd114d19f65d8a5cdfddbaf6d3ef8119c6169b28Marco Nelissen                // notify duration first, so that it's definitely set when
1717dd114d19f65d8a5cdfddbaf6d3ef8119c6169b28Marco Nelissen                // the app received the "prepare complete" callback.
1718dd114d19f65d8a5cdfddbaf6d3ef8119c6169b28Marco Nelissen                int64_t durationUs;
1719dd114d19f65d8a5cdfddbaf6d3ef8119c6169b28Marco Nelissen                if (mSource->getDuration(&durationUs) == OK) {
1720997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber                    driver->notifyDuration(durationUs);
1721997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber                }
1722dd114d19f65d8a5cdfddbaf6d3ef8119c6169b28Marco Nelissen                driver->notifyPrepareCompleted(err);
1723997594088164cfb33c1cb8c376884346fbf1e7aeAndreas Huber            }
1724dd114d19f65d8a5cdfddbaf6d3ef8119c6169b28Marco Nelissen
17259575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
17269575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
17279575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
17289575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatFlagsChanged:
17299575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
17309575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            uint32_t flags;
17319575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
17329575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
17334b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang            sp<NuPlayerDriver> driver = mDriver.promote();
17344b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang            if (driver != NULL) {
1735895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia                if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
1736895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia                    driver->notifyListener(
1737895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia                            MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
1738895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia                }
17394b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                driver->notifyFlagsChanged(flags);
17404b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang            }
17414b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang
17429575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
17439575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
17449575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                cancelPollDuration();
17459575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
17469575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (flags & Source::FLAG_DYNAMIC_DURATION)
17479575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
17489575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber                schedulePollDuration();
17499575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            }
17509575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
17519575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            mSourceFlags = flags;
17529575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
17539575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
17549575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
17559575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        case Source::kWhatVideoSizeChanged:
17569575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        {
1757ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            sp<AMessage> format;
1758ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            CHECK(msg->findMessage("format", &format));
17599575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1760ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            updateVideoSize(format);
17619575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            break;
17629575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        }
17639575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
17642a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        case Source::kWhatBufferingUpdate:
17652a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        {
17662a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            int32_t percentage;
17672a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            CHECK(msg->findInt32("percentage", &percentage));
17682a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
17692a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
17702a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            break;
17712a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        }
17722a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
1773efbb61950db36a5eb789be83f077246172507c67Chong Zhang        case Source::kWhatPauseOnBufferingStart:
1774efbb61950db36a5eb789be83f077246172507c67Chong Zhang        {
1775efbb61950db36a5eb789be83f077246172507c67Chong Zhang            // ignore if not playing
1776efbb61950db36a5eb789be83f077246172507c67Chong Zhang            if (mStarted && !mPausedByClient) {
1777efbb61950db36a5eb789be83f077246172507c67Chong Zhang                ALOGI("buffer low, pausing...");
1778efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1779efbb61950db36a5eb789be83f077246172507c67Chong Zhang                onPause();
1780efbb61950db36a5eb789be83f077246172507c67Chong Zhang            }
1781efbb61950db36a5eb789be83f077246172507c67Chong Zhang            // fall-thru
1782efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
1783efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1784b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        case Source::kWhatBufferingStart:
1785b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        {
1786b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1787b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            break;
1788b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        }
1789b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson
1790efbb61950db36a5eb789be83f077246172507c67Chong Zhang        case Source::kWhatResumeOnBufferingEnd:
1791efbb61950db36a5eb789be83f077246172507c67Chong Zhang        {
1792efbb61950db36a5eb789be83f077246172507c67Chong Zhang            // ignore if not playing
1793efbb61950db36a5eb789be83f077246172507c67Chong Zhang            if (mStarted && !mPausedByClient) {
1794efbb61950db36a5eb789be83f077246172507c67Chong Zhang                ALOGI("buffer ready, resuming...");
1795efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1796efbb61950db36a5eb789be83f077246172507c67Chong Zhang                onResume();
1797efbb61950db36a5eb789be83f077246172507c67Chong Zhang            }
1798efbb61950db36a5eb789be83f077246172507c67Chong Zhang            // fall-thru
1799efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
1800efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1801b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        case Source::kWhatBufferingEnd:
1802b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        {
1803b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1804b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson            break;
1805b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        }
1806b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson
1807efbb61950db36a5eb789be83f077246172507c67Chong Zhang        case Source::kWhatCacheStats:
1808efbb61950db36a5eb789be83f077246172507c67Chong Zhang        {
1809efbb61950db36a5eb789be83f077246172507c67Chong Zhang            int32_t kbps;
1810efbb61950db36a5eb789be83f077246172507c67Chong Zhang            CHECK(msg->findInt32("bandwidth", &kbps));
1811efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1812efbb61950db36a5eb789be83f077246172507c67Chong Zhang            notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
1813efbb61950db36a5eb789be83f077246172507c67Chong Zhang            break;
1814efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
1815efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1816dcb89b3b505522efde173c105a851c412f947178Chong Zhang        case Source::kWhatSubtitleData:
1817dcb89b3b505522efde173c105a851c412f947178Chong Zhang        {
1818dcb89b3b505522efde173c105a851c412f947178Chong Zhang            sp<ABuffer> buffer;
1819dcb89b3b505522efde173c105a851c412f947178Chong Zhang            CHECK(msg->findBuffer("buffer", &buffer));
1820dcb89b3b505522efde173c105a851c412f947178Chong Zhang
1821404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang            sendSubtitleData(buffer, 0 /* baseIndex */);
1822dcb89b3b505522efde173c105a851c412f947178Chong Zhang            break;
1823dcb89b3b505522efde173c105a851c412f947178Chong Zhang        }
1824dcb89b3b505522efde173c105a851c412f947178Chong Zhang
1825d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        case Source::kWhatTimedTextData:
1826d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        {
1827d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            int32_t generation;
1828d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            if (msg->findInt32("generation", &generation)
1829d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                    && generation != mTimedTextGeneration) {
1830d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                break;
1831d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            }
1832d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1833d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            sp<ABuffer> buffer;
1834d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            CHECK(msg->findBuffer("buffer", &buffer));
1835d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1836d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            sp<NuPlayerDriver> driver = mDriver.promote();
1837d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            if (driver == NULL) {
1838d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                break;
1839d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            }
1840d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1841d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            int posMs;
1842d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            int64_t timeUs, posUs;
1843d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            driver->getCurrentPosition(&posMs);
1844d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            posUs = posMs * 1000;
1845d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1846d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1847d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            if (posUs < timeUs) {
1848d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                if (!msg->findInt32("generation", &generation)) {
1849d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                    msg->setInt32("generation", mTimedTextGeneration);
1850d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                }
1851d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                msg->post(timeUs - posUs);
1852d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            } else {
1853d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                sendTimedTextData(buffer);
1854d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            }
1855d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih            break;
1856d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        }
1857d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
185814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case Source::kWhatQueueDecoderShutdown:
185914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
186014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            int32_t audio, video;
186114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            CHECK(msg->findInt32("audio", &audio));
186214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            CHECK(msg->findInt32("video", &video));
186314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
186414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            sp<AMessage> reply;
186514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            CHECK(msg->findMessage("reply", &reply));
186614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
186714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            queueDecoderShutdown(audio, video, reply);
186814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
186914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
187014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
1871802768790c131f8237364906fd13981a6bb91193Ronghua Wu        case Source::kWhatDrmNoLicense:
1872802768790c131f8237364906fd13981a6bb91193Ronghua Wu        {
1873802768790c131f8237364906fd13981a6bb91193Ronghua Wu            notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
1874802768790c131f8237364906fd13981a6bb91193Ronghua Wu            break;
1875802768790c131f8237364906fd13981a6bb91193Ronghua Wu        }
1876802768790c131f8237364906fd13981a6bb91193Ronghua Wu
18779575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        default:
18789575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            TRESPASS();
18799575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    }
18809575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
18819575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1882a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhangvoid NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
1883a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    int32_t what;
1884a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    CHECK(msg->findInt32("what", &what));
1885a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1886a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    switch (what) {
1887a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        case NuPlayer::CCDecoder::kWhatClosedCaptionData:
1888a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        {
1889a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            sp<ABuffer> buffer;
1890a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            CHECK(msg->findBuffer("buffer", &buffer));
1891a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1892a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            size_t inbandTracks = 0;
1893a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            if (mSource != NULL) {
1894a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                inbandTracks = mSource->getTrackCount();
1895a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            }
1896a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1897a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            sendSubtitleData(buffer, inbandTracks);
1898a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            break;
1899a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        }
1900a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1901a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        case NuPlayer::CCDecoder::kWhatTrackAdded:
1902a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        {
1903a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
1904a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1905a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            break;
1906a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        }
1907a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1908a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang        default:
1909a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang            TRESPASS();
1910a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang    }
1911a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1912a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1913a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang}
1914a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
1915404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangvoid NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
1916404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    int32_t trackIndex;
1917404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    int64_t timeUs, durationUs;
1918404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
1919404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1920404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
1921404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
1922404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    Parcel in;
1923404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    in.writeInt32(trackIndex + baseIndex);
1924404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    in.writeInt64(timeUs);
1925404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    in.writeInt64(durationUs);
1926404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    in.writeInt32(buffer->size());
1927404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    in.writeInt32(buffer->size());
1928404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    in.write(buffer->data(), buffer->size());
1929404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang
1930404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang    notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
1931404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang}
1932d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1933d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shihvoid NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
1934d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    const void *data;
1935d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    size_t size = 0;
1936d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    int64_t timeUs;
1937d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
1938d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1939d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    AString mime;
1940d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    CHECK(buffer->meta()->findString("mime", &mime));
1941d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
1942d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1943d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    data = buffer->data();
1944d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    size = buffer->size();
1945d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1946d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    Parcel parcel;
1947d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    if (size > 0) {
1948d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1949d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
1950d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        TextDescriptions::getParcelOfDescriptions(
1951d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih                (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
1952d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    }
1953d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih
1954d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    if ((parcel.dataSize() > 0)) {
1955d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
1956d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    } else {  // send an empty timed text
1957d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih        notifyListener(MEDIA_TIMED_TEXT, 0, 0);
1958d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih    }
1959d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih}
1960b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber////////////////////////////////////////////////////////////////////////////////
1961b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
1962ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhangsp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1963ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    sp<MetaData> meta = getFormatMeta(audio);
1964ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1965ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    if (meta == NULL) {
1966ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        return NULL;
1967ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    }
1968ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1969ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    sp<AMessage> msg = new AMessage;
1970ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
1971ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    if(convertMetaDataToMessage(meta, &msg) == OK) {
1972ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang        return msg;
1973ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    }
1974ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    return NULL;
1975ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang}
1976ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang
19779575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
19789575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
19799575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatFlagsChanged);
19809575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("flags", flags);
19819575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
19829575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
19839575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1984ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhangvoid NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
19859575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
19869575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatVideoSizeChanged);
1987ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang    notify->setMessage("format", format);
19889575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
19899575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
19909575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1991ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Hubervoid NuPlayer::Source::notifyPrepared(status_t err) {
19929575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    sp<AMessage> notify = dupNotify();
19939575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->setInt32("what", kWhatPrepared);
1994ec0c597cabf169ca646bcea5faac1bd81ed4484dAndreas Huber    notify->setInt32("err", err);
19959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notify->post();
19969575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
19979575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
199822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnarvoid NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
199922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    sp<AMessage> notify = dupNotify();
200022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    notify->setInt32("what", kWhatInstantiateSecureDecoders);
200122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    notify->setMessage("reply", reply);
200222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    notify->post();
200322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar}
200422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
200584333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
2006b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    TRESPASS();
2007b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber}
2008b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
2010