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