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