• 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 
20 #include <inttypes.h>
21 
22 #include <utils/Log.h>
23 
24 #include "NuPlayer.h"
25 
26 #include "HTTPLiveSource.h"
27 #include "NuPlayerCCDecoder.h"
28 #include "NuPlayerDecoder.h"
29 #include "NuPlayerDecoderBase.h"
30 #include "NuPlayerDecoderPassThrough.h"
31 #include "NuPlayerDriver.h"
32 #include "NuPlayerRenderer.h"
33 #include "NuPlayerSource.h"
34 #include "RTPSource.h"
35 #include "RTSPSource.h"
36 #include "StreamingSource.h"
37 #include "GenericSource.h"
38 #include "TextDescriptions.h"
39 
40 #include "ATSParser.h"
41 
42 #include <cutils/properties.h>
43 
44 #include <media/AudioResamplerPublic.h>
45 #include <media/AVSyncSettings.h>
46 #include <media/MediaCodecBuffer.h>
47 
48 #include <media/stagefright/foundation/hexdump.h>
49 #include <media/stagefright/foundation/ABuffer.h>
50 #include <media/stagefright/foundation/ADebug.h>
51 #include <media/stagefright/foundation/AMessage.h>
52 #include <media/stagefright/foundation/avc_utils.h>
53 #include <media/stagefright/MediaBuffer.h>
54 #include <media/stagefright/MediaClock.h>
55 #include <media/stagefright/MediaDefs.h>
56 #include <media/stagefright/MediaErrors.h>
57 #include <media/stagefright/MetaData.h>
58 
59 #include <gui/IGraphicBufferProducer.h>
60 #include <gui/Surface.h>
61 
62 
63 #include "ESDS.h"
64 #include <media/stagefright/Utils.h>
65 
66 namespace android {
67 
68 struct NuPlayer::Action : public RefBase {
Actionandroid::NuPlayer::Action69     Action() {}
70 
71     virtual void execute(NuPlayer *player) = 0;
72 
73 private:
74     DISALLOW_EVIL_CONSTRUCTORS(Action);
75 };
76 
77 struct NuPlayer::SeekAction : public Action {
SeekActionandroid::NuPlayer::SeekAction78     explicit SeekAction(int64_t seekTimeUs, MediaPlayerSeekMode mode)
79         : mSeekTimeUs(seekTimeUs),
80           mMode(mode) {
81     }
82 
executeandroid::NuPlayer::SeekAction83     virtual void execute(NuPlayer *player) {
84         player->performSeek(mSeekTimeUs, mMode);
85     }
86 
87 private:
88     int64_t mSeekTimeUs;
89     MediaPlayerSeekMode mMode;
90 
91     DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
92 };
93 
94 struct NuPlayer::ResumeDecoderAction : public Action {
ResumeDecoderActionandroid::NuPlayer::ResumeDecoderAction95     explicit ResumeDecoderAction(bool needNotify)
96         : mNeedNotify(needNotify) {
97     }
98 
executeandroid::NuPlayer::ResumeDecoderAction99     virtual void execute(NuPlayer *player) {
100         player->performResumeDecoders(mNeedNotify);
101     }
102 
103 private:
104     bool mNeedNotify;
105 
106     DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
107 };
108 
109 struct NuPlayer::SetSurfaceAction : public Action {
SetSurfaceActionandroid::NuPlayer::SetSurfaceAction110     explicit SetSurfaceAction(const sp<Surface> &surface)
111         : mSurface(surface) {
112     }
113 
executeandroid::NuPlayer::SetSurfaceAction114     virtual void execute(NuPlayer *player) {
115         player->performSetSurface(mSurface);
116     }
117 
118 private:
119     sp<Surface> mSurface;
120 
121     DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
122 };
123 
124 struct NuPlayer::FlushDecoderAction : public Action {
FlushDecoderActionandroid::NuPlayer::FlushDecoderAction125     FlushDecoderAction(FlushCommand audio, FlushCommand video)
126         : mAudio(audio),
127           mVideo(video) {
128     }
129 
executeandroid::NuPlayer::FlushDecoderAction130     virtual void execute(NuPlayer *player) {
131         player->performDecoderFlush(mAudio, mVideo);
132     }
133 
134 private:
135     FlushCommand mAudio;
136     FlushCommand mVideo;
137 
138     DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
139 };
140 
141 struct NuPlayer::PostMessageAction : public Action {
PostMessageActionandroid::NuPlayer::PostMessageAction142     explicit PostMessageAction(const sp<AMessage> &msg)
143         : mMessage(msg) {
144     }
145 
executeandroid::NuPlayer::PostMessageAction146     virtual void execute(NuPlayer *) {
147         mMessage->post();
148     }
149 
150 private:
151     sp<AMessage> mMessage;
152 
153     DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
154 };
155 
156 // Use this if there's no state necessary to save in order to execute
157 // the action.
158 struct NuPlayer::SimpleAction : public Action {
159     typedef void (NuPlayer::*ActionFunc)();
160 
SimpleActionandroid::NuPlayer::SimpleAction161     explicit SimpleAction(ActionFunc func)
162         : mFunc(func) {
163     }
164 
executeandroid::NuPlayer::SimpleAction165     virtual void execute(NuPlayer *player) {
166         (player->*mFunc)();
167     }
168 
169 private:
170     ActionFunc mFunc;
171 
172     DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
173 };
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 
NuPlayer(pid_t pid,const sp<MediaClock> & mediaClock)177 NuPlayer::NuPlayer(pid_t pid, const sp<MediaClock> &mediaClock)
178     : mUIDValid(false),
179       mPID(pid),
180       mMediaClock(mediaClock),
181       mSourceFlags(0),
182       mOffloadAudio(false),
183       mAudioDecoderGeneration(0),
184       mVideoDecoderGeneration(0),
185       mRendererGeneration(0),
186       mLastStartedPlayingTimeNs(0),
187       mLastStartedRebufferingTimeNs(0),
188       mPreviousSeekTimeUs(0),
189       mAudioEOS(false),
190       mVideoEOS(false),
191       mScanSourcesPending(false),
192       mScanSourcesGeneration(0),
193       mPollDurationGeneration(0),
194       mTimedTextGeneration(0),
195       mFlushingAudio(NONE),
196       mFlushingVideo(NONE),
197       mResumePending(false),
198       mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
199       mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
200       mVideoFpsHint(-1.f),
201       mStarted(false),
202       mPrepared(false),
203       mResetting(false),
204       mSourceStarted(false),
205       mAudioDecoderError(false),
206       mVideoDecoderError(false),
207       mPaused(false),
208       mPausedByClient(true),
209       mPausedForBuffering(false),
210       mIsDrmProtected(false),
211       mDataSourceType(DATA_SOURCE_TYPE_NONE) {
212     CHECK(mediaClock != NULL);
213     clearFlushComplete();
214 }
215 
~NuPlayer()216 NuPlayer::~NuPlayer() {
217 }
218 
setUID(uid_t uid)219 void NuPlayer::setUID(uid_t uid) {
220     mUIDValid = true;
221     mUID = uid;
222 }
223 
init(const wp<NuPlayerDriver> & driver)224 void NuPlayer::init(const wp<NuPlayerDriver> &driver) {
225     mDriver = driver;
226 
227     sp<AMessage> notify = new AMessage(kWhatMediaClockNotify, this);
228     mMediaClock->setNotificationMessage(notify);
229 }
230 
setDataSourceAsync(const sp<IStreamSource> & source)231 void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
232     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
233 
234     sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
235 
236     msg->setObject("source", new StreamingSource(notify, source));
237     msg->post();
238     mDataSourceType = DATA_SOURCE_TYPE_STREAM;
239 }
240 
IsHTTPLiveURL(const char * url)241 static bool IsHTTPLiveURL(const char *url) {
242     if (!strncasecmp("http://", url, 7)
243             || !strncasecmp("https://", url, 8)
244             || !strncasecmp("file://", url, 7)) {
245         size_t len = strlen(url);
246         if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
247             return true;
248         }
249 
250         if (strstr(url,"m3u8")) {
251             return true;
252         }
253     }
254 
255     return false;
256 }
257 
setDataSourceAsync(const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)258 void NuPlayer::setDataSourceAsync(
259         const sp<IMediaHTTPService> &httpService,
260         const char *url,
261         const KeyedVector<String8, String8> *headers) {
262 
263     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
264     size_t len = strlen(url);
265 
266     sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
267 
268     sp<Source> source;
269     if (IsHTTPLiveURL(url)) {
270         source = new HTTPLiveSource(notify, httpService, url, headers);
271         ALOGV("setDataSourceAsync HTTPLiveSource %s", url);
272         mDataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
273     } else if (!strncasecmp(url, "rtsp://", 7)) {
274         source = new RTSPSource(
275                 notify, httpService, url, headers, mUIDValid, mUID);
276         ALOGV("setDataSourceAsync RTSPSource %s", url);
277         mDataSourceType = DATA_SOURCE_TYPE_RTSP;
278     } else if ((!strncasecmp(url, "http://", 7)
279                 || !strncasecmp(url, "https://", 8))
280                     && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
281                     || strstr(url, ".sdp?"))) {
282         source = new RTSPSource(
283                 notify, httpService, url, headers, mUIDValid, mUID, true);
284         ALOGV("setDataSourceAsync RTSPSource http/https/.sdp %s", url);
285         mDataSourceType = DATA_SOURCE_TYPE_RTSP;
286     } else {
287         ALOGV("setDataSourceAsync GenericSource %s", url);
288 
289         sp<GenericSource> genericSource =
290                 new GenericSource(notify, mUIDValid, mUID, mMediaClock);
291 
292         status_t err = genericSource->setDataSource(httpService, url, headers);
293 
294         if (err == OK) {
295             source = genericSource;
296         } else {
297             ALOGE("Failed to set data source!");
298         }
299 
300         // regardless of success/failure
301         mDataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
302     }
303     msg->setObject("source", source);
304     msg->post();
305 }
306 
setDataSourceAsync(int fd,int64_t offset,int64_t length)307 void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
308     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
309 
310     sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
311 
312     sp<GenericSource> source =
313             new GenericSource(notify, mUIDValid, mUID, mMediaClock);
314 
315     ALOGV("setDataSourceAsync fd %d/%lld/%lld source: %p",
316             fd, (long long)offset, (long long)length, source.get());
317 
318     status_t err = source->setDataSource(fd, offset, length);
319 
320     if (err != OK) {
321         ALOGE("Failed to set data source!");
322         source = NULL;
323     }
324 
325     msg->setObject("source", source);
326     msg->post();
327     mDataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
328 }
329 
setDataSourceAsync(const sp<DataSource> & dataSource)330 void NuPlayer::setDataSourceAsync(const sp<DataSource> &dataSource) {
331     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
332     sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
333 
334     sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID, mMediaClock);
335     status_t err = source->setDataSource(dataSource);
336 
337     if (err != OK) {
338         ALOGE("Failed to set data source!");
339         source = NULL;
340     }
341 
342     msg->setObject("source", source);
343     msg->post();
344     mDataSourceType = DATA_SOURCE_TYPE_MEDIA;
345 }
346 
getBufferingSettings(BufferingSettings * buffering)347 status_t NuPlayer::getBufferingSettings(
348         BufferingSettings *buffering /* nonnull */) {
349     sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
350     sp<AMessage> response;
351     status_t err = msg->postAndAwaitResponse(&response);
352     if (err == OK && response != NULL) {
353         CHECK(response->findInt32("err", &err));
354         if (err == OK) {
355             readFromAMessage(response, buffering);
356         }
357     }
358     return err;
359 }
360 
setBufferingSettings(const BufferingSettings & buffering)361 status_t NuPlayer::setBufferingSettings(const BufferingSettings& buffering) {
362     sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
363     writeToAMessage(msg, buffering);
364     sp<AMessage> response;
365     status_t err = msg->postAndAwaitResponse(&response);
366     if (err == OK && response != NULL) {
367         CHECK(response->findInt32("err", &err));
368     }
369     return err;
370 }
371 
setDataSourceAsync(const String8 & rtpParams)372 void NuPlayer::setDataSourceAsync(const String8& rtpParams) {
373     ALOGD("setDataSourceAsync for RTP = %s", rtpParams.string());
374     sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
375 
376     sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
377     sp<Source> source = new RTPSource(notify, rtpParams);
378 
379     msg->setObject("source", source);
380     msg->post();
381     mDataSourceType = DATA_SOURCE_TYPE_RTP;
382 }
383 
prepareAsync()384 void NuPlayer::prepareAsync() {
385     ALOGV("prepareAsync");
386 
387     (new AMessage(kWhatPrepare, this))->post();
388 }
389 
setVideoSurfaceTextureAsync(const sp<IGraphicBufferProducer> & bufferProducer)390 void NuPlayer::setVideoSurfaceTextureAsync(
391         const sp<IGraphicBufferProducer> &bufferProducer) {
392     sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
393 
394     if (bufferProducer == NULL) {
395         msg->setObject("surface", NULL);
396     } else {
397         msg->setObject("surface", new Surface(bufferProducer, true /* controlledByApp */));
398     }
399 
400     msg->post();
401 }
402 
setAudioSink(const sp<MediaPlayerBase::AudioSink> & sink)403 void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
404     sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
405     msg->setObject("sink", sink);
406     msg->post();
407 }
408 
start()409 void NuPlayer::start() {
410     (new AMessage(kWhatStart, this))->post();
411 }
412 
setPlaybackSettings(const AudioPlaybackRate & rate)413 status_t NuPlayer::setPlaybackSettings(const AudioPlaybackRate &rate) {
414     // do some cursory validation of the settings here. audio modes are
415     // only validated when set on the audiosink.
416      if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN)
417             || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
418             || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
419             || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
420         return BAD_VALUE;
421     }
422     sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
423     writeToAMessage(msg, rate);
424     sp<AMessage> response;
425     status_t err = msg->postAndAwaitResponse(&response);
426     if (err == OK && response != NULL) {
427         CHECK(response->findInt32("err", &err));
428     }
429     return err;
430 }
431 
getPlaybackSettings(AudioPlaybackRate * rate)432 status_t NuPlayer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
433     sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
434     sp<AMessage> response;
435     status_t err = msg->postAndAwaitResponse(&response);
436     if (err == OK && response != NULL) {
437         CHECK(response->findInt32("err", &err));
438         if (err == OK) {
439             readFromAMessage(response, rate);
440         }
441     }
442     return err;
443 }
444 
setSyncSettings(const AVSyncSettings & sync,float videoFpsHint)445 status_t NuPlayer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
446     sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
447     writeToAMessage(msg, sync, videoFpsHint);
448     sp<AMessage> response;
449     status_t err = msg->postAndAwaitResponse(&response);
450     if (err == OK && response != NULL) {
451         CHECK(response->findInt32("err", &err));
452     }
453     return err;
454 }
455 
getSyncSettings(AVSyncSettings * sync,float * videoFps)456 status_t NuPlayer::getSyncSettings(
457         AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
458     sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
459     sp<AMessage> response;
460     status_t err = msg->postAndAwaitResponse(&response);
461     if (err == OK && response != NULL) {
462         CHECK(response->findInt32("err", &err));
463         if (err == OK) {
464             readFromAMessage(response, sync, videoFps);
465         }
466     }
467     return err;
468 }
469 
pause()470 void NuPlayer::pause() {
471     (new AMessage(kWhatPause, this))->post();
472 }
473 
resetAsync()474 void NuPlayer::resetAsync() {
475     sp<Source> source;
476     {
477         Mutex::Autolock autoLock(mSourceLock);
478         source = mSource;
479     }
480 
481     if (source != NULL) {
482         // During a reset, the data source might be unresponsive already, we need to
483         // disconnect explicitly so that reads exit promptly.
484         // We can't queue the disconnect request to the looper, as it might be
485         // queued behind a stuck read and never gets processed.
486         // Doing a disconnect outside the looper to allows the pending reads to exit
487         // (either successfully or with error).
488         source->disconnect();
489     }
490 
491     (new AMessage(kWhatReset, this))->post();
492 }
493 
notifyAt(int64_t mediaTimeUs)494 status_t NuPlayer::notifyAt(int64_t mediaTimeUs) {
495     sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
496     notify->setInt64("timerUs", mediaTimeUs);
497     mMediaClock->addTimer(notify, mediaTimeUs);
498     return OK;
499 }
500 
seekToAsync(int64_t seekTimeUs,MediaPlayerSeekMode mode,bool needNotify)501 void NuPlayer::seekToAsync(int64_t seekTimeUs, MediaPlayerSeekMode mode, bool needNotify) {
502     sp<AMessage> msg = new AMessage(kWhatSeek, this);
503     msg->setInt64("seekTimeUs", seekTimeUs);
504     msg->setInt32("mode", mode);
505     msg->setInt32("needNotify", needNotify);
506     msg->post();
507 }
508 
509 
writeTrackInfo(Parcel * reply,const sp<AMessage> & format) const510 void NuPlayer::writeTrackInfo(
511         Parcel* reply, const sp<AMessage>& format) const {
512     if (format == NULL) {
513         ALOGE("NULL format");
514         return;
515     }
516     int32_t trackType;
517     if (!format->findInt32("type", &trackType)) {
518         ALOGE("no track type");
519         return;
520     }
521 
522     AString mime;
523     if (!format->findString("mime", &mime)) {
524         // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
525         // If we can't find the mimetype here it means that we wouldn't be needing
526         // the mimetype on the Java end. We still write a placeholder mime to keep the
527         // (de)serialization logic simple.
528         if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
529             mime = "audio/";
530         } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
531             mime = "video/";
532         } else {
533             ALOGE("unknown track type: %d", trackType);
534             return;
535         }
536     }
537 
538     AString lang;
539     if (!format->findString("language", &lang)) {
540         ALOGE("no language");
541         return;
542     }
543 
544     reply->writeInt32(2); // write something non-zero
545     reply->writeInt32(trackType);
546     reply->writeString16(String16(mime.c_str()));
547     reply->writeString16(String16(lang.c_str()));
548 
549     if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
550         int32_t isAuto, isDefault, isForced;
551         CHECK(format->findInt32("auto", &isAuto));
552         CHECK(format->findInt32("default", &isDefault));
553         CHECK(format->findInt32("forced", &isForced));
554 
555         reply->writeInt32(isAuto);
556         reply->writeInt32(isDefault);
557         reply->writeInt32(isForced);
558     }
559 }
560 
onMessageReceived(const sp<AMessage> & msg)561 void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
562     switch (msg->what()) {
563         case kWhatSetDataSource:
564         {
565             ALOGV("kWhatSetDataSource");
566 
567             CHECK(mSource == NULL);
568 
569             status_t err = OK;
570             sp<RefBase> obj;
571             CHECK(msg->findObject("source", &obj));
572             if (obj != NULL) {
573                 Mutex::Autolock autoLock(mSourceLock);
574                 mSource = static_cast<Source *>(obj.get());
575             } else {
576                 err = UNKNOWN_ERROR;
577             }
578 
579             CHECK(mDriver != NULL);
580             sp<NuPlayerDriver> driver = mDriver.promote();
581             if (driver != NULL) {
582                 driver->notifySetDataSourceCompleted(err);
583             }
584             break;
585         }
586 
587         case kWhatGetBufferingSettings:
588         {
589             sp<AReplyToken> replyID;
590             CHECK(msg->senderAwaitsResponse(&replyID));
591 
592             ALOGV("kWhatGetBufferingSettings");
593             BufferingSettings buffering;
594             status_t err = OK;
595             if (mSource != NULL) {
596                 err = mSource->getBufferingSettings(&buffering);
597             } else {
598                 err = INVALID_OPERATION;
599             }
600             sp<AMessage> response = new AMessage;
601             if (err == OK) {
602                 writeToAMessage(response, buffering);
603             }
604             response->setInt32("err", err);
605             response->postReply(replyID);
606             break;
607         }
608 
609         case kWhatSetBufferingSettings:
610         {
611             sp<AReplyToken> replyID;
612             CHECK(msg->senderAwaitsResponse(&replyID));
613 
614             ALOGV("kWhatSetBufferingSettings");
615             BufferingSettings buffering;
616             readFromAMessage(msg, &buffering);
617             status_t err = OK;
618             if (mSource != NULL) {
619                 err = mSource->setBufferingSettings(buffering);
620             } else {
621                 err = INVALID_OPERATION;
622             }
623             sp<AMessage> response = new AMessage;
624             response->setInt32("err", err);
625             response->postReply(replyID);
626             break;
627         }
628 
629         case kWhatPrepare:
630         {
631             ALOGV("onMessageReceived kWhatPrepare");
632 
633             mSource->prepareAsync();
634             break;
635         }
636 
637         case kWhatGetTrackInfo:
638         {
639             sp<AReplyToken> replyID;
640             CHECK(msg->senderAwaitsResponse(&replyID));
641 
642             Parcel* reply;
643             CHECK(msg->findPointer("reply", (void**)&reply));
644 
645             size_t inbandTracks = 0;
646             if (mSource != NULL) {
647                 inbandTracks = mSource->getTrackCount();
648             }
649 
650             size_t ccTracks = 0;
651             if (mCCDecoder != NULL) {
652                 ccTracks = mCCDecoder->getTrackCount();
653             }
654 
655             // total track count
656             reply->writeInt32(inbandTracks + ccTracks);
657 
658             // write inband tracks
659             for (size_t i = 0; i < inbandTracks; ++i) {
660                 writeTrackInfo(reply, mSource->getTrackInfo(i));
661             }
662 
663             // write CC track
664             for (size_t i = 0; i < ccTracks; ++i) {
665                 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
666             }
667 
668             sp<AMessage> response = new AMessage;
669             response->postReply(replyID);
670             break;
671         }
672 
673         case kWhatGetSelectedTrack:
674         {
675             int32_t type32;
676             CHECK(msg->findInt32("type", (int32_t*)&type32));
677             media_track_type type = (media_track_type)type32;
678 
679             size_t inbandTracks = 0;
680             status_t err = INVALID_OPERATION;
681             ssize_t selectedTrack = -1;
682             if (mSource != NULL) {
683                 err = OK;
684                 inbandTracks = mSource->getTrackCount();
685                 selectedTrack = mSource->getSelectedTrack(type);
686             }
687 
688             if (selectedTrack == -1 && mCCDecoder != NULL) {
689                 err = OK;
690                 selectedTrack = mCCDecoder->getSelectedTrack(type);
691                 if (selectedTrack != -1) {
692                     selectedTrack += inbandTracks;
693                 }
694             }
695 
696             Parcel* reply;
697             CHECK(msg->findPointer("reply", (void**)&reply));
698             reply->writeInt32(selectedTrack);
699 
700             sp<AMessage> response = new AMessage;
701             response->setInt32("err", err);
702 
703             sp<AReplyToken> replyID;
704             CHECK(msg->senderAwaitsResponse(&replyID));
705             response->postReply(replyID);
706             break;
707         }
708 
709         case kWhatSelectTrack:
710         {
711             sp<AReplyToken> replyID;
712             CHECK(msg->senderAwaitsResponse(&replyID));
713 
714             size_t trackIndex;
715             int32_t select;
716             int64_t timeUs;
717             CHECK(msg->findSize("trackIndex", &trackIndex));
718             CHECK(msg->findInt32("select", &select));
719             CHECK(msg->findInt64("timeUs", &timeUs));
720 
721             status_t err = INVALID_OPERATION;
722 
723             size_t inbandTracks = 0;
724             if (mSource != NULL) {
725                 inbandTracks = mSource->getTrackCount();
726             }
727             size_t ccTracks = 0;
728             if (mCCDecoder != NULL) {
729                 ccTracks = mCCDecoder->getTrackCount();
730             }
731 
732             if (trackIndex < inbandTracks) {
733                 err = mSource->selectTrack(trackIndex, select, timeUs);
734 
735                 if (!select && err == OK) {
736                     int32_t type;
737                     sp<AMessage> info = mSource->getTrackInfo(trackIndex);
738                     if (info != NULL
739                             && info->findInt32("type", &type)
740                             && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
741                         ++mTimedTextGeneration;
742                     }
743                 }
744             } else {
745                 trackIndex -= inbandTracks;
746 
747                 if (trackIndex < ccTracks) {
748                     err = mCCDecoder->selectTrack(trackIndex, select);
749                 }
750             }
751 
752             sp<AMessage> response = new AMessage;
753             response->setInt32("err", err);
754 
755             response->postReply(replyID);
756             break;
757         }
758 
759         case kWhatPollDuration:
760         {
761             int32_t generation;
762             CHECK(msg->findInt32("generation", &generation));
763 
764             if (generation != mPollDurationGeneration) {
765                 // stale
766                 break;
767             }
768 
769             int64_t durationUs;
770             if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
771                 sp<NuPlayerDriver> driver = mDriver.promote();
772                 if (driver != NULL) {
773                     driver->notifyDuration(durationUs);
774                 }
775             }
776 
777             msg->post(1000000LL);  // poll again in a second.
778             break;
779         }
780 
781         case kWhatSetVideoSurface:
782         {
783 
784             sp<RefBase> obj;
785             CHECK(msg->findObject("surface", &obj));
786             sp<Surface> surface = static_cast<Surface *>(obj.get());
787 
788             ALOGD("onSetVideoSurface(%p, %s video decoder)",
789                     surface.get(),
790                     (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
791                             && mVideoDecoder != NULL) ? "have" : "no");
792 
793             // Need to check mStarted before calling mSource->getFormat because NuPlayer might
794             // be in preparing state and it could take long time.
795             // When mStarted is true, mSource must have been set.
796             if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
797                     // NOTE: mVideoDecoder's mSurface is always non-null
798                     || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) {
799                 performSetSurface(surface);
800                 break;
801             }
802 
803             mDeferredActions.push_back(
804                     new FlushDecoderAction(
805                             (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
806                                            FLUSH_CMD_SHUTDOWN /* video */));
807 
808             mDeferredActions.push_back(new SetSurfaceAction(surface));
809 
810             if (obj != NULL) {
811                 if (mStarted) {
812                     // Issue a seek to refresh the video screen only if started otherwise
813                     // the extractor may not yet be started and will assert.
814                     // If the video decoder is not set (perhaps audio only in this case)
815                     // do not perform a seek as it is not needed.
816                     int64_t currentPositionUs = 0;
817                     if (getCurrentPosition(&currentPositionUs) == OK) {
818                         mDeferredActions.push_back(
819                                 new SeekAction(currentPositionUs,
820                                         MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
821                     }
822                 }
823 
824                 // If there is a new surface texture, instantiate decoders
825                 // again if possible.
826                 mDeferredActions.push_back(
827                         new SimpleAction(&NuPlayer::performScanSources));
828 
829                 // After a flush without shutdown, decoder is paused.
830                 // Don't resume it until source seek is done, otherwise it could
831                 // start pulling stale data too soon.
832                 mDeferredActions.push_back(
833                         new ResumeDecoderAction(false /* needNotify */));
834             }
835 
836             processDeferredActions();
837             break;
838         }
839 
840         case kWhatSetAudioSink:
841         {
842             ALOGV("kWhatSetAudioSink");
843 
844             sp<RefBase> obj;
845             CHECK(msg->findObject("sink", &obj));
846 
847             mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
848             break;
849         }
850 
851         case kWhatStart:
852         {
853             ALOGV("kWhatStart");
854             if (mStarted) {
855                 // do not resume yet if the source is still buffering
856                 if (!mPausedForBuffering) {
857                     onResume();
858                 }
859             } else {
860                 onStart();
861             }
862             mPausedByClient = false;
863             break;
864         }
865 
866         case kWhatConfigPlayback:
867         {
868             sp<AReplyToken> replyID;
869             CHECK(msg->senderAwaitsResponse(&replyID));
870             AudioPlaybackRate rate /* sanitized */;
871             readFromAMessage(msg, &rate);
872             status_t err = OK;
873             if (mRenderer != NULL) {
874                 // AudioSink allows only 1.f and 0.f for offload and direct modes.
875                 // For other speeds, restart audio to fallback to supported paths
876                 bool audioDirectOutput = (mAudioSink->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0;
877                 if ((mOffloadAudio || audioDirectOutput) &&
878                         ((rate.mSpeed != 0.f && rate.mSpeed != 1.f) || rate.mPitch != 1.f)) {
879 
880                     int64_t currentPositionUs;
881                     if (getCurrentPosition(&currentPositionUs) != OK) {
882                         currentPositionUs = mPreviousSeekTimeUs;
883                     }
884 
885                     // Set mPlaybackSettings so that the new audio decoder can
886                     // be created correctly.
887                     mPlaybackSettings = rate;
888                     if (!mPaused) {
889                         mRenderer->pause();
890                     }
891                     restartAudio(
892                             currentPositionUs, true /* forceNonOffload */,
893                             true /* needsToCreateAudioDecoder */);
894                     if (!mPaused) {
895                         mRenderer->resume();
896                     }
897                 }
898 
899                 err = mRenderer->setPlaybackSettings(rate);
900             }
901             if (err == OK) {
902                 if (rate.mSpeed == 0.f) {
903                     onPause();
904                     mPausedByClient = true;
905                     // save all other settings (using non-paused speed)
906                     // so we can restore them on start
907                     AudioPlaybackRate newRate = rate;
908                     newRate.mSpeed = mPlaybackSettings.mSpeed;
909                     mPlaybackSettings = newRate;
910                 } else { /* rate.mSpeed != 0.f */
911                     mPlaybackSettings = rate;
912                     if (mStarted) {
913                         // do not resume yet if the source is still buffering
914                         if (!mPausedForBuffering) {
915                             onResume();
916                         }
917                     } else if (mPrepared) {
918                         onStart();
919                     }
920 
921                     mPausedByClient = false;
922                 }
923             }
924 
925             if (mVideoDecoder != NULL) {
926                 sp<AMessage> params = new AMessage();
927                 params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
928                 mVideoDecoder->setParameters(params);
929             }
930 
931             sp<AMessage> response = new AMessage;
932             response->setInt32("err", err);
933             response->postReply(replyID);
934             break;
935         }
936 
937         case kWhatGetPlaybackSettings:
938         {
939             sp<AReplyToken> replyID;
940             CHECK(msg->senderAwaitsResponse(&replyID));
941             AudioPlaybackRate rate = mPlaybackSettings;
942             status_t err = OK;
943             if (mRenderer != NULL) {
944                 err = mRenderer->getPlaybackSettings(&rate);
945             }
946             if (err == OK) {
947                 // get playback settings used by renderer, as it may be
948                 // slightly off due to audiosink not taking small changes.
949                 mPlaybackSettings = rate;
950                 if (mPaused) {
951                     rate.mSpeed = 0.f;
952                 }
953             }
954             sp<AMessage> response = new AMessage;
955             if (err == OK) {
956                 writeToAMessage(response, rate);
957             }
958             response->setInt32("err", err);
959             response->postReply(replyID);
960             break;
961         }
962 
963         case kWhatConfigSync:
964         {
965             sp<AReplyToken> replyID;
966             CHECK(msg->senderAwaitsResponse(&replyID));
967 
968             ALOGV("kWhatConfigSync");
969             AVSyncSettings sync;
970             float videoFpsHint;
971             readFromAMessage(msg, &sync, &videoFpsHint);
972             status_t err = OK;
973             if (mRenderer != NULL) {
974                 err = mRenderer->setSyncSettings(sync, videoFpsHint);
975             }
976             if (err == OK) {
977                 mSyncSettings = sync;
978                 mVideoFpsHint = videoFpsHint;
979             }
980             sp<AMessage> response = new AMessage;
981             response->setInt32("err", err);
982             response->postReply(replyID);
983             break;
984         }
985 
986         case kWhatGetSyncSettings:
987         {
988             sp<AReplyToken> replyID;
989             CHECK(msg->senderAwaitsResponse(&replyID));
990             AVSyncSettings sync = mSyncSettings;
991             float videoFps = mVideoFpsHint;
992             status_t err = OK;
993             if (mRenderer != NULL) {
994                 err = mRenderer->getSyncSettings(&sync, &videoFps);
995                 if (err == OK) {
996                     mSyncSettings = sync;
997                     mVideoFpsHint = videoFps;
998                 }
999             }
1000             sp<AMessage> response = new AMessage;
1001             if (err == OK) {
1002                 writeToAMessage(response, sync, videoFps);
1003             }
1004             response->setInt32("err", err);
1005             response->postReply(replyID);
1006             break;
1007         }
1008 
1009         case kWhatScanSources:
1010         {
1011             int32_t generation;
1012             CHECK(msg->findInt32("generation", &generation));
1013             if (generation != mScanSourcesGeneration) {
1014                 // Drop obsolete msg.
1015                 break;
1016             }
1017 
1018             mScanSourcesPending = false;
1019 
1020             ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
1021                  mAudioDecoder != NULL, mVideoDecoder != NULL);
1022 
1023             bool mHadAnySourcesBefore =
1024                 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
1025             bool rescan = false;
1026 
1027             // initialize video before audio because successful initialization of
1028             // video may change deep buffer mode of audio.
1029             if (mSurface != NULL) {
1030                 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
1031                     rescan = true;
1032                 }
1033             }
1034 
1035             // Don't try to re-open audio sink if there's an existing decoder.
1036             if (mAudioSink != NULL && mAudioDecoder == NULL) {
1037                 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
1038                     rescan = true;
1039                 }
1040             }
1041 
1042             if (!mHadAnySourcesBefore
1043                     && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1044                 // This is the first time we've found anything playable.
1045 
1046                 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
1047                     schedulePollDuration();
1048                 }
1049             }
1050 
1051             status_t err;
1052             if ((err = mSource->feedMoreTSData()) != OK) {
1053                 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1054                     // We're not currently decoding anything (no audio or
1055                     // video tracks found) and we just ran out of input data.
1056 
1057                     if (err == ERROR_END_OF_STREAM) {
1058                         notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1059                     } else {
1060                         notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1061                     }
1062                 }
1063                 break;
1064             }
1065 
1066             if (rescan) {
1067                 msg->post(100000LL);
1068                 mScanSourcesPending = true;
1069             }
1070             break;
1071         }
1072 
1073         case kWhatVideoNotify:
1074         case kWhatAudioNotify:
1075         {
1076             bool audio = msg->what() == kWhatAudioNotify;
1077 
1078             int32_t currentDecoderGeneration =
1079                 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
1080             int32_t requesterGeneration = currentDecoderGeneration - 1;
1081             CHECK(msg->findInt32("generation", &requesterGeneration));
1082 
1083             if (requesterGeneration != currentDecoderGeneration) {
1084                 ALOGV("got message from old %s decoder, generation(%d:%d)",
1085                         audio ? "audio" : "video", requesterGeneration,
1086                         currentDecoderGeneration);
1087                 sp<AMessage> reply;
1088                 if (!(msg->findMessage("reply", &reply))) {
1089                     return;
1090                 }
1091 
1092                 reply->setInt32("err", INFO_DISCONTINUITY);
1093                 reply->post();
1094                 return;
1095             }
1096 
1097             int32_t what;
1098             CHECK(msg->findInt32("what", &what));
1099 
1100             if (what == DecoderBase::kWhatInputDiscontinuity) {
1101                 int32_t formatChange;
1102                 CHECK(msg->findInt32("formatChange", &formatChange));
1103 
1104                 ALOGV("%s discontinuity: formatChange %d",
1105                         audio ? "audio" : "video", formatChange);
1106 
1107                 if (formatChange) {
1108                     mDeferredActions.push_back(
1109                             new FlushDecoderAction(
1110                                 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1111                                 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1112                 }
1113 
1114                 mDeferredActions.push_back(
1115                         new SimpleAction(
1116                                 &NuPlayer::performScanSources));
1117 
1118                 processDeferredActions();
1119             } else if (what == DecoderBase::kWhatEOS) {
1120                 int32_t err;
1121                 CHECK(msg->findInt32("err", &err));
1122 
1123                 if (err == ERROR_END_OF_STREAM) {
1124                     ALOGV("got %s decoder EOS", audio ? "audio" : "video");
1125                 } else {
1126                     ALOGV("got %s decoder EOS w/ error %d",
1127                          audio ? "audio" : "video",
1128                          err);
1129                 }
1130 
1131                 mRenderer->queueEOS(audio, err);
1132             } else if (what == DecoderBase::kWhatFlushCompleted) {
1133                 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
1134 
1135                 handleFlushComplete(audio, true /* isDecoder */);
1136                 finishFlushIfPossible();
1137             } else if (what == DecoderBase::kWhatVideoSizeChanged) {
1138                 sp<AMessage> format;
1139                 CHECK(msg->findMessage("format", &format));
1140 
1141                 sp<AMessage> inputFormat =
1142                         mSource->getFormat(false /* audio */);
1143 
1144                 setVideoScalingMode(mVideoScalingMode);
1145                 updateVideoSize(inputFormat, format);
1146             } else if (what == DecoderBase::kWhatShutdownCompleted) {
1147                 ALOGV("%s shutdown completed", audio ? "audio" : "video");
1148                 if (audio) {
1149                     Mutex::Autolock autoLock(mDecoderLock);
1150                     mAudioDecoder.clear();
1151                     mAudioDecoderError = false;
1152                     ++mAudioDecoderGeneration;
1153 
1154                     CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
1155                     mFlushingAudio = SHUT_DOWN;
1156                 } else {
1157                     Mutex::Autolock autoLock(mDecoderLock);
1158                     mVideoDecoder.clear();
1159                     mVideoDecoderError = false;
1160                     ++mVideoDecoderGeneration;
1161 
1162                     CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
1163                     mFlushingVideo = SHUT_DOWN;
1164                 }
1165 
1166                 finishFlushIfPossible();
1167             } else if (what == DecoderBase::kWhatResumeCompleted) {
1168                 finishResume();
1169             } else if (what == DecoderBase::kWhatError) {
1170                 status_t err;
1171                 if (!msg->findInt32("err", &err) || err == OK) {
1172                     err = UNKNOWN_ERROR;
1173                 }
1174 
1175                 // Decoder errors can be due to Source (e.g. from streaming),
1176                 // or from decoding corrupted bitstreams, or from other decoder
1177                 // MediaCodec operations (e.g. from an ongoing reset or seek).
1178                 // They may also be due to openAudioSink failure at
1179                 // decoder start or after a format change.
1180                 //
1181                 // We try to gracefully shut down the affected decoder if possible,
1182                 // rather than trying to force the shutdown with something
1183                 // similar to performReset(). This method can lead to a hang
1184                 // if MediaCodec functions block after an error, but they should
1185                 // typically return INVALID_OPERATION instead of blocking.
1186 
1187                 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
1188                 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
1189                         err, audio ? "audio" : "video", *flushing);
1190 
1191                 switch (*flushing) {
1192                     case NONE:
1193                         mDeferredActions.push_back(
1194                                 new FlushDecoderAction(
1195                                     audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1196                                     audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
1197                         processDeferredActions();
1198                         break;
1199                     case FLUSHING_DECODER:
1200                         *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
1201                         break; // Wait for flush to complete.
1202                     case FLUSHING_DECODER_SHUTDOWN:
1203                         break; // Wait for flush to complete.
1204                     case SHUTTING_DOWN_DECODER:
1205                         break; // Wait for shutdown to complete.
1206                     case FLUSHED:
1207                         getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
1208                         *flushing = SHUTTING_DOWN_DECODER;     // Shut down.
1209                         break;
1210                     case SHUT_DOWN:
1211                         finishFlushIfPossible();  // Should not occur.
1212                         break;                    // Finish anyways.
1213                 }
1214                 if (mSource != nullptr) {
1215                     if (audio) {
1216                         if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
1217                                 || mSurface == NULL || mVideoDecoder == NULL) {
1218                             // When both audio and video have error, or this stream has only audio
1219                             // which has error, notify client of error.
1220                             notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1221                         } else {
1222                             // Only audio track has error. Video track could be still good to play.
1223                             notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_AUDIO_ERROR, err);
1224                         }
1225                         mAudioDecoderError = true;
1226                     } else {
1227                         if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
1228                                 || mAudioSink == NULL || mAudioDecoder == NULL) {
1229                             // When both audio and video have error, or this stream has only video
1230                             // which has error, notify client of error.
1231                             notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1232                         } else {
1233                             // Only video track has error. Audio track could be still good to play.
1234                             notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_VIDEO_ERROR, err);
1235                         }
1236                         mVideoDecoderError = true;
1237                     }
1238                 }
1239             } else {
1240                 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
1241                       what,
1242                       what >> 24,
1243                       (what >> 16) & 0xff,
1244                       (what >> 8) & 0xff,
1245                       what & 0xff);
1246             }
1247 
1248             break;
1249         }
1250 
1251         case kWhatRendererNotify:
1252         {
1253             int32_t requesterGeneration = mRendererGeneration - 1;
1254             CHECK(msg->findInt32("generation", &requesterGeneration));
1255             if (requesterGeneration != mRendererGeneration) {
1256                 ALOGV("got message from old renderer, generation(%d:%d)",
1257                         requesterGeneration, mRendererGeneration);
1258                 return;
1259             }
1260 
1261             int32_t what;
1262             CHECK(msg->findInt32("what", &what));
1263 
1264             if (what == Renderer::kWhatEOS) {
1265                 int32_t audio;
1266                 CHECK(msg->findInt32("audio", &audio));
1267 
1268                 int32_t finalResult;
1269                 CHECK(msg->findInt32("finalResult", &finalResult));
1270 
1271                 if (audio) {
1272                     mAudioEOS = true;
1273                 } else {
1274                     mVideoEOS = true;
1275                 }
1276 
1277                 if (finalResult == ERROR_END_OF_STREAM) {
1278                     ALOGV("reached %s EOS", audio ? "audio" : "video");
1279                 } else {
1280                     ALOGE("%s track encountered an error (%d)",
1281                          audio ? "audio" : "video", finalResult);
1282 
1283                     notifyListener(
1284                             MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
1285                 }
1286 
1287                 if ((mAudioEOS || mAudioDecoder == NULL)
1288                         && (mVideoEOS || mVideoDecoder == NULL)) {
1289                     notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
1290                 }
1291             } else if (what == Renderer::kWhatFlushComplete) {
1292                 int32_t audio;
1293                 CHECK(msg->findInt32("audio", &audio));
1294 
1295                 if (audio) {
1296                     mAudioEOS = false;
1297                 } else {
1298                     mVideoEOS = false;
1299                 }
1300 
1301                 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
1302                 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
1303                         || mFlushingAudio == SHUT_DOWN)) {
1304                     // Flush has been handled by tear down.
1305                     break;
1306                 }
1307                 handleFlushComplete(audio, false /* isDecoder */);
1308                 finishFlushIfPossible();
1309             } else if (what == Renderer::kWhatVideoRenderingStart) {
1310                 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
1311             } else if (what == Renderer::kWhatMediaRenderingStart) {
1312                 ALOGV("media rendering started");
1313                 notifyListener(MEDIA_STARTED, 0, 0);
1314             } else if (what == Renderer::kWhatAudioTearDown) {
1315                 int32_t reason;
1316                 CHECK(msg->findInt32("reason", &reason));
1317                 ALOGV("Tear down audio with reason %d.", reason);
1318                 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
1319                     // TimeoutWhenPaused is only for offload mode.
1320                     ALOGW("Received a stale message for teardown, mPaused(%d), mOffloadAudio(%d)",
1321                           mPaused, mOffloadAudio);
1322                     break;
1323                 }
1324                 int64_t positionUs;
1325                 if (!msg->findInt64("positionUs", &positionUs)) {
1326                     positionUs = mPreviousSeekTimeUs;
1327                 }
1328 
1329                 restartAudio(
1330                         positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
1331                         reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
1332             }
1333             break;
1334         }
1335 
1336         case kWhatMoreDataQueued:
1337         {
1338             break;
1339         }
1340 
1341         case kWhatReset:
1342         {
1343             ALOGV("kWhatReset");
1344 
1345             mResetting = true;
1346             updatePlaybackTimer(true /* stopping */, "kWhatReset");
1347             updateRebufferingTimer(true /* stopping */, true /* exiting */);
1348 
1349             mDeferredActions.push_back(
1350                     new FlushDecoderAction(
1351                         FLUSH_CMD_SHUTDOWN /* audio */,
1352                         FLUSH_CMD_SHUTDOWN /* video */));
1353 
1354             mDeferredActions.push_back(
1355                     new SimpleAction(&NuPlayer::performReset));
1356 
1357             processDeferredActions();
1358             break;
1359         }
1360 
1361         case kWhatNotifyTime:
1362         {
1363             ALOGV("kWhatNotifyTime");
1364             int64_t timerUs;
1365             CHECK(msg->findInt64("timerUs", &timerUs));
1366 
1367             notifyListener(MEDIA_NOTIFY_TIME, timerUs, 0);
1368             break;
1369         }
1370 
1371         case kWhatSeek:
1372         {
1373             int64_t seekTimeUs;
1374             int32_t mode;
1375             int32_t needNotify;
1376             CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1377             CHECK(msg->findInt32("mode", &mode));
1378             CHECK(msg->findInt32("needNotify", &needNotify));
1379 
1380             ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
1381                     (long long)seekTimeUs, mode, needNotify);
1382 
1383             if (!mStarted) {
1384                 // Seek before the player is started. In order to preview video,
1385                 // need to start the player and pause it. This branch is called
1386                 // only once if needed. After the player is started, any seek
1387                 // operation will go through normal path.
1388                 // Audio-only cases are handled separately.
1389                 onStart(seekTimeUs, (MediaPlayerSeekMode)mode);
1390                 if (mStarted) {
1391                     onPause();
1392                     mPausedByClient = true;
1393                 }
1394                 if (needNotify) {
1395                     notifyDriverSeekComplete();
1396                 }
1397                 break;
1398             }
1399 
1400             mDeferredActions.push_back(
1401                     new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
1402                                            FLUSH_CMD_FLUSH /* video */));
1403 
1404             mDeferredActions.push_back(
1405                     new SeekAction(seekTimeUs, (MediaPlayerSeekMode)mode));
1406 
1407             // After a flush without shutdown, decoder is paused.
1408             // Don't resume it until source seek is done, otherwise it could
1409             // start pulling stale data too soon.
1410             mDeferredActions.push_back(
1411                     new ResumeDecoderAction(needNotify));
1412 
1413             processDeferredActions();
1414             break;
1415         }
1416 
1417         case kWhatPause:
1418         {
1419             onPause();
1420             mPausedByClient = true;
1421             break;
1422         }
1423 
1424         case kWhatSourceNotify:
1425         {
1426             onSourceNotify(msg);
1427             break;
1428         }
1429 
1430         case kWhatClosedCaptionNotify:
1431         {
1432             onClosedCaptionNotify(msg);
1433             break;
1434         }
1435 
1436         case kWhatPrepareDrm:
1437         {
1438             status_t status = onPrepareDrm(msg);
1439 
1440             sp<AMessage> response = new AMessage;
1441             response->setInt32("status", status);
1442             sp<AReplyToken> replyID;
1443             CHECK(msg->senderAwaitsResponse(&replyID));
1444             response->postReply(replyID);
1445             break;
1446         }
1447 
1448         case kWhatReleaseDrm:
1449         {
1450             status_t status = onReleaseDrm();
1451 
1452             sp<AMessage> response = new AMessage;
1453             response->setInt32("status", status);
1454             sp<AReplyToken> replyID;
1455             CHECK(msg->senderAwaitsResponse(&replyID));
1456             response->postReply(replyID);
1457             break;
1458         }
1459 
1460         case kWhatMediaClockNotify:
1461         {
1462             ALOGV("kWhatMediaClockNotify");
1463             int64_t anchorMediaUs, anchorRealUs;
1464             float playbackRate;
1465             CHECK(msg->findInt64("anchor-media-us", &anchorMediaUs));
1466             CHECK(msg->findInt64("anchor-real-us", &anchorRealUs));
1467             CHECK(msg->findFloat("playback-rate", &playbackRate));
1468 
1469             Parcel in;
1470             in.writeInt64(anchorMediaUs);
1471             in.writeInt64(anchorRealUs);
1472             in.writeFloat(playbackRate);
1473 
1474             notifyListener(MEDIA_TIME_DISCONTINUITY, 0, 0, &in);
1475             break;
1476         }
1477 
1478         default:
1479             TRESPASS();
1480             break;
1481     }
1482 }
1483 
onResume()1484 void NuPlayer::onResume() {
1485     if (!mPaused || mResetting) {
1486         ALOGD_IF(mResetting, "resetting, onResume discarded");
1487         return;
1488     }
1489     mPaused = false;
1490     if (mSource != NULL) {
1491         mSource->resume();
1492     } else {
1493         ALOGW("resume called when source is gone or not set");
1494     }
1495     // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1496     // needed.
1497     if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1498         instantiateDecoder(true /* audio */, &mAudioDecoder);
1499     }
1500     if (mRenderer != NULL) {
1501         mRenderer->resume();
1502     } else {
1503         ALOGW("resume called when renderer is gone or not set");
1504     }
1505 
1506     startPlaybackTimer("onresume");
1507 }
1508 
onInstantiateSecureDecoders()1509 status_t NuPlayer::onInstantiateSecureDecoders() {
1510     status_t err;
1511     if (!(mSourceFlags & Source::FLAG_SECURE)) {
1512         return BAD_TYPE;
1513     }
1514 
1515     if (mRenderer != NULL) {
1516         ALOGE("renderer should not be set when instantiating secure decoders");
1517         return UNKNOWN_ERROR;
1518     }
1519 
1520     // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
1521     // data on instantiation.
1522     if (mSurface != NULL) {
1523         err = instantiateDecoder(false, &mVideoDecoder);
1524         if (err != OK) {
1525             return err;
1526         }
1527     }
1528 
1529     if (mAudioSink != NULL) {
1530         err = instantiateDecoder(true, &mAudioDecoder);
1531         if (err != OK) {
1532             return err;
1533         }
1534     }
1535     return OK;
1536 }
1537 
onStart(int64_t startPositionUs,MediaPlayerSeekMode mode)1538 void NuPlayer::onStart(int64_t startPositionUs, MediaPlayerSeekMode mode) {
1539     ALOGV("onStart: mCrypto: %p (%d)", mCrypto.get(),
1540             (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
1541 
1542     if (!mSourceStarted) {
1543         mSourceStarted = true;
1544         mSource->start();
1545     }
1546     if (startPositionUs > 0) {
1547         performSeek(startPositionUs, mode);
1548         if (mSource->getFormat(false /* audio */) == NULL) {
1549             return;
1550         }
1551     }
1552 
1553     mOffloadAudio = false;
1554     mAudioEOS = false;
1555     mVideoEOS = false;
1556     mStarted = true;
1557     mPaused = false;
1558 
1559     uint32_t flags = 0;
1560 
1561     if (mSource->isRealTime()) {
1562         flags |= Renderer::FLAG_REAL_TIME;
1563     }
1564 
1565     bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
1566     bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
1567     if (!hasAudio && !hasVideo) {
1568         ALOGE("no metadata for either audio or video source");
1569         mSource->stop();
1570         mSourceStarted = false;
1571         notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_MALFORMED);
1572         return;
1573     }
1574     ALOGV_IF(!hasAudio, "no metadata for audio source");  // video only stream
1575 
1576     sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1577 
1578     audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1579     if (mAudioSink != NULL) {
1580         streamType = mAudioSink->getAudioStreamType();
1581     }
1582 
1583     mOffloadAudio =
1584         canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
1585                 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1586 
1587     // Modular DRM: Disabling audio offload if the source is protected
1588     if (mOffloadAudio && mIsDrmProtected) {
1589         mOffloadAudio = false;
1590         ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
1591     }
1592 
1593     if (mOffloadAudio) {
1594         flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1595     }
1596 
1597     sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1598     ++mRendererGeneration;
1599     notify->setInt32("generation", mRendererGeneration);
1600     mRenderer = new Renderer(mAudioSink, mMediaClock, notify, flags);
1601     mRendererLooper = new ALooper;
1602     mRendererLooper->setName("NuPlayerRenderer");
1603     mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1604     mRendererLooper->registerHandler(mRenderer);
1605 
1606     status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
1607     if (err != OK) {
1608         mSource->stop();
1609         mSourceStarted = false;
1610         notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
1611         return;
1612     }
1613 
1614     float rate = getFrameRate();
1615     if (rate > 0) {
1616         mRenderer->setVideoFrameRate(rate);
1617     }
1618 
1619     if (mVideoDecoder != NULL) {
1620         mVideoDecoder->setRenderer(mRenderer);
1621     }
1622     if (mAudioDecoder != NULL) {
1623         mAudioDecoder->setRenderer(mRenderer);
1624     }
1625 
1626     startPlaybackTimer("onstart");
1627 
1628     postScanSources();
1629 }
1630 
startPlaybackTimer(const char * where)1631 void NuPlayer::startPlaybackTimer(const char *where) {
1632     Mutex::Autolock autoLock(mPlayingTimeLock);
1633     if (mLastStartedPlayingTimeNs == 0) {
1634         mLastStartedPlayingTimeNs = systemTime();
1635         ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)",  mLastStartedPlayingTimeNs, where);
1636     }
1637 }
1638 
updatePlaybackTimer(bool stopping,const char * where)1639 void NuPlayer::updatePlaybackTimer(bool stopping, const char *where) {
1640     Mutex::Autolock autoLock(mPlayingTimeLock);
1641 
1642     ALOGV("updatePlaybackTimer(%s)  time %20" PRId64 " (%s)",
1643 	  stopping ? "stop" : "snap", mLastStartedPlayingTimeNs, where);
1644 
1645     if (mLastStartedPlayingTimeNs != 0) {
1646         sp<NuPlayerDriver> driver = mDriver.promote();
1647         int64_t now = systemTime();
1648         if (driver != NULL) {
1649             int64_t played = now - mLastStartedPlayingTimeNs;
1650             ALOGV("updatePlaybackTimer()  log  %20" PRId64 "", played);
1651 
1652             if (played > 0) {
1653                 driver->notifyMorePlayingTimeUs((played+500)/1000);
1654             }
1655         }
1656 	if (stopping) {
1657             mLastStartedPlayingTimeNs = 0;
1658 	} else {
1659             mLastStartedPlayingTimeNs = now;
1660 	}
1661     }
1662 }
1663 
startRebufferingTimer()1664 void NuPlayer::startRebufferingTimer() {
1665     Mutex::Autolock autoLock(mPlayingTimeLock);
1666     if (mLastStartedRebufferingTimeNs == 0) {
1667         mLastStartedRebufferingTimeNs = systemTime();
1668         ALOGV("startRebufferingTimer() time %20" PRId64 "",  mLastStartedRebufferingTimeNs);
1669     }
1670 }
1671 
updateRebufferingTimer(bool stopping,bool exitingPlayback)1672 void NuPlayer::updateRebufferingTimer(bool stopping, bool exitingPlayback) {
1673     Mutex::Autolock autoLock(mPlayingTimeLock);
1674 
1675     ALOGV("updateRebufferingTimer(%s)  time %20" PRId64 " (exiting %d)",
1676 	  stopping ? "stop" : "snap", mLastStartedRebufferingTimeNs, exitingPlayback);
1677 
1678     if (mLastStartedRebufferingTimeNs != 0) {
1679         sp<NuPlayerDriver> driver = mDriver.promote();
1680         int64_t now = systemTime();
1681         if (driver != NULL) {
1682             int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
1683             ALOGV("updateRebufferingTimer()  log  %20" PRId64 "", rebuffered);
1684 
1685             if (rebuffered > 0) {
1686                 driver->notifyMoreRebufferingTimeUs((rebuffered+500)/1000);
1687                 if (exitingPlayback) {
1688                     driver->notifyRebufferingWhenExit(true);
1689                 }
1690             }
1691         }
1692 	if (stopping) {
1693             mLastStartedRebufferingTimeNs = 0;
1694 	} else {
1695             mLastStartedRebufferingTimeNs = now;
1696 	}
1697     }
1698 }
1699 
updateInternalTimers()1700 void NuPlayer::updateInternalTimers() {
1701     // update values, but ticking clocks keep ticking
1702     ALOGV("updateInternalTimers()");
1703     updatePlaybackTimer(false /* stopping */, "updateInternalTimers");
1704     updateRebufferingTimer(false /* stopping */, false /* exiting */);
1705 }
1706 
setTargetBitrate(int bitrate)1707 void NuPlayer::setTargetBitrate(int bitrate) {
1708     if (mSource != NULL) {
1709         mSource->setTargetBitrate(bitrate);
1710     }
1711 }
1712 
onPause()1713 void NuPlayer::onPause() {
1714 
1715     updatePlaybackTimer(true /* stopping */, "onPause");
1716 
1717     if (mPaused) {
1718         return;
1719     }
1720     mPaused = true;
1721     if (mSource != NULL) {
1722         mSource->pause();
1723     } else {
1724         ALOGW("pause called when source is gone or not set");
1725     }
1726     if (mRenderer != NULL) {
1727         mRenderer->pause();
1728     } else {
1729         ALOGW("pause called when renderer is gone or not set");
1730     }
1731 
1732 }
1733 
audioDecoderStillNeeded()1734 bool NuPlayer::audioDecoderStillNeeded() {
1735     // Audio decoder is no longer needed if it's in shut/shutting down status.
1736     return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1737 }
1738 
handleFlushComplete(bool audio,bool isDecoder)1739 void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
1740     // We wait for both the decoder flush and the renderer flush to complete
1741     // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1742 
1743     mFlushComplete[audio][isDecoder] = true;
1744     if (!mFlushComplete[audio][!isDecoder]) {
1745         return;
1746     }
1747 
1748     FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1749     switch (*state) {
1750         case FLUSHING_DECODER:
1751         {
1752             *state = FLUSHED;
1753             break;
1754         }
1755 
1756         case FLUSHING_DECODER_SHUTDOWN:
1757         {
1758             *state = SHUTTING_DOWN_DECODER;
1759 
1760             ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1761             getDecoder(audio)->initiateShutdown();
1762             break;
1763         }
1764 
1765         default:
1766             // decoder flush completes only occur in a flushing state.
1767             LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1768             break;
1769     }
1770 }
1771 
finishFlushIfPossible()1772 void NuPlayer::finishFlushIfPossible() {
1773     if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1774             && mFlushingAudio != SHUT_DOWN) {
1775         return;
1776     }
1777 
1778     if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1779             && mFlushingVideo != SHUT_DOWN) {
1780         return;
1781     }
1782 
1783     ALOGV("both audio and video are flushed now.");
1784 
1785     mFlushingAudio = NONE;
1786     mFlushingVideo = NONE;
1787 
1788     clearFlushComplete();
1789 
1790     processDeferredActions();
1791 }
1792 
postScanSources()1793 void NuPlayer::postScanSources() {
1794     if (mScanSourcesPending) {
1795         return;
1796     }
1797 
1798     sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1799     msg->setInt32("generation", mScanSourcesGeneration);
1800     msg->post();
1801 
1802     mScanSourcesPending = true;
1803 }
1804 
tryOpenAudioSinkForOffload(const sp<AMessage> & format,const sp<MetaData> & audioMeta,bool hasVideo)1805 void NuPlayer::tryOpenAudioSinkForOffload(
1806         const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
1807     // Note: This is called early in NuPlayer to determine whether offloading
1808     // is possible; otherwise the decoders call the renderer openAudioSink directly.
1809 
1810     status_t err = mRenderer->openAudioSink(
1811             format, true /* offloadOnly */, hasVideo,
1812             AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
1813     if (err != OK) {
1814         // Any failure we turn off mOffloadAudio.
1815         mOffloadAudio = false;
1816     } else if (mOffloadAudio) {
1817         sendMetaDataToHal(mAudioSink, audioMeta);
1818     }
1819 }
1820 
closeAudioSink()1821 void NuPlayer::closeAudioSink() {
1822     if (mRenderer != NULL) {
1823         mRenderer->closeAudioSink();
1824     }
1825 }
1826 
restartAudio(int64_t currentPositionUs,bool forceNonOffload,bool needsToCreateAudioDecoder)1827 void NuPlayer::restartAudio(
1828         int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
1829     ALOGD("restartAudio timeUs(%lld), dontOffload(%d), createDecoder(%d)",
1830           (long long)currentPositionUs, forceNonOffload, needsToCreateAudioDecoder);
1831     if (mAudioDecoder != NULL) {
1832         mAudioDecoder->pause();
1833         Mutex::Autolock autoLock(mDecoderLock);
1834         mAudioDecoder.clear();
1835         mAudioDecoderError = false;
1836         ++mAudioDecoderGeneration;
1837     }
1838     if (mFlushingAudio == FLUSHING_DECODER) {
1839         mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1840         mFlushingAudio = FLUSHED;
1841         finishFlushIfPossible();
1842     } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
1843             || mFlushingAudio == SHUTTING_DOWN_DECODER) {
1844         mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
1845         mFlushingAudio = SHUT_DOWN;
1846         finishFlushIfPossible();
1847         needsToCreateAudioDecoder = false;
1848     }
1849     if (mRenderer == NULL) {
1850         return;
1851     }
1852     closeAudioSink();
1853     mRenderer->flush(true /* audio */, false /* notifyComplete */);
1854     if (mVideoDecoder != NULL) {
1855         mDeferredActions.push_back(
1856                 new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
1857                                        FLUSH_CMD_FLUSH /* video */));
1858         mDeferredActions.push_back(
1859                 new SeekAction(currentPositionUs,
1860                 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
1861         // After a flush without shutdown, decoder is paused.
1862         // Don't resume it until source seek is done, otherwise it could
1863         // start pulling stale data too soon.
1864         mDeferredActions.push_back(new ResumeDecoderAction(false));
1865         processDeferredActions();
1866     } else {
1867         performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
1868     }
1869 
1870     if (forceNonOffload) {
1871         mRenderer->signalDisableOffloadAudio();
1872         mOffloadAudio = false;
1873     }
1874     if (needsToCreateAudioDecoder) {
1875         instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
1876     }
1877 }
1878 
determineAudioModeChange(const sp<AMessage> & audioFormat)1879 void NuPlayer::determineAudioModeChange(const sp<AMessage> &audioFormat) {
1880     if (mSource == NULL || mAudioSink == NULL) {
1881         return;
1882     }
1883 
1884     if (mRenderer == NULL) {
1885         ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
1886         mOffloadAudio = false;
1887         return;
1888     }
1889 
1890     sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1891     sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1892     audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
1893     const bool hasVideo = (videoFormat != NULL);
1894     bool canOffload = canOffloadStream(
1895             audioMeta, hasVideo, mSource->isStreaming(), streamType)
1896                     && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
1897 
1898     // Modular DRM: Disabling audio offload if the source is protected
1899     if (canOffload && mIsDrmProtected) {
1900         canOffload = false;
1901         ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
1902     }
1903 
1904     if (canOffload) {
1905         if (!mOffloadAudio) {
1906             mRenderer->signalEnableOffloadAudio();
1907         }
1908         // open audio sink early under offload mode.
1909         tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
1910     } else {
1911         if (mOffloadAudio) {
1912             mRenderer->signalDisableOffloadAudio();
1913             mOffloadAudio = false;
1914         }
1915     }
1916 }
1917 
instantiateDecoder(bool audio,sp<DecoderBase> * decoder,bool checkAudioModeChange)1918 status_t NuPlayer::instantiateDecoder(
1919         bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
1920     // The audio decoder could be cleared by tear down. If still in shut down
1921     // process, no need to create a new audio decoder.
1922     if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
1923         return OK;
1924     }
1925 
1926     sp<AMessage> format = mSource->getFormat(audio);
1927 
1928     if (format == NULL) {
1929         return UNKNOWN_ERROR;
1930     } else {
1931         status_t err;
1932         if (format->findInt32("err", &err) && err) {
1933             return err;
1934         }
1935     }
1936 
1937     format->setInt32("priority", 0 /* realtime */);
1938 
1939     if (mDataSourceType == DATA_SOURCE_TYPE_RTP) {
1940         ALOGV("instantiateDecoder: set decoder error free on stream corrupt.");
1941         format->setInt32("corrupt-free", true);
1942     }
1943 
1944     if (!audio) {
1945         AString mime;
1946         CHECK(format->findString("mime", &mime));
1947 
1948         sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
1949         if (mCCDecoder == NULL) {
1950             mCCDecoder = new CCDecoder(ccNotify);
1951         }
1952 
1953         if (mSourceFlags & Source::FLAG_SECURE) {
1954             format->setInt32("secure", true);
1955         }
1956 
1957         if (mSourceFlags & Source::FLAG_PROTECTED) {
1958             format->setInt32("protected", true);
1959         }
1960 
1961         float rate = getFrameRate();
1962         if (rate > 0) {
1963             format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
1964         }
1965     }
1966 
1967     Mutex::Autolock autoLock(mDecoderLock);
1968 
1969     if (audio) {
1970         sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
1971         ++mAudioDecoderGeneration;
1972         notify->setInt32("generation", mAudioDecoderGeneration);
1973 
1974         if (checkAudioModeChange) {
1975             determineAudioModeChange(format);
1976         }
1977         if (mOffloadAudio) {
1978             mSource->setOffloadAudio(true /* offload */);
1979 
1980             const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1981             format->setInt32("has-video", hasVideo);
1982             *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
1983             ALOGV("instantiateDecoder audio DecoderPassThrough  hasVideo: %d", hasVideo);
1984         } else {
1985             mSource->setOffloadAudio(false /* offload */);
1986 
1987             *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
1988             ALOGV("instantiateDecoder audio Decoder");
1989         }
1990         mAudioDecoderError = false;
1991     } else {
1992         sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
1993         ++mVideoDecoderGeneration;
1994         notify->setInt32("generation", mVideoDecoderGeneration);
1995 
1996         *decoder = new Decoder(
1997                 notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder);
1998         mVideoDecoderError = false;
1999 
2000         // enable FRC if high-quality AV sync is requested, even if not
2001         // directly queuing to display, as this will even improve textureview
2002         // playback.
2003         {
2004             if (property_get_bool("persist.sys.media.avsync", false)) {
2005                 format->setInt32("auto-frc", 1);
2006             }
2007         }
2008     }
2009     (*decoder)->init();
2010 
2011     // Modular DRM
2012     if (mIsDrmProtected) {
2013         format->setPointer("crypto", mCrypto.get());
2014         ALOGV("instantiateDecoder: mCrypto: %p (%d) isSecure: %d", mCrypto.get(),
2015                 (mCrypto != NULL ? mCrypto->getStrongCount() : 0),
2016                 (mSourceFlags & Source::FLAG_SECURE) != 0);
2017     }
2018 
2019     (*decoder)->configure(format);
2020 
2021     if (!audio) {
2022         sp<AMessage> params = new AMessage();
2023         float rate = getFrameRate();
2024         if (rate > 0) {
2025             params->setFloat("frame-rate-total", rate);
2026         }
2027 
2028         sp<MetaData> fileMeta = getFileMeta();
2029         if (fileMeta != NULL) {
2030             int32_t videoTemporalLayerCount;
2031             if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2032                     && videoTemporalLayerCount > 0) {
2033                 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2034             }
2035         }
2036 
2037         if (params->countEntries() > 0) {
2038             (*decoder)->setParameters(params);
2039         }
2040     }
2041     return OK;
2042 }
2043 
updateVideoSize(const sp<AMessage> & inputFormat,const sp<AMessage> & outputFormat)2044 void NuPlayer::updateVideoSize(
2045         const sp<AMessage> &inputFormat,
2046         const sp<AMessage> &outputFormat) {
2047     if (inputFormat == NULL) {
2048         ALOGW("Unknown video size, reporting 0x0!");
2049         notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
2050         return;
2051     }
2052     int32_t err = OK;
2053     inputFormat->findInt32("err", &err);
2054     if (err == -EWOULDBLOCK) {
2055         ALOGW("Video meta is not available yet!");
2056         return;
2057     }
2058     if (err != OK) {
2059         ALOGW("Something is wrong with video meta!");
2060         return;
2061     }
2062 
2063     int32_t displayWidth, displayHeight;
2064     if (outputFormat != NULL) {
2065         int32_t width, height;
2066         CHECK(outputFormat->findInt32("width", &width));
2067         CHECK(outputFormat->findInt32("height", &height));
2068 
2069         int32_t cropLeft, cropTop, cropRight, cropBottom;
2070         CHECK(outputFormat->findRect(
2071                     "crop",
2072                     &cropLeft, &cropTop, &cropRight, &cropBottom));
2073 
2074         displayWidth = cropRight - cropLeft + 1;
2075         displayHeight = cropBottom - cropTop + 1;
2076 
2077         ALOGV("Video output format changed to %d x %d "
2078              "(crop: %d x %d @ (%d, %d))",
2079              width, height,
2080              displayWidth,
2081              displayHeight,
2082              cropLeft, cropTop);
2083     } else {
2084         CHECK(inputFormat->findInt32("width", &displayWidth));
2085         CHECK(inputFormat->findInt32("height", &displayHeight));
2086 
2087         ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2088     }
2089 
2090     // Take into account sample aspect ratio if necessary:
2091     int32_t sarWidth, sarHeight;
2092     if (inputFormat->findInt32("sar-width", &sarWidth)
2093             && inputFormat->findInt32("sar-height", &sarHeight)
2094             && sarWidth > 0 && sarHeight > 0) {
2095         ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2096 
2097         displayWidth = (displayWidth * sarWidth) / sarHeight;
2098 
2099         ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2100     } else {
2101         int32_t width, height;
2102         if (inputFormat->findInt32("display-width", &width)
2103                 && inputFormat->findInt32("display-height", &height)
2104                 && width > 0 && height > 0
2105                 && displayWidth > 0 && displayHeight > 0) {
2106             if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2107                 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2108             } else {
2109                 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2110             }
2111             ALOGV("Video display width and height are overridden to %d x %d",
2112                  displayWidth, displayHeight);
2113         }
2114     }
2115 
2116     int32_t rotationDegrees;
2117     if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2118         rotationDegrees = 0;
2119     }
2120 
2121     if (rotationDegrees == 90 || rotationDegrees == 270) {
2122         int32_t tmp = displayWidth;
2123         displayWidth = displayHeight;
2124         displayHeight = tmp;
2125     }
2126 
2127     notifyListener(
2128             MEDIA_SET_VIDEO_SIZE,
2129             displayWidth,
2130             displayHeight);
2131 }
2132 
notifyListener(int msg,int ext1,int ext2,const Parcel * in)2133 void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
2134     if (mDriver == NULL) {
2135         return;
2136     }
2137 
2138     sp<NuPlayerDriver> driver = mDriver.promote();
2139 
2140     if (driver == NULL) {
2141         return;
2142     }
2143 
2144     driver->notifyListener(msg, ext1, ext2, in);
2145 }
2146 
flushDecoder(bool audio,bool needShutdown)2147 void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
2148     ALOGV("[%s] flushDecoder needShutdown=%d",
2149           audio ? "audio" : "video", needShutdown);
2150 
2151     const sp<DecoderBase> &decoder = getDecoder(audio);
2152     if (decoder == NULL) {
2153         ALOGI("flushDecoder %s without decoder present",
2154              audio ? "audio" : "video");
2155         return;
2156     }
2157 
2158     // Make sure we don't continue to scan sources until we finish flushing.
2159     ++mScanSourcesGeneration;
2160     if (mScanSourcesPending) {
2161         if (!needShutdown) {
2162             mDeferredActions.push_back(
2163                     new SimpleAction(&NuPlayer::performScanSources));
2164         }
2165         mScanSourcesPending = false;
2166     }
2167 
2168     decoder->signalFlush();
2169 
2170     FlushStatus newStatus =
2171         needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2172 
2173     mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2174     mFlushComplete[audio][true /* isDecoder */] = false;
2175     if (audio) {
2176         ALOGE_IF(mFlushingAudio != NONE,
2177                 "audio flushDecoder() is called in state %d", mFlushingAudio);
2178         mFlushingAudio = newStatus;
2179     } else {
2180         ALOGE_IF(mFlushingVideo != NONE,
2181                 "video flushDecoder() is called in state %d", mFlushingVideo);
2182         mFlushingVideo = newStatus;
2183     }
2184 }
2185 
queueDecoderShutdown(bool audio,bool video,const sp<AMessage> & reply)2186 void NuPlayer::queueDecoderShutdown(
2187         bool audio, bool video, const sp<AMessage> &reply) {
2188     ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2189 
2190     mDeferredActions.push_back(
2191             new FlushDecoderAction(
2192                 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2193                 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2194 
2195     mDeferredActions.push_back(
2196             new SimpleAction(&NuPlayer::performScanSources));
2197 
2198     mDeferredActions.push_back(new PostMessageAction(reply));
2199 
2200     processDeferredActions();
2201 }
2202 
setVideoScalingMode(int32_t mode)2203 status_t NuPlayer::setVideoScalingMode(int32_t mode) {
2204     mVideoScalingMode = mode;
2205     if (mSurface != NULL) {
2206         status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode);
2207         if (ret != OK) {
2208             ALOGE("Failed to set scaling mode (%d): %s",
2209                 -ret, strerror(-ret));
2210             return ret;
2211         }
2212     }
2213     return OK;
2214 }
2215 
getTrackInfo(Parcel * reply) const2216 status_t NuPlayer::getTrackInfo(Parcel* reply) const {
2217     sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2218     msg->setPointer("reply", reply);
2219 
2220     sp<AMessage> response;
2221     status_t err = msg->postAndAwaitResponse(&response);
2222     return err;
2223 }
2224 
getSelectedTrack(int32_t type,Parcel * reply) const2225 status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
2226     sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2227     msg->setPointer("reply", reply);
2228     msg->setInt32("type", type);
2229 
2230     sp<AMessage> response;
2231     status_t err = msg->postAndAwaitResponse(&response);
2232     if (err == OK && response != NULL) {
2233         CHECK(response->findInt32("err", &err));
2234     }
2235     return err;
2236 }
2237 
selectTrack(size_t trackIndex,bool select,int64_t timeUs)2238 status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2239     sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2240     msg->setSize("trackIndex", trackIndex);
2241     msg->setInt32("select", select);
2242     msg->setInt64("timeUs", timeUs);
2243 
2244     sp<AMessage> response;
2245     status_t err = msg->postAndAwaitResponse(&response);
2246 
2247     if (err != OK) {
2248         return err;
2249     }
2250 
2251     if (!response->findInt32("err", &err)) {
2252         err = OK;
2253     }
2254 
2255     return err;
2256 }
2257 
getCurrentPosition(int64_t * mediaUs)2258 status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
2259     sp<Renderer> renderer = mRenderer;
2260     if (renderer == NULL) {
2261         return NO_INIT;
2262     }
2263 
2264     return renderer->getCurrentPosition(mediaUs);
2265 }
2266 
getStats(Vector<sp<AMessage>> * trackStats)2267 void NuPlayer::getStats(Vector<sp<AMessage> > *trackStats) {
2268     CHECK(trackStats != NULL);
2269 
2270     trackStats->clear();
2271 
2272     Mutex::Autolock autoLock(mDecoderLock);
2273     if (mVideoDecoder != NULL) {
2274         trackStats->push_back(mVideoDecoder->getStats());
2275     }
2276     if (mAudioDecoder != NULL) {
2277         trackStats->push_back(mAudioDecoder->getStats());
2278     }
2279 }
2280 
getFileMeta()2281 sp<MetaData> NuPlayer::getFileMeta() {
2282     return mSource->getFileFormatMeta();
2283 }
2284 
getFrameRate()2285 float NuPlayer::getFrameRate() {
2286     sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2287     if (meta == NULL) {
2288         return 0;
2289     }
2290     int32_t rate;
2291     if (!meta->findInt32(kKeyFrameRate, &rate)) {
2292         // fall back to try file meta
2293         sp<MetaData> fileMeta = getFileMeta();
2294         if (fileMeta == NULL) {
2295             ALOGW("source has video meta but not file meta");
2296             return -1;
2297         }
2298         int32_t fileMetaRate;
2299         if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2300             return -1;
2301         }
2302         return fileMetaRate;
2303     }
2304     return rate;
2305 }
2306 
schedulePollDuration()2307 void NuPlayer::schedulePollDuration() {
2308     sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2309     msg->setInt32("generation", mPollDurationGeneration);
2310     msg->post();
2311 }
2312 
cancelPollDuration()2313 void NuPlayer::cancelPollDuration() {
2314     ++mPollDurationGeneration;
2315 }
2316 
processDeferredActions()2317 void NuPlayer::processDeferredActions() {
2318     while (!mDeferredActions.empty()) {
2319         // We won't execute any deferred actions until we're no longer in
2320         // an intermediate state, i.e. one more more decoders are currently
2321         // flushing or shutting down.
2322 
2323         if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2324             // We're currently flushing, postpone the reset until that's
2325             // completed.
2326 
2327             ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2328                   mFlushingAudio, mFlushingVideo);
2329 
2330             break;
2331         }
2332 
2333         sp<Action> action = *mDeferredActions.begin();
2334         mDeferredActions.erase(mDeferredActions.begin());
2335 
2336         action->execute(this);
2337     }
2338 }
2339 
performSeek(int64_t seekTimeUs,MediaPlayerSeekMode mode)2340 void NuPlayer::performSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
2341     ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2342           (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2343 
2344     if (mSource == NULL) {
2345         // This happens when reset occurs right before the loop mode
2346         // asynchronously seeks to the start of the stream.
2347         LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2348                 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2349                 mAudioDecoder.get(), mVideoDecoder.get());
2350         return;
2351     }
2352     mPreviousSeekTimeUs = seekTimeUs;
2353     mSource->seekTo(seekTimeUs, mode);
2354     ++mTimedTextGeneration;
2355 
2356     // everything's flushed, continue playback.
2357 }
2358 
performDecoderFlush(FlushCommand audio,FlushCommand video)2359 void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2360     ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2361 
2362     if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2363             && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2364         return;
2365     }
2366 
2367     if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2368         flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2369     }
2370 
2371     if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2372         flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2373     }
2374 }
2375 
performReset()2376 void NuPlayer::performReset() {
2377     ALOGV("performReset");
2378 
2379     CHECK(mAudioDecoder == NULL);
2380     CHECK(mVideoDecoder == NULL);
2381 
2382     updatePlaybackTimer(true /* stopping */, "performReset");
2383     updateRebufferingTimer(true /* stopping */, true /* exiting */);
2384 
2385     cancelPollDuration();
2386 
2387     ++mScanSourcesGeneration;
2388     mScanSourcesPending = false;
2389 
2390     if (mRendererLooper != NULL) {
2391         if (mRenderer != NULL) {
2392             mRendererLooper->unregisterHandler(mRenderer->id());
2393         }
2394         mRendererLooper->stop();
2395         mRendererLooper.clear();
2396     }
2397     mRenderer.clear();
2398     ++mRendererGeneration;
2399 
2400     if (mSource != NULL) {
2401         mSource->stop();
2402 
2403         Mutex::Autolock autoLock(mSourceLock);
2404         mSource.clear();
2405     }
2406 
2407     if (mDriver != NULL) {
2408         sp<NuPlayerDriver> driver = mDriver.promote();
2409         if (driver != NULL) {
2410             driver->notifyResetComplete();
2411         }
2412     }
2413 
2414     mStarted = false;
2415     mPrepared = false;
2416     mResetting = false;
2417     mSourceStarted = false;
2418 
2419     // Modular DRM
2420     if (mCrypto != NULL) {
2421         // decoders will be flushed before this so their mCrypto would go away on their own
2422         // TODO change to ALOGV
2423         ALOGD("performReset mCrypto: %p (%d)", mCrypto.get(),
2424                 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
2425         mCrypto.clear();
2426     }
2427     mIsDrmProtected = false;
2428 }
2429 
performScanSources()2430 void NuPlayer::performScanSources() {
2431     ALOGV("performScanSources");
2432 
2433     if (!mStarted) {
2434         return;
2435     }
2436 
2437     if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2438         postScanSources();
2439     }
2440 }
2441 
performSetSurface(const sp<Surface> & surface)2442 void NuPlayer::performSetSurface(const sp<Surface> &surface) {
2443     ALOGV("performSetSurface");
2444 
2445     mSurface = surface;
2446 
2447     // XXX - ignore error from setVideoScalingMode for now
2448     setVideoScalingMode(mVideoScalingMode);
2449 
2450     if (mDriver != NULL) {
2451         sp<NuPlayerDriver> driver = mDriver.promote();
2452         if (driver != NULL) {
2453             driver->notifySetSurfaceComplete();
2454         }
2455     }
2456 }
2457 
performResumeDecoders(bool needNotify)2458 void NuPlayer::performResumeDecoders(bool needNotify) {
2459     if (needNotify) {
2460         mResumePending = true;
2461         if (mVideoDecoder == NULL) {
2462             // if audio-only, we can notify seek complete now,
2463             // as the resume operation will be relatively fast.
2464             finishResume();
2465         }
2466     }
2467 
2468     if (mVideoDecoder != NULL) {
2469         // When there is continuous seek, MediaPlayer will cache the seek
2470         // position, and send down new seek request when previous seek is
2471         // complete. Let's wait for at least one video output frame before
2472         // notifying seek complete, so that the video thumbnail gets updated
2473         // when seekbar is dragged.
2474         mVideoDecoder->signalResume(needNotify);
2475     }
2476 
2477     if (mAudioDecoder != NULL) {
2478         mAudioDecoder->signalResume(false /* needNotify */);
2479     }
2480 }
2481 
finishResume()2482 void NuPlayer::finishResume() {
2483     if (mResumePending) {
2484         mResumePending = false;
2485         notifyDriverSeekComplete();
2486     }
2487 }
2488 
notifyDriverSeekComplete()2489 void NuPlayer::notifyDriverSeekComplete() {
2490     if (mDriver != NULL) {
2491         sp<NuPlayerDriver> driver = mDriver.promote();
2492         if (driver != NULL) {
2493             driver->notifySeekComplete();
2494         }
2495     }
2496 }
2497 
onSourceNotify(const sp<AMessage> & msg)2498 void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
2499     int32_t what;
2500     CHECK(msg->findInt32("what", &what));
2501 
2502     switch (what) {
2503         case Source::kWhatInstantiateSecureDecoders:
2504         {
2505             if (mSource == NULL) {
2506                 // This is a stale notification from a source that was
2507                 // asynchronously preparing when the client called reset().
2508                 // We handled the reset, the source is gone.
2509                 break;
2510             }
2511 
2512             sp<AMessage> reply;
2513             CHECK(msg->findMessage("reply", &reply));
2514             status_t err = onInstantiateSecureDecoders();
2515             reply->setInt32("err", err);
2516             reply->post();
2517             break;
2518         }
2519 
2520         case Source::kWhatPrepared:
2521         {
2522             ALOGV("NuPlayer::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
2523             if (mSource == NULL) {
2524                 // This is a stale notification from a source that was
2525                 // asynchronously preparing when the client called reset().
2526                 // We handled the reset, the source is gone.
2527                 break;
2528             }
2529 
2530             int32_t err;
2531             CHECK(msg->findInt32("err", &err));
2532 
2533             if (err != OK) {
2534                 // shut down potential secure codecs in case client never calls reset
2535                 mDeferredActions.push_back(
2536                         new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2537                                                FLUSH_CMD_SHUTDOWN /* video */));
2538                 processDeferredActions();
2539             } else {
2540                 mPrepared = true;
2541             }
2542 
2543             sp<NuPlayerDriver> driver = mDriver.promote();
2544             if (driver != NULL) {
2545                 // notify duration first, so that it's definitely set when
2546                 // the app received the "prepare complete" callback.
2547                 int64_t durationUs;
2548                 if (mSource->getDuration(&durationUs) == OK) {
2549                     driver->notifyDuration(durationUs);
2550                 }
2551                 driver->notifyPrepareCompleted(err);
2552             }
2553 
2554             break;
2555         }
2556 
2557         // Modular DRM
2558         case Source::kWhatDrmInfo:
2559         {
2560             Parcel parcel;
2561             sp<ABuffer> drmInfo;
2562             CHECK(msg->findBuffer("drmInfo", &drmInfo));
2563             parcel.setData(drmInfo->data(), drmInfo->size());
2564 
2565             ALOGV("onSourceNotify() kWhatDrmInfo MEDIA_DRM_INFO drmInfo: %p  parcel size: %zu",
2566                     drmInfo.get(), parcel.dataSize());
2567 
2568             notifyListener(MEDIA_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
2569 
2570             break;
2571         }
2572 
2573         case Source::kWhatFlagsChanged:
2574         {
2575             uint32_t flags;
2576             CHECK(msg->findInt32("flags", (int32_t *)&flags));
2577 
2578             sp<NuPlayerDriver> driver = mDriver.promote();
2579             if (driver != NULL) {
2580 
2581                 ALOGV("onSourceNotify() kWhatFlagsChanged  FLAG_CAN_PAUSE: %d  "
2582                         "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d  "
2583                         "FLAG_CAN_SEEK: %d  FLAG_DYNAMIC_DURATION: %d \n"
2584                         "\t\t\t\t FLAG_SECURE: %d  FLAG_PROTECTED: %d",
2585                         (flags & Source::FLAG_CAN_PAUSE) != 0,
2586                         (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2587                         (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2588                         (flags & Source::FLAG_CAN_SEEK) != 0,
2589                         (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2590                         (flags & Source::FLAG_SECURE) != 0,
2591                         (flags & Source::FLAG_PROTECTED) != 0);
2592 
2593                 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
2594                     driver->notifyListener(
2595                             MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
2596                 }
2597                 driver->notifyFlagsChanged(flags);
2598             }
2599 
2600             if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2601                     && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2602                 cancelPollDuration();
2603             } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2604                     && (flags & Source::FLAG_DYNAMIC_DURATION)
2605                     && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2606                 schedulePollDuration();
2607             }
2608 
2609             mSourceFlags = flags;
2610             break;
2611         }
2612 
2613         case Source::kWhatVideoSizeChanged:
2614         {
2615             sp<AMessage> format;
2616             CHECK(msg->findMessage("format", &format));
2617 
2618             updateVideoSize(format);
2619             break;
2620         }
2621 
2622         case Source::kWhatBufferingUpdate:
2623         {
2624             int32_t percentage;
2625             CHECK(msg->findInt32("percentage", &percentage));
2626 
2627             notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
2628             break;
2629         }
2630 
2631         case Source::kWhatPauseOnBufferingStart:
2632         {
2633             // ignore if not playing
2634             if (mStarted) {
2635                 ALOGI("buffer low, pausing...");
2636 
2637                 startRebufferingTimer();
2638                 mPausedForBuffering = true;
2639                 onPause();
2640             }
2641             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
2642             break;
2643         }
2644 
2645         case Source::kWhatResumeOnBufferingEnd:
2646         {
2647             // ignore if not playing
2648             if (mStarted) {
2649                 ALOGI("buffer ready, resuming...");
2650 
2651                 updateRebufferingTimer(true /* stopping */, false /* exiting */);
2652                 mPausedForBuffering = false;
2653 
2654                 // do not resume yet if client didn't unpause
2655                 if (!mPausedByClient) {
2656                     onResume();
2657                 }
2658             }
2659             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
2660             break;
2661         }
2662 
2663         case Source::kWhatCacheStats:
2664         {
2665             int32_t kbps;
2666             CHECK(msg->findInt32("bandwidth", &kbps));
2667 
2668             notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
2669             break;
2670         }
2671 
2672         case Source::kWhatSubtitleData:
2673         {
2674             sp<ABuffer> buffer;
2675             CHECK(msg->findBuffer("buffer", &buffer));
2676 
2677             sendSubtitleData(buffer, 0 /* baseIndex */);
2678             break;
2679         }
2680 
2681         case Source::kWhatTimedMetaData:
2682         {
2683             sp<ABuffer> buffer;
2684             if (!msg->findBuffer("buffer", &buffer)) {
2685                 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2686             } else {
2687                 sendTimedMetaData(buffer);
2688             }
2689             break;
2690         }
2691 
2692         case Source::kWhatTimedTextData:
2693         {
2694             int32_t generation;
2695             if (msg->findInt32("generation", &generation)
2696                     && generation != mTimedTextGeneration) {
2697                 break;
2698             }
2699 
2700             sp<ABuffer> buffer;
2701             CHECK(msg->findBuffer("buffer", &buffer));
2702 
2703             sp<NuPlayerDriver> driver = mDriver.promote();
2704             if (driver == NULL) {
2705                 break;
2706             }
2707 
2708             int posMs;
2709             int64_t timeUs, posUs;
2710             driver->getCurrentPosition(&posMs);
2711             posUs = (int64_t) posMs * 1000LL;
2712             CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2713 
2714             if (posUs < timeUs) {
2715                 if (!msg->findInt32("generation", &generation)) {
2716                     msg->setInt32("generation", mTimedTextGeneration);
2717                 }
2718                 msg->post(timeUs - posUs);
2719             } else {
2720                 sendTimedTextData(buffer);
2721             }
2722             break;
2723         }
2724 
2725         case Source::kWhatQueueDecoderShutdown:
2726         {
2727             int32_t audio, video;
2728             CHECK(msg->findInt32("audio", &audio));
2729             CHECK(msg->findInt32("video", &video));
2730 
2731             sp<AMessage> reply;
2732             CHECK(msg->findMessage("reply", &reply));
2733 
2734             queueDecoderShutdown(audio, video, reply);
2735             break;
2736         }
2737 
2738         case Source::kWhatDrmNoLicense:
2739         {
2740             notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2741             break;
2742         }
2743 
2744         case Source::kWhatIMSRxNotice:
2745         {
2746             sp<AMessage> IMSRxNotice;
2747             CHECK(msg->findMessage("message", &IMSRxNotice));
2748             sendIMSRxNotice(IMSRxNotice);
2749             break;
2750         }
2751 
2752         default:
2753             TRESPASS();
2754     }
2755 }
2756 
onClosedCaptionNotify(const sp<AMessage> & msg)2757 void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2758     int32_t what;
2759     CHECK(msg->findInt32("what", &what));
2760 
2761     switch (what) {
2762         case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2763         {
2764             sp<ABuffer> buffer;
2765             CHECK(msg->findBuffer("buffer", &buffer));
2766 
2767             size_t inbandTracks = 0;
2768             if (mSource != NULL) {
2769                 inbandTracks = mSource->getTrackCount();
2770             }
2771 
2772             sendSubtitleData(buffer, inbandTracks);
2773             break;
2774         }
2775 
2776         case NuPlayer::CCDecoder::kWhatTrackAdded:
2777         {
2778             notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2779 
2780             break;
2781         }
2782 
2783         default:
2784             TRESPASS();
2785     }
2786 
2787 
2788 }
2789 
sendSubtitleData(const sp<ABuffer> & buffer,int32_t baseIndex)2790 void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2791     int32_t trackIndex;
2792     int64_t timeUs, durationUs;
2793     CHECK(buffer->meta()->findInt32("track-index", &trackIndex));
2794     CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2795     CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2796 
2797     Parcel in;
2798     in.writeInt32(trackIndex + baseIndex);
2799     in.writeInt64(timeUs);
2800     in.writeInt64(durationUs);
2801     in.writeInt32(buffer->size());
2802     in.writeInt32(buffer->size());
2803     in.write(buffer->data(), buffer->size());
2804 
2805     notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2806 }
2807 
sendTimedMetaData(const sp<ABuffer> & buffer)2808 void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) {
2809     int64_t timeUs;
2810     CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2811 
2812     Parcel in;
2813     in.writeInt64(timeUs);
2814     in.writeInt32(buffer->size());
2815     in.writeInt32(buffer->size());
2816     in.write(buffer->data(), buffer->size());
2817 
2818     notifyListener(MEDIA_META_DATA, 0, 0, &in);
2819 }
2820 
sendTimedTextData(const sp<ABuffer> & buffer)2821 void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2822     const void *data;
2823     size_t size = 0;
2824     int64_t timeUs;
2825     int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
2826 
2827     AString mime;
2828     CHECK(buffer->meta()->findString("mime", &mime));
2829     CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2830 
2831     data = buffer->data();
2832     size = buffer->size();
2833 
2834     Parcel parcel;
2835     if (size > 0) {
2836         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2837         int32_t global = 0;
2838         if (buffer->meta()->findInt32("global", &global) && global) {
2839             flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
2840         } else {
2841             flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
2842         }
2843         TextDescriptions::getParcelOfDescriptions(
2844                 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2845     }
2846 
2847     if ((parcel.dataSize() > 0)) {
2848         notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2849     } else {  // send an empty timed text
2850         notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2851     }
2852 }
2853 
sendIMSRxNotice(const sp<AMessage> & msg)2854 void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
2855     int32_t payloadType;
2856 
2857     CHECK(msg->findInt32("payload-type", &payloadType));
2858 
2859     int32_t rtpSeq = 0, rtpTime = 0;
2860     int64_t ntpTime = 0, recvTimeUs = 0;
2861 
2862     Parcel in;
2863     in.writeInt32(payloadType);
2864 
2865     switch (payloadType) {
2866         case ARTPSource::RTP_FIRST_PACKET:
2867         {
2868             CHECK(msg->findInt32("rtp-time", &rtpTime));
2869             CHECK(msg->findInt32("rtp-seq-num", &rtpSeq));
2870             CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2871             in.writeInt32(rtpTime);
2872             in.writeInt32(rtpSeq);
2873             in.writeInt32(recvTimeUs >> 32);
2874             in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2875             break;
2876         }
2877         case ARTPSource::RTCP_FIRST_PACKET:
2878         {
2879             CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2880             in.writeInt32(recvTimeUs >> 32);
2881             in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2882             break;
2883         }
2884         case ARTPSource::RTCP_SR:
2885         {
2886             CHECK(msg->findInt32("rtp-time", &rtpTime));
2887             CHECK(msg->findInt64("ntp-time", &ntpTime));
2888             CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2889             in.writeInt32(rtpTime);
2890             in.writeInt32(ntpTime >> 32);
2891             in.writeInt32(ntpTime & 0xFFFFFFFF);
2892             in.writeInt32(recvTimeUs >> 32);
2893             in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2894             break;
2895         }
2896         case ARTPSource::RTCP_TSFB:   // RTCP TSFB
2897         case ARTPSource::RTCP_PSFB:   // RTCP PSFB
2898         case ARTPSource::RTP_AUTODOWN:
2899         {
2900             int32_t feedbackType, id;
2901             CHECK(msg->findInt32("feedback-type", &feedbackType));
2902             CHECK(msg->findInt32("sender", &id));
2903             in.writeInt32(feedbackType);
2904             in.writeInt32(id);
2905             if (payloadType == ARTPSource::RTCP_TSFB) {
2906                 int32_t bitrate;
2907                 CHECK(msg->findInt32("bit-rate", &bitrate));
2908                 in.writeInt32(bitrate);
2909             }
2910             break;
2911         }
2912         case ARTPSource::RTP_QUALITY:
2913         case ARTPSource::RTP_QUALITY_EMC:
2914         {
2915             int32_t feedbackType, bitrate;
2916             int32_t highestSeqNum, baseSeqNum, prevExpected;
2917             int32_t numBufRecv, prevNumBufRecv;
2918             int32_t latestRtpTime, jbTimeMs, rtpRtcpSrTimeGapMs;
2919             int64_t recvTimeUs;
2920             CHECK(msg->findInt32("feedback-type", &feedbackType));
2921             CHECK(msg->findInt32("bit-rate", &bitrate));
2922             CHECK(msg->findInt32("highest-seq-num", &highestSeqNum));
2923             CHECK(msg->findInt32("base-seq-num", &baseSeqNum));
2924             CHECK(msg->findInt32("prev-expected", &prevExpected));
2925             CHECK(msg->findInt32("num-buf-recv", &numBufRecv));
2926             CHECK(msg->findInt32("prev-num-buf-recv", &prevNumBufRecv));
2927             CHECK(msg->findInt32("latest-rtp-time", &latestRtpTime));
2928             CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2929             CHECK(msg->findInt32("rtp-jitter-time-ms", &jbTimeMs));
2930             CHECK(msg->findInt32("rtp-rtcpsr-time-gap-ms", &rtpRtcpSrTimeGapMs));
2931             in.writeInt32(feedbackType);
2932             in.writeInt32(bitrate);
2933             in.writeInt32(highestSeqNum);
2934             in.writeInt32(baseSeqNum);
2935             in.writeInt32(prevExpected);
2936             in.writeInt32(numBufRecv);
2937             in.writeInt32(prevNumBufRecv);
2938             in.writeInt32(latestRtpTime);
2939             in.writeInt32(recvTimeUs >> 32);
2940             in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2941             in.writeInt32(jbTimeMs);
2942             in.writeInt32(rtpRtcpSrTimeGapMs);
2943             break;
2944         }
2945         case ARTPSource::RTP_CVO:
2946         {
2947             int32_t cvo;
2948             CHECK(msg->findInt32("cvo", &cvo));
2949             in.writeInt32(cvo);
2950             break;
2951         }
2952         default:
2953         break;
2954     }
2955 
2956     notifyListener(MEDIA_IMS_RX_NOTICE, 0, 0, &in);
2957 }
2958 
getDataSourceType()2959 const char *NuPlayer::getDataSourceType() {
2960     switch (mDataSourceType) {
2961         case DATA_SOURCE_TYPE_HTTP_LIVE:
2962             return "HTTPLive";
2963 
2964         case DATA_SOURCE_TYPE_RTP:
2965             return "RTP";
2966 
2967         case DATA_SOURCE_TYPE_RTSP:
2968             return "RTSP";
2969 
2970         case DATA_SOURCE_TYPE_GENERIC_URL:
2971             return "GenURL";
2972 
2973         case DATA_SOURCE_TYPE_GENERIC_FD:
2974             return "GenFD";
2975 
2976         case DATA_SOURCE_TYPE_MEDIA:
2977             return "Media";
2978 
2979         case DATA_SOURCE_TYPE_STREAM:
2980             return "Stream";
2981 
2982         case DATA_SOURCE_TYPE_NONE:
2983         default:
2984             return "None";
2985     }
2986  }
2987 
2988 // Modular DRM begin
prepareDrm(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId)2989 status_t NuPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
2990 {
2991     ALOGV("prepareDrm ");
2992 
2993     // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
2994     sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
2995     // synchronous call so just passing the address but with local copies of "const" args
2996     uint8_t UUID[16];
2997     memcpy(UUID, uuid, sizeof(UUID));
2998     Vector<uint8_t> sessionId = drmSessionId;
2999     msg->setPointer("uuid", (void*)UUID);
3000     msg->setPointer("drmSessionId", (void*)&sessionId);
3001 
3002     sp<AMessage> response;
3003     status_t status = msg->postAndAwaitResponse(&response);
3004 
3005     if (status == OK && response != NULL) {
3006         CHECK(response->findInt32("status", &status));
3007         ALOGV("prepareDrm ret: %d ", status);
3008     } else {
3009         ALOGE("prepareDrm err: %d", status);
3010     }
3011 
3012     return status;
3013 }
3014 
releaseDrm()3015 status_t NuPlayer::releaseDrm()
3016 {
3017     ALOGV("releaseDrm ");
3018 
3019     sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3020 
3021     sp<AMessage> response;
3022     status_t status = msg->postAndAwaitResponse(&response);
3023 
3024     if (status == OK && response != NULL) {
3025         CHECK(response->findInt32("status", &status));
3026         ALOGV("releaseDrm ret: %d ", status);
3027     } else {
3028         ALOGE("releaseDrm err: %d", status);
3029     }
3030 
3031     return status;
3032 }
3033 
onPrepareDrm(const sp<AMessage> & msg)3034 status_t NuPlayer::onPrepareDrm(const sp<AMessage> &msg)
3035 {
3036     // TODO change to ALOGV
3037     ALOGD("onPrepareDrm ");
3038 
3039     status_t status = INVALID_OPERATION;
3040     if (mSource == NULL) {
3041         ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3042         return status;
3043     }
3044 
3045     uint8_t *uuid;
3046     Vector<uint8_t> *drmSessionId;
3047     CHECK(msg->findPointer("uuid", (void**)&uuid));
3048     CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3049 
3050     status = OK;
3051     sp<ICrypto> crypto = NULL;
3052 
3053     status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
3054     if (crypto == NULL) {
3055         ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
3056         return status;
3057     }
3058     ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
3059 
3060     if (mCrypto != NULL) {
3061         ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p (%d)",
3062                 mCrypto.get(), mCrypto->getStrongCount());
3063         mCrypto.clear();
3064     }
3065 
3066     mCrypto = crypto;
3067     mIsDrmProtected = true;
3068     // TODO change to ALOGV
3069     ALOGD("onPrepareDrm: mCrypto: %p (%d)", mCrypto.get(),
3070             (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3071 
3072     return status;
3073 }
3074 
onReleaseDrm()3075 status_t NuPlayer::onReleaseDrm()
3076 {
3077     // TODO change to ALOGV
3078     ALOGD("onReleaseDrm ");
3079 
3080     if (!mIsDrmProtected) {
3081         ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3082     }
3083 
3084     mIsDrmProtected = false;
3085 
3086     status_t status;
3087     if (mCrypto != NULL) {
3088         // notifying the source first before removing crypto from codec
3089         if (mSource != NULL) {
3090             mSource->releaseDrm();
3091         }
3092 
3093         status=OK;
3094         // first making sure the codecs have released their crypto reference
3095         const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3096         if (videoDecoder != NULL) {
3097             status = videoDecoder->releaseCrypto();
3098             ALOGV("onReleaseDrm: video decoder ret: %d", status);
3099         }
3100 
3101         const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3102         if (audioDecoder != NULL) {
3103             status_t status_audio = audioDecoder->releaseCrypto();
3104             if (status == OK) {   // otherwise, returning the first error
3105                 status = status_audio;
3106             }
3107             ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3108         }
3109 
3110         // TODO change to ALOGV
3111         ALOGD("onReleaseDrm: mCrypto: %p (%d)", mCrypto.get(),
3112                 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3113         mCrypto.clear();
3114     } else {   // mCrypto == NULL
3115         ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3116         status = INVALID_OPERATION;
3117     }
3118 
3119     return status;
3120 }
3121 // Modular DRM end
3122 ////////////////////////////////////////////////////////////////////////////////
3123 
getFormat(bool audio)3124 sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
3125     sp<MetaData> meta = getFormatMeta(audio);
3126 
3127     if (meta == NULL) {
3128         return NULL;
3129     }
3130 
3131     sp<AMessage> msg = new AMessage;
3132 
3133     if(convertMetaDataToMessage(meta, &msg) == OK) {
3134         return msg;
3135     }
3136     return NULL;
3137 }
3138 
notifyFlagsChanged(uint32_t flags)3139 void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
3140     sp<AMessage> notify = dupNotify();
3141     notify->setInt32("what", kWhatFlagsChanged);
3142     notify->setInt32("flags", flags);
3143     notify->post();
3144 }
3145 
notifyVideoSizeChanged(const sp<AMessage> & format)3146 void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3147     sp<AMessage> notify = dupNotify();
3148     notify->setInt32("what", kWhatVideoSizeChanged);
3149     notify->setMessage("format", format);
3150     notify->post();
3151 }
3152 
notifyPrepared(status_t err)3153 void NuPlayer::Source::notifyPrepared(status_t err) {
3154     ALOGV("Source::notifyPrepared %d", err);
3155     sp<AMessage> notify = dupNotify();
3156     notify->setInt32("what", kWhatPrepared);
3157     notify->setInt32("err", err);
3158     notify->post();
3159 }
3160 
notifyDrmInfo(const sp<ABuffer> & drmInfoBuffer)3161 void NuPlayer::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3162 {
3163     ALOGV("Source::notifyDrmInfo");
3164 
3165     sp<AMessage> notify = dupNotify();
3166     notify->setInt32("what", kWhatDrmInfo);
3167     notify->setBuffer("drmInfo", drmInfoBuffer);
3168 
3169     notify->post();
3170 }
3171 
notifyInstantiateSecureDecoders(const sp<AMessage> & reply)3172 void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
3173     sp<AMessage> notify = dupNotify();
3174     notify->setInt32("what", kWhatInstantiateSecureDecoders);
3175     notify->setMessage("reply", reply);
3176     notify->post();
3177 }
3178 
onMessageReceived(const sp<AMessage> &)3179 void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3180     TRESPASS();
3181 }
3182 
3183 }  // namespace android
3184