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