NuPlayer.cpp revision da38df5f080eb62a06b22c5bada4357cf756255e
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 "NuPlayerDriver.h"
26#include "NuPlayerRenderer.h"
27#include "NuPlayerSource.h"
28#include "RTSPSource.h"
29#include "StreamingSource.h"
30#include "GenericSource.h"
31#include "mp4/MP4Source.h"
32
33#include "ATSParser.h"
34
35#include "SoftwareRenderer.h"
36
37#include <cutils/properties.h> // for property_get
38#include <media/stagefright/foundation/hexdump.h>
39#include <media/stagefright/foundation/ABuffer.h>
40#include <media/stagefright/foundation/ADebug.h>
41#include <media/stagefright/foundation/AMessage.h>
42#include <media/stagefright/ACodec.h>
43#include <media/stagefright/MediaDefs.h>
44#include <media/stagefright/MediaErrors.h>
45#include <media/stagefright/MetaData.h>
46#include <gui/IGraphicBufferProducer.h>
47
48#include "avc_utils.h"
49
50#include "ESDS.h"
51#include <media/stagefright/Utils.h>
52
53namespace android {
54
55struct NuPlayer::Action : public RefBase {
56    Action() {}
57
58    virtual void execute(NuPlayer *player) = 0;
59
60private:
61    DISALLOW_EVIL_CONSTRUCTORS(Action);
62};
63
64struct NuPlayer::SeekAction : public Action {
65    SeekAction(int64_t seekTimeUs)
66        : mSeekTimeUs(seekTimeUs) {
67    }
68
69    virtual void execute(NuPlayer *player) {
70        player->performSeek(mSeekTimeUs);
71    }
72
73private:
74    int64_t mSeekTimeUs;
75
76    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
77};
78
79struct NuPlayer::SetSurfaceAction : public Action {
80    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
81        : mWrapper(wrapper) {
82    }
83
84    virtual void execute(NuPlayer *player) {
85        player->performSetSurface(mWrapper);
86    }
87
88private:
89    sp<NativeWindowWrapper> mWrapper;
90
91    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
92};
93
94// Use this if there's no state necessary to save in order to execute
95// the action.
96struct NuPlayer::SimpleAction : public Action {
97    typedef void (NuPlayer::*ActionFunc)();
98
99    SimpleAction(ActionFunc func)
100        : mFunc(func) {
101    }
102
103    virtual void execute(NuPlayer *player) {
104        (player->*mFunc)();
105    }
106
107private:
108    ActionFunc mFunc;
109
110    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
111};
112
113////////////////////////////////////////////////////////////////////////////////
114
115NuPlayer::NuPlayer()
116    : mUIDValid(false),
117      mSourceFlags(0),
118      mVideoIsAVC(false),
119      mNeedsSwRenderer(false),
120      mAudioEOS(false),
121      mVideoEOS(false),
122      mScanSourcesPending(false),
123      mScanSourcesGeneration(0),
124      mPollDurationGeneration(0),
125      mTimeDiscontinuityPending(false),
126      mFlushingAudio(NONE),
127      mFlushingVideo(NONE),
128      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
129      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
130      mVideoLateByUs(0ll),
131      mNumFramesTotal(0ll),
132      mNumFramesDropped(0ll),
133      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
134      mStarted(false) {
135}
136
137NuPlayer::~NuPlayer() {
138}
139
140void NuPlayer::setUID(uid_t uid) {
141    mUIDValid = true;
142    mUID = uid;
143}
144
145void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
146    mDriver = driver;
147}
148
149void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
150    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
151
152    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
153
154    char prop[PROPERTY_VALUE_MAX];
155    if (property_get("media.stagefright.use-mp4source", prop, NULL)
156            && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
157        msg->setObject("source", new MP4Source(notify, source));
158    } else {
159        msg->setObject("source", new StreamingSource(notify, source));
160    }
161
162    msg->post();
163}
164
165static bool IsHTTPLiveURL(const char *url) {
166    if (!strncasecmp("http://", url, 7)
167            || !strncasecmp("https://", url, 8)
168            || !strncasecmp("file://", url, 7)) {
169        size_t len = strlen(url);
170        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
171            return true;
172        }
173
174        if (strstr(url,"m3u8")) {
175            return true;
176        }
177    }
178
179    return false;
180}
181
182void NuPlayer::setDataSourceAsync(
183        const char *url, const KeyedVector<String8, String8> *headers) {
184    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
185    size_t len = strlen(url);
186
187    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
188
189    sp<Source> source;
190    if (IsHTTPLiveURL(url)) {
191        source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
192    } else if (!strncasecmp(url, "rtsp://", 7)) {
193        source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
194    } else if ((!strncasecmp(url, "http://", 7)
195                || !strncasecmp(url, "https://", 8))
196                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
197                    || strstr(url, ".sdp?"))) {
198        source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
199    } else {
200        source = new GenericSource(notify, url, headers, mUIDValid, mUID);
201    }
202
203    msg->setObject("source", source);
204    msg->post();
205}
206
207void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
208    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
209
210    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
211
212    sp<Source> source = new GenericSource(notify, fd, offset, length);
213    msg->setObject("source", source);
214    msg->post();
215}
216
217void NuPlayer::prepareAsync() {
218    (new AMessage(kWhatPrepare, id()))->post();
219}
220
221void NuPlayer::setVideoSurfaceTextureAsync(
222        const sp<IGraphicBufferProducer> &bufferProducer) {
223    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
224
225    if (bufferProducer == NULL) {
226        msg->setObject("native-window", NULL);
227    } else {
228        msg->setObject(
229                "native-window",
230                new NativeWindowWrapper(
231                    new Surface(bufferProducer)));
232    }
233
234    msg->post();
235}
236
237void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
238    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
239    msg->setObject("sink", sink);
240    msg->post();
241}
242
243void NuPlayer::start() {
244    (new AMessage(kWhatStart, id()))->post();
245}
246
247void NuPlayer::pause() {
248    (new AMessage(kWhatPause, id()))->post();
249}
250
251void NuPlayer::resume() {
252    (new AMessage(kWhatResume, id()))->post();
253}
254
255void NuPlayer::resetAsync() {
256    (new AMessage(kWhatReset, id()))->post();
257}
258
259void NuPlayer::seekToAsync(int64_t seekTimeUs) {
260    sp<AMessage> msg = new AMessage(kWhatSeek, id());
261    msg->setInt64("seekTimeUs", seekTimeUs);
262    msg->post();
263}
264
265// static
266bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
267    switch (state) {
268        case FLUSHING_DECODER:
269            if (needShutdown != NULL) {
270                *needShutdown = false;
271            }
272            return true;
273
274        case FLUSHING_DECODER_SHUTDOWN:
275            if (needShutdown != NULL) {
276                *needShutdown = true;
277            }
278            return true;
279
280        default:
281            return false;
282    }
283}
284
285void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
286    switch (msg->what()) {
287        case kWhatSetDataSource:
288        {
289            ALOGV("kWhatSetDataSource");
290
291            CHECK(mSource == NULL);
292
293            sp<RefBase> obj;
294            CHECK(msg->findObject("source", &obj));
295
296            mSource = static_cast<Source *>(obj.get());
297
298            looper()->registerHandler(mSource);
299
300            CHECK(mDriver != NULL);
301            sp<NuPlayerDriver> driver = mDriver.promote();
302            if (driver != NULL) {
303                driver->notifySetDataSourceCompleted(OK);
304            }
305            break;
306        }
307
308        case kWhatPrepare:
309        {
310            mSource->prepareAsync();
311            break;
312        }
313
314        case kWhatPollDuration:
315        {
316            int32_t generation;
317            CHECK(msg->findInt32("generation", &generation));
318
319            if (generation != mPollDurationGeneration) {
320                // stale
321                break;
322            }
323
324            int64_t durationUs;
325            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
326                sp<NuPlayerDriver> driver = mDriver.promote();
327                if (driver != NULL) {
328                    driver->notifyDuration(durationUs);
329                }
330            }
331
332            msg->post(1000000ll);  // poll again in a second.
333            break;
334        }
335
336        case kWhatSetVideoNativeWindow:
337        {
338            ALOGV("kWhatSetVideoNativeWindow");
339
340            mDeferredActions.push_back(
341                    new SimpleAction(&NuPlayer::performDecoderShutdown));
342
343            sp<RefBase> obj;
344            CHECK(msg->findObject("native-window", &obj));
345
346            mDeferredActions.push_back(
347                    new SetSurfaceAction(
348                        static_cast<NativeWindowWrapper *>(obj.get())));
349
350            if (obj != NULL) {
351                // If there is a new surface texture, instantiate decoders
352                // again if possible.
353                mDeferredActions.push_back(
354                        new SimpleAction(&NuPlayer::performScanSources));
355            }
356
357            processDeferredActions();
358            break;
359        }
360
361        case kWhatSetAudioSink:
362        {
363            ALOGV("kWhatSetAudioSink");
364
365            sp<RefBase> obj;
366            CHECK(msg->findObject("sink", &obj));
367
368            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
369            break;
370        }
371
372        case kWhatStart:
373        {
374            ALOGV("kWhatStart");
375
376            mVideoIsAVC = false;
377            mNeedsSwRenderer = false;
378            mAudioEOS = false;
379            mVideoEOS = false;
380            mSkipRenderingAudioUntilMediaTimeUs = -1;
381            mSkipRenderingVideoUntilMediaTimeUs = -1;
382            mVideoLateByUs = 0;
383            mNumFramesTotal = 0;
384            mNumFramesDropped = 0;
385            mStarted = true;
386
387            mSource->start();
388
389            uint32_t flags = 0;
390
391            if (mSource->isRealTime()) {
392                flags |= Renderer::FLAG_REAL_TIME;
393            }
394
395            mRenderer = new Renderer(
396                    mAudioSink,
397                    new AMessage(kWhatRendererNotify, id()),
398                    flags);
399
400            looper()->registerHandler(mRenderer);
401
402            postScanSources();
403            break;
404        }
405
406        case kWhatScanSources:
407        {
408            int32_t generation;
409            CHECK(msg->findInt32("generation", &generation));
410            if (generation != mScanSourcesGeneration) {
411                // Drop obsolete msg.
412                break;
413            }
414
415            mScanSourcesPending = false;
416
417            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
418                 mAudioDecoder != NULL, mVideoDecoder != NULL);
419
420            bool mHadAnySourcesBefore =
421                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
422
423            if (mNativeWindow != NULL) {
424                instantiateDecoder(false, &mVideoDecoder);
425            }
426
427            if (mAudioSink != NULL) {
428                instantiateDecoder(true, &mAudioDecoder);
429            }
430
431            if (!mHadAnySourcesBefore
432                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
433                // This is the first time we've found anything playable.
434
435                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
436                    schedulePollDuration();
437                }
438            }
439
440            status_t err;
441            if ((err = mSource->feedMoreTSData()) != OK) {
442                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
443                    // We're not currently decoding anything (no audio or
444                    // video tracks found) and we just ran out of input data.
445
446                    if (err == ERROR_END_OF_STREAM) {
447                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
448                    } else {
449                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
450                    }
451                }
452                break;
453            }
454
455            if ((mAudioDecoder == NULL && mAudioSink != NULL)
456                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
457                msg->post(100000ll);
458                mScanSourcesPending = true;
459            }
460            break;
461        }
462
463        case kWhatVideoNotify:
464        case kWhatAudioNotify:
465        {
466            bool audio = msg->what() == kWhatAudioNotify;
467
468            sp<AMessage> codecRequest;
469            CHECK(msg->findMessage("codec-request", &codecRequest));
470
471            int32_t what;
472            CHECK(codecRequest->findInt32("what", &what));
473
474            if (what == ACodec::kWhatFillThisBuffer) {
475                status_t err = feedDecoderInputData(
476                        audio, codecRequest);
477
478                if (err == -EWOULDBLOCK) {
479                    if (mSource->feedMoreTSData() == OK) {
480                        msg->post(10000ll);
481                    }
482                }
483            } else if (what == ACodec::kWhatEOS) {
484                int32_t err;
485                CHECK(codecRequest->findInt32("err", &err));
486
487                if (err == ERROR_END_OF_STREAM) {
488                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
489                } else {
490                    ALOGV("got %s decoder EOS w/ error %d",
491                         audio ? "audio" : "video",
492                         err);
493                }
494
495                mRenderer->queueEOS(audio, err);
496            } else if (what == ACodec::kWhatFlushCompleted) {
497                bool needShutdown;
498
499                if (audio) {
500                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
501                    mFlushingAudio = FLUSHED;
502                } else {
503                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
504                    mFlushingVideo = FLUSHED;
505
506                    mVideoLateByUs = 0;
507                }
508
509                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
510
511                if (needShutdown) {
512                    ALOGV("initiating %s decoder shutdown",
513                         audio ? "audio" : "video");
514
515                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
516
517                    if (audio) {
518                        mFlushingAudio = SHUTTING_DOWN_DECODER;
519                    } else {
520                        mFlushingVideo = SHUTTING_DOWN_DECODER;
521                    }
522                }
523
524                finishFlushIfPossible();
525            } else if (what == ACodec::kWhatOutputFormatChanged) {
526                if (audio) {
527                    int32_t numChannels;
528                    CHECK(codecRequest->findInt32(
529                                "channel-count", &numChannels));
530
531                    int32_t sampleRate;
532                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
533
534                    ALOGV("Audio output format changed to %d Hz, %d channels",
535                         sampleRate, numChannels);
536
537                    mAudioSink->close();
538
539                    audio_output_flags_t flags;
540                    int64_t durationUs;
541                    // FIXME: we should handle the case where the video decoder
542                    // is created after we receive the format change indication.
543                    // Current code will just make that we select deep buffer
544                    // with video which should not be a problem as it should
545                    // not prevent from keeping A/V sync.
546                    if (mVideoDecoder == NULL &&
547                            mSource->getDuration(&durationUs) == OK &&
548                            durationUs
549                                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
550                        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
551                    } else {
552                        flags = AUDIO_OUTPUT_FLAG_NONE;
553                    }
554
555                    int32_t channelMask;
556                    if (!codecRequest->findInt32("channel-mask", &channelMask)) {
557                        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
558                    }
559
560                    CHECK_EQ(mAudioSink->open(
561                                sampleRate,
562                                numChannels,
563                                (audio_channel_mask_t)channelMask,
564                                AUDIO_FORMAT_PCM_16_BIT,
565                                8 /* bufferCount */,
566                                NULL,
567                                NULL,
568                                flags),
569                             (status_t)OK);
570                    mAudioSink->start();
571
572                    mRenderer->signalAudioSinkChanged();
573                } else {
574                    // video
575
576                    int32_t width, height;
577                    CHECK(codecRequest->findInt32("width", &width));
578                    CHECK(codecRequest->findInt32("height", &height));
579
580                    int32_t cropLeft, cropTop, cropRight, cropBottom;
581                    CHECK(codecRequest->findRect(
582                                "crop",
583                                &cropLeft, &cropTop, &cropRight, &cropBottom));
584
585                    int32_t displayWidth = cropRight - cropLeft + 1;
586                    int32_t displayHeight = cropBottom - cropTop + 1;
587
588                    ALOGV("Video output format changed to %d x %d "
589                         "(crop: %d x %d @ (%d, %d))",
590                         width, height,
591                         displayWidth,
592                         displayHeight,
593                         cropLeft, cropTop);
594
595                    sp<AMessage> videoInputFormat =
596                        mSource->getFormat(false /* audio */);
597
598                    // Take into account sample aspect ratio if necessary:
599                    int32_t sarWidth, sarHeight;
600                    if (videoInputFormat->findInt32("sar-width", &sarWidth)
601                            && videoInputFormat->findInt32(
602                                "sar-height", &sarHeight)) {
603                        ALOGV("Sample aspect ratio %d : %d",
604                              sarWidth, sarHeight);
605
606                        displayWidth = (displayWidth * sarWidth) / sarHeight;
607
608                        ALOGV("display dimensions %d x %d",
609                              displayWidth, displayHeight);
610                    }
611
612                    notifyListener(
613                            MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
614
615                    if (mNeedsSwRenderer && mNativeWindow != NULL) {
616                        int32_t colorFormat;
617                        CHECK(codecRequest->findInt32("color-format", &colorFormat));
618
619                        sp<MetaData> meta = new MetaData;
620                        meta->setInt32(kKeyWidth, width);
621                        meta->setInt32(kKeyHeight, height);
622                        meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
623                        meta->setInt32(kKeyColorFormat, colorFormat);
624
625                        mRenderer->setSoftRenderer(
626                                new SoftwareRenderer(mNativeWindow->getNativeWindow(), meta));
627                    }
628                }
629            } else if (what == ACodec::kWhatShutdownCompleted) {
630                ALOGV("%s shutdown completed", audio ? "audio" : "video");
631                if (audio) {
632                    mAudioDecoder.clear();
633
634                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
635                    mFlushingAudio = SHUT_DOWN;
636                } else {
637                    mVideoDecoder.clear();
638
639                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
640                    mFlushingVideo = SHUT_DOWN;
641                }
642
643                finishFlushIfPossible();
644            } else if (what == ACodec::kWhatError) {
645                ALOGE("Received error from %s decoder, aborting playback.",
646                     audio ? "audio" : "video");
647
648                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
649            } else if (what == ACodec::kWhatDrainThisBuffer) {
650                renderBuffer(audio, codecRequest);
651            } else if (what == ACodec::kWhatComponentAllocated) {
652                if (!audio) {
653                    AString name;
654                    CHECK(codecRequest->findString("componentName", &name));
655                    mNeedsSwRenderer = name.startsWith("OMX.google.");
656                }
657            } else if (what != ACodec::kWhatComponentConfigured
658                    && what != ACodec::kWhatBuffersAllocated) {
659                ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
660                      what,
661                      what >> 24,
662                      (what >> 16) & 0xff,
663                      (what >> 8) & 0xff,
664                      what & 0xff);
665            }
666
667            break;
668        }
669
670        case kWhatRendererNotify:
671        {
672            int32_t what;
673            CHECK(msg->findInt32("what", &what));
674
675            if (what == Renderer::kWhatEOS) {
676                int32_t audio;
677                CHECK(msg->findInt32("audio", &audio));
678
679                int32_t finalResult;
680                CHECK(msg->findInt32("finalResult", &finalResult));
681
682                if (audio) {
683                    mAudioEOS = true;
684                } else {
685                    mVideoEOS = true;
686                }
687
688                if (finalResult == ERROR_END_OF_STREAM) {
689                    ALOGV("reached %s EOS", audio ? "audio" : "video");
690                } else {
691                    ALOGE("%s track encountered an error (%d)",
692                         audio ? "audio" : "video", finalResult);
693
694                    notifyListener(
695                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
696                }
697
698                if ((mAudioEOS || mAudioDecoder == NULL)
699                        && (mVideoEOS || mVideoDecoder == NULL)) {
700                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
701                }
702            } else if (what == Renderer::kWhatPosition) {
703                int64_t positionUs;
704                CHECK(msg->findInt64("positionUs", &positionUs));
705
706                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
707
708                if (mDriver != NULL) {
709                    sp<NuPlayerDriver> driver = mDriver.promote();
710                    if (driver != NULL) {
711                        driver->notifyPosition(positionUs);
712
713                        driver->notifyFrameStats(
714                                mNumFramesTotal, mNumFramesDropped);
715                    }
716                }
717            } else if (what == Renderer::kWhatFlushComplete) {
718                int32_t audio;
719                CHECK(msg->findInt32("audio", &audio));
720
721                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
722            } else if (what == Renderer::kWhatVideoRenderingStart) {
723                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
724            }
725            break;
726        }
727
728        case kWhatMoreDataQueued:
729        {
730            break;
731        }
732
733        case kWhatReset:
734        {
735            ALOGV("kWhatReset");
736
737            mDeferredActions.push_back(
738                    new SimpleAction(&NuPlayer::performDecoderShutdown));
739
740            mDeferredActions.push_back(
741                    new SimpleAction(&NuPlayer::performReset));
742
743            processDeferredActions();
744            break;
745        }
746
747        case kWhatSeek:
748        {
749            int64_t seekTimeUs;
750            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
751
752            ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
753
754            mDeferredActions.push_back(
755                    new SimpleAction(&NuPlayer::performDecoderFlush));
756
757            mDeferredActions.push_back(new SeekAction(seekTimeUs));
758
759            processDeferredActions();
760            break;
761        }
762
763        case kWhatPause:
764        {
765            CHECK(mRenderer != NULL);
766            mSource->pause();
767            mRenderer->pause();
768            break;
769        }
770
771        case kWhatResume:
772        {
773            CHECK(mRenderer != NULL);
774            mSource->resume();
775            mRenderer->resume();
776            break;
777        }
778
779        case kWhatSourceNotify:
780        {
781            onSourceNotify(msg);
782            break;
783        }
784
785        default:
786            TRESPASS();
787            break;
788    }
789}
790
791void NuPlayer::finishFlushIfPossible() {
792    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
793        return;
794    }
795
796    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
797        return;
798    }
799
800    ALOGV("both audio and video are flushed now.");
801
802    if (mTimeDiscontinuityPending) {
803        mRenderer->signalTimeDiscontinuity();
804        mTimeDiscontinuityPending = false;
805    }
806
807    if (mAudioDecoder != NULL) {
808        mAudioDecoder->signalResume();
809    }
810
811    if (mVideoDecoder != NULL) {
812        mVideoDecoder->signalResume();
813    }
814
815    mFlushingAudio = NONE;
816    mFlushingVideo = NONE;
817
818    processDeferredActions();
819}
820
821void NuPlayer::postScanSources() {
822    if (mScanSourcesPending) {
823        return;
824    }
825
826    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
827    msg->setInt32("generation", mScanSourcesGeneration);
828    msg->post();
829
830    mScanSourcesPending = true;
831}
832
833status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
834    if (*decoder != NULL) {
835        return OK;
836    }
837
838    sp<AMessage> format = mSource->getFormat(audio);
839
840    if (format == NULL) {
841        return -EWOULDBLOCK;
842    }
843
844    if (!audio) {
845        AString mime;
846        CHECK(format->findString("mime", &mime));
847        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
848    }
849
850    sp<AMessage> notify =
851        new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
852                     id());
853
854    *decoder = audio ? new Decoder(notify) :
855                       new Decoder(notify, mNativeWindow);
856    looper()->registerHandler(*decoder);
857
858    (*decoder)->configure(format);
859
860    return OK;
861}
862
863status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
864    sp<AMessage> reply;
865    CHECK(msg->findMessage("reply", &reply));
866
867    if ((audio && IsFlushingState(mFlushingAudio))
868            || (!audio && IsFlushingState(mFlushingVideo))) {
869        reply->setInt32("err", INFO_DISCONTINUITY);
870        reply->post();
871        return OK;
872    }
873
874    sp<ABuffer> accessUnit;
875
876    bool dropAccessUnit;
877    do {
878        status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
879
880        if (err == -EWOULDBLOCK) {
881            return err;
882        } else if (err != OK) {
883            if (err == INFO_DISCONTINUITY) {
884                int32_t type;
885                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
886
887                bool formatChange =
888                    (audio &&
889                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
890                    || (!audio &&
891                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
892
893                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
894
895                ALOGI("%s discontinuity (formatChange=%d, time=%d)",
896                     audio ? "audio" : "video", formatChange, timeChange);
897
898                if (audio) {
899                    mSkipRenderingAudioUntilMediaTimeUs = -1;
900                } else {
901                    mSkipRenderingVideoUntilMediaTimeUs = -1;
902                }
903
904                if (timeChange) {
905                    sp<AMessage> extra;
906                    if (accessUnit->meta()->findMessage("extra", &extra)
907                            && extra != NULL) {
908                        int64_t resumeAtMediaTimeUs;
909                        if (extra->findInt64(
910                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
911                            ALOGI("suppressing rendering of %s until %lld us",
912                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
913
914                            if (audio) {
915                                mSkipRenderingAudioUntilMediaTimeUs =
916                                    resumeAtMediaTimeUs;
917                            } else {
918                                mSkipRenderingVideoUntilMediaTimeUs =
919                                    resumeAtMediaTimeUs;
920                            }
921                        }
922                    }
923                }
924
925                mTimeDiscontinuityPending =
926                    mTimeDiscontinuityPending || timeChange;
927
928                if (formatChange || timeChange) {
929                    if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
930                        // And we'll resume scanning sources once we're done
931                        // flushing.
932                        mDeferredActions.push_front(
933                                new SimpleAction(
934                                    &NuPlayer::performScanSources));
935                    }
936
937                    flushDecoder(audio, formatChange);
938                } else {
939                    // This stream is unaffected by the discontinuity
940
941                    if (audio) {
942                        mFlushingAudio = FLUSHED;
943                    } else {
944                        mFlushingVideo = FLUSHED;
945                    }
946
947                    finishFlushIfPossible();
948
949                    return -EWOULDBLOCK;
950                }
951            }
952
953            reply->setInt32("err", err);
954            reply->post();
955            return OK;
956        }
957
958        if (!audio) {
959            ++mNumFramesTotal;
960        }
961
962        dropAccessUnit = false;
963        if (!audio
964                && mVideoLateByUs > 100000ll
965                && mVideoIsAVC
966                && !IsAVCReferenceFrame(accessUnit)) {
967            dropAccessUnit = true;
968            ++mNumFramesDropped;
969        }
970    } while (dropAccessUnit);
971
972    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
973
974#if 0
975    int64_t mediaTimeUs;
976    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
977    ALOGV("feeding %s input buffer at media time %.2f secs",
978         audio ? "audio" : "video",
979         mediaTimeUs / 1E6);
980#endif
981
982    reply->setBuffer("buffer", accessUnit);
983    reply->post();
984
985    return OK;
986}
987
988void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
989    // ALOGV("renderBuffer %s", audio ? "audio" : "video");
990
991    sp<AMessage> reply;
992    CHECK(msg->findMessage("reply", &reply));
993
994    if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
995        // We're currently attempting to flush the decoder, in order
996        // to complete this, the decoder wants all its buffers back,
997        // so we don't want any output buffers it sent us (from before
998        // we initiated the flush) to be stuck in the renderer's queue.
999
1000        ALOGV("we're still flushing the %s decoder, sending its output buffer"
1001             " right back.", audio ? "audio" : "video");
1002
1003        reply->post();
1004        return;
1005    }
1006
1007    sp<ABuffer> buffer;
1008    CHECK(msg->findBuffer("buffer", &buffer));
1009
1010    int64_t &skipUntilMediaTimeUs =
1011        audio
1012            ? mSkipRenderingAudioUntilMediaTimeUs
1013            : mSkipRenderingVideoUntilMediaTimeUs;
1014
1015    if (skipUntilMediaTimeUs >= 0) {
1016        int64_t mediaTimeUs;
1017        CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1018
1019        if (mediaTimeUs < skipUntilMediaTimeUs) {
1020            ALOGV("dropping %s buffer at time %lld as requested.",
1021                 audio ? "audio" : "video",
1022                 mediaTimeUs);
1023
1024            reply->post();
1025            return;
1026        }
1027
1028        skipUntilMediaTimeUs = -1;
1029    }
1030
1031    mRenderer->queueBuffer(audio, buffer, reply);
1032}
1033
1034void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
1035    if (mDriver == NULL) {
1036        return;
1037    }
1038
1039    sp<NuPlayerDriver> driver = mDriver.promote();
1040
1041    if (driver == NULL) {
1042        return;
1043    }
1044
1045    driver->notifyListener(msg, ext1, ext2);
1046}
1047
1048void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
1049    if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
1050        ALOGI("flushDecoder %s without decoder present",
1051             audio ? "audio" : "video");
1052    }
1053
1054    // Make sure we don't continue to scan sources until we finish flushing.
1055    ++mScanSourcesGeneration;
1056    mScanSourcesPending = false;
1057
1058    (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
1059    mRenderer->flush(audio);
1060
1061    FlushStatus newStatus =
1062        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1063
1064    if (audio) {
1065        CHECK(mFlushingAudio == NONE
1066                || mFlushingAudio == AWAITING_DISCONTINUITY);
1067
1068        mFlushingAudio = newStatus;
1069
1070        if (mFlushingVideo == NONE) {
1071            mFlushingVideo = (mVideoDecoder != NULL)
1072                ? AWAITING_DISCONTINUITY
1073                : FLUSHED;
1074        }
1075    } else {
1076        CHECK(mFlushingVideo == NONE
1077                || mFlushingVideo == AWAITING_DISCONTINUITY);
1078
1079        mFlushingVideo = newStatus;
1080
1081        if (mFlushingAudio == NONE) {
1082            mFlushingAudio = (mAudioDecoder != NULL)
1083                ? AWAITING_DISCONTINUITY
1084                : FLUSHED;
1085        }
1086    }
1087}
1088
1089sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
1090    sp<MetaData> meta = getFormatMeta(audio);
1091
1092    if (meta == NULL) {
1093        return NULL;
1094    }
1095
1096    sp<AMessage> msg = new AMessage;
1097
1098    if(convertMetaDataToMessage(meta, &msg) == OK) {
1099        return msg;
1100    }
1101    return NULL;
1102}
1103
1104status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1105    mVideoScalingMode = mode;
1106    if (mNativeWindow != NULL) {
1107        status_t ret = native_window_set_scaling_mode(
1108                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1109        if (ret != OK) {
1110            ALOGE("Failed to set scaling mode (%d): %s",
1111                -ret, strerror(-ret));
1112            return ret;
1113        }
1114    }
1115    return OK;
1116}
1117
1118void NuPlayer::schedulePollDuration() {
1119    sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1120    msg->setInt32("generation", mPollDurationGeneration);
1121    msg->post();
1122}
1123
1124void NuPlayer::cancelPollDuration() {
1125    ++mPollDurationGeneration;
1126}
1127
1128void NuPlayer::processDeferredActions() {
1129    while (!mDeferredActions.empty()) {
1130        // We won't execute any deferred actions until we're no longer in
1131        // an intermediate state, i.e. one more more decoders are currently
1132        // flushing or shutting down.
1133
1134        if (mRenderer != NULL) {
1135            // There's an edge case where the renderer owns all output
1136            // buffers and is paused, therefore the decoder will not read
1137            // more input data and will never encounter the matching
1138            // discontinuity. To avoid this, we resume the renderer.
1139
1140            if (mFlushingAudio == AWAITING_DISCONTINUITY
1141                    || mFlushingVideo == AWAITING_DISCONTINUITY) {
1142                mRenderer->resume();
1143            }
1144        }
1145
1146        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1147            // We're currently flushing, postpone the reset until that's
1148            // completed.
1149
1150            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1151                  mFlushingAudio, mFlushingVideo);
1152
1153            break;
1154        }
1155
1156        sp<Action> action = *mDeferredActions.begin();
1157        mDeferredActions.erase(mDeferredActions.begin());
1158
1159        action->execute(this);
1160    }
1161}
1162
1163void NuPlayer::performSeek(int64_t seekTimeUs) {
1164    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1165          seekTimeUs,
1166          seekTimeUs / 1E6);
1167
1168    mSource->seekTo(seekTimeUs);
1169
1170    if (mDriver != NULL) {
1171        sp<NuPlayerDriver> driver = mDriver.promote();
1172        if (driver != NULL) {
1173            driver->notifyPosition(seekTimeUs);
1174            driver->notifySeekComplete();
1175        }
1176    }
1177
1178    // everything's flushed, continue playback.
1179}
1180
1181void NuPlayer::performDecoderFlush() {
1182    ALOGV("performDecoderFlush");
1183
1184    if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1185        return;
1186    }
1187
1188    mTimeDiscontinuityPending = true;
1189
1190    if (mAudioDecoder != NULL) {
1191        flushDecoder(true /* audio */, false /* needShutdown */);
1192    }
1193
1194    if (mVideoDecoder != NULL) {
1195        flushDecoder(false /* audio */, false /* needShutdown */);
1196    }
1197}
1198
1199void NuPlayer::performDecoderShutdown() {
1200    ALOGV("performDecoderShutdown");
1201
1202    if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1203        return;
1204    }
1205
1206    mTimeDiscontinuityPending = true;
1207
1208    if (mAudioDecoder != NULL) {
1209        flushDecoder(true /* audio */, true /* needShutdown */);
1210    }
1211
1212    if (mVideoDecoder != NULL) {
1213        flushDecoder(false /* audio */, true /* needShutdown */);
1214    }
1215}
1216
1217void NuPlayer::performReset() {
1218    ALOGV("performReset");
1219
1220    CHECK(mAudioDecoder == NULL);
1221    CHECK(mVideoDecoder == NULL);
1222
1223    cancelPollDuration();
1224
1225    ++mScanSourcesGeneration;
1226    mScanSourcesPending = false;
1227
1228    mRenderer.clear();
1229
1230    if (mSource != NULL) {
1231        mSource->stop();
1232
1233        looper()->unregisterHandler(mSource->id());
1234
1235        mSource.clear();
1236    }
1237
1238    if (mDriver != NULL) {
1239        sp<NuPlayerDriver> driver = mDriver.promote();
1240        if (driver != NULL) {
1241            driver->notifyResetComplete();
1242        }
1243    }
1244
1245    mStarted = false;
1246}
1247
1248void NuPlayer::performScanSources() {
1249    ALOGV("performScanSources");
1250
1251    if (!mStarted) {
1252        return;
1253    }
1254
1255    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1256        postScanSources();
1257    }
1258}
1259
1260void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1261    ALOGV("performSetSurface");
1262
1263    mNativeWindow = wrapper;
1264
1265    // XXX - ignore error from setVideoScalingMode for now
1266    setVideoScalingMode(mVideoScalingMode);
1267
1268    if (mDriver != NULL) {
1269        sp<NuPlayerDriver> driver = mDriver.promote();
1270        if (driver != NULL) {
1271            driver->notifySetSurfaceComplete();
1272        }
1273    }
1274}
1275
1276void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1277    int32_t what;
1278    CHECK(msg->findInt32("what", &what));
1279
1280    switch (what) {
1281        case Source::kWhatPrepared:
1282        {
1283            if (mSource == NULL) {
1284                // This is a stale notification from a source that was
1285                // asynchronously preparing when the client called reset().
1286                // We handled the reset, the source is gone.
1287                break;
1288            }
1289
1290            int32_t err;
1291            CHECK(msg->findInt32("err", &err));
1292
1293            sp<NuPlayerDriver> driver = mDriver.promote();
1294            if (driver != NULL) {
1295                driver->notifyPrepareCompleted(err);
1296            }
1297
1298            int64_t durationUs;
1299            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
1300                sp<NuPlayerDriver> driver = mDriver.promote();
1301                if (driver != NULL) {
1302                    driver->notifyDuration(durationUs);
1303                }
1304            }
1305            break;
1306        }
1307
1308        case Source::kWhatFlagsChanged:
1309        {
1310            uint32_t flags;
1311            CHECK(msg->findInt32("flags", (int32_t *)&flags));
1312
1313            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1314                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1315                cancelPollDuration();
1316            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1317                    && (flags & Source::FLAG_DYNAMIC_DURATION)
1318                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1319                schedulePollDuration();
1320            }
1321
1322            mSourceFlags = flags;
1323            break;
1324        }
1325
1326        case Source::kWhatVideoSizeChanged:
1327        {
1328            int32_t width, height;
1329            CHECK(msg->findInt32("width", &width));
1330            CHECK(msg->findInt32("height", &height));
1331
1332            notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
1333            break;
1334        }
1335
1336        case Source::kWhatBufferingStart:
1337        {
1338            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1339            break;
1340        }
1341
1342        case Source::kWhatBufferingEnd:
1343        {
1344            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1345            break;
1346        }
1347
1348        default:
1349            TRESPASS();
1350    }
1351}
1352
1353////////////////////////////////////////////////////////////////////////////////
1354
1355void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
1356    sp<AMessage> notify = dupNotify();
1357    notify->setInt32("what", kWhatFlagsChanged);
1358    notify->setInt32("flags", flags);
1359    notify->post();
1360}
1361
1362void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
1363    sp<AMessage> notify = dupNotify();
1364    notify->setInt32("what", kWhatVideoSizeChanged);
1365    notify->setInt32("width", width);
1366    notify->setInt32("height", height);
1367    notify->post();
1368}
1369
1370void NuPlayer::Source::notifyPrepared(status_t err) {
1371    sp<AMessage> notify = dupNotify();
1372    notify->setInt32("what", kWhatPrepared);
1373    notify->setInt32("err", err);
1374    notify->post();
1375}
1376
1377void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
1378    TRESPASS();
1379}
1380
1381}  // namespace android
1382