NuPlayer.cpp revision 6d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aab
1ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi/*
2ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Copyright (C) 2010 The Android Open Source Project
3ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi *
4ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
5ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * you may not use this file except in compliance with the License.
6ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * You may obtain a copy of the License at
7ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi *
8ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
9ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi *
10ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Unless required by applicable law or agreed to in writing, software
11ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
12ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * See the License for the specific language governing permissions and
14ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * limitations under the License.
15ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi */
16ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
17ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi//#define LOG_NDEBUG 0
18ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#define LOG_TAG "NuPlayer"
19ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <utils/Log.h>
20ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
21ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayer.h"
22ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
23ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "HTTPLiveSource.h"
24ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerDecoder.h"
25ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerDriver.h"
26ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerRenderer.h"
27ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerSource.h"
28ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "RTSPSource.h"
29ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "StreamingSource.h"
30ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "GenericSource.h"
31ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
32ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "ATSParser.h"
33ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
34ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "SoftwareRenderer.h"
35ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
36ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/hexdump.h>
37ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/ABuffer.h>
38ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/ADebug.h>
39ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/AMessage.h>
40ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/ACodec.h>
41ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/MediaDefs.h>
42ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/MediaErrors.h>
43ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/MetaData.h>
44ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <gui/IGraphicBufferProducer.h>
45ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
46ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "avc_utils.h"
47ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
48ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "ESDS.h"
49ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/Utils.h>
50ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
51ecbab3662d4474bbb45477939aaa167eb883212bJorim Jagginamespace android {
52ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
53ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::Action : public RefBase {
54ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    Action() {}
55ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
56ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    virtual void execute(NuPlayer *player) = 0;
57ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
58ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate:
59ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    DISALLOW_EVIL_CONSTRUCTORS(Action);
60ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi};
61ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
62ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::SeekAction : public Action {
63ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    SeekAction(int64_t seekTimeUs)
64ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        : mSeekTimeUs(seekTimeUs) {
65ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
66ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
67ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    virtual void execute(NuPlayer *player) {
68ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        player->performSeek(mSeekTimeUs);
69ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
70ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
71ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate:
72ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    int64_t mSeekTimeUs;
73ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
74ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
75ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi};
76ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
77ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::SetSurfaceAction : public Action {
78ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
79ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        : mWrapper(wrapper) {
80ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
81ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
82ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    virtual void execute(NuPlayer *player) {
83ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        player->performSetSurface(mWrapper);
84ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
85ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
86ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate:
87ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    sp<NativeWindowWrapper> mWrapper;
88ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
89ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
90ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi};
91ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
92ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::ShutdownDecoderAction : public Action {
93ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    ShutdownDecoderAction(bool audio, bool video)
94ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        : mAudio(audio),
95ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi          mVideo(video) {
96ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
97ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
98ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    virtual void execute(NuPlayer *player) {
99ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        player->performDecoderShutdown(mAudio, mVideo);
100ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
101ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
102ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate:
103ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    bool mAudio;
104ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    bool mVideo;
105ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
106ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction);
107ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi};
108ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
109ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::PostMessageAction : public Action {
110ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    PostMessageAction(const sp<AMessage> &msg)
111ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        : mMessage(msg) {
112ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
113ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
114ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    virtual void execute(NuPlayer *) {
115ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        mMessage->post();
116ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
117ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
118ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate:
119ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    sp<AMessage> mMessage;
120ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
121ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
122ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi};
123ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
124ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi// Use this if there's no state necessary to save in order to execute
125ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi// the action.
126ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::SimpleAction : public Action {
127ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    typedef void (NuPlayer::*ActionFunc)();
128ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
129ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    SimpleAction(ActionFunc func)
130ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        : mFunc(func) {
131ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
132ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
133ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    virtual void execute(NuPlayer *player) {
134ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi        (player->*mFunc)();
135ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    }
136ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
137ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate:
138ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    ActionFunc mFunc;
139ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
140ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
141ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi};
142ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
143ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi////////////////////////////////////////////////////////////////////////////////
144ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi
145ecbab3662d4474bbb45477939aaa167eb883212bJorim JaggiNuPlayer::NuPlayer()
146ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi    : mUIDValid(false),
147ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mSourceFlags(0),
148ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mVideoIsAVC(false),
149ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mNeedsSwRenderer(false),
150ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mAudioEOS(false),
151ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mVideoEOS(false),
152ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mScanSourcesPending(false),
153ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mScanSourcesGeneration(0),
154ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mPollDurationGeneration(0),
155ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mTimeDiscontinuityPending(false),
156ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mFlushingAudio(NONE),
157ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mFlushingVideo(NONE),
158ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
159      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
160      mVideoLateByUs(0ll),
161      mNumFramesTotal(0ll),
162      mNumFramesDropped(0ll),
163      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
164      mStarted(false) {
165}
166
167NuPlayer::~NuPlayer() {
168}
169
170void NuPlayer::setUID(uid_t uid) {
171    mUIDValid = true;
172    mUID = uid;
173}
174
175void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
176    mDriver = driver;
177}
178
179void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
180    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
181
182    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
183
184    msg->setObject("source", new StreamingSource(notify, source));
185    msg->post();
186}
187
188static bool IsHTTPLiveURL(const char *url) {
189    if (!strncasecmp("http://", url, 7)
190            || !strncasecmp("https://", url, 8)
191            || !strncasecmp("file://", url, 7)) {
192        size_t len = strlen(url);
193        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
194            return true;
195        }
196
197        if (strstr(url,"m3u8")) {
198            return true;
199        }
200    }
201
202    return false;
203}
204
205void NuPlayer::setDataSourceAsync(
206        const sp<IMediaHTTPService> &httpService,
207        const char *url,
208        const KeyedVector<String8, String8> *headers) {
209    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
210    size_t len = strlen(url);
211
212    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
213
214    sp<Source> source;
215    if (IsHTTPLiveURL(url)) {
216        source = new HTTPLiveSource(notify, httpService, url, headers);
217    } else if (!strncasecmp(url, "rtsp://", 7)) {
218        source = new RTSPSource(
219                notify, httpService, url, headers, mUIDValid, mUID);
220    } else if ((!strncasecmp(url, "http://", 7)
221                || !strncasecmp(url, "https://", 8))
222                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
223                    || strstr(url, ".sdp?"))) {
224        source = new RTSPSource(
225                notify, httpService, url, headers, mUIDValid, mUID, true);
226    } else {
227        source = new GenericSource(notify, httpService, url, headers);
228    }
229
230    msg->setObject("source", source);
231    msg->post();
232}
233
234void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
235    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
236
237    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
238
239    sp<Source> source = new GenericSource(notify, fd, offset, length);
240    msg->setObject("source", source);
241    msg->post();
242}
243
244void NuPlayer::prepareAsync() {
245    (new AMessage(kWhatPrepare, id()))->post();
246}
247
248void NuPlayer::setVideoSurfaceTextureAsync(
249        const sp<IGraphicBufferProducer> &bufferProducer) {
250    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
251
252    if (bufferProducer == NULL) {
253        msg->setObject("native-window", NULL);
254    } else {
255        msg->setObject(
256                "native-window",
257                new NativeWindowWrapper(
258                    new Surface(bufferProducer)));
259    }
260
261    msg->post();
262}
263
264void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
265    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
266    msg->setObject("sink", sink);
267    msg->post();
268}
269
270void NuPlayer::start() {
271    (new AMessage(kWhatStart, id()))->post();
272}
273
274void NuPlayer::pause() {
275    (new AMessage(kWhatPause, id()))->post();
276}
277
278void NuPlayer::resume() {
279    (new AMessage(kWhatResume, id()))->post();
280}
281
282void NuPlayer::resetAsync() {
283    (new AMessage(kWhatReset, id()))->post();
284}
285
286void NuPlayer::seekToAsync(int64_t seekTimeUs) {
287    sp<AMessage> msg = new AMessage(kWhatSeek, id());
288    msg->setInt64("seekTimeUs", seekTimeUs);
289    msg->post();
290}
291
292// static
293bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
294    switch (state) {
295        case FLUSHING_DECODER:
296            if (needShutdown != NULL) {
297                *needShutdown = false;
298            }
299            return true;
300
301        case FLUSHING_DECODER_SHUTDOWN:
302            if (needShutdown != NULL) {
303                *needShutdown = true;
304            }
305            return true;
306
307        default:
308            return false;
309    }
310}
311
312void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
313    switch (msg->what()) {
314        case kWhatSetDataSource:
315        {
316            ALOGV("kWhatSetDataSource");
317
318            CHECK(mSource == NULL);
319
320            sp<RefBase> obj;
321            CHECK(msg->findObject("source", &obj));
322
323            mSource = static_cast<Source *>(obj.get());
324
325            looper()->registerHandler(mSource);
326
327            CHECK(mDriver != NULL);
328            sp<NuPlayerDriver> driver = mDriver.promote();
329            if (driver != NULL) {
330                driver->notifySetDataSourceCompleted(OK);
331            }
332            break;
333        }
334
335        case kWhatPrepare:
336        {
337            mSource->prepareAsync();
338            break;
339        }
340
341        case kWhatGetTrackInfo:
342        {
343            uint32_t replyID;
344            CHECK(msg->senderAwaitsResponse(&replyID));
345
346            status_t err = INVALID_OPERATION;
347            if (mSource != NULL) {
348                Parcel* reply;
349                CHECK(msg->findPointer("reply", (void**)&reply));
350                err = mSource->getTrackInfo(reply);
351            }
352
353            sp<AMessage> response = new AMessage;
354            response->setInt32("err", err);
355
356            response->postReply(replyID);
357            break;
358        }
359
360        case kWhatSelectTrack:
361        {
362            uint32_t replyID;
363            CHECK(msg->senderAwaitsResponse(&replyID));
364
365            status_t err = INVALID_OPERATION;
366            if (mSource != NULL) {
367                size_t trackIndex;
368                int32_t select;
369                CHECK(msg->findSize("trackIndex", &trackIndex));
370                CHECK(msg->findInt32("select", &select));
371                err = mSource->selectTrack(trackIndex, select);
372            }
373
374            sp<AMessage> response = new AMessage;
375            response->setInt32("err", err);
376
377            response->postReply(replyID);
378            break;
379        }
380
381        case kWhatPollDuration:
382        {
383            int32_t generation;
384            CHECK(msg->findInt32("generation", &generation));
385
386            if (generation != mPollDurationGeneration) {
387                // stale
388                break;
389            }
390
391            int64_t durationUs;
392            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
393                sp<NuPlayerDriver> driver = mDriver.promote();
394                if (driver != NULL) {
395                    driver->notifyDuration(durationUs);
396                }
397            }
398
399            msg->post(1000000ll);  // poll again in a second.
400            break;
401        }
402
403        case kWhatSetVideoNativeWindow:
404        {
405            ALOGV("kWhatSetVideoNativeWindow");
406
407            mDeferredActions.push_back(
408                    new ShutdownDecoderAction(
409                        false /* audio */, true /* video */));
410
411            sp<RefBase> obj;
412            CHECK(msg->findObject("native-window", &obj));
413
414            mDeferredActions.push_back(
415                    new SetSurfaceAction(
416                        static_cast<NativeWindowWrapper *>(obj.get())));
417
418            if (obj != NULL) {
419                // If there is a new surface texture, instantiate decoders
420                // again if possible.
421                mDeferredActions.push_back(
422                        new SimpleAction(&NuPlayer::performScanSources));
423            }
424
425            processDeferredActions();
426            break;
427        }
428
429        case kWhatSetAudioSink:
430        {
431            ALOGV("kWhatSetAudioSink");
432
433            sp<RefBase> obj;
434            CHECK(msg->findObject("sink", &obj));
435
436            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
437            break;
438        }
439
440        case kWhatStart:
441        {
442            ALOGV("kWhatStart");
443
444            mVideoIsAVC = false;
445            mNeedsSwRenderer = false;
446            mAudioEOS = false;
447            mVideoEOS = false;
448            mSkipRenderingAudioUntilMediaTimeUs = -1;
449            mSkipRenderingVideoUntilMediaTimeUs = -1;
450            mVideoLateByUs = 0;
451            mNumFramesTotal = 0;
452            mNumFramesDropped = 0;
453            mStarted = true;
454
455            mSource->start();
456
457            uint32_t flags = 0;
458
459            if (mSource->isRealTime()) {
460                flags |= Renderer::FLAG_REAL_TIME;
461            }
462
463            mRenderer = new Renderer(
464                    mAudioSink,
465                    new AMessage(kWhatRendererNotify, id()),
466                    flags);
467
468            looper()->registerHandler(mRenderer);
469
470            postScanSources();
471            break;
472        }
473
474        case kWhatScanSources:
475        {
476            int32_t generation;
477            CHECK(msg->findInt32("generation", &generation));
478            if (generation != mScanSourcesGeneration) {
479                // Drop obsolete msg.
480                break;
481            }
482
483            mScanSourcesPending = false;
484
485            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
486                 mAudioDecoder != NULL, mVideoDecoder != NULL);
487
488            bool mHadAnySourcesBefore =
489                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
490
491            if (mNativeWindow != NULL) {
492                instantiateDecoder(false, &mVideoDecoder);
493            }
494
495            if (mAudioSink != NULL) {
496                instantiateDecoder(true, &mAudioDecoder);
497            }
498
499            if (!mHadAnySourcesBefore
500                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
501                // This is the first time we've found anything playable.
502
503                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
504                    schedulePollDuration();
505                }
506            }
507
508            status_t err;
509            if ((err = mSource->feedMoreTSData()) != OK) {
510                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
511                    // We're not currently decoding anything (no audio or
512                    // video tracks found) and we just ran out of input data.
513
514                    if (err == ERROR_END_OF_STREAM) {
515                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
516                    } else {
517                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
518                    }
519                }
520                break;
521            }
522
523            if ((mAudioDecoder == NULL && mAudioSink != NULL)
524                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
525                msg->post(100000ll);
526                mScanSourcesPending = true;
527            }
528            break;
529        }
530
531        case kWhatVideoNotify:
532        case kWhatAudioNotify:
533        {
534            bool audio = msg->what() == kWhatAudioNotify;
535
536            sp<AMessage> codecRequest;
537            CHECK(msg->findMessage("codec-request", &codecRequest));
538
539            int32_t what;
540            CHECK(codecRequest->findInt32("what", &what));
541
542            if (what == ACodec::kWhatFillThisBuffer) {
543                status_t err = feedDecoderInputData(
544                        audio, codecRequest);
545
546                if (err == -EWOULDBLOCK) {
547                    if (mSource->feedMoreTSData() == OK) {
548                        msg->post(10000ll);
549                    }
550                }
551            } else if (what == ACodec::kWhatEOS) {
552                int32_t err;
553                CHECK(codecRequest->findInt32("err", &err));
554
555                if (err == ERROR_END_OF_STREAM) {
556                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
557                } else {
558                    ALOGV("got %s decoder EOS w/ error %d",
559                         audio ? "audio" : "video",
560                         err);
561                }
562
563                mRenderer->queueEOS(audio, err);
564            } else if (what == ACodec::kWhatFlushCompleted) {
565                bool needShutdown;
566
567                if (audio) {
568                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
569                    mFlushingAudio = FLUSHED;
570                } else {
571                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
572                    mFlushingVideo = FLUSHED;
573
574                    mVideoLateByUs = 0;
575                }
576
577                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
578
579                if (needShutdown) {
580                    ALOGV("initiating %s decoder shutdown",
581                         audio ? "audio" : "video");
582
583                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
584
585                    if (audio) {
586                        mFlushingAudio = SHUTTING_DOWN_DECODER;
587                    } else {
588                        mFlushingVideo = SHUTTING_DOWN_DECODER;
589                    }
590                }
591
592                finishFlushIfPossible();
593            } else if (what == ACodec::kWhatOutputFormatChanged) {
594                if (audio) {
595                    int32_t numChannels;
596                    CHECK(codecRequest->findInt32(
597                                "channel-count", &numChannels));
598
599                    int32_t sampleRate;
600                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
601
602                    ALOGV("Audio output format changed to %d Hz, %d channels",
603                         sampleRate, numChannels);
604
605                    mAudioSink->close();
606
607                    audio_output_flags_t flags;
608                    int64_t durationUs;
609                    // FIXME: we should handle the case where the video decoder
610                    // is created after we receive the format change indication.
611                    // Current code will just make that we select deep buffer
612                    // with video which should not be a problem as it should
613                    // not prevent from keeping A/V sync.
614                    if (mVideoDecoder == NULL &&
615                            mSource->getDuration(&durationUs) == OK &&
616                            durationUs
617                                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
618                        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
619                    } else {
620                        flags = AUDIO_OUTPUT_FLAG_NONE;
621                    }
622
623                    int32_t channelMask;
624                    if (!codecRequest->findInt32("channel-mask", &channelMask)) {
625                        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
626                    }
627
628                    CHECK_EQ(mAudioSink->open(
629                                sampleRate,
630                                numChannels,
631                                (audio_channel_mask_t)channelMask,
632                                AUDIO_FORMAT_PCM_16_BIT,
633                                8 /* bufferCount */,
634                                NULL,
635                                NULL,
636                                flags),
637                             (status_t)OK);
638                    mAudioSink->start();
639
640                    mRenderer->signalAudioSinkChanged();
641                } else {
642                    // video
643
644                    int32_t width, height;
645                    CHECK(codecRequest->findInt32("width", &width));
646                    CHECK(codecRequest->findInt32("height", &height));
647
648                    int32_t cropLeft, cropTop, cropRight, cropBottom;
649                    CHECK(codecRequest->findRect(
650                                "crop",
651                                &cropLeft, &cropTop, &cropRight, &cropBottom));
652
653                    int32_t displayWidth = cropRight - cropLeft + 1;
654                    int32_t displayHeight = cropBottom - cropTop + 1;
655
656                    ALOGV("Video output format changed to %d x %d "
657                         "(crop: %d x %d @ (%d, %d))",
658                         width, height,
659                         displayWidth,
660                         displayHeight,
661                         cropLeft, cropTop);
662
663                    sp<AMessage> videoInputFormat =
664                        mSource->getFormat(false /* audio */);
665
666                    // Take into account sample aspect ratio if necessary:
667                    int32_t sarWidth, sarHeight;
668                    if (videoInputFormat->findInt32("sar-width", &sarWidth)
669                            && videoInputFormat->findInt32(
670                                "sar-height", &sarHeight)) {
671                        ALOGV("Sample aspect ratio %d : %d",
672                              sarWidth, sarHeight);
673
674                        displayWidth = (displayWidth * sarWidth) / sarHeight;
675
676                        ALOGV("display dimensions %d x %d",
677                              displayWidth, displayHeight);
678                    }
679
680                    notifyListener(
681                            MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
682
683                    if (mNeedsSwRenderer && mNativeWindow != NULL) {
684                        int32_t colorFormat;
685                        CHECK(codecRequest->findInt32("color-format", &colorFormat));
686
687                        sp<MetaData> meta = new MetaData;
688                        meta->setInt32(kKeyWidth, width);
689                        meta->setInt32(kKeyHeight, height);
690                        meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
691                        meta->setInt32(kKeyColorFormat, colorFormat);
692
693                        mRenderer->setSoftRenderer(
694                                new SoftwareRenderer(mNativeWindow->getNativeWindow(), meta));
695                    }
696                }
697            } else if (what == ACodec::kWhatShutdownCompleted) {
698                ALOGV("%s shutdown completed", audio ? "audio" : "video");
699                if (audio) {
700                    mAudioDecoder.clear();
701
702                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
703                    mFlushingAudio = SHUT_DOWN;
704                } else {
705                    mVideoDecoder.clear();
706
707                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
708                    mFlushingVideo = SHUT_DOWN;
709                }
710
711                finishFlushIfPossible();
712            } else if (what == ACodec::kWhatError) {
713                ALOGE("Received error from %s decoder, aborting playback.",
714                     audio ? "audio" : "video");
715
716                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
717            } else if (what == ACodec::kWhatDrainThisBuffer) {
718                renderBuffer(audio, codecRequest);
719            } else if (what == ACodec::kWhatComponentAllocated) {
720                if (!audio) {
721                    AString name;
722                    CHECK(codecRequest->findString("componentName", &name));
723                    mNeedsSwRenderer = name.startsWith("OMX.google.");
724                }
725            } else if (what != ACodec::kWhatComponentConfigured
726                    && what != ACodec::kWhatBuffersAllocated) {
727                ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
728                      what,
729                      what >> 24,
730                      (what >> 16) & 0xff,
731                      (what >> 8) & 0xff,
732                      what & 0xff);
733            }
734
735            break;
736        }
737
738        case kWhatRendererNotify:
739        {
740            int32_t what;
741            CHECK(msg->findInt32("what", &what));
742
743            if (what == Renderer::kWhatEOS) {
744                int32_t audio;
745                CHECK(msg->findInt32("audio", &audio));
746
747                int32_t finalResult;
748                CHECK(msg->findInt32("finalResult", &finalResult));
749
750                if (audio) {
751                    mAudioEOS = true;
752                } else {
753                    mVideoEOS = true;
754                }
755
756                if (finalResult == ERROR_END_OF_STREAM) {
757                    ALOGV("reached %s EOS", audio ? "audio" : "video");
758                } else {
759                    ALOGE("%s track encountered an error (%d)",
760                         audio ? "audio" : "video", finalResult);
761
762                    notifyListener(
763                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
764                }
765
766                if ((mAudioEOS || mAudioDecoder == NULL)
767                        && (mVideoEOS || mVideoDecoder == NULL)) {
768                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
769                }
770            } else if (what == Renderer::kWhatPosition) {
771                int64_t positionUs;
772                CHECK(msg->findInt64("positionUs", &positionUs));
773
774                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
775
776                if (mDriver != NULL) {
777                    sp<NuPlayerDriver> driver = mDriver.promote();
778                    if (driver != NULL) {
779                        driver->notifyPosition(positionUs);
780
781                        driver->notifyFrameStats(
782                                mNumFramesTotal, mNumFramesDropped);
783                    }
784                }
785            } else if (what == Renderer::kWhatFlushComplete) {
786                int32_t audio;
787                CHECK(msg->findInt32("audio", &audio));
788
789                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
790            } else if (what == Renderer::kWhatVideoRenderingStart) {
791                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
792            } else if (what == Renderer::kWhatMediaRenderingStart) {
793                ALOGV("media rendering started");
794                notifyListener(MEDIA_STARTED, 0, 0);
795            }
796            break;
797        }
798
799        case kWhatMoreDataQueued:
800        {
801            break;
802        }
803
804        case kWhatReset:
805        {
806            ALOGV("kWhatReset");
807
808            mDeferredActions.push_back(
809                    new ShutdownDecoderAction(
810                        true /* audio */, true /* video */));
811
812            mDeferredActions.push_back(
813                    new SimpleAction(&NuPlayer::performReset));
814
815            processDeferredActions();
816            break;
817        }
818
819        case kWhatSeek:
820        {
821            int64_t seekTimeUs;
822            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
823
824            ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
825
826            mDeferredActions.push_back(
827                    new SimpleAction(&NuPlayer::performDecoderFlush));
828
829            mDeferredActions.push_back(new SeekAction(seekTimeUs));
830
831            processDeferredActions();
832            break;
833        }
834
835        case kWhatPause:
836        {
837            CHECK(mRenderer != NULL);
838            mSource->pause();
839            mRenderer->pause();
840            break;
841        }
842
843        case kWhatResume:
844        {
845            CHECK(mRenderer != NULL);
846            mSource->resume();
847            mRenderer->resume();
848            break;
849        }
850
851        case kWhatSourceNotify:
852        {
853            onSourceNotify(msg);
854            break;
855        }
856
857        default:
858            TRESPASS();
859            break;
860    }
861}
862
863void NuPlayer::finishFlushIfPossible() {
864    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
865        return;
866    }
867
868    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
869        return;
870    }
871
872    ALOGV("both audio and video are flushed now.");
873
874    if (mTimeDiscontinuityPending) {
875        mRenderer->signalTimeDiscontinuity();
876        mTimeDiscontinuityPending = false;
877    }
878
879    if (mAudioDecoder != NULL) {
880        mAudioDecoder->signalResume();
881    }
882
883    if (mVideoDecoder != NULL) {
884        mVideoDecoder->signalResume();
885    }
886
887    mFlushingAudio = NONE;
888    mFlushingVideo = NONE;
889
890    processDeferredActions();
891}
892
893void NuPlayer::postScanSources() {
894    if (mScanSourcesPending) {
895        return;
896    }
897
898    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
899    msg->setInt32("generation", mScanSourcesGeneration);
900    msg->post();
901
902    mScanSourcesPending = true;
903}
904
905status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
906    if (*decoder != NULL) {
907        return OK;
908    }
909
910    sp<AMessage> format = mSource->getFormat(audio);
911
912    if (format == NULL) {
913        return -EWOULDBLOCK;
914    }
915
916    if (!audio) {
917        AString mime;
918        CHECK(format->findString("mime", &mime));
919        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
920    }
921
922    sp<AMessage> notify =
923        new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
924                     id());
925
926    *decoder = audio ? new Decoder(notify) :
927                       new Decoder(notify, mNativeWindow);
928    looper()->registerHandler(*decoder);
929
930    (*decoder)->configure(format);
931
932    return OK;
933}
934
935status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
936    sp<AMessage> reply;
937    CHECK(msg->findMessage("reply", &reply));
938
939    if ((audio && IsFlushingState(mFlushingAudio))
940            || (!audio && IsFlushingState(mFlushingVideo))) {
941        reply->setInt32("err", INFO_DISCONTINUITY);
942        reply->post();
943        return OK;
944    }
945
946    sp<ABuffer> accessUnit;
947
948    bool dropAccessUnit;
949    do {
950        status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
951
952        if (err == -EWOULDBLOCK) {
953            return err;
954        } else if (err != OK) {
955            if (err == INFO_DISCONTINUITY) {
956                int32_t type;
957                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
958
959                bool formatChange =
960                    (audio &&
961                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
962                    || (!audio &&
963                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
964
965                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
966
967                ALOGI("%s discontinuity (formatChange=%d, time=%d)",
968                     audio ? "audio" : "video", formatChange, timeChange);
969
970                if (audio) {
971                    mSkipRenderingAudioUntilMediaTimeUs = -1;
972                } else {
973                    mSkipRenderingVideoUntilMediaTimeUs = -1;
974                }
975
976                if (timeChange) {
977                    sp<AMessage> extra;
978                    if (accessUnit->meta()->findMessage("extra", &extra)
979                            && extra != NULL) {
980                        int64_t resumeAtMediaTimeUs;
981                        if (extra->findInt64(
982                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
983                            ALOGI("suppressing rendering of %s until %lld us",
984                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
985
986                            if (audio) {
987                                mSkipRenderingAudioUntilMediaTimeUs =
988                                    resumeAtMediaTimeUs;
989                            } else {
990                                mSkipRenderingVideoUntilMediaTimeUs =
991                                    resumeAtMediaTimeUs;
992                            }
993                        }
994                    }
995                }
996
997                mTimeDiscontinuityPending =
998                    mTimeDiscontinuityPending || timeChange;
999
1000                if (formatChange || timeChange) {
1001                    if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
1002                        // And we'll resume scanning sources once we're done
1003                        // flushing.
1004                        mDeferredActions.push_front(
1005                                new SimpleAction(
1006                                    &NuPlayer::performScanSources));
1007                    }
1008
1009                    sp<AMessage> newFormat = mSource->getFormat(audio);
1010                    sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder;
1011                    if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) {
1012                        flushDecoder(audio, /* needShutdown = */ true);
1013                    } else {
1014                        flushDecoder(audio, /* needShutdown = */ false);
1015                        err = OK;
1016                    }
1017                } else {
1018                    // This stream is unaffected by the discontinuity
1019
1020                    if (audio) {
1021                        mFlushingAudio = FLUSHED;
1022                    } else {
1023                        mFlushingVideo = FLUSHED;
1024                    }
1025
1026                    finishFlushIfPossible();
1027
1028                    return -EWOULDBLOCK;
1029                }
1030            }
1031
1032            reply->setInt32("err", err);
1033            reply->post();
1034            return OK;
1035        }
1036
1037        if (!audio) {
1038            ++mNumFramesTotal;
1039        }
1040
1041        dropAccessUnit = false;
1042        if (!audio
1043                && mVideoLateByUs > 100000ll
1044                && mVideoIsAVC
1045                && !IsAVCReferenceFrame(accessUnit)) {
1046            dropAccessUnit = true;
1047            ++mNumFramesDropped;
1048        }
1049    } while (dropAccessUnit);
1050
1051    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
1052
1053#if 0
1054    int64_t mediaTimeUs;
1055    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
1056    ALOGV("feeding %s input buffer at media time %.2f secs",
1057         audio ? "audio" : "video",
1058         mediaTimeUs / 1E6);
1059#endif
1060
1061    reply->setBuffer("buffer", accessUnit);
1062    reply->post();
1063
1064    return OK;
1065}
1066
1067void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
1068    // ALOGV("renderBuffer %s", audio ? "audio" : "video");
1069
1070    sp<AMessage> reply;
1071    CHECK(msg->findMessage("reply", &reply));
1072
1073    if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
1074        // We're currently attempting to flush the decoder, in order
1075        // to complete this, the decoder wants all its buffers back,
1076        // so we don't want any output buffers it sent us (from before
1077        // we initiated the flush) to be stuck in the renderer's queue.
1078
1079        ALOGV("we're still flushing the %s decoder, sending its output buffer"
1080             " right back.", audio ? "audio" : "video");
1081
1082        reply->post();
1083        return;
1084    }
1085
1086    sp<ABuffer> buffer;
1087    CHECK(msg->findBuffer("buffer", &buffer));
1088
1089    int64_t &skipUntilMediaTimeUs =
1090        audio
1091            ? mSkipRenderingAudioUntilMediaTimeUs
1092            : mSkipRenderingVideoUntilMediaTimeUs;
1093
1094    if (skipUntilMediaTimeUs >= 0) {
1095        int64_t mediaTimeUs;
1096        CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1097
1098        if (mediaTimeUs < skipUntilMediaTimeUs) {
1099            ALOGV("dropping %s buffer at time %lld as requested.",
1100                 audio ? "audio" : "video",
1101                 mediaTimeUs);
1102
1103            reply->post();
1104            return;
1105        }
1106
1107        skipUntilMediaTimeUs = -1;
1108    }
1109
1110    mRenderer->queueBuffer(audio, buffer, reply);
1111}
1112
1113void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
1114    if (mDriver == NULL) {
1115        return;
1116    }
1117
1118    sp<NuPlayerDriver> driver = mDriver.promote();
1119
1120    if (driver == NULL) {
1121        return;
1122    }
1123
1124    driver->notifyListener(msg, ext1, ext2, in);
1125}
1126
1127void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
1128    ALOGV("[%s] flushDecoder needShutdown=%d",
1129          audio ? "audio" : "video", needShutdown);
1130
1131    if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
1132        ALOGI("flushDecoder %s without decoder present",
1133             audio ? "audio" : "video");
1134    }
1135
1136    // Make sure we don't continue to scan sources until we finish flushing.
1137    ++mScanSourcesGeneration;
1138    mScanSourcesPending = false;
1139
1140    (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1141    mRenderer->flush(audio);
1142
1143    FlushStatus newStatus =
1144        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1145
1146    if (audio) {
1147        CHECK(mFlushingAudio == NONE
1148                || mFlushingAudio == AWAITING_DISCONTINUITY);
1149
1150        mFlushingAudio = newStatus;
1151
1152        if (mFlushingVideo == NONE) {
1153            mFlushingVideo = (mVideoDecoder != NULL)
1154                ? AWAITING_DISCONTINUITY
1155                : FLUSHED;
1156        }
1157    } else {
1158        CHECK(mFlushingVideo == NONE
1159                || mFlushingVideo == AWAITING_DISCONTINUITY);
1160
1161        mFlushingVideo = newStatus;
1162
1163        if (mFlushingAudio == NONE) {
1164            mFlushingAudio = (mAudioDecoder != NULL)
1165                ? AWAITING_DISCONTINUITY
1166                : FLUSHED;
1167        }
1168    }
1169}
1170
1171sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1172    sp<MetaData> meta = getFormatMeta(audio);
1173
1174    if (meta == NULL) {
1175        return NULL;
1176    }
1177
1178    sp<AMessage> msg = new AMessage;
1179
1180    if(convertMetaDataToMessage(meta, &msg) == OK) {
1181        return msg;
1182    }
1183    return NULL;
1184}
1185
1186status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1187    mVideoScalingMode = mode;
1188    if (mNativeWindow != NULL) {
1189        status_t ret = native_window_set_scaling_mode(
1190                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1191        if (ret != OK) {
1192            ALOGE("Failed to set scaling mode (%d): %s",
1193                -ret, strerror(-ret));
1194            return ret;
1195        }
1196    }
1197    return OK;
1198}
1199
1200status_t NuPlayer::getTrackInfo(Parcel* reply) const {
1201    sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
1202    msg->setPointer("reply", reply);
1203
1204    sp<AMessage> response;
1205    status_t err = msg->postAndAwaitResponse(&response);
1206    return err;
1207}
1208
1209status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
1210    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
1211    msg->setSize("trackIndex", trackIndex);
1212    msg->setInt32("select", select);
1213
1214    sp<AMessage> response;
1215    status_t err = msg->postAndAwaitResponse(&response);
1216
1217    return err;
1218}
1219
1220void NuPlayer::schedulePollDuration() {
1221    sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1222    msg->setInt32("generation", mPollDurationGeneration);
1223    msg->post();
1224}
1225
1226void NuPlayer::cancelPollDuration() {
1227    ++mPollDurationGeneration;
1228}
1229
1230void NuPlayer::processDeferredActions() {
1231    while (!mDeferredActions.empty()) {
1232        // We won't execute any deferred actions until we're no longer in
1233        // an intermediate state, i.e. one more more decoders are currently
1234        // flushing or shutting down.
1235
1236        if (mRenderer != NULL) {
1237            // There's an edge case where the renderer owns all output
1238            // buffers and is paused, therefore the decoder will not read
1239            // more input data and will never encounter the matching
1240            // discontinuity. To avoid this, we resume the renderer.
1241
1242            if (mFlushingAudio == AWAITING_DISCONTINUITY
1243                    || mFlushingVideo == AWAITING_DISCONTINUITY) {
1244                mRenderer->resume();
1245            }
1246        }
1247
1248        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1249            // We're currently flushing, postpone the reset until that's
1250            // completed.
1251
1252            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1253                  mFlushingAudio, mFlushingVideo);
1254
1255            break;
1256        }
1257
1258        sp<Action> action = *mDeferredActions.begin();
1259        mDeferredActions.erase(mDeferredActions.begin());
1260
1261        action->execute(this);
1262    }
1263}
1264
1265void NuPlayer::performSeek(int64_t seekTimeUs) {
1266    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1267          seekTimeUs,
1268          seekTimeUs / 1E6);
1269
1270    mSource->seekTo(seekTimeUs);
1271
1272    if (mDriver != NULL) {
1273        sp<NuPlayerDriver> driver = mDriver.promote();
1274        if (driver != NULL) {
1275            driver->notifyPosition(seekTimeUs);
1276            driver->notifySeekComplete();
1277        }
1278    }
1279
1280    // everything's flushed, continue playback.
1281}
1282
1283void NuPlayer::performDecoderFlush() {
1284    ALOGV("performDecoderFlush");
1285
1286    if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1287        return;
1288    }
1289
1290    mTimeDiscontinuityPending = true;
1291
1292    if (mAudioDecoder != NULL) {
1293        flushDecoder(true /* audio */, false /* needShutdown */);
1294    }
1295
1296    if (mVideoDecoder != NULL) {
1297        flushDecoder(false /* audio */, false /* needShutdown */);
1298    }
1299}
1300
1301void NuPlayer::performDecoderShutdown(bool audio, bool video) {
1302    ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video);
1303
1304    if ((!audio || mAudioDecoder == NULL)
1305            && (!video || mVideoDecoder == NULL)) {
1306        return;
1307    }
1308
1309    mTimeDiscontinuityPending = true;
1310
1311    if (mFlushingAudio == NONE && (!audio || mAudioDecoder == NULL)) {
1312        mFlushingAudio = FLUSHED;
1313    }
1314
1315    if (mFlushingVideo == NONE && (!video || mVideoDecoder == NULL)) {
1316        mFlushingVideo = FLUSHED;
1317    }
1318
1319    if (audio && mAudioDecoder != NULL) {
1320        flushDecoder(true /* audio */, true /* needShutdown */);
1321    }
1322
1323    if (video && mVideoDecoder != NULL) {
1324        flushDecoder(false /* audio */, true /* needShutdown */);
1325    }
1326}
1327
1328void NuPlayer::performReset() {
1329    ALOGV("performReset");
1330
1331    CHECK(mAudioDecoder == NULL);
1332    CHECK(mVideoDecoder == NULL);
1333
1334    cancelPollDuration();
1335
1336    ++mScanSourcesGeneration;
1337    mScanSourcesPending = false;
1338
1339    mRenderer.clear();
1340
1341    if (mSource != NULL) {
1342        mSource->stop();
1343
1344        looper()->unregisterHandler(mSource->id());
1345
1346        mSource.clear();
1347    }
1348
1349    if (mDriver != NULL) {
1350        sp<NuPlayerDriver> driver = mDriver.promote();
1351        if (driver != NULL) {
1352            driver->notifyResetComplete();
1353        }
1354    }
1355
1356    mStarted = false;
1357}
1358
1359void NuPlayer::performScanSources() {
1360    ALOGV("performScanSources");
1361
1362    if (!mStarted) {
1363        return;
1364    }
1365
1366    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1367        postScanSources();
1368    }
1369}
1370
1371void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1372    ALOGV("performSetSurface");
1373
1374    mNativeWindow = wrapper;
1375
1376    // XXX - ignore error from setVideoScalingMode for now
1377    setVideoScalingMode(mVideoScalingMode);
1378
1379    if (mDriver != NULL) {
1380        sp<NuPlayerDriver> driver = mDriver.promote();
1381        if (driver != NULL) {
1382            driver->notifySetSurfaceComplete();
1383        }
1384    }
1385}
1386
1387void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1388    int32_t what;
1389    CHECK(msg->findInt32("what", &what));
1390
1391    switch (what) {
1392        case Source::kWhatPrepared:
1393        {
1394            if (mSource == NULL) {
1395                // This is a stale notification from a source that was
1396                // asynchronously preparing when the client called reset().
1397                // We handled the reset, the source is gone.
1398                break;
1399            }
1400
1401            int32_t err;
1402            CHECK(msg->findInt32("err", &err));
1403
1404            sp<NuPlayerDriver> driver = mDriver.promote();
1405            if (driver != NULL) {
1406                driver->notifyPrepareCompleted(err);
1407            }
1408
1409            int64_t durationUs;
1410            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
1411                sp<NuPlayerDriver> driver = mDriver.promote();
1412                if (driver != NULL) {
1413                    driver->notifyDuration(durationUs);
1414                }
1415            }
1416            break;
1417        }
1418
1419        case Source::kWhatFlagsChanged:
1420        {
1421            uint32_t flags;
1422            CHECK(msg->findInt32("flags", (int32_t *)&flags));
1423
1424            sp<NuPlayerDriver> driver = mDriver.promote();
1425            if (driver != NULL) {
1426                driver->notifyFlagsChanged(flags);
1427            }
1428
1429            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1430                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1431                cancelPollDuration();
1432            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1433                    && (flags & Source::FLAG_DYNAMIC_DURATION)
1434                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1435                schedulePollDuration();
1436            }
1437
1438            mSourceFlags = flags;
1439            break;
1440        }
1441
1442        case Source::kWhatVideoSizeChanged:
1443        {
1444            int32_t width, height;
1445            CHECK(msg->findInt32("width", &width));
1446            CHECK(msg->findInt32("height", &height));
1447
1448            notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
1449            break;
1450        }
1451
1452        case Source::kWhatBufferingStart:
1453        {
1454            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1455            break;
1456        }
1457
1458        case Source::kWhatBufferingEnd:
1459        {
1460            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1461            break;
1462        }
1463
1464        case Source::kWhatSubtitleData:
1465        {
1466            sp<ABuffer> buffer;
1467            CHECK(msg->findBuffer("buffer", &buffer));
1468
1469            int32_t trackIndex;
1470            int64_t timeUs, durationUs;
1471            CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
1472            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1473            CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
1474
1475            Parcel in;
1476            in.writeInt32(trackIndex);
1477            in.writeInt64(timeUs);
1478            in.writeInt64(durationUs);
1479            in.writeInt32(buffer->size());
1480            in.writeInt32(buffer->size());
1481            in.write(buffer->data(), buffer->size());
1482
1483            notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
1484            break;
1485        }
1486
1487        case Source::kWhatQueueDecoderShutdown:
1488        {
1489            int32_t audio, video;
1490            CHECK(msg->findInt32("audio", &audio));
1491            CHECK(msg->findInt32("video", &video));
1492
1493            sp<AMessage> reply;
1494            CHECK(msg->findMessage("reply", &reply));
1495
1496            queueDecoderShutdown(audio, video, reply);
1497            break;
1498        }
1499
1500        default:
1501            TRESPASS();
1502    }
1503}
1504
1505////////////////////////////////////////////////////////////////////////////////
1506
1507void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
1508    sp<AMessage> notify = dupNotify();
1509    notify->setInt32("what", kWhatFlagsChanged);
1510    notify->setInt32("flags", flags);
1511    notify->post();
1512}
1513
1514void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
1515    sp<AMessage> notify = dupNotify();
1516    notify->setInt32("what", kWhatVideoSizeChanged);
1517    notify->setInt32("width", width);
1518    notify->setInt32("height", height);
1519    notify->post();
1520}
1521
1522void NuPlayer::Source::notifyPrepared(status_t err) {
1523    sp<AMessage> notify = dupNotify();
1524    notify->setInt32("what", kWhatPrepared);
1525    notify->setInt32("err", err);
1526    notify->post();
1527}
1528
1529void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
1530    TRESPASS();
1531}
1532
1533void NuPlayer::queueDecoderShutdown(
1534        bool audio, bool video, const sp<AMessage> &reply) {
1535    ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
1536
1537    mDeferredActions.push_back(
1538            new ShutdownDecoderAction(audio, video));
1539
1540    mDeferredActions.push_back(
1541            new SimpleAction(&NuPlayer::performScanSources));
1542
1543    mDeferredActions.push_back(new PostMessageAction(reply));
1544
1545    processDeferredActions();
1546}
1547
1548}  // namespace android
1549