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