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