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