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