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