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