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