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