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