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