NuPlayer.cpp revision 7e9f7f7a9fb6c5d93fc9163e32936f3ea284caad
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            if (mSource != NULL) {
988                mSource->pause();
989            } else {
990                ALOGW("pause called when source is gone or not set");
991            }
992            if (mRenderer != NULL) {
993                mRenderer->pause();
994            } else {
995                ALOGW("pause called when renderer is gone or not set");
996            }
997            break;
998        }
999
1000        case kWhatResume:
1001        {
1002            if (mSource != NULL) {
1003                mSource->resume();
1004            } else {
1005                ALOGW("resume called when source is gone or not set");
1006            }
1007            if (mRenderer != NULL) {
1008                mRenderer->resume();
1009            } else {
1010                ALOGW("resume called when renderer is gone or not set");
1011            }
1012            break;
1013        }
1014
1015        case kWhatSourceNotify:
1016        {
1017            onSourceNotify(msg);
1018            break;
1019        }
1020
1021        case kWhatClosedCaptionNotify:
1022        {
1023            onClosedCaptionNotify(msg);
1024            break;
1025        }
1026
1027        default:
1028            TRESPASS();
1029            break;
1030    }
1031}
1032
1033void NuPlayer::finishFlushIfPossible() {
1034    if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1035            && mFlushingAudio != SHUT_DOWN) {
1036        return;
1037    }
1038
1039    if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1040            && mFlushingVideo != SHUT_DOWN) {
1041        return;
1042    }
1043
1044    ALOGV("both audio and video are flushed now.");
1045
1046    mPendingAudioAccessUnit.clear();
1047    mAggregateBuffer.clear();
1048
1049    if (mTimeDiscontinuityPending) {
1050        mRenderer->signalTimeDiscontinuity();
1051        mTimeDiscontinuityPending = false;
1052    }
1053
1054    if (mAudioDecoder != NULL && mFlushingAudio == FLUSHED) {
1055        mAudioDecoder->signalResume();
1056    }
1057
1058    if (mVideoDecoder != NULL && mFlushingVideo == FLUSHED) {
1059        mVideoDecoder->signalResume();
1060    }
1061
1062    mFlushingAudio = NONE;
1063    mFlushingVideo = NONE;
1064
1065    processDeferredActions();
1066}
1067
1068void NuPlayer::postScanSources() {
1069    if (mScanSourcesPending) {
1070        return;
1071    }
1072
1073    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
1074    msg->setInt32("generation", mScanSourcesGeneration);
1075    msg->post();
1076
1077    mScanSourcesPending = true;
1078}
1079
1080void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
1081    ALOGV("openAudioSink: offloadOnly(%d) mOffloadAudio(%d)",
1082            offloadOnly, mOffloadAudio);
1083    bool audioSinkChanged = false;
1084
1085    int32_t numChannels;
1086    CHECK(format->findInt32("channel-count", &numChannels));
1087
1088    int32_t channelMask;
1089    if (!format->findInt32("channel-mask", &channelMask)) {
1090        // signal to the AudioSink to derive the mask from count.
1091        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
1092    }
1093
1094    int32_t sampleRate;
1095    CHECK(format->findInt32("sample-rate", &sampleRate));
1096
1097    uint32_t flags;
1098    int64_t durationUs;
1099    // FIXME: we should handle the case where the video decoder
1100    // is created after we receive the format change indication.
1101    // Current code will just make that we select deep buffer
1102    // with video which should not be a problem as it should
1103    // not prevent from keeping A/V sync.
1104    if (mVideoDecoder == NULL &&
1105            mSource->getDuration(&durationUs) == OK &&
1106            durationUs
1107                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
1108        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1109    } else {
1110        flags = AUDIO_OUTPUT_FLAG_NONE;
1111    }
1112
1113    if (mOffloadAudio) {
1114        audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
1115        AString mime;
1116        CHECK(format->findString("mime", &mime));
1117        status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
1118
1119        if (err != OK) {
1120            ALOGE("Couldn't map mime \"%s\" to a valid "
1121                    "audio_format", mime.c_str());
1122            mOffloadAudio = false;
1123        } else {
1124            ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
1125                    mime.c_str(), audioFormat);
1126
1127            int avgBitRate = -1;
1128            format->findInt32("bit-rate", &avgBitRate);
1129
1130            int32_t aacProfile = -1;
1131            if (audioFormat == AUDIO_FORMAT_AAC
1132                    && format->findInt32("aac-profile", &aacProfile)) {
1133                // Redefine AAC format as per aac profile
1134                mapAACProfileToAudioFormat(
1135                        audioFormat,
1136                        aacProfile);
1137            }
1138
1139            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
1140            offloadInfo.duration_us = -1;
1141            format->findInt64(
1142                    "durationUs", &offloadInfo.duration_us);
1143            offloadInfo.sample_rate = sampleRate;
1144            offloadInfo.channel_mask = channelMask;
1145            offloadInfo.format = audioFormat;
1146            offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
1147            offloadInfo.bit_rate = avgBitRate;
1148            offloadInfo.has_video = (mVideoDecoder != NULL);
1149            offloadInfo.is_streaming = true;
1150
1151            if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
1152                ALOGV("openAudioSink: no change in offload mode");
1153                return;  // no change from previous configuration, everything ok.
1154            }
1155            ALOGV("openAudioSink: try to open AudioSink in offload mode");
1156            flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
1157            flags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1158            audioSinkChanged = true;
1159            mAudioSink->close();
1160            err = mAudioSink->open(
1161                    sampleRate,
1162                    numChannels,
1163                    (audio_channel_mask_t)channelMask,
1164                    audioFormat,
1165                    8 /* bufferCount */,
1166                    &NuPlayer::Renderer::AudioSinkCallback,
1167                    mRenderer.get(),
1168                    (audio_output_flags_t)flags,
1169                    &offloadInfo);
1170
1171            if (err == OK) {
1172                // If the playback is offloaded to h/w, we pass
1173                // the HAL some metadata information.
1174                // We don't want to do this for PCM because it
1175                // will be going through the AudioFlinger mixer
1176                // before reaching the hardware.
1177                sp<MetaData> audioMeta =
1178                        mSource->getFormatMeta(true /* audio */);
1179                sendMetaDataToHal(mAudioSink, audioMeta);
1180                mCurrentOffloadInfo = offloadInfo;
1181                err = mAudioSink->start();
1182                ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
1183            }
1184            if (err != OK) {
1185                // Clean up, fall back to non offload mode.
1186                mAudioSink->close();
1187                mRenderer->signalDisableOffloadAudio();
1188                mOffloadAudio = false;
1189                mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1190                ALOGV("openAudioSink: offload failed");
1191            }
1192        }
1193    }
1194    if (!offloadOnly && !mOffloadAudio) {
1195        flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
1196        ALOGV("openAudioSink: open AudioSink in NON-offload mode");
1197
1198        audioSinkChanged = true;
1199        mAudioSink->close();
1200        mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1201        CHECK_EQ(mAudioSink->open(
1202                    sampleRate,
1203                    numChannels,
1204                    (audio_channel_mask_t)channelMask,
1205                    AUDIO_FORMAT_PCM_16_BIT,
1206                    8 /* bufferCount */,
1207                    NULL,
1208                    NULL,
1209                    (audio_output_flags_t)flags),
1210                 (status_t)OK);
1211        mAudioSink->start();
1212    }
1213    if (audioSinkChanged) {
1214        mRenderer->signalAudioSinkChanged();
1215    }
1216}
1217
1218void NuPlayer::closeAudioSink() {
1219    mAudioSink->close();
1220    mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1221}
1222
1223status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
1224    if (*decoder != NULL) {
1225        return OK;
1226    }
1227
1228    sp<AMessage> format = mSource->getFormat(audio);
1229
1230    if (format == NULL) {
1231        return -EWOULDBLOCK;
1232    }
1233
1234    if (!audio) {
1235        AString mime;
1236        CHECK(format->findString("mime", &mime));
1237        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
1238
1239        sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
1240        mCCDecoder = new CCDecoder(ccNotify);
1241
1242        if (mSourceFlags & Source::FLAG_SECURE) {
1243            format->setInt32("secure", true);
1244        }
1245    }
1246
1247    if (audio) {
1248        sp<AMessage> notify = new AMessage(kWhatAudioNotify, id());
1249        ++mAudioDecoderGeneration;
1250        notify->setInt32("generation", mAudioDecoderGeneration);
1251
1252        if (mOffloadAudio) {
1253            *decoder = new DecoderPassThrough(notify);
1254        } else {
1255            *decoder = new Decoder(notify);
1256        }
1257    } else {
1258        sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());
1259        ++mVideoDecoderGeneration;
1260        notify->setInt32("generation", mVideoDecoderGeneration);
1261
1262        *decoder = new Decoder(notify, mNativeWindow);
1263    }
1264    (*decoder)->init();
1265    (*decoder)->configure(format);
1266
1267    // allocate buffers to decrypt widevine source buffers
1268    if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1269        Vector<sp<ABuffer> > inputBufs;
1270        CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1271
1272        Vector<MediaBuffer *> mediaBufs;
1273        for (size_t i = 0; i < inputBufs.size(); i++) {
1274            const sp<ABuffer> &buffer = inputBufs[i];
1275            MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1276            mediaBufs.push(mbuf);
1277        }
1278
1279        status_t err = mSource->setBuffers(audio, mediaBufs);
1280        if (err != OK) {
1281            for (size_t i = 0; i < mediaBufs.size(); ++i) {
1282                mediaBufs[i]->release();
1283            }
1284            mediaBufs.clear();
1285            ALOGE("Secure source didn't support secure mediaBufs.");
1286            return err;
1287        }
1288    }
1289    return OK;
1290}
1291
1292status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
1293    sp<AMessage> reply;
1294    CHECK(msg->findMessage("reply", &reply));
1295
1296    if ((audio && mFlushingAudio != NONE)
1297            || (!audio && mFlushingVideo != NONE)
1298            || mSource == NULL) {
1299        reply->setInt32("err", INFO_DISCONTINUITY);
1300        reply->post();
1301        return OK;
1302    }
1303
1304    sp<ABuffer> accessUnit;
1305
1306    // Aggregate smaller buffers into a larger buffer.
1307    // The goal is to reduce power consumption.
1308    // Note this will not work if the decoder requires one frame per buffer.
1309    bool doBufferAggregation = (audio && mOffloadAudio);
1310    bool needMoreData = false;
1311
1312    bool dropAccessUnit;
1313    do {
1314        status_t err;
1315        // Did we save an accessUnit earlier because of a discontinuity?
1316        if (audio && (mPendingAudioAccessUnit != NULL)) {
1317            accessUnit = mPendingAudioAccessUnit;
1318            mPendingAudioAccessUnit.clear();
1319            err = mPendingAudioErr;
1320            ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit");
1321        } else {
1322            err = mSource->dequeueAccessUnit(audio, &accessUnit);
1323        }
1324
1325        if (err == -EWOULDBLOCK) {
1326            return err;
1327        } else if (err != OK) {
1328            if (err == INFO_DISCONTINUITY) {
1329                if (doBufferAggregation && (mAggregateBuffer != NULL)) {
1330                    // We already have some data so save this for later.
1331                    mPendingAudioErr = err;
1332                    mPendingAudioAccessUnit = accessUnit;
1333                    accessUnit.clear();
1334                    ALOGD("feedDecoderInputData() save discontinuity for later");
1335                    break;
1336                }
1337                int32_t type;
1338                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
1339
1340                bool formatChange =
1341                    (audio &&
1342                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
1343                    || (!audio &&
1344                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
1345
1346                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
1347
1348                ALOGI("%s discontinuity (formatChange=%d, time=%d)",
1349                     audio ? "audio" : "video", formatChange, timeChange);
1350
1351                if (audio) {
1352                    mSkipRenderingAudioUntilMediaTimeUs = -1;
1353                } else {
1354                    mSkipRenderingVideoUntilMediaTimeUs = -1;
1355                }
1356
1357                if (timeChange) {
1358                    sp<AMessage> extra;
1359                    if (accessUnit->meta()->findMessage("extra", &extra)
1360                            && extra != NULL) {
1361                        int64_t resumeAtMediaTimeUs;
1362                        if (extra->findInt64(
1363                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
1364                            ALOGI("suppressing rendering of %s until %lld us",
1365                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
1366
1367                            if (audio) {
1368                                mSkipRenderingAudioUntilMediaTimeUs =
1369                                    resumeAtMediaTimeUs;
1370                            } else {
1371                                mSkipRenderingVideoUntilMediaTimeUs =
1372                                    resumeAtMediaTimeUs;
1373                            }
1374                        }
1375                    }
1376                }
1377
1378                mTimeDiscontinuityPending =
1379                    mTimeDiscontinuityPending || timeChange;
1380
1381                bool seamlessFormatChange = false;
1382                sp<AMessage> newFormat = mSource->getFormat(audio);
1383                if (formatChange) {
1384                    seamlessFormatChange =
1385                        getDecoder(audio)->supportsSeamlessFormatChange(newFormat);
1386                    // treat seamless format change separately
1387                    formatChange = !seamlessFormatChange;
1388                }
1389                bool shutdownOrFlush = formatChange || timeChange;
1390
1391                // We want to queue up scan-sources only once per discontinuity.
1392                // We control this by doing it only if neither audio nor video are
1393                // flushing or shutting down.  (After handling 1st discontinuity, one
1394                // of the flushing states will not be NONE.)
1395                // No need to scan sources if this discontinuity does not result
1396                // in a flush or shutdown, as the flushing state will stay NONE.
1397                if (mFlushingAudio == NONE && mFlushingVideo == NONE &&
1398                        shutdownOrFlush) {
1399                    // And we'll resume scanning sources once we're done
1400                    // flushing.
1401                    mDeferredActions.push_front(
1402                            new SimpleAction(
1403                                &NuPlayer::performScanSources));
1404                }
1405
1406                if (formatChange /* not seamless */) {
1407                    // must change decoder
1408                    flushDecoder(audio, /* needShutdown = */ true);
1409                } else if (timeChange) {
1410                    // need to flush
1411                    flushDecoder(audio, /* needShutdown = */ false, newFormat);
1412                    err = OK;
1413                } else if (seamlessFormatChange) {
1414                    // reuse existing decoder and don't flush
1415                    updateDecoderFormatWithoutFlush(audio, newFormat);
1416                    err = OK;
1417                } else {
1418                    // This stream is unaffected by the discontinuity
1419                    return -EWOULDBLOCK;
1420                }
1421            }
1422
1423            reply->setInt32("err", err);
1424            reply->post();
1425            return OK;
1426        }
1427
1428        if (!audio) {
1429            ++mNumFramesTotal;
1430        }
1431
1432        dropAccessUnit = false;
1433        if (!audio
1434                && !(mSourceFlags & Source::FLAG_SECURE)
1435                && mVideoLateByUs > 100000ll
1436                && mVideoIsAVC
1437                && !IsAVCReferenceFrame(accessUnit)) {
1438            dropAccessUnit = true;
1439            ++mNumFramesDropped;
1440        }
1441
1442        size_t smallSize = accessUnit->size();
1443        needMoreData = false;
1444        if (doBufferAggregation && (mAggregateBuffer == NULL)
1445                // Don't bother if only room for a few small buffers.
1446                && (smallSize < (kAggregateBufferSizeBytes / 3))) {
1447            // Create a larger buffer for combining smaller buffers from the extractor.
1448            mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes);
1449            mAggregateBuffer->setRange(0, 0); // start empty
1450        }
1451
1452        if (doBufferAggregation && (mAggregateBuffer != NULL)) {
1453            int64_t timeUs;
1454            int64_t dummy;
1455            bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs);
1456            bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy);
1457            // Will the smaller buffer fit?
1458            size_t bigSize = mAggregateBuffer->size();
1459            size_t roomLeft = mAggregateBuffer->capacity() - bigSize;
1460            // Should we save this small buffer for the next big buffer?
1461            // If the first small buffer did not have a timestamp then save
1462            // any buffer that does have a timestamp until the next big buffer.
1463            if ((smallSize > roomLeft)
1464                || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) {
1465                mPendingAudioErr = err;
1466                mPendingAudioAccessUnit = accessUnit;
1467                accessUnit.clear();
1468            } else {
1469                // Grab time from first small buffer if available.
1470                if ((bigSize == 0) && smallTimestampValid) {
1471                    mAggregateBuffer->meta()->setInt64("timeUs", timeUs);
1472                }
1473                // Append small buffer to the bigger buffer.
1474                memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize);
1475                bigSize += smallSize;
1476                mAggregateBuffer->setRange(0, bigSize);
1477
1478                // Keep looping until we run out of room in the mAggregateBuffer.
1479                needMoreData = true;
1480
1481                ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu",
1482                        smallSize, bigSize, mAggregateBuffer->capacity());
1483            }
1484        }
1485    } while (dropAccessUnit || needMoreData);
1486
1487    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
1488
1489#if 0
1490    int64_t mediaTimeUs;
1491    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
1492    ALOGV("feeding %s input buffer at media time %.2f secs",
1493         audio ? "audio" : "video",
1494         mediaTimeUs / 1E6);
1495#endif
1496
1497    if (!audio) {
1498        mCCDecoder->decode(accessUnit);
1499    }
1500
1501    if (doBufferAggregation && (mAggregateBuffer != NULL)) {
1502        ALOGV("feedDecoderInputData() reply with aggregated buffer, %zu",
1503                mAggregateBuffer->size());
1504        reply->setBuffer("buffer", mAggregateBuffer);
1505        mAggregateBuffer.clear();
1506    } else {
1507        reply->setBuffer("buffer", accessUnit);
1508    }
1509
1510    reply->post();
1511
1512    return OK;
1513}
1514
1515void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
1516    // ALOGV("renderBuffer %s", audio ? "audio" : "video");
1517
1518    sp<AMessage> reply;
1519    CHECK(msg->findMessage("reply", &reply));
1520
1521    if ((audio && mFlushingAudio != NONE)
1522            || (!audio && mFlushingVideo != NONE)) {
1523        // We're currently attempting to flush the decoder, in order
1524        // to complete this, the decoder wants all its buffers back,
1525        // so we don't want any output buffers it sent us (from before
1526        // we initiated the flush) to be stuck in the renderer's queue.
1527
1528        ALOGV("we're still flushing the %s decoder, sending its output buffer"
1529             " right back.", audio ? "audio" : "video");
1530
1531        reply->post();
1532        return;
1533    }
1534
1535    sp<ABuffer> buffer;
1536    CHECK(msg->findBuffer("buffer", &buffer));
1537
1538    int64_t mediaTimeUs;
1539    CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1540
1541    int64_t &skipUntilMediaTimeUs =
1542        audio
1543            ? mSkipRenderingAudioUntilMediaTimeUs
1544            : mSkipRenderingVideoUntilMediaTimeUs;
1545
1546    if (skipUntilMediaTimeUs >= 0) {
1547
1548        if (mediaTimeUs < skipUntilMediaTimeUs) {
1549            ALOGV("dropping %s buffer at time %lld as requested.",
1550                 audio ? "audio" : "video",
1551                 mediaTimeUs);
1552
1553            reply->post();
1554            return;
1555        }
1556
1557        skipUntilMediaTimeUs = -1;
1558    }
1559
1560    if (!audio && mCCDecoder->isSelected()) {
1561        mCCDecoder->display(mediaTimeUs);
1562    }
1563
1564    mRenderer->queueBuffer(audio, buffer, reply);
1565}
1566
1567void NuPlayer::updateVideoSize(
1568        const sp<AMessage> &inputFormat,
1569        const sp<AMessage> &outputFormat) {
1570    if (inputFormat == NULL) {
1571        ALOGW("Unknown video size, reporting 0x0!");
1572        notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1573        return;
1574    }
1575
1576    int32_t displayWidth, displayHeight;
1577    int32_t cropLeft, cropTop, cropRight, cropBottom;
1578
1579    if (outputFormat != NULL) {
1580        int32_t width, height;
1581        CHECK(outputFormat->findInt32("width", &width));
1582        CHECK(outputFormat->findInt32("height", &height));
1583
1584        int32_t cropLeft, cropTop, cropRight, cropBottom;
1585        CHECK(outputFormat->findRect(
1586                    "crop",
1587                    &cropLeft, &cropTop, &cropRight, &cropBottom));
1588
1589        displayWidth = cropRight - cropLeft + 1;
1590        displayHeight = cropBottom - cropTop + 1;
1591
1592        ALOGV("Video output format changed to %d x %d "
1593             "(crop: %d x %d @ (%d, %d))",
1594             width, height,
1595             displayWidth,
1596             displayHeight,
1597             cropLeft, cropTop);
1598    } else {
1599        CHECK(inputFormat->findInt32("width", &displayWidth));
1600        CHECK(inputFormat->findInt32("height", &displayHeight));
1601
1602        ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1603    }
1604
1605    // Take into account sample aspect ratio if necessary:
1606    int32_t sarWidth, sarHeight;
1607    if (inputFormat->findInt32("sar-width", &sarWidth)
1608            && inputFormat->findInt32("sar-height", &sarHeight)) {
1609        ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1610
1611        displayWidth = (displayWidth * sarWidth) / sarHeight;
1612
1613        ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
1614    }
1615
1616    int32_t rotationDegrees;
1617    if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1618        rotationDegrees = 0;
1619    }
1620
1621    if (rotationDegrees == 90 || rotationDegrees == 270) {
1622        int32_t tmp = displayWidth;
1623        displayWidth = displayHeight;
1624        displayHeight = tmp;
1625    }
1626
1627    notifyListener(
1628            MEDIA_SET_VIDEO_SIZE,
1629            displayWidth,
1630            displayHeight);
1631}
1632
1633void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
1634    if (mDriver == NULL) {
1635        return;
1636    }
1637
1638    sp<NuPlayerDriver> driver = mDriver.promote();
1639
1640    if (driver == NULL) {
1641        return;
1642    }
1643
1644    driver->notifyListener(msg, ext1, ext2, in);
1645}
1646
1647void NuPlayer::flushDecoder(
1648        bool audio, bool needShutdown, const sp<AMessage> &newFormat) {
1649    ALOGV("[%s] flushDecoder needShutdown=%d",
1650          audio ? "audio" : "video", needShutdown);
1651
1652    const sp<Decoder> &decoder = getDecoder(audio);
1653    if (decoder == NULL) {
1654        ALOGI("flushDecoder %s without decoder present",
1655             audio ? "audio" : "video");
1656        return;
1657    }
1658
1659    // Make sure we don't continue to scan sources until we finish flushing.
1660    ++mScanSourcesGeneration;
1661    mScanSourcesPending = false;
1662
1663    decoder->signalFlush(newFormat);
1664    mRenderer->flush(audio);
1665
1666    FlushStatus newStatus =
1667        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1668
1669    if (audio) {
1670        ALOGE_IF(mFlushingAudio != NONE,
1671                "audio flushDecoder() is called in state %d", mFlushingAudio);
1672        mFlushingAudio = newStatus;
1673    } else {
1674        ALOGE_IF(mFlushingVideo != NONE,
1675                "video flushDecoder() is called in state %d", mFlushingVideo);
1676        mFlushingVideo = newStatus;
1677
1678        if (mCCDecoder != NULL) {
1679            mCCDecoder->flush();
1680        }
1681    }
1682}
1683
1684void NuPlayer::updateDecoderFormatWithoutFlush(
1685        bool audio, const sp<AMessage> &format) {
1686    ALOGV("[%s] updateDecoderFormatWithoutFlush", audio ? "audio" : "video");
1687
1688    const sp<Decoder> &decoder = getDecoder(audio);
1689    if (decoder == NULL) {
1690        ALOGI("updateDecoderFormatWithoutFlush %s without decoder present",
1691             audio ? "audio" : "video");
1692        return;
1693    }
1694
1695    decoder->signalUpdateFormat(format);
1696}
1697
1698void NuPlayer::queueDecoderShutdown(
1699        bool audio, bool video, const sp<AMessage> &reply) {
1700    ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
1701
1702    mDeferredActions.push_back(
1703            new ShutdownDecoderAction(audio, video));
1704
1705    mDeferredActions.push_back(
1706            new SimpleAction(&NuPlayer::performScanSources));
1707
1708    mDeferredActions.push_back(new PostMessageAction(reply));
1709
1710    processDeferredActions();
1711}
1712
1713status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1714    mVideoScalingMode = mode;
1715    if (mNativeWindow != NULL) {
1716        status_t ret = native_window_set_scaling_mode(
1717                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1718        if (ret != OK) {
1719            ALOGE("Failed to set scaling mode (%d): %s",
1720                -ret, strerror(-ret));
1721            return ret;
1722        }
1723    }
1724    return OK;
1725}
1726
1727status_t NuPlayer::getTrackInfo(Parcel* reply) const {
1728    sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
1729    msg->setPointer("reply", reply);
1730
1731    sp<AMessage> response;
1732    status_t err = msg->postAndAwaitResponse(&response);
1733    return err;
1734}
1735
1736status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
1737    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
1738    msg->setPointer("reply", reply);
1739    msg->setInt32("type", type);
1740
1741    sp<AMessage> response;
1742    status_t err = msg->postAndAwaitResponse(&response);
1743    if (err == OK && response != NULL) {
1744        CHECK(response->findInt32("err", &err));
1745    }
1746    return err;
1747}
1748
1749status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
1750    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
1751    msg->setSize("trackIndex", trackIndex);
1752    msg->setInt32("select", select);
1753
1754    sp<AMessage> response;
1755    status_t err = msg->postAndAwaitResponse(&response);
1756
1757    if (err != OK) {
1758        return err;
1759    }
1760
1761    if (!response->findInt32("err", &err)) {
1762        err = OK;
1763    }
1764
1765    return err;
1766}
1767
1768sp<MetaData> NuPlayer::getFileMeta() {
1769    return mSource->getFileFormatMeta();
1770}
1771
1772void NuPlayer::schedulePollDuration() {
1773    sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1774    msg->setInt32("generation", mPollDurationGeneration);
1775    msg->post();
1776}
1777
1778void NuPlayer::cancelPollDuration() {
1779    ++mPollDurationGeneration;
1780}
1781
1782void NuPlayer::processDeferredActions() {
1783    while (!mDeferredActions.empty()) {
1784        // We won't execute any deferred actions until we're no longer in
1785        // an intermediate state, i.e. one more more decoders are currently
1786        // flushing or shutting down.
1787
1788        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1789            // We're currently flushing, postpone the reset until that's
1790            // completed.
1791
1792            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1793                  mFlushingAudio, mFlushingVideo);
1794
1795            break;
1796        }
1797
1798        sp<Action> action = *mDeferredActions.begin();
1799        mDeferredActions.erase(mDeferredActions.begin());
1800
1801        action->execute(this);
1802    }
1803}
1804
1805void NuPlayer::performSeek(int64_t seekTimeUs) {
1806    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1807          seekTimeUs,
1808          seekTimeUs / 1E6);
1809
1810    if (mSource == NULL) {
1811        // This happens when reset occurs right before the loop mode
1812        // asynchronously seeks to the start of the stream.
1813        LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
1814                "mSource is NULL and decoders not NULL audio(%p) video(%p)",
1815                mAudioDecoder.get(), mVideoDecoder.get());
1816        return;
1817    }
1818    mSource->seekTo(seekTimeUs);
1819    ++mTimedTextGeneration;
1820
1821    if (mDriver != NULL) {
1822        sp<NuPlayerDriver> driver = mDriver.promote();
1823        if (driver != NULL) {
1824            driver->notifyPosition(seekTimeUs);
1825            driver->notifySeekComplete();
1826        }
1827    }
1828
1829    // everything's flushed, continue playback.
1830}
1831
1832void NuPlayer::performDecoderFlush() {
1833    ALOGV("performDecoderFlush");
1834
1835    if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1836        return;
1837    }
1838
1839    mTimeDiscontinuityPending = true;
1840
1841    if (mAudioDecoder != NULL) {
1842        flushDecoder(true /* audio */, false /* needShutdown */);
1843    }
1844
1845    if (mVideoDecoder != NULL) {
1846        flushDecoder(false /* audio */, false /* needShutdown */);
1847    }
1848}
1849
1850void NuPlayer::performDecoderShutdown(bool audio, bool video) {
1851    ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video);
1852
1853    if ((!audio || mAudioDecoder == NULL)
1854            && (!video || mVideoDecoder == NULL)) {
1855        return;
1856    }
1857
1858    mTimeDiscontinuityPending = true;
1859
1860    if (audio && mAudioDecoder != NULL) {
1861        flushDecoder(true /* audio */, true /* needShutdown */);
1862    }
1863
1864    if (video && mVideoDecoder != NULL) {
1865        flushDecoder(false /* audio */, true /* needShutdown */);
1866    }
1867}
1868
1869void NuPlayer::performReset() {
1870    ALOGV("performReset");
1871
1872    CHECK(mAudioDecoder == NULL);
1873    CHECK(mVideoDecoder == NULL);
1874
1875    cancelPollDuration();
1876
1877    ++mScanSourcesGeneration;
1878    mScanSourcesPending = false;
1879
1880    if (mRendererLooper != NULL) {
1881        if (mRenderer != NULL) {
1882            mRendererLooper->unregisterHandler(mRenderer->id());
1883        }
1884        mRendererLooper->stop();
1885        mRendererLooper.clear();
1886    }
1887    mRenderer.clear();
1888    ++mRendererGeneration;
1889
1890    if (mSource != NULL) {
1891        mSource->stop();
1892
1893        mSource.clear();
1894    }
1895
1896    if (mDriver != NULL) {
1897        sp<NuPlayerDriver> driver = mDriver.promote();
1898        if (driver != NULL) {
1899            driver->notifyResetComplete();
1900        }
1901    }
1902
1903    mStarted = false;
1904}
1905
1906void NuPlayer::performScanSources() {
1907    ALOGV("performScanSources");
1908
1909    if (!mStarted) {
1910        return;
1911    }
1912
1913    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1914        postScanSources();
1915    }
1916}
1917
1918void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1919    ALOGV("performSetSurface");
1920
1921    mNativeWindow = wrapper;
1922
1923    // XXX - ignore error from setVideoScalingMode for now
1924    setVideoScalingMode(mVideoScalingMode);
1925
1926    if (mDriver != NULL) {
1927        sp<NuPlayerDriver> driver = mDriver.promote();
1928        if (driver != NULL) {
1929            driver->notifySetSurfaceComplete();
1930        }
1931    }
1932}
1933
1934void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1935    int32_t what;
1936    CHECK(msg->findInt32("what", &what));
1937
1938    switch (what) {
1939        case Source::kWhatPrepared:
1940        {
1941            if (mSource == NULL) {
1942                // This is a stale notification from a source that was
1943                // asynchronously preparing when the client called reset().
1944                // We handled the reset, the source is gone.
1945                break;
1946            }
1947
1948            int32_t err;
1949            CHECK(msg->findInt32("err", &err));
1950
1951            sp<NuPlayerDriver> driver = mDriver.promote();
1952            if (driver != NULL) {
1953                // notify duration first, so that it's definitely set when
1954                // the app received the "prepare complete" callback.
1955                int64_t durationUs;
1956                if (mSource->getDuration(&durationUs) == OK) {
1957                    driver->notifyDuration(durationUs);
1958                }
1959                driver->notifyPrepareCompleted(err);
1960            }
1961
1962            break;
1963        }
1964
1965        case Source::kWhatFlagsChanged:
1966        {
1967            uint32_t flags;
1968            CHECK(msg->findInt32("flags", (int32_t *)&flags));
1969
1970            sp<NuPlayerDriver> driver = mDriver.promote();
1971            if (driver != NULL) {
1972                driver->notifyFlagsChanged(flags);
1973            }
1974
1975            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1976                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1977                cancelPollDuration();
1978            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1979                    && (flags & Source::FLAG_DYNAMIC_DURATION)
1980                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1981                schedulePollDuration();
1982            }
1983
1984            mSourceFlags = flags;
1985            break;
1986        }
1987
1988        case Source::kWhatVideoSizeChanged:
1989        {
1990            sp<AMessage> format;
1991            CHECK(msg->findMessage("format", &format));
1992
1993            updateVideoSize(format);
1994            break;
1995        }
1996
1997        case Source::kWhatBufferingUpdate:
1998        {
1999            int32_t percentage;
2000            CHECK(msg->findInt32("percentage", &percentage));
2001
2002            notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
2003            break;
2004        }
2005
2006        case Source::kWhatBufferingStart:
2007        {
2008            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
2009            break;
2010        }
2011
2012        case Source::kWhatBufferingEnd:
2013        {
2014            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
2015            break;
2016        }
2017
2018        case Source::kWhatSubtitleData:
2019        {
2020            sp<ABuffer> buffer;
2021            CHECK(msg->findBuffer("buffer", &buffer));
2022
2023            sendSubtitleData(buffer, 0 /* baseIndex */);
2024            break;
2025        }
2026
2027        case Source::kWhatTimedTextData:
2028        {
2029            int32_t generation;
2030            if (msg->findInt32("generation", &generation)
2031                    && generation != mTimedTextGeneration) {
2032                break;
2033            }
2034
2035            sp<ABuffer> buffer;
2036            CHECK(msg->findBuffer("buffer", &buffer));
2037
2038            sp<NuPlayerDriver> driver = mDriver.promote();
2039            if (driver == NULL) {
2040                break;
2041            }
2042
2043            int posMs;
2044            int64_t timeUs, posUs;
2045            driver->getCurrentPosition(&posMs);
2046            posUs = posMs * 1000;
2047            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2048
2049            if (posUs < timeUs) {
2050                if (!msg->findInt32("generation", &generation)) {
2051                    msg->setInt32("generation", mTimedTextGeneration);
2052                }
2053                msg->post(timeUs - posUs);
2054            } else {
2055                sendTimedTextData(buffer);
2056            }
2057            break;
2058        }
2059
2060        case Source::kWhatQueueDecoderShutdown:
2061        {
2062            int32_t audio, video;
2063            CHECK(msg->findInt32("audio", &audio));
2064            CHECK(msg->findInt32("video", &video));
2065
2066            sp<AMessage> reply;
2067            CHECK(msg->findMessage("reply", &reply));
2068
2069            queueDecoderShutdown(audio, video, reply);
2070            break;
2071        }
2072
2073        case Source::kWhatDrmNoLicense:
2074        {
2075            notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2076            break;
2077        }
2078
2079        default:
2080            TRESPASS();
2081    }
2082}
2083
2084void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2085    int32_t what;
2086    CHECK(msg->findInt32("what", &what));
2087
2088    switch (what) {
2089        case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2090        {
2091            sp<ABuffer> buffer;
2092            CHECK(msg->findBuffer("buffer", &buffer));
2093
2094            size_t inbandTracks = 0;
2095            if (mSource != NULL) {
2096                inbandTracks = mSource->getTrackCount();
2097            }
2098
2099            sendSubtitleData(buffer, inbandTracks);
2100            break;
2101        }
2102
2103        case NuPlayer::CCDecoder::kWhatTrackAdded:
2104        {
2105            notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2106
2107            break;
2108        }
2109
2110        default:
2111            TRESPASS();
2112    }
2113
2114
2115}
2116
2117void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2118    int32_t trackIndex;
2119    int64_t timeUs, durationUs;
2120    CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
2121    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2122    CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2123
2124    Parcel in;
2125    in.writeInt32(trackIndex + baseIndex);
2126    in.writeInt64(timeUs);
2127    in.writeInt64(durationUs);
2128    in.writeInt32(buffer->size());
2129    in.writeInt32(buffer->size());
2130    in.write(buffer->data(), buffer->size());
2131
2132    notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2133}
2134
2135void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2136    const void *data;
2137    size_t size = 0;
2138    int64_t timeUs;
2139    int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
2140
2141    AString mime;
2142    CHECK(buffer->meta()->findString("mime", &mime));
2143    CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2144
2145    data = buffer->data();
2146    size = buffer->size();
2147
2148    Parcel parcel;
2149    if (size > 0) {
2150        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2151        flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
2152        TextDescriptions::getParcelOfDescriptions(
2153                (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2154    }
2155
2156    if ((parcel.dataSize() > 0)) {
2157        notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2158    } else {  // send an empty timed text
2159        notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2160    }
2161}
2162////////////////////////////////////////////////////////////////////////////////
2163
2164sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
2165    sp<MetaData> meta = getFormatMeta(audio);
2166
2167    if (meta == NULL) {
2168        return NULL;
2169    }
2170
2171    sp<AMessage> msg = new AMessage;
2172
2173    if(convertMetaDataToMessage(meta, &msg) == OK) {
2174        return msg;
2175    }
2176    return NULL;
2177}
2178
2179void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
2180    sp<AMessage> notify = dupNotify();
2181    notify->setInt32("what", kWhatFlagsChanged);
2182    notify->setInt32("flags", flags);
2183    notify->post();
2184}
2185
2186void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
2187    sp<AMessage> notify = dupNotify();
2188    notify->setInt32("what", kWhatVideoSizeChanged);
2189    notify->setMessage("format", format);
2190    notify->post();
2191}
2192
2193void NuPlayer::Source::notifyPrepared(status_t err) {
2194    sp<AMessage> notify = dupNotify();
2195    notify->setInt32("what", kWhatPrepared);
2196    notify->setInt32("err", err);
2197    notify->post();
2198}
2199
2200void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
2201    TRESPASS();
2202}
2203
2204}  // namespace android
2205