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.c_str());
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 format->setInt32("android._video-scaling", mVideoScalingMode);
1982 }
1983
1984 Mutex::Autolock autoLock(mDecoderLock);
1985
1986 if (audio) {
1987 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
1988 ++mAudioDecoderGeneration;
1989 notify->setInt32("generation", mAudioDecoderGeneration);
1990
1991 if (checkAudioModeChange) {
1992 determineAudioModeChange(format);
1993 }
1994 if (mOffloadAudio) {
1995 mSource->setOffloadAudio(true /* offload */);
1996
1997 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1998 format->setInt32("has-video", hasVideo);
1999 *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
2000 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
2001 } else {
2002 mSource->setOffloadAudio(false /* offload */);
2003
2004 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
2005 ALOGV("instantiateDecoder audio Decoder");
2006 }
2007 mAudioDecoderError = false;
2008 } else {
2009 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
2010 ++mVideoDecoderGeneration;
2011 notify->setInt32("generation", mVideoDecoderGeneration);
2012
2013 *decoder = new Decoder(
2014 notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder);
2015 mVideoDecoderError = false;
2016
2017 // enable FRC if high-quality AV sync is requested, even if not
2018 // directly queuing to display, as this will even improve textureview
2019 // playback.
2020 {
2021 if (property_get_bool("persist.sys.media.avsync", false)) {
2022 format->setInt32("auto-frc", 1);
2023 }
2024 }
2025 }
2026 (*decoder)->init();
2027
2028 // Modular DRM
2029 if (mIsDrmProtected) {
2030 format->setPointer("crypto", mCrypto.get());
2031 ALOGV("instantiateDecoder: mCrypto: %p (%d) isSecure: %d", mCrypto.get(),
2032 (mCrypto != NULL ? mCrypto->getStrongCount() : 0),
2033 (mSourceFlags & Source::FLAG_SECURE) != 0);
2034 }
2035
2036 (*decoder)->configure(format);
2037
2038 if (!audio) {
2039 sp<AMessage> params = new AMessage();
2040 float rate = getFrameRate();
2041 if (rate > 0) {
2042 params->setFloat("frame-rate-total", rate);
2043 }
2044
2045 sp<MetaData> fileMeta = getFileMeta();
2046 if (fileMeta != NULL) {
2047 int32_t videoTemporalLayerCount;
2048 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
2049 && videoTemporalLayerCount > 0) {
2050 params->setInt32("temporal-layer-count", videoTemporalLayerCount);
2051 }
2052 }
2053
2054 if (params->countEntries() > 0) {
2055 (*decoder)->setParameters(params);
2056 }
2057 }
2058 return OK;
2059 }
2060
updateVideoSize(const sp<AMessage> & inputFormat,const sp<AMessage> & outputFormat)2061 void NuPlayer::updateVideoSize(
2062 const sp<AMessage> &inputFormat,
2063 const sp<AMessage> &outputFormat) {
2064 if (inputFormat == NULL) {
2065 ALOGW("Unknown video size, reporting 0x0!");
2066 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
2067 return;
2068 }
2069 int32_t err = OK;
2070 inputFormat->findInt32("err", &err);
2071 if (err == -EWOULDBLOCK) {
2072 ALOGW("Video meta is not available yet!");
2073 return;
2074 }
2075 if (err != OK) {
2076 ALOGW("Something is wrong with video meta!");
2077 return;
2078 }
2079
2080 int32_t displayWidth, displayHeight;
2081 if (outputFormat != NULL) {
2082 int32_t width, height;
2083 CHECK(outputFormat->findInt32("width", &width));
2084 CHECK(outputFormat->findInt32("height", &height));
2085
2086 int32_t cropLeft, cropTop, cropRight, cropBottom;
2087 CHECK(outputFormat->findRect(
2088 "crop",
2089 &cropLeft, &cropTop, &cropRight, &cropBottom));
2090
2091 displayWidth = cropRight - cropLeft + 1;
2092 displayHeight = cropBottom - cropTop + 1;
2093
2094 ALOGV("Video output format changed to %d x %d "
2095 "(crop: %d x %d @ (%d, %d))",
2096 width, height,
2097 displayWidth,
2098 displayHeight,
2099 cropLeft, cropTop);
2100 } else {
2101 if (!inputFormat->findInt32("width", &displayWidth)
2102 || !inputFormat->findInt32("height", &displayHeight)) {
2103 ALOGW("Either video width or video height missing, reporting 0x0!");
2104 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
2105 return;
2106 }
2107 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
2108 }
2109
2110 // Take into account sample aspect ratio if necessary:
2111 int32_t sarWidth, sarHeight;
2112 if (inputFormat->findInt32("sar-width", &sarWidth)
2113 && inputFormat->findInt32("sar-height", &sarHeight)
2114 && sarWidth > 0 && sarHeight > 0) {
2115 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
2116
2117 displayWidth = (displayWidth * sarWidth) / sarHeight;
2118
2119 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
2120 } else {
2121 int32_t width, height;
2122 if (inputFormat->findInt32("display-width", &width)
2123 && inputFormat->findInt32("display-height", &height)
2124 && width > 0 && height > 0
2125 && displayWidth > 0 && displayHeight > 0) {
2126 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
2127 displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
2128 } else {
2129 displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
2130 }
2131 ALOGV("Video display width and height are overridden to %d x %d",
2132 displayWidth, displayHeight);
2133 }
2134 }
2135
2136 int32_t rotationDegrees;
2137 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
2138 rotationDegrees = 0;
2139 }
2140
2141 if (rotationDegrees == 90 || rotationDegrees == 270) {
2142 int32_t tmp = displayWidth;
2143 displayWidth = displayHeight;
2144 displayHeight = tmp;
2145 }
2146
2147 notifyListener(
2148 MEDIA_SET_VIDEO_SIZE,
2149 displayWidth,
2150 displayHeight);
2151 }
2152
notifyListener(int msg,int ext1,int ext2,const Parcel * in)2153 void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
2154 if (mDriver == NULL) {
2155 return;
2156 }
2157
2158 sp<NuPlayerDriver> driver = mDriver.promote();
2159
2160 if (driver == NULL) {
2161 return;
2162 }
2163
2164 driver->notifyListener(msg, ext1, ext2, in);
2165 }
2166
flushDecoder(bool audio,bool needShutdown)2167 void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
2168 ALOGV("[%s] flushDecoder needShutdown=%d",
2169 audio ? "audio" : "video", needShutdown);
2170
2171 const sp<DecoderBase> &decoder = getDecoder(audio);
2172 if (decoder == NULL) {
2173 ALOGI("flushDecoder %s without decoder present",
2174 audio ? "audio" : "video");
2175 return;
2176 }
2177
2178 // Make sure we don't continue to scan sources until we finish flushing.
2179 ++mScanSourcesGeneration;
2180 if (mScanSourcesPending) {
2181 if (!needShutdown) {
2182 mDeferredActions.push_back(
2183 new SimpleAction(&NuPlayer::performScanSources));
2184 }
2185 mScanSourcesPending = false;
2186 }
2187
2188 decoder->signalFlush();
2189
2190 FlushStatus newStatus =
2191 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
2192
2193 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
2194 mFlushComplete[audio][true /* isDecoder */] = false;
2195 if (audio) {
2196 ALOGE_IF(mFlushingAudio != NONE,
2197 "audio flushDecoder() is called in state %d", mFlushingAudio);
2198 mFlushingAudio = newStatus;
2199 } else {
2200 ALOGE_IF(mFlushingVideo != NONE,
2201 "video flushDecoder() is called in state %d", mFlushingVideo);
2202 mFlushingVideo = newStatus;
2203 }
2204 }
2205
queueDecoderShutdown(bool audio,bool video,const sp<AMessage> & reply)2206 void NuPlayer::queueDecoderShutdown(
2207 bool audio, bool video, const sp<AMessage> &reply) {
2208 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
2209
2210 mDeferredActions.push_back(
2211 new FlushDecoderAction(
2212 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
2213 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
2214
2215 mDeferredActions.push_back(
2216 new SimpleAction(&NuPlayer::performScanSources));
2217
2218 mDeferredActions.push_back(new PostMessageAction(reply));
2219
2220 processDeferredActions();
2221 }
2222
setVideoScalingMode(int32_t mode)2223 status_t NuPlayer::setVideoScalingMode(int32_t mode) {
2224 mVideoScalingMode = mode;
2225 if (mSurface != NULL) {
2226 status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode);
2227 if (ret != OK) {
2228 ALOGE("Failed to set scaling mode (%d): %s",
2229 -ret, strerror(-ret));
2230 return ret;
2231 }
2232 if (mVideoDecoder != NULL) {
2233 sp<AMessage> params = new AMessage();
2234 params->setInt32("android._video-scaling", mode);
2235 mVideoDecoder->setParameters(params);
2236 }
2237 }
2238 return OK;
2239 }
2240
getTrackInfo(Parcel * reply) const2241 status_t NuPlayer::getTrackInfo(Parcel* reply) const {
2242 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
2243 msg->setPointer("reply", reply);
2244
2245 sp<AMessage> response;
2246 status_t err = msg->postAndAwaitResponse(&response);
2247 return err;
2248 }
2249
getSelectedTrack(int32_t type,Parcel * reply) const2250 status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
2251 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
2252 msg->setPointer("reply", reply);
2253 msg->setInt32("type", type);
2254
2255 sp<AMessage> response;
2256 status_t err = msg->postAndAwaitResponse(&response);
2257 if (err == OK && response != NULL) {
2258 CHECK(response->findInt32("err", &err));
2259 }
2260 return err;
2261 }
2262
selectTrack(size_t trackIndex,bool select,int64_t timeUs)2263 status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
2264 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
2265 msg->setSize("trackIndex", trackIndex);
2266 msg->setInt32("select", select);
2267 msg->setInt64("timeUs", timeUs);
2268
2269 sp<AMessage> response;
2270 status_t err = msg->postAndAwaitResponse(&response);
2271
2272 if (err != OK) {
2273 return err;
2274 }
2275
2276 if (!response->findInt32("err", &err)) {
2277 err = OK;
2278 }
2279
2280 return err;
2281 }
2282
getCurrentPosition(int64_t * mediaUs)2283 status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
2284 sp<Renderer> renderer = mRenderer;
2285 if (renderer == NULL) {
2286 return NO_INIT;
2287 }
2288
2289 return renderer->getCurrentPosition(mediaUs);
2290 }
2291
getStats(Vector<sp<AMessage>> * trackStats)2292 void NuPlayer::getStats(Vector<sp<AMessage> > *trackStats) {
2293 CHECK(trackStats != NULL);
2294
2295 trackStats->clear();
2296
2297 Mutex::Autolock autoLock(mDecoderLock);
2298 if (mVideoDecoder != NULL) {
2299 trackStats->push_back(mVideoDecoder->getStats());
2300 }
2301 if (mAudioDecoder != NULL) {
2302 trackStats->push_back(mAudioDecoder->getStats());
2303 }
2304 }
2305
getFileMeta()2306 sp<MetaData> NuPlayer::getFileMeta() {
2307 return mSource->getFileFormatMeta();
2308 }
2309
getFrameRate()2310 float NuPlayer::getFrameRate() {
2311 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
2312 if (meta == NULL) {
2313 return 0;
2314 }
2315 int32_t rate;
2316 if (!meta->findInt32(kKeyFrameRate, &rate)) {
2317 // fall back to try file meta
2318 sp<MetaData> fileMeta = getFileMeta();
2319 if (fileMeta == NULL) {
2320 ALOGW("source has video meta but not file meta");
2321 return -1;
2322 }
2323 int32_t fileMetaRate;
2324 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
2325 return -1;
2326 }
2327 return fileMetaRate;
2328 }
2329 return rate;
2330 }
2331
schedulePollDuration()2332 void NuPlayer::schedulePollDuration() {
2333 sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
2334 msg->setInt32("generation", mPollDurationGeneration);
2335 msg->post();
2336 }
2337
cancelPollDuration()2338 void NuPlayer::cancelPollDuration() {
2339 ++mPollDurationGeneration;
2340 }
2341
processDeferredActions()2342 void NuPlayer::processDeferredActions() {
2343 while (!mDeferredActions.empty()) {
2344 // We won't execute any deferred actions until we're no longer in
2345 // an intermediate state, i.e. one more more decoders are currently
2346 // flushing or shutting down.
2347
2348 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
2349 // We're currently flushing, postpone the reset until that's
2350 // completed.
2351
2352 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
2353 mFlushingAudio, mFlushingVideo);
2354
2355 break;
2356 }
2357
2358 sp<Action> action = *mDeferredActions.begin();
2359 mDeferredActions.erase(mDeferredActions.begin());
2360
2361 action->execute(this);
2362 }
2363 }
2364
performSeek(int64_t seekTimeUs,MediaPlayerSeekMode mode)2365 void NuPlayer::performSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
2366 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
2367 (long long)seekTimeUs, seekTimeUs / 1E6, mode);
2368
2369 if (mSource == NULL) {
2370 // This happens when reset occurs right before the loop mode
2371 // asynchronously seeks to the start of the stream.
2372 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
2373 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
2374 mAudioDecoder.get(), mVideoDecoder.get());
2375 return;
2376 }
2377 mPreviousSeekTimeUs = seekTimeUs;
2378 mSource->seekTo(seekTimeUs, mode);
2379 ++mTimedTextGeneration;
2380
2381 // everything's flushed, continue playback.
2382 }
2383
performDecoderFlush(FlushCommand audio,FlushCommand video)2384 void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
2385 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
2386
2387 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
2388 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
2389 return;
2390 }
2391
2392 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
2393 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
2394 }
2395
2396 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
2397 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
2398 }
2399 }
2400
performReset()2401 void NuPlayer::performReset() {
2402 ALOGV("performReset");
2403
2404 CHECK(mAudioDecoder == NULL);
2405 CHECK(mVideoDecoder == NULL);
2406
2407 updatePlaybackTimer(true /* stopping */, "performReset");
2408 updateRebufferingTimer(true /* stopping */, true /* exiting */);
2409
2410 cancelPollDuration();
2411
2412 ++mScanSourcesGeneration;
2413 mScanSourcesPending = false;
2414
2415 if (mRendererLooper != NULL) {
2416 if (mRenderer != NULL) {
2417 mRendererLooper->unregisterHandler(mRenderer->id());
2418 }
2419 mRendererLooper->stop();
2420 mRendererLooper.clear();
2421 }
2422 mRenderer.clear();
2423 ++mRendererGeneration;
2424
2425 if (mSource != NULL) {
2426 mSource->stop();
2427
2428 Mutex::Autolock autoLock(mSourceLock);
2429 mSource.clear();
2430 }
2431
2432 if (mDriver != NULL) {
2433 sp<NuPlayerDriver> driver = mDriver.promote();
2434 if (driver != NULL) {
2435 driver->notifyResetComplete();
2436 }
2437 }
2438
2439 mStarted = false;
2440 mPrepared = false;
2441 mResetting = false;
2442 mSourceStarted = false;
2443
2444 // Modular DRM
2445 if (mCrypto != NULL) {
2446 // decoders will be flushed before this so their mCrypto would go away on their own
2447 // TODO change to ALOGV
2448 ALOGD("performReset mCrypto: %p (%d)", mCrypto.get(),
2449 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
2450 mCrypto.clear();
2451 }
2452 mIsDrmProtected = false;
2453 }
2454
performScanSources()2455 void NuPlayer::performScanSources() {
2456 ALOGV("performScanSources");
2457
2458 if (!mStarted) {
2459 return;
2460 }
2461
2462 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
2463 postScanSources();
2464 }
2465 }
2466
performSetSurface(const sp<Surface> & surface)2467 void NuPlayer::performSetSurface(const sp<Surface> &surface) {
2468 ALOGV("performSetSurface");
2469
2470 mSurface = surface;
2471
2472 // XXX - ignore error from setVideoScalingMode for now
2473 setVideoScalingMode(mVideoScalingMode);
2474
2475 if (mDriver != NULL) {
2476 sp<NuPlayerDriver> driver = mDriver.promote();
2477 if (driver != NULL) {
2478 driver->notifySetSurfaceComplete();
2479 }
2480 }
2481 }
2482
performResumeDecoders(bool needNotify)2483 void NuPlayer::performResumeDecoders(bool needNotify) {
2484 if (needNotify) {
2485 mResumePending = true;
2486 if (mVideoDecoder == NULL) {
2487 // if audio-only, we can notify seek complete now,
2488 // as the resume operation will be relatively fast.
2489 finishResume();
2490 }
2491 }
2492
2493 if (mVideoDecoder != NULL) {
2494 // When there is continuous seek, MediaPlayer will cache the seek
2495 // position, and send down new seek request when previous seek is
2496 // complete. Let's wait for at least one video output frame before
2497 // notifying seek complete, so that the video thumbnail gets updated
2498 // when seekbar is dragged.
2499 mVideoDecoder->signalResume(needNotify);
2500 }
2501
2502 if (mAudioDecoder != NULL) {
2503 mAudioDecoder->signalResume(false /* needNotify */);
2504 }
2505 }
2506
finishResume()2507 void NuPlayer::finishResume() {
2508 if (mResumePending) {
2509 mResumePending = false;
2510 notifyDriverSeekComplete();
2511 }
2512 }
2513
notifyDriverSeekComplete()2514 void NuPlayer::notifyDriverSeekComplete() {
2515 if (mDriver != NULL) {
2516 sp<NuPlayerDriver> driver = mDriver.promote();
2517 if (driver != NULL) {
2518 driver->notifySeekComplete();
2519 }
2520 }
2521 }
2522
onSourceNotify(const sp<AMessage> & msg)2523 void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
2524 int32_t what;
2525 CHECK(msg->findInt32("what", &what));
2526
2527 switch (what) {
2528 case Source::kWhatInstantiateSecureDecoders:
2529 {
2530 if (mSource == NULL) {
2531 // This is a stale notification from a source that was
2532 // asynchronously preparing when the client called reset().
2533 // We handled the reset, the source is gone.
2534 break;
2535 }
2536
2537 sp<AMessage> reply;
2538 CHECK(msg->findMessage("reply", &reply));
2539 status_t err = onInstantiateSecureDecoders();
2540 reply->setInt32("err", err);
2541 reply->post();
2542 break;
2543 }
2544
2545 case Source::kWhatPrepared:
2546 {
2547 ALOGV("NuPlayer::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
2548 if (mSource == NULL) {
2549 // This is a stale notification from a source that was
2550 // asynchronously preparing when the client called reset().
2551 // We handled the reset, the source is gone.
2552 break;
2553 }
2554
2555 int32_t err;
2556 CHECK(msg->findInt32("err", &err));
2557
2558 if (err != OK) {
2559 // shut down potential secure codecs in case client never calls reset
2560 mDeferredActions.push_back(
2561 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
2562 FLUSH_CMD_SHUTDOWN /* video */));
2563 processDeferredActions();
2564 } else {
2565 mPrepared = true;
2566 }
2567
2568 sp<NuPlayerDriver> driver = mDriver.promote();
2569 if (driver != NULL) {
2570 // notify duration first, so that it's definitely set when
2571 // the app received the "prepare complete" callback.
2572 int64_t durationUs;
2573 if (mSource->getDuration(&durationUs) == OK) {
2574 driver->notifyDuration(durationUs);
2575 }
2576 driver->notifyPrepareCompleted(err);
2577 }
2578
2579 break;
2580 }
2581
2582 // Modular DRM
2583 case Source::kWhatDrmInfo:
2584 {
2585 Parcel parcel;
2586 sp<ABuffer> drmInfo;
2587 CHECK(msg->findBuffer("drmInfo", &drmInfo));
2588 parcel.setData(drmInfo->data(), drmInfo->size());
2589
2590 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA_DRM_INFO drmInfo: %p parcel size: %zu",
2591 drmInfo.get(), parcel.dataSize());
2592
2593 notifyListener(MEDIA_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel);
2594
2595 break;
2596 }
2597
2598 case Source::kWhatFlagsChanged:
2599 {
2600 uint32_t flags;
2601 CHECK(msg->findInt32("flags", (int32_t *)&flags));
2602
2603 sp<NuPlayerDriver> driver = mDriver.promote();
2604 if (driver != NULL) {
2605
2606 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d "
2607 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d "
2608 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n"
2609 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d",
2610 (flags & Source::FLAG_CAN_PAUSE) != 0,
2611 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
2612 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
2613 (flags & Source::FLAG_CAN_SEEK) != 0,
2614 (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
2615 (flags & Source::FLAG_SECURE) != 0,
2616 (flags & Source::FLAG_PROTECTED) != 0);
2617
2618 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
2619 driver->notifyListener(
2620 MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
2621 }
2622 driver->notifyFlagsChanged(flags);
2623 }
2624
2625 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2626 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
2627 cancelPollDuration();
2628 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
2629 && (flags & Source::FLAG_DYNAMIC_DURATION)
2630 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
2631 schedulePollDuration();
2632 }
2633
2634 mSourceFlags = flags;
2635 break;
2636 }
2637
2638 case Source::kWhatVideoSizeChanged:
2639 {
2640 sp<AMessage> format;
2641 CHECK(msg->findMessage("format", &format));
2642
2643 updateVideoSize(format);
2644 break;
2645 }
2646
2647 case Source::kWhatBufferingUpdate:
2648 {
2649 int32_t percentage;
2650 CHECK(msg->findInt32("percentage", &percentage));
2651
2652 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
2653 break;
2654 }
2655
2656 case Source::kWhatPauseOnBufferingStart:
2657 {
2658 // ignore if not playing
2659 if (mStarted) {
2660 ALOGI("buffer low, pausing...");
2661
2662 startRebufferingTimer();
2663 mPausedForBuffering = true;
2664 onPause();
2665 }
2666 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
2667 break;
2668 }
2669
2670 case Source::kWhatResumeOnBufferingEnd:
2671 {
2672 // ignore if not playing
2673 if (mStarted) {
2674 ALOGI("buffer ready, resuming...");
2675
2676 updateRebufferingTimer(true /* stopping */, false /* exiting */);
2677 mPausedForBuffering = false;
2678
2679 // do not resume yet if client didn't unpause
2680 if (!mPausedByClient) {
2681 onResume();
2682 }
2683 }
2684 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
2685 break;
2686 }
2687
2688 case Source::kWhatCacheStats:
2689 {
2690 int32_t kbps;
2691 CHECK(msg->findInt32("bandwidth", &kbps));
2692
2693 notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
2694 break;
2695 }
2696
2697 case Source::kWhatSubtitleData:
2698 {
2699 sp<ABuffer> buffer;
2700 CHECK(msg->findBuffer("buffer", &buffer));
2701
2702 sendSubtitleData(buffer, 0 /* baseIndex */);
2703 break;
2704 }
2705
2706 case Source::kWhatTimedMetaData:
2707 {
2708 sp<ABuffer> buffer;
2709 if (!msg->findBuffer("buffer", &buffer)) {
2710 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2711 } else {
2712 sendTimedMetaData(buffer);
2713 }
2714 break;
2715 }
2716
2717 case Source::kWhatTimedTextData:
2718 {
2719 int32_t generation;
2720 if (msg->findInt32("generation", &generation)
2721 && generation != mTimedTextGeneration) {
2722 break;
2723 }
2724
2725 sp<ABuffer> buffer;
2726 CHECK(msg->findBuffer("buffer", &buffer));
2727
2728 sp<NuPlayerDriver> driver = mDriver.promote();
2729 if (driver == NULL) {
2730 break;
2731 }
2732
2733 int posMs;
2734 int64_t timeUs, posUs;
2735 driver->getCurrentPosition(&posMs);
2736 posUs = (int64_t) posMs * 1000LL;
2737 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2738
2739 if (posUs < timeUs) {
2740 if (!msg->findInt32("generation", &generation)) {
2741 msg->setInt32("generation", mTimedTextGeneration);
2742 }
2743 msg->post(timeUs - posUs);
2744 } else {
2745 sendTimedTextData(buffer);
2746 }
2747 break;
2748 }
2749
2750 case Source::kWhatQueueDecoderShutdown:
2751 {
2752 int32_t audio, video;
2753 CHECK(msg->findInt32("audio", &audio));
2754 CHECK(msg->findInt32("video", &video));
2755
2756 sp<AMessage> reply;
2757 CHECK(msg->findMessage("reply", &reply));
2758
2759 queueDecoderShutdown(audio, video, reply);
2760 break;
2761 }
2762
2763 case Source::kWhatDrmNoLicense:
2764 {
2765 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2766 break;
2767 }
2768
2769 case Source::kWhatIMSRxNotice:
2770 {
2771 sp<AMessage> IMSRxNotice;
2772 CHECK(msg->findMessage("message", &IMSRxNotice));
2773 sendIMSRxNotice(IMSRxNotice);
2774 break;
2775 }
2776
2777 default:
2778 TRESPASS();
2779 }
2780 }
2781
onClosedCaptionNotify(const sp<AMessage> & msg)2782 void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2783 int32_t what;
2784 CHECK(msg->findInt32("what", &what));
2785
2786 switch (what) {
2787 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2788 {
2789 sp<ABuffer> buffer;
2790 CHECK(msg->findBuffer("buffer", &buffer));
2791
2792 size_t inbandTracks = 0;
2793 if (mSource != NULL) {
2794 inbandTracks = mSource->getTrackCount();
2795 }
2796
2797 sendSubtitleData(buffer, inbandTracks);
2798 break;
2799 }
2800
2801 case NuPlayer::CCDecoder::kWhatTrackAdded:
2802 {
2803 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2804
2805 break;
2806 }
2807
2808 default:
2809 TRESPASS();
2810 }
2811
2812
2813 }
2814
sendSubtitleData(const sp<ABuffer> & buffer,int32_t baseIndex)2815 void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2816 int32_t trackIndex;
2817 int64_t timeUs, durationUs;
2818 CHECK(buffer->meta()->findInt32("track-index", &trackIndex));
2819 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2820 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2821
2822 Parcel in;
2823 in.writeInt32(trackIndex + baseIndex);
2824 in.writeInt64(timeUs);
2825 in.writeInt64(durationUs);
2826 in.writeInt32(buffer->size());
2827 in.writeInt32(buffer->size());
2828 in.write(buffer->data(), buffer->size());
2829
2830 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2831 }
2832
sendTimedMetaData(const sp<ABuffer> & buffer)2833 void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) {
2834 int64_t timeUs;
2835 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2836
2837 Parcel in;
2838 in.writeInt64(timeUs);
2839 in.writeInt32(buffer->size());
2840 in.writeInt32(buffer->size());
2841 in.write(buffer->data(), buffer->size());
2842
2843 notifyListener(MEDIA_META_DATA, 0, 0, &in);
2844 }
2845
sendTimedTextData(const sp<ABuffer> & buffer)2846 void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2847 const void *data;
2848 size_t size = 0;
2849 int64_t timeUs;
2850 int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP;
2851
2852 AString mime;
2853 CHECK(buffer->meta()->findString("mime", &mime));
2854 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2855
2856 data = buffer->data();
2857 size = buffer->size();
2858
2859 Parcel parcel;
2860 if (size > 0) {
2861 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2862 int32_t global = 0;
2863 if (buffer->meta()->findInt32("global", &global) && global) {
2864 flag |= TextDescriptions::GLOBAL_DESCRIPTIONS;
2865 } else {
2866 flag |= TextDescriptions::LOCAL_DESCRIPTIONS;
2867 }
2868 TextDescriptions::getParcelOfDescriptions(
2869 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2870 }
2871
2872 if ((parcel.dataSize() > 0)) {
2873 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2874 } else { // send an empty timed text
2875 notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2876 }
2877 }
2878
sendIMSRxNotice(const sp<AMessage> & msg)2879 void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
2880 int32_t payloadType;
2881
2882 CHECK(msg->findInt32("payload-type", &payloadType));
2883
2884 int32_t rtpSeq = 0, rtpTime = 0;
2885 int64_t ntpTime = 0, recvTimeUs = 0;
2886
2887 Parcel in;
2888 in.writeInt32(payloadType);
2889
2890 switch (payloadType) {
2891 case ARTPSource::RTP_FIRST_PACKET:
2892 {
2893 CHECK(msg->findInt32("rtp-time", &rtpTime));
2894 CHECK(msg->findInt32("rtp-seq-num", &rtpSeq));
2895 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2896 in.writeInt32(rtpTime);
2897 in.writeInt32(rtpSeq);
2898 in.writeInt32(recvTimeUs >> 32);
2899 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2900 break;
2901 }
2902 case ARTPSource::RTCP_FIRST_PACKET:
2903 {
2904 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2905 in.writeInt32(recvTimeUs >> 32);
2906 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2907 break;
2908 }
2909 case ARTPSource::RTCP_SR:
2910 {
2911 CHECK(msg->findInt32("rtp-time", &rtpTime));
2912 CHECK(msg->findInt64("ntp-time", &ntpTime));
2913 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2914 in.writeInt32(rtpTime);
2915 in.writeInt32(ntpTime >> 32);
2916 in.writeInt32(ntpTime & 0xFFFFFFFF);
2917 in.writeInt32(recvTimeUs >> 32);
2918 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2919 break;
2920 }
2921 case ARTPSource::RTCP_RR:
2922 {
2923 int64_t recvTimeUs;
2924 int32_t senderId;
2925 int32_t ssrc;
2926 int32_t fraction;
2927 int32_t lost;
2928 int32_t lastSeq;
2929 int32_t jitter;
2930 int32_t lsr;
2931 int32_t dlsr;
2932 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2933 CHECK(msg->findInt32("rtcp-rr-ssrc", &senderId));
2934 CHECK(msg->findInt32("rtcp-rrb-ssrc", &ssrc));
2935 CHECK(msg->findInt32("rtcp-rrb-fraction", &fraction));
2936 CHECK(msg->findInt32("rtcp-rrb-lost", &lost));
2937 CHECK(msg->findInt32("rtcp-rrb-lastSeq", &lastSeq));
2938 CHECK(msg->findInt32("rtcp-rrb-jitter", &jitter));
2939 CHECK(msg->findInt32("rtcp-rrb-lsr", &lsr));
2940 CHECK(msg->findInt32("rtcp-rrb-dlsr", &dlsr));
2941 in.writeInt32(recvTimeUs >> 32);
2942 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2943 in.writeInt32(senderId);
2944 in.writeInt32(ssrc);
2945 in.writeInt32(fraction);
2946 in.writeInt32(lost);
2947 in.writeInt32(lastSeq);
2948 in.writeInt32(jitter);
2949 in.writeInt32(lsr);
2950 in.writeInt32(dlsr);
2951 break;
2952 }
2953 case ARTPSource::RTCP_TSFB: // RTCP TSFB
2954 case ARTPSource::RTCP_PSFB: // RTCP PSFB
2955 case ARTPSource::RTP_AUTODOWN:
2956 {
2957 int32_t feedbackType, id;
2958 CHECK(msg->findInt32("feedback-type", &feedbackType));
2959 CHECK(msg->findInt32("sender", &id));
2960 in.writeInt32(feedbackType);
2961 in.writeInt32(id);
2962 if (payloadType == ARTPSource::RTCP_TSFB) {
2963 int32_t bitrate;
2964 CHECK(msg->findInt32("bit-rate", &bitrate));
2965 in.writeInt32(bitrate);
2966 }
2967 break;
2968 }
2969 case ARTPSource::RTP_QUALITY:
2970 case ARTPSource::RTP_QUALITY_EMC:
2971 {
2972 int32_t feedbackType, bitrate;
2973 int32_t highestSeqNum, baseSeqNum, prevExpected;
2974 int32_t numBufRecv, prevNumBufRecv;
2975 int32_t latestRtpTime, jbTimeMs, rtpRtcpSrTimeGapMs;
2976 int64_t recvTimeUs;
2977 CHECK(msg->findInt32("feedback-type", &feedbackType));
2978 CHECK(msg->findInt32("bit-rate", &bitrate));
2979 CHECK(msg->findInt32("highest-seq-num", &highestSeqNum));
2980 CHECK(msg->findInt32("base-seq-num", &baseSeqNum));
2981 CHECK(msg->findInt32("prev-expected", &prevExpected));
2982 CHECK(msg->findInt32("num-buf-recv", &numBufRecv));
2983 CHECK(msg->findInt32("prev-num-buf-recv", &prevNumBufRecv));
2984 CHECK(msg->findInt32("latest-rtp-time", &latestRtpTime));
2985 CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
2986 CHECK(msg->findInt32("rtp-jitter-time-ms", &jbTimeMs));
2987 CHECK(msg->findInt32("rtp-rtcpsr-time-gap-ms", &rtpRtcpSrTimeGapMs));
2988 in.writeInt32(feedbackType);
2989 in.writeInt32(bitrate);
2990 in.writeInt32(highestSeqNum);
2991 in.writeInt32(baseSeqNum);
2992 in.writeInt32(prevExpected);
2993 in.writeInt32(numBufRecv);
2994 in.writeInt32(prevNumBufRecv);
2995 in.writeInt32(latestRtpTime);
2996 in.writeInt32(recvTimeUs >> 32);
2997 in.writeInt32(recvTimeUs & 0xFFFFFFFF);
2998 in.writeInt32(jbTimeMs);
2999 in.writeInt32(rtpRtcpSrTimeGapMs);
3000 break;
3001 }
3002 case ARTPSource::RTP_CVO:
3003 {
3004 int32_t cvo;
3005 CHECK(msg->findInt32("cvo", &cvo));
3006 in.writeInt32(cvo);
3007 break;
3008 }
3009 default:
3010 break;
3011 }
3012
3013 notifyListener(MEDIA_IMS_RX_NOTICE, 0, 0, &in);
3014 }
3015
getDataSourceType()3016 const char *NuPlayer::getDataSourceType() {
3017 switch (mDataSourceType) {
3018 case DATA_SOURCE_TYPE_HTTP_LIVE:
3019 return "HTTPLive";
3020
3021 case DATA_SOURCE_TYPE_RTP:
3022 return "RTP";
3023
3024 case DATA_SOURCE_TYPE_RTSP:
3025 return "RTSP";
3026
3027 case DATA_SOURCE_TYPE_GENERIC_URL:
3028 return "GenURL";
3029
3030 case DATA_SOURCE_TYPE_GENERIC_FD:
3031 return "GenFD";
3032
3033 case DATA_SOURCE_TYPE_MEDIA:
3034 return "Media";
3035
3036 case DATA_SOURCE_TYPE_STREAM:
3037 return "Stream";
3038
3039 case DATA_SOURCE_TYPE_NONE:
3040 default:
3041 return "None";
3042 }
3043 }
3044
dump(AString & logString)3045 void NuPlayer::dump(AString& logString) {
3046 logString.append("renderer(");
3047 if (mRenderer != nullptr) {
3048 mRenderer->dump(logString);
3049 } else {
3050 logString.append("null");
3051 }
3052 logString.append(")");
3053 }
3054
3055 // Modular DRM begin
prepareDrm(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId)3056 status_t NuPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
3057 {
3058 ALOGV("prepareDrm ");
3059
3060 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
3061 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
3062 // synchronous call so just passing the address but with local copies of "const" args
3063 uint8_t UUID[16];
3064 memcpy(UUID, uuid, sizeof(UUID));
3065 Vector<uint8_t> sessionId = drmSessionId;
3066 msg->setPointer("uuid", (void*)UUID);
3067 msg->setPointer("drmSessionId", (void*)&sessionId);
3068
3069 sp<AMessage> response;
3070 status_t status = msg->postAndAwaitResponse(&response);
3071
3072 if (status == OK && response != NULL) {
3073 CHECK(response->findInt32("status", &status));
3074 ALOGV("prepareDrm ret: %d ", status);
3075 } else {
3076 ALOGE("prepareDrm err: %d", status);
3077 }
3078
3079 return status;
3080 }
3081
releaseDrm()3082 status_t NuPlayer::releaseDrm()
3083 {
3084 ALOGV("releaseDrm ");
3085
3086 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
3087
3088 sp<AMessage> response;
3089 status_t status = msg->postAndAwaitResponse(&response);
3090
3091 if (status == OK && response != NULL) {
3092 CHECK(response->findInt32("status", &status));
3093 ALOGV("releaseDrm ret: %d ", status);
3094 } else {
3095 ALOGE("releaseDrm err: %d", status);
3096 }
3097
3098 return status;
3099 }
3100
onPrepareDrm(const sp<AMessage> & msg)3101 status_t NuPlayer::onPrepareDrm(const sp<AMessage> &msg)
3102 {
3103 // TODO change to ALOGV
3104 ALOGD("onPrepareDrm ");
3105
3106 status_t status = INVALID_OPERATION;
3107 if (mSource == NULL) {
3108 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
3109 return status;
3110 }
3111
3112 uint8_t *uuid;
3113 Vector<uint8_t> *drmSessionId;
3114 CHECK(msg->findPointer("uuid", (void**)&uuid));
3115 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
3116
3117 status = OK;
3118 sp<ICrypto> crypto = NULL;
3119
3120 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
3121 if (crypto == NULL) {
3122 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
3123 return status;
3124 }
3125 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
3126
3127 if (mCrypto != NULL) {
3128 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p (%d)",
3129 mCrypto.get(), mCrypto->getStrongCount());
3130 mCrypto.clear();
3131 }
3132
3133 mCrypto = crypto;
3134 mIsDrmProtected = true;
3135 // TODO change to ALOGV
3136 ALOGD("onPrepareDrm: mCrypto: %p (%d)", mCrypto.get(),
3137 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3138
3139 return status;
3140 }
3141
onReleaseDrm()3142 status_t NuPlayer::onReleaseDrm()
3143 {
3144 // TODO change to ALOGV
3145 ALOGD("onReleaseDrm ");
3146
3147 if (!mIsDrmProtected) {
3148 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false.");
3149 }
3150
3151 mIsDrmProtected = false;
3152
3153 status_t status;
3154 if (mCrypto != NULL) {
3155 // notifying the source first before removing crypto from codec
3156 if (mSource != NULL) {
3157 mSource->releaseDrm();
3158 }
3159
3160 status=OK;
3161 // first making sure the codecs have released their crypto reference
3162 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
3163 if (videoDecoder != NULL) {
3164 status = videoDecoder->releaseCrypto();
3165 ALOGV("onReleaseDrm: video decoder ret: %d", status);
3166 }
3167
3168 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
3169 if (audioDecoder != NULL) {
3170 status_t status_audio = audioDecoder->releaseCrypto();
3171 if (status == OK) { // otherwise, returning the first error
3172 status = status_audio;
3173 }
3174 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
3175 }
3176
3177 // TODO change to ALOGV
3178 ALOGD("onReleaseDrm: mCrypto: %p (%d)", mCrypto.get(),
3179 (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
3180 mCrypto.clear();
3181 } else { // mCrypto == NULL
3182 ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
3183 status = INVALID_OPERATION;
3184 }
3185
3186 return status;
3187 }
3188 // Modular DRM end
3189 ////////////////////////////////////////////////////////////////////////////////
3190
getFormat(bool audio)3191 sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
3192 sp<MetaData> meta = getFormatMeta(audio);
3193
3194 if (meta == NULL) {
3195 return NULL;
3196 }
3197
3198 sp<AMessage> msg = new AMessage;
3199
3200 if(convertMetaDataToMessage(meta, &msg) == OK) {
3201 return msg;
3202 }
3203 return NULL;
3204 }
3205
notifyFlagsChanged(uint32_t flags)3206 void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
3207 sp<AMessage> notify = dupNotify();
3208 notify->setInt32("what", kWhatFlagsChanged);
3209 notify->setInt32("flags", flags);
3210 notify->post();
3211 }
3212
notifyVideoSizeChanged(const sp<AMessage> & format)3213 void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
3214 sp<AMessage> notify = dupNotify();
3215 notify->setInt32("what", kWhatVideoSizeChanged);
3216 notify->setMessage("format", format);
3217 notify->post();
3218 }
3219
notifyPrepared(status_t err)3220 void NuPlayer::Source::notifyPrepared(status_t err) {
3221 ALOGV("Source::notifyPrepared %d", err);
3222 sp<AMessage> notify = dupNotify();
3223 notify->setInt32("what", kWhatPrepared);
3224 notify->setInt32("err", err);
3225 notify->post();
3226 }
3227
notifyDrmInfo(const sp<ABuffer> & drmInfoBuffer)3228 void NuPlayer::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
3229 {
3230 ALOGV("Source::notifyDrmInfo");
3231
3232 sp<AMessage> notify = dupNotify();
3233 notify->setInt32("what", kWhatDrmInfo);
3234 notify->setBuffer("drmInfo", drmInfoBuffer);
3235
3236 notify->post();
3237 }
3238
notifyInstantiateSecureDecoders(const sp<AMessage> & reply)3239 void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
3240 sp<AMessage> notify = dupNotify();
3241 notify->setInt32("what", kWhatInstantiateSecureDecoders);
3242 notify->setMessage("reply", reply);
3243 notify->post();
3244 }
3245
onMessageReceived(const sp<AMessage> &)3246 void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
3247 TRESPASS();
3248 }
3249
3250 } // namespace android
3251