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