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