1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "NuPlayer"
19 #include <utils/Log.h>
20
21 #include "NuPlayer.h"
22
23 #include "HTTPLiveSource.h"
24 #include "NuPlayerDecoder.h"
25 #include "NuPlayerDecoderPassThrough.h"
26 #include "NuPlayerDriver.h"
27 #include "NuPlayerRenderer.h"
28 #include "NuPlayerSource.h"
29 #include "RTSPSource.h"
30 #include "StreamingSource.h"
31 #include "GenericSource.h"
32 #include "TextDescriptions.h"
33
34 #include "ATSParser.h"
35
36 #include <media/stagefright/foundation/hexdump.h>
37 #include <media/stagefright/foundation/ABuffer.h>
38 #include <media/stagefright/foundation/ADebug.h>
39 #include <media/stagefright/foundation/AMessage.h>
40 #include <media/stagefright/MediaBuffer.h>
41 #include <media/stagefright/MediaDefs.h>
42 #include <media/stagefright/MediaErrors.h>
43 #include <media/stagefright/MetaData.h>
44 #include <gui/IGraphicBufferProducer.h>
45
46 #include "avc_utils.h"
47
48 #include "ESDS.h"
49 #include <media/stagefright/Utils.h>
50
51 namespace android {
52
53 // TODO optimize buffer size for power consumption
54 // The offload read buffer size is 32 KB but 24 KB uses less power.
55 const size_t NuPlayer::kAggregateBufferSizeBytes = 24 * 1024;
56
57 struct NuPlayer::Action : public RefBase {
Actionandroid::NuPlayer::Action58 Action() {}
59
60 virtual void execute(NuPlayer *player) = 0;
61
62 private:
63 DISALLOW_EVIL_CONSTRUCTORS(Action);
64 };
65
66 struct NuPlayer::SeekAction : public Action {
SeekActionandroid::NuPlayer::SeekAction67 SeekAction(int64_t seekTimeUs, bool needNotify)
68 : mSeekTimeUs(seekTimeUs),
69 mNeedNotify(needNotify) {
70 }
71
executeandroid::NuPlayer::SeekAction72 virtual void execute(NuPlayer *player) {
73 player->performSeek(mSeekTimeUs, mNeedNotify);
74 }
75
76 private:
77 int64_t mSeekTimeUs;
78 bool mNeedNotify;
79
80 DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
81 };
82
83 struct NuPlayer::SetSurfaceAction : public Action {
SetSurfaceActionandroid::NuPlayer::SetSurfaceAction84 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
85 : mWrapper(wrapper) {
86 }
87
executeandroid::NuPlayer::SetSurfaceAction88 virtual void execute(NuPlayer *player) {
89 player->performSetSurface(mWrapper);
90 }
91
92 private:
93 sp<NativeWindowWrapper> mWrapper;
94
95 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
96 };
97
98 struct NuPlayer::ShutdownDecoderAction : public Action {
ShutdownDecoderActionandroid::NuPlayer::ShutdownDecoderAction99 ShutdownDecoderAction(bool audio, bool video)
100 : mAudio(audio),
101 mVideo(video) {
102 }
103
executeandroid::NuPlayer::ShutdownDecoderAction104 virtual void execute(NuPlayer *player) {
105 player->performDecoderShutdown(mAudio, mVideo);
106 }
107
108 private:
109 bool mAudio;
110 bool mVideo;
111
112 DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction);
113 };
114
115 struct NuPlayer::PostMessageAction : public Action {
PostMessageActionandroid::NuPlayer::PostMessageAction116 PostMessageAction(const sp<AMessage> &msg)
117 : mMessage(msg) {
118 }
119
executeandroid::NuPlayer::PostMessageAction120 virtual void execute(NuPlayer *) {
121 mMessage->post();
122 }
123
124 private:
125 sp<AMessage> mMessage;
126
127 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
128 };
129
130 // Use this if there's no state necessary to save in order to execute
131 // the action.
132 struct NuPlayer::SimpleAction : public Action {
133 typedef void (NuPlayer::*ActionFunc)();
134
SimpleActionandroid::NuPlayer::SimpleAction135 SimpleAction(ActionFunc func)
136 : mFunc(func) {
137 }
138
executeandroid::NuPlayer::SimpleAction139 virtual void execute(NuPlayer *player) {
140 (player->*mFunc)();
141 }
142
143 private:
144 ActionFunc mFunc;
145
146 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
147 };
148
149 ////////////////////////////////////////////////////////////////////////////////
150
NuPlayer()151 NuPlayer::NuPlayer()
152 : mUIDValid(false),
153 mSourceFlags(0),
154 mVideoIsAVC(false),
155 mOffloadAudio(false),
156 mAudioDecoderGeneration(0),
157 mVideoDecoderGeneration(0),
158 mRendererGeneration(0),
159 mAudioEOS(false),
160 mVideoEOS(false),
161 mScanSourcesPending(false),
162 mScanSourcesGeneration(0),
163 mPollDurationGeneration(0),
164 mTimedTextGeneration(0),
165 mTimeDiscontinuityPending(false),
166 mFlushingAudio(NONE),
167 mFlushingVideo(NONE),
168 mSkipRenderingAudioUntilMediaTimeUs(-1ll),
169 mSkipRenderingVideoUntilMediaTimeUs(-1ll),
170 mNumFramesTotal(0ll),
171 mNumFramesDropped(0ll),
172 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
173 mStarted(false) {
174 clearFlushComplete();
175 }
176
~NuPlayer()177 NuPlayer::~NuPlayer() {
178 }
179
setUID(uid_t uid)180 void NuPlayer::setUID(uid_t uid) {
181 mUIDValid = true;
182 mUID = uid;
183 }
184
setDriver(const wp<NuPlayerDriver> & driver)185 void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
186 mDriver = driver;
187 }
188
setDataSourceAsync(const sp<IStreamSource> & source)189 void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
190 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
191
192 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
193
194 msg->setObject("source", new StreamingSource(notify, source));
195 msg->post();
196 }
197
IsHTTPLiveURL(const char * url)198 static bool IsHTTPLiveURL(const char *url) {
199 if (!strncasecmp("http://", url, 7)
200 || !strncasecmp("https://", url, 8)
201 || !strncasecmp("file://", url, 7)) {
202 size_t len = strlen(url);
203 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
204 return true;
205 }
206
207 if (strstr(url,"m3u8")) {
208 return true;
209 }
210 }
211
212 return false;
213 }
214
setDataSourceAsync(const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)215 void NuPlayer::setDataSourceAsync(
216 const sp<IMediaHTTPService> &httpService,
217 const char *url,
218 const KeyedVector<String8, String8> *headers) {
219
220 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
221 size_t len = strlen(url);
222
223 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
224
225 sp<Source> source;
226 if (IsHTTPLiveURL(url)) {
227 source = new HTTPLiveSource(notify, httpService, url, headers);
228 } else if (!strncasecmp(url, "rtsp://", 7)) {
229 source = new RTSPSource(
230 notify, httpService, url, headers, mUIDValid, mUID);
231 } else if ((!strncasecmp(url, "http://", 7)
232 || !strncasecmp(url, "https://", 8))
233 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
234 || strstr(url, ".sdp?"))) {
235 source = new RTSPSource(
236 notify, httpService, url, headers, mUIDValid, mUID, true);
237 } else {
238 sp<GenericSource> genericSource =
239 new GenericSource(notify, mUIDValid, mUID);
240 // Don't set FLAG_SECURE on mSourceFlags here for widevine.
241 // The correct flags will be updated in Source::kWhatFlagsChanged
242 // handler when GenericSource is prepared.
243
244 status_t err = genericSource->setDataSource(httpService, url, headers);
245
246 if (err == OK) {
247 source = genericSource;
248 } else {
249 ALOGE("Failed to set data source!");
250 }
251 }
252 msg->setObject("source", source);
253 msg->post();
254 }
255
setDataSourceAsync(int fd,int64_t offset,int64_t length)256 void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
257 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
258
259 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
260
261 sp<GenericSource> source =
262 new GenericSource(notify, mUIDValid, mUID);
263
264 status_t err = source->setDataSource(fd, offset, length);
265
266 if (err != OK) {
267 ALOGE("Failed to set data source!");
268 source = NULL;
269 }
270
271 msg->setObject("source", source);
272 msg->post();
273 }
274
prepareAsync()275 void NuPlayer::prepareAsync() {
276 (new AMessage(kWhatPrepare, id()))->post();
277 }
278
setVideoSurfaceTextureAsync(const sp<IGraphicBufferProducer> & bufferProducer)279 void NuPlayer::setVideoSurfaceTextureAsync(
280 const sp<IGraphicBufferProducer> &bufferProducer) {
281 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
282
283 if (bufferProducer == NULL) {
284 msg->setObject("native-window", NULL);
285 } else {
286 msg->setObject(
287 "native-window",
288 new NativeWindowWrapper(
289 new Surface(bufferProducer, true /* controlledByApp */)));
290 }
291
292 msg->post();
293 }
294
setAudioSink(const sp<MediaPlayerBase::AudioSink> & sink)295 void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
296 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
297 msg->setObject("sink", sink);
298 msg->post();
299 }
300
start()301 void NuPlayer::start() {
302 (new AMessage(kWhatStart, id()))->post();
303 }
304
pause()305 void NuPlayer::pause() {
306 (new AMessage(kWhatPause, id()))->post();
307 }
308
resume()309 void NuPlayer::resume() {
310 (new AMessage(kWhatResume, id()))->post();
311 }
312
resetAsync()313 void NuPlayer::resetAsync() {
314 if (mSource != NULL) {
315 // During a reset, the data source might be unresponsive already, we need to
316 // disconnect explicitly so that reads exit promptly.
317 // We can't queue the disconnect request to the looper, as it might be
318 // queued behind a stuck read and never gets processed.
319 // Doing a disconnect outside the looper to allows the pending reads to exit
320 // (either successfully or with error).
321 mSource->disconnect();
322 }
323
324 (new AMessage(kWhatReset, id()))->post();
325 }
326
seekToAsync(int64_t seekTimeUs,bool needNotify)327 void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
328 sp<AMessage> msg = new AMessage(kWhatSeek, id());
329 msg->setInt64("seekTimeUs", seekTimeUs);
330 msg->setInt32("needNotify", needNotify);
331 msg->post();
332 }
333
334
writeTrackInfo(Parcel * reply,const sp<AMessage> format) const335 void NuPlayer::writeTrackInfo(
336 Parcel* reply, const sp<AMessage> format) const {
337 int32_t trackType;
338 CHECK(format->findInt32("type", &trackType));
339
340 AString lang;
341 CHECK(format->findString("language", &lang));
342
343 reply->writeInt32(2); // write something non-zero
344 reply->writeInt32(trackType);
345 reply->writeString16(String16(lang.c_str()));
346
347 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
348 AString mime;
349 CHECK(format->findString("mime", &mime));
350
351 int32_t isAuto, isDefault, isForced;
352 CHECK(format->findInt32("auto", &isAuto));
353 CHECK(format->findInt32("default", &isDefault));
354 CHECK(format->findInt32("forced", &isForced));
355
356 reply->writeString16(String16(mime.c_str()));
357 reply->writeInt32(isAuto);
358 reply->writeInt32(isDefault);
359 reply->writeInt32(isForced);
360 }
361 }
362
onMessageReceived(const sp<AMessage> & msg)363 void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
364 switch (msg->what()) {
365 case kWhatSetDataSource:
366 {
367 ALOGV("kWhatSetDataSource");
368
369 CHECK(mSource == NULL);
370
371 status_t err = OK;
372 sp<RefBase> obj;
373 CHECK(msg->findObject("source", &obj));
374 if (obj != NULL) {
375 mSource = static_cast<Source *>(obj.get());
376 } else {
377 err = UNKNOWN_ERROR;
378 }
379
380 CHECK(mDriver != NULL);
381 sp<NuPlayerDriver> driver = mDriver.promote();
382 if (driver != NULL) {
383 driver->notifySetDataSourceCompleted(err);
384 }
385 break;
386 }
387
388 case kWhatPrepare:
389 {
390 mSource->prepareAsync();
391 break;
392 }
393
394 case kWhatGetTrackInfo:
395 {
396 uint32_t replyID;
397 CHECK(msg->senderAwaitsResponse(&replyID));
398
399 Parcel* reply;
400 CHECK(msg->findPointer("reply", (void**)&reply));
401
402 size_t inbandTracks = 0;
403 if (mSource != NULL) {
404 inbandTracks = mSource->getTrackCount();
405 }
406
407 size_t ccTracks = 0;
408 if (mCCDecoder != NULL) {
409 ccTracks = mCCDecoder->getTrackCount();
410 }
411
412 // total track count
413 reply->writeInt32(inbandTracks + ccTracks);
414
415 // write inband tracks
416 for (size_t i = 0; i < inbandTracks; ++i) {
417 writeTrackInfo(reply, mSource->getTrackInfo(i));
418 }
419
420 // write CC track
421 for (size_t i = 0; i < ccTracks; ++i) {
422 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
423 }
424
425 sp<AMessage> response = new AMessage;
426 response->postReply(replyID);
427 break;
428 }
429
430 case kWhatGetSelectedTrack:
431 {
432 status_t err = INVALID_OPERATION;
433 if (mSource != NULL) {
434 err = OK;
435
436 int32_t type32;
437 CHECK(msg->findInt32("type", (int32_t*)&type32));
438 media_track_type type = (media_track_type)type32;
439 ssize_t selectedTrack = mSource->getSelectedTrack(type);
440
441 Parcel* reply;
442 CHECK(msg->findPointer("reply", (void**)&reply));
443 reply->writeInt32(selectedTrack);
444 }
445
446 sp<AMessage> response = new AMessage;
447 response->setInt32("err", err);
448
449 uint32_t replyID;
450 CHECK(msg->senderAwaitsResponse(&replyID));
451 response->postReply(replyID);
452 break;
453 }
454
455 case kWhatSelectTrack:
456 {
457 uint32_t replyID;
458 CHECK(msg->senderAwaitsResponse(&replyID));
459
460 size_t trackIndex;
461 int32_t select;
462 CHECK(msg->findSize("trackIndex", &trackIndex));
463 CHECK(msg->findInt32("select", &select));
464
465 status_t err = INVALID_OPERATION;
466
467 size_t inbandTracks = 0;
468 if (mSource != NULL) {
469 inbandTracks = mSource->getTrackCount();
470 }
471 size_t ccTracks = 0;
472 if (mCCDecoder != NULL) {
473 ccTracks = mCCDecoder->getTrackCount();
474 }
475
476 if (trackIndex < inbandTracks) {
477 err = mSource->selectTrack(trackIndex, select);
478
479 if (!select && err == OK) {
480 int32_t type;
481 sp<AMessage> info = mSource->getTrackInfo(trackIndex);
482 if (info != NULL
483 && info->findInt32("type", &type)
484 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
485 ++mTimedTextGeneration;
486 }
487 }
488 } else {
489 trackIndex -= inbandTracks;
490
491 if (trackIndex < ccTracks) {
492 err = mCCDecoder->selectTrack(trackIndex, select);
493 }
494 }
495
496 sp<AMessage> response = new AMessage;
497 response->setInt32("err", err);
498
499 response->postReply(replyID);
500 break;
501 }
502
503 case kWhatPollDuration:
504 {
505 int32_t generation;
506 CHECK(msg->findInt32("generation", &generation));
507
508 if (generation != mPollDurationGeneration) {
509 // stale
510 break;
511 }
512
513 int64_t durationUs;
514 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
515 sp<NuPlayerDriver> driver = mDriver.promote();
516 if (driver != NULL) {
517 driver->notifyDuration(durationUs);
518 }
519 }
520
521 msg->post(1000000ll); // poll again in a second.
522 break;
523 }
524
525 case kWhatSetVideoNativeWindow:
526 {
527 ALOGV("kWhatSetVideoNativeWindow");
528
529 mDeferredActions.push_back(
530 new ShutdownDecoderAction(
531 false /* audio */, true /* video */));
532
533 sp<RefBase> obj;
534 CHECK(msg->findObject("native-window", &obj));
535
536 mDeferredActions.push_back(
537 new SetSurfaceAction(
538 static_cast<NativeWindowWrapper *>(obj.get())));
539
540 if (obj != NULL) {
541 if (mStarted && mSource->getFormat(false /* audio */) != NULL) {
542 // Issue a seek to refresh the video screen only if started otherwise
543 // the extractor may not yet be started and will assert.
544 // If the video decoder is not set (perhaps audio only in this case)
545 // do not perform a seek as it is not needed.
546 int64_t currentPositionUs = 0;
547 if (getCurrentPosition(¤tPositionUs) == OK) {
548 mDeferredActions.push_back(
549 new SeekAction(currentPositionUs, false /* needNotify */));
550 }
551 }
552
553 // If there is a new surface texture, instantiate decoders
554 // again if possible.
555 mDeferredActions.push_back(
556 new SimpleAction(&NuPlayer::performScanSources));
557 }
558
559 processDeferredActions();
560 break;
561 }
562
563 case kWhatSetAudioSink:
564 {
565 ALOGV("kWhatSetAudioSink");
566
567 sp<RefBase> obj;
568 CHECK(msg->findObject("sink", &obj));
569
570 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
571 break;
572 }
573
574 case kWhatStart:
575 {
576 ALOGV("kWhatStart");
577
578 mVideoIsAVC = false;
579 mOffloadAudio = false;
580 mAudioEOS = false;
581 mVideoEOS = false;
582 mSkipRenderingAudioUntilMediaTimeUs = -1;
583 mSkipRenderingVideoUntilMediaTimeUs = -1;
584 mNumFramesTotal = 0;
585 mNumFramesDropped = 0;
586 mStarted = true;
587
588 /* instantiate decoders now for secure playback */
589 if (mSourceFlags & Source::FLAG_SECURE) {
590 if (mNativeWindow != NULL) {
591 instantiateDecoder(false, &mVideoDecoder);
592 }
593
594 if (mAudioSink != NULL) {
595 instantiateDecoder(true, &mAudioDecoder);
596 }
597 }
598
599 mSource->start();
600
601 uint32_t flags = 0;
602
603 if (mSource->isRealTime()) {
604 flags |= Renderer::FLAG_REAL_TIME;
605 }
606
607 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
608 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
609 if (mAudioSink != NULL) {
610 streamType = mAudioSink->getAudioStreamType();
611 }
612
613 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
614
615 mOffloadAudio =
616 canOffloadStream(audioMeta, (videoFormat != NULL),
617 true /* is_streaming */, streamType);
618 if (mOffloadAudio) {
619 flags |= Renderer::FLAG_OFFLOAD_AUDIO;
620 }
621
622 sp<AMessage> notify = new AMessage(kWhatRendererNotify, id());
623 ++mRendererGeneration;
624 notify->setInt32("generation", mRendererGeneration);
625 mRenderer = new Renderer(mAudioSink, notify, flags);
626
627 mRendererLooper = new ALooper;
628 mRendererLooper->setName("NuPlayerRenderer");
629 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
630 mRendererLooper->registerHandler(mRenderer);
631
632 sp<MetaData> meta = getFileMeta();
633 int32_t rate;
634 if (meta != NULL
635 && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
636 mRenderer->setVideoFrameRate(rate);
637 }
638
639 postScanSources();
640 break;
641 }
642
643 case kWhatScanSources:
644 {
645 int32_t generation;
646 CHECK(msg->findInt32("generation", &generation));
647 if (generation != mScanSourcesGeneration) {
648 // Drop obsolete msg.
649 break;
650 }
651
652 mScanSourcesPending = false;
653
654 ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
655 mAudioDecoder != NULL, mVideoDecoder != NULL);
656
657 bool mHadAnySourcesBefore =
658 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
659
660 // initialize video before audio because successful initialization of
661 // video may change deep buffer mode of audio.
662 if (mNativeWindow != NULL) {
663 instantiateDecoder(false, &mVideoDecoder);
664 }
665
666 if (mAudioSink != NULL) {
667 if (mOffloadAudio) {
668 // open audio sink early under offload mode.
669 sp<AMessage> format = mSource->getFormat(true /*audio*/);
670 openAudioSink(format, true /*offloadOnly*/);
671 }
672 instantiateDecoder(true, &mAudioDecoder);
673 }
674
675 if (!mHadAnySourcesBefore
676 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
677 // This is the first time we've found anything playable.
678
679 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
680 schedulePollDuration();
681 }
682 }
683
684 status_t err;
685 if ((err = mSource->feedMoreTSData()) != OK) {
686 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
687 // We're not currently decoding anything (no audio or
688 // video tracks found) and we just ran out of input data.
689
690 if (err == ERROR_END_OF_STREAM) {
691 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
692 } else {
693 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
694 }
695 }
696 break;
697 }
698
699 if ((mAudioDecoder == NULL && mAudioSink != NULL)
700 || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
701 msg->post(100000ll);
702 mScanSourcesPending = true;
703 }
704 break;
705 }
706
707 case kWhatVideoNotify:
708 case kWhatAudioNotify:
709 {
710 bool audio = msg->what() == kWhatAudioNotify;
711
712 int32_t currentDecoderGeneration =
713 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
714 int32_t requesterGeneration = currentDecoderGeneration - 1;
715 CHECK(msg->findInt32("generation", &requesterGeneration));
716
717 if (requesterGeneration != currentDecoderGeneration) {
718 ALOGV("got message from old %s decoder, generation(%d:%d)",
719 audio ? "audio" : "video", requesterGeneration,
720 currentDecoderGeneration);
721 sp<AMessage> reply;
722 if (!(msg->findMessage("reply", &reply))) {
723 return;
724 }
725
726 reply->setInt32("err", INFO_DISCONTINUITY);
727 reply->post();
728 return;
729 }
730
731 int32_t what;
732 CHECK(msg->findInt32("what", &what));
733
734 if (what == Decoder::kWhatFillThisBuffer) {
735 status_t err = feedDecoderInputData(
736 audio, msg);
737
738 if (err == -EWOULDBLOCK) {
739 if (mSource->feedMoreTSData() == OK) {
740 msg->post(10 * 1000ll);
741 }
742 }
743 } else if (what == Decoder::kWhatEOS) {
744 int32_t err;
745 CHECK(msg->findInt32("err", &err));
746
747 if (err == ERROR_END_OF_STREAM) {
748 ALOGV("got %s decoder EOS", audio ? "audio" : "video");
749 } else {
750 ALOGV("got %s decoder EOS w/ error %d",
751 audio ? "audio" : "video",
752 err);
753 }
754
755 mRenderer->queueEOS(audio, err);
756 } else if (what == Decoder::kWhatFlushCompleted) {
757 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
758
759 handleFlushComplete(audio, true /* isDecoder */);
760 finishFlushIfPossible();
761 } else if (what == Decoder::kWhatOutputFormatChanged) {
762 sp<AMessage> format;
763 CHECK(msg->findMessage("format", &format));
764
765 if (audio) {
766 openAudioSink(format, false /*offloadOnly*/);
767 } else {
768 // video
769 sp<AMessage> inputFormat =
770 mSource->getFormat(false /* audio */);
771
772 updateVideoSize(inputFormat, format);
773 }
774 } else if (what == Decoder::kWhatShutdownCompleted) {
775 ALOGV("%s shutdown completed", audio ? "audio" : "video");
776 if (audio) {
777 mAudioDecoder.clear();
778 ++mAudioDecoderGeneration;
779
780 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
781 mFlushingAudio = SHUT_DOWN;
782 } else {
783 mVideoDecoder.clear();
784 ++mVideoDecoderGeneration;
785
786 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
787 mFlushingVideo = SHUT_DOWN;
788 }
789
790 finishFlushIfPossible();
791 } else if (what == Decoder::kWhatError) {
792 status_t err;
793 if (!msg->findInt32("err", &err) || err == OK) {
794 err = UNKNOWN_ERROR;
795 }
796
797 // Decoder errors can be due to Source (e.g. from streaming),
798 // or from decoding corrupted bitstreams, or from other decoder
799 // MediaCodec operations (e.g. from an ongoing reset or seek).
800 //
801 // We try to gracefully shut down the affected decoder if possible,
802 // rather than trying to force the shutdown with something
803 // similar to performReset(). This method can lead to a hang
804 // if MediaCodec functions block after an error, but they should
805 // typically return INVALID_OPERATION instead of blocking.
806
807 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
808 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
809 err, audio ? "audio" : "video", *flushing);
810
811 switch (*flushing) {
812 case NONE:
813 mDeferredActions.push_back(
814 new ShutdownDecoderAction(audio, !audio /* video */));
815 processDeferredActions();
816 break;
817 case FLUSHING_DECODER:
818 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
819 break; // Wait for flush to complete.
820 case FLUSHING_DECODER_SHUTDOWN:
821 break; // Wait for flush to complete.
822 case SHUTTING_DOWN_DECODER:
823 break; // Wait for shutdown to complete.
824 case FLUSHED:
825 // Widevine source reads must stop before releasing the video decoder.
826 if (!audio && mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
827 mSource->stop();
828 }
829 getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
830 *flushing = SHUTTING_DOWN_DECODER; // Shut down.
831 break;
832 case SHUT_DOWN:
833 finishFlushIfPossible(); // Should not occur.
834 break; // Finish anyways.
835 }
836 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
837 } else if (what == Decoder::kWhatDrainThisBuffer) {
838 renderBuffer(audio, msg);
839 } else {
840 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
841 what,
842 what >> 24,
843 (what >> 16) & 0xff,
844 (what >> 8) & 0xff,
845 what & 0xff);
846 }
847
848 break;
849 }
850
851 case kWhatRendererNotify:
852 {
853 int32_t requesterGeneration = mRendererGeneration - 1;
854 CHECK(msg->findInt32("generation", &requesterGeneration));
855 if (requesterGeneration != mRendererGeneration) {
856 ALOGV("got message from old renderer, generation(%d:%d)",
857 requesterGeneration, mRendererGeneration);
858 return;
859 }
860
861 int32_t what;
862 CHECK(msg->findInt32("what", &what));
863
864 if (what == Renderer::kWhatEOS) {
865 int32_t audio;
866 CHECK(msg->findInt32("audio", &audio));
867
868 int32_t finalResult;
869 CHECK(msg->findInt32("finalResult", &finalResult));
870
871 if (audio) {
872 mAudioEOS = true;
873 } else {
874 mVideoEOS = true;
875 }
876
877 if (finalResult == ERROR_END_OF_STREAM) {
878 ALOGV("reached %s EOS", audio ? "audio" : "video");
879 } else {
880 ALOGE("%s track encountered an error (%d)",
881 audio ? "audio" : "video", finalResult);
882
883 notifyListener(
884 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
885 }
886
887 if ((mAudioEOS || mAudioDecoder == NULL)
888 && (mVideoEOS || mVideoDecoder == NULL)) {
889 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
890 }
891 } else if (what == Renderer::kWhatFlushComplete) {
892 int32_t audio;
893 CHECK(msg->findInt32("audio", &audio));
894
895 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
896 handleFlushComplete(audio, false /* isDecoder */);
897 finishFlushIfPossible();
898 } else if (what == Renderer::kWhatVideoRenderingStart) {
899 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
900 } else if (what == Renderer::kWhatMediaRenderingStart) {
901 ALOGV("media rendering started");
902 notifyListener(MEDIA_STARTED, 0, 0);
903 } else if (what == Renderer::kWhatAudioOffloadTearDown) {
904 ALOGV("Tear down audio offload, fall back to s/w path");
905 int64_t positionUs;
906 CHECK(msg->findInt64("positionUs", &positionUs));
907 int32_t reason;
908 CHECK(msg->findInt32("reason", &reason));
909 closeAudioSink();
910 mAudioDecoder.clear();
911 ++mAudioDecoderGeneration;
912 mRenderer->flush(true /* audio */);
913 if (mVideoDecoder != NULL) {
914 mRenderer->flush(false /* audio */);
915 }
916 mRenderer->signalDisableOffloadAudio();
917 mOffloadAudio = false;
918
919 performSeek(positionUs, false /* needNotify */);
920 if (reason == Renderer::kDueToError) {
921 instantiateDecoder(true /* audio */, &mAudioDecoder);
922 }
923 }
924 break;
925 }
926
927 case kWhatMoreDataQueued:
928 {
929 break;
930 }
931
932 case kWhatReset:
933 {
934 ALOGV("kWhatReset");
935
936 mDeferredActions.push_back(
937 new ShutdownDecoderAction(
938 true /* audio */, true /* video */));
939
940 mDeferredActions.push_back(
941 new SimpleAction(&NuPlayer::performReset));
942
943 processDeferredActions();
944 break;
945 }
946
947 case kWhatSeek:
948 {
949 int64_t seekTimeUs;
950 int32_t needNotify;
951 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
952 CHECK(msg->findInt32("needNotify", &needNotify));
953
954 ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d",
955 seekTimeUs, needNotify);
956
957 mDeferredActions.push_back(
958 new SimpleAction(&NuPlayer::performDecoderFlush));
959
960 mDeferredActions.push_back(
961 new SeekAction(seekTimeUs, needNotify));
962
963 processDeferredActions();
964 break;
965 }
966
967 case kWhatPause:
968 {
969 if (mSource != NULL) {
970 mSource->pause();
971 } else {
972 ALOGW("pause called when source is gone or not set");
973 }
974 if (mRenderer != NULL) {
975 mRenderer->pause();
976 } else {
977 ALOGW("pause called when renderer is gone or not set");
978 }
979 break;
980 }
981
982 case kWhatResume:
983 {
984 if (mSource != NULL) {
985 mSource->resume();
986 } else {
987 ALOGW("resume called when source is gone or not set");
988 }
989 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
990 // needed.
991 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
992 instantiateDecoder(true /* audio */, &mAudioDecoder);
993 }
994 if (mRenderer != NULL) {
995 mRenderer->resume();
996 } else {
997 ALOGW("resume called when renderer is gone or not set");
998 }
999 break;
1000 }
1001
1002 case kWhatSourceNotify:
1003 {
1004 onSourceNotify(msg);
1005 break;
1006 }
1007
1008 case kWhatClosedCaptionNotify:
1009 {
1010 onClosedCaptionNotify(msg);
1011 break;
1012 }
1013
1014 default:
1015 TRESPASS();
1016 break;
1017 }
1018 }
1019
audioDecoderStillNeeded()1020 bool NuPlayer::audioDecoderStillNeeded() {
1021 // Audio decoder is no longer needed if it's in shut/shutting down status.
1022 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1023 }
1024
handleFlushComplete(bool audio,bool isDecoder)1025 void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
1026 // We wait for both the decoder flush and the renderer flush to complete
1027 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1028
1029 mFlushComplete[audio][isDecoder] = true;
1030 if (!mFlushComplete[audio][!isDecoder]) {
1031 return;
1032 }
1033
1034 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1035 switch (*state) {
1036 case FLUSHING_DECODER:
1037 {
1038 *state = FLUSHED;
1039 break;
1040 }
1041
1042 case FLUSHING_DECODER_SHUTDOWN:
1043 {
1044 *state = SHUTTING_DOWN_DECODER;
1045
1046 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1047 if (!audio) {
1048 // Widevine source reads must stop before releasing the video decoder.
1049 if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
1050 mSource->stop();
1051 }
1052 }
1053 getDecoder(audio)->initiateShutdown();
1054 break;
1055 }
1056
1057 default:
1058 // decoder flush completes only occur in a flushing state.
1059 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1060 break;
1061 }
1062 }
1063
finishFlushIfPossible()1064 void NuPlayer::finishFlushIfPossible() {
1065 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1066 && mFlushingAudio != SHUT_DOWN) {
1067 return;
1068 }
1069
1070 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1071 && mFlushingVideo != SHUT_DOWN) {
1072 return;
1073 }
1074
1075 ALOGV("both audio and video are flushed now.");
1076
1077 mPendingAudioAccessUnit.clear();
1078 mAggregateBuffer.clear();
1079
1080 if (mTimeDiscontinuityPending) {
1081 mRenderer->signalTimeDiscontinuity();
1082 mTimeDiscontinuityPending = false;
1083 }
1084
1085 if (mAudioDecoder != NULL && mFlushingAudio == FLUSHED) {
1086 mAudioDecoder->signalResume();
1087 }
1088
1089 if (mVideoDecoder != NULL && mFlushingVideo == FLUSHED) {
1090 mVideoDecoder->signalResume();
1091 }
1092
1093 mFlushingAudio = NONE;
1094 mFlushingVideo = NONE;
1095
1096 clearFlushComplete();
1097
1098 processDeferredActions();
1099 }
1100
postScanSources()1101 void NuPlayer::postScanSources() {
1102 if (mScanSourcesPending) {
1103 return;
1104 }
1105
1106 sp<AMessage> msg = new AMessage(kWhatScanSources, id());
1107 msg->setInt32("generation", mScanSourcesGeneration);
1108 msg->post();
1109
1110 mScanSourcesPending = true;
1111 }
1112
openAudioSink(const sp<AMessage> & format,bool offloadOnly)1113 void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
1114 uint32_t flags;
1115 int64_t durationUs;
1116 bool hasVideo = (mVideoDecoder != NULL);
1117 // FIXME: we should handle the case where the video decoder
1118 // is created after we receive the format change indication.
1119 // Current code will just make that we select deep buffer
1120 // with video which should not be a problem as it should
1121 // not prevent from keeping A/V sync.
1122 if (hasVideo &&
1123 mSource->getDuration(&durationUs) == OK &&
1124 durationUs
1125 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
1126 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1127 } else {
1128 flags = AUDIO_OUTPUT_FLAG_NONE;
1129 }
1130
1131 mOffloadAudio = mRenderer->openAudioSink(
1132 format, offloadOnly, hasVideo, flags);
1133
1134 if (mOffloadAudio) {
1135 sp<MetaData> audioMeta =
1136 mSource->getFormatMeta(true /* audio */);
1137 sendMetaDataToHal(mAudioSink, audioMeta);
1138 }
1139 }
1140
closeAudioSink()1141 void NuPlayer::closeAudioSink() {
1142 mRenderer->closeAudioSink();
1143 }
1144
instantiateDecoder(bool audio,sp<Decoder> * decoder)1145 status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
1146 if (*decoder != NULL) {
1147 return OK;
1148 }
1149
1150 sp<AMessage> format = mSource->getFormat(audio);
1151
1152 if (format == NULL) {
1153 return -EWOULDBLOCK;
1154 }
1155
1156 if (!audio) {
1157 AString mime;
1158 CHECK(format->findString("mime", &mime));
1159 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
1160
1161 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
1162 mCCDecoder = new CCDecoder(ccNotify);
1163
1164 if (mSourceFlags & Source::FLAG_SECURE) {
1165 format->setInt32("secure", true);
1166 }
1167 }
1168
1169 if (audio) {
1170 sp<AMessage> notify = new AMessage(kWhatAudioNotify, id());
1171 ++mAudioDecoderGeneration;
1172 notify->setInt32("generation", mAudioDecoderGeneration);
1173
1174 if (mOffloadAudio) {
1175 *decoder = new DecoderPassThrough(notify);
1176 } else {
1177 *decoder = new Decoder(notify);
1178 }
1179 } else {
1180 sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());
1181 ++mVideoDecoderGeneration;
1182 notify->setInt32("generation", mVideoDecoderGeneration);
1183
1184 *decoder = new Decoder(notify, mNativeWindow);
1185 }
1186 (*decoder)->init();
1187 (*decoder)->configure(format);
1188
1189 // allocate buffers to decrypt widevine source buffers
1190 if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1191 Vector<sp<ABuffer> > inputBufs;
1192 CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1193
1194 Vector<MediaBuffer *> mediaBufs;
1195 for (size_t i = 0; i < inputBufs.size(); i++) {
1196 const sp<ABuffer> &buffer = inputBufs[i];
1197 MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1198 mediaBufs.push(mbuf);
1199 }
1200
1201 status_t err = mSource->setBuffers(audio, mediaBufs);
1202 if (err != OK) {
1203 for (size_t i = 0; i < mediaBufs.size(); ++i) {
1204 mediaBufs[i]->release();
1205 }
1206 mediaBufs.clear();
1207 ALOGE("Secure source didn't support secure mediaBufs.");
1208 return err;
1209 }
1210 }
1211 return OK;
1212 }
1213
feedDecoderInputData(bool audio,const sp<AMessage> & msg)1214 status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
1215 sp<AMessage> reply;
1216 CHECK(msg->findMessage("reply", &reply));
1217
1218 if ((audio && mFlushingAudio != NONE)
1219 || (!audio && mFlushingVideo != NONE)
1220 || mSource == NULL) {
1221 reply->setInt32("err", INFO_DISCONTINUITY);
1222 reply->post();
1223 return OK;
1224 }
1225
1226 sp<ABuffer> accessUnit;
1227
1228 // Aggregate smaller buffers into a larger buffer.
1229 // The goal is to reduce power consumption.
1230 // Note this will not work if the decoder requires one frame per buffer.
1231 bool doBufferAggregation = (audio && mOffloadAudio);
1232 bool needMoreData = false;
1233
1234 bool dropAccessUnit;
1235 do {
1236 status_t err;
1237 // Did we save an accessUnit earlier because of a discontinuity?
1238 if (audio && (mPendingAudioAccessUnit != NULL)) {
1239 accessUnit = mPendingAudioAccessUnit;
1240 mPendingAudioAccessUnit.clear();
1241 err = mPendingAudioErr;
1242 ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit");
1243 } else {
1244 err = mSource->dequeueAccessUnit(audio, &accessUnit);
1245 }
1246
1247 if (err == -EWOULDBLOCK) {
1248 return err;
1249 } else if (err != OK) {
1250 if (err == INFO_DISCONTINUITY) {
1251 if (doBufferAggregation && (mAggregateBuffer != NULL)) {
1252 // We already have some data so save this for later.
1253 mPendingAudioErr = err;
1254 mPendingAudioAccessUnit = accessUnit;
1255 accessUnit.clear();
1256 ALOGD("feedDecoderInputData() save discontinuity for later");
1257 break;
1258 }
1259 int32_t type;
1260 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
1261
1262 bool formatChange =
1263 (audio &&
1264 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
1265 || (!audio &&
1266 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
1267
1268 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
1269
1270 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
1271 audio ? "audio" : "video", formatChange, timeChange);
1272
1273 if (audio) {
1274 mSkipRenderingAudioUntilMediaTimeUs = -1;
1275 } else {
1276 mSkipRenderingVideoUntilMediaTimeUs = -1;
1277 }
1278
1279 if (timeChange) {
1280 sp<AMessage> extra;
1281 if (accessUnit->meta()->findMessage("extra", &extra)
1282 && extra != NULL) {
1283 int64_t resumeAtMediaTimeUs;
1284 if (extra->findInt64(
1285 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
1286 ALOGI("suppressing rendering of %s until %lld us",
1287 audio ? "audio" : "video", resumeAtMediaTimeUs);
1288
1289 if (audio) {
1290 mSkipRenderingAudioUntilMediaTimeUs =
1291 resumeAtMediaTimeUs;
1292 } else {
1293 mSkipRenderingVideoUntilMediaTimeUs =
1294 resumeAtMediaTimeUs;
1295 }
1296 }
1297 }
1298 }
1299
1300 mTimeDiscontinuityPending =
1301 mTimeDiscontinuityPending || timeChange;
1302
1303 bool seamlessFormatChange = false;
1304 sp<AMessage> newFormat = mSource->getFormat(audio);
1305 if (formatChange) {
1306 seamlessFormatChange =
1307 getDecoder(audio)->supportsSeamlessFormatChange(newFormat);
1308 // treat seamless format change separately
1309 formatChange = !seamlessFormatChange;
1310 }
1311 bool shutdownOrFlush = formatChange || timeChange;
1312
1313 // We want to queue up scan-sources only once per discontinuity.
1314 // We control this by doing it only if neither audio nor video are
1315 // flushing or shutting down. (After handling 1st discontinuity, one
1316 // of the flushing states will not be NONE.)
1317 // No need to scan sources if this discontinuity does not result
1318 // in a flush or shutdown, as the flushing state will stay NONE.
1319 if (mFlushingAudio == NONE && mFlushingVideo == NONE &&
1320 shutdownOrFlush) {
1321 // And we'll resume scanning sources once we're done
1322 // flushing.
1323 mDeferredActions.push_front(
1324 new SimpleAction(
1325 &NuPlayer::performScanSources));
1326 }
1327
1328 if (formatChange /* not seamless */) {
1329 // must change decoder
1330 flushDecoder(audio, /* needShutdown = */ true);
1331 } else if (timeChange) {
1332 // need to flush
1333 flushDecoder(audio, /* needShutdown = */ false, newFormat);
1334 err = OK;
1335 } else if (seamlessFormatChange) {
1336 // reuse existing decoder and don't flush
1337 updateDecoderFormatWithoutFlush(audio, newFormat);
1338 err = OK;
1339 } else {
1340 // This stream is unaffected by the discontinuity
1341 return -EWOULDBLOCK;
1342 }
1343 }
1344
1345 reply->setInt32("err", err);
1346 reply->post();
1347 return OK;
1348 }
1349
1350 if (!audio) {
1351 ++mNumFramesTotal;
1352 }
1353
1354 dropAccessUnit = false;
1355 if (!audio
1356 && !(mSourceFlags & Source::FLAG_SECURE)
1357 && mRenderer->getVideoLateByUs() > 100000ll
1358 && mVideoIsAVC
1359 && !IsAVCReferenceFrame(accessUnit)) {
1360 dropAccessUnit = true;
1361 ++mNumFramesDropped;
1362 }
1363
1364 size_t smallSize = accessUnit->size();
1365 needMoreData = false;
1366 if (doBufferAggregation && (mAggregateBuffer == NULL)
1367 // Don't bother if only room for a few small buffers.
1368 && (smallSize < (kAggregateBufferSizeBytes / 3))) {
1369 // Create a larger buffer for combining smaller buffers from the extractor.
1370 mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes);
1371 mAggregateBuffer->setRange(0, 0); // start empty
1372 }
1373
1374 if (doBufferAggregation && (mAggregateBuffer != NULL)) {
1375 int64_t timeUs;
1376 int64_t dummy;
1377 bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs);
1378 bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy);
1379 // Will the smaller buffer fit?
1380 size_t bigSize = mAggregateBuffer->size();
1381 size_t roomLeft = mAggregateBuffer->capacity() - bigSize;
1382 // Should we save this small buffer for the next big buffer?
1383 // If the first small buffer did not have a timestamp then save
1384 // any buffer that does have a timestamp until the next big buffer.
1385 if ((smallSize > roomLeft)
1386 || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) {
1387 mPendingAudioErr = err;
1388 mPendingAudioAccessUnit = accessUnit;
1389 accessUnit.clear();
1390 } else {
1391 // Grab time from first small buffer if available.
1392 if ((bigSize == 0) && smallTimestampValid) {
1393 mAggregateBuffer->meta()->setInt64("timeUs", timeUs);
1394 }
1395 // Append small buffer to the bigger buffer.
1396 memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize);
1397 bigSize += smallSize;
1398 mAggregateBuffer->setRange(0, bigSize);
1399
1400 // Keep looping until we run out of room in the mAggregateBuffer.
1401 needMoreData = true;
1402
1403 ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu",
1404 smallSize, bigSize, mAggregateBuffer->capacity());
1405 }
1406 }
1407 } while (dropAccessUnit || needMoreData);
1408
1409 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
1410
1411 #if 0
1412 int64_t mediaTimeUs;
1413 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
1414 ALOGV("feeding %s input buffer at media time %.2f secs",
1415 audio ? "audio" : "video",
1416 mediaTimeUs / 1E6);
1417 #endif
1418
1419 if (!audio) {
1420 mCCDecoder->decode(accessUnit);
1421 }
1422
1423 if (doBufferAggregation && (mAggregateBuffer != NULL)) {
1424 ALOGV("feedDecoderInputData() reply with aggregated buffer, %zu",
1425 mAggregateBuffer->size());
1426 reply->setBuffer("buffer", mAggregateBuffer);
1427 mAggregateBuffer.clear();
1428 } else {
1429 reply->setBuffer("buffer", accessUnit);
1430 }
1431
1432 reply->post();
1433
1434 return OK;
1435 }
1436
renderBuffer(bool audio,const sp<AMessage> & msg)1437 void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
1438 // ALOGV("renderBuffer %s", audio ? "audio" : "video");
1439
1440 sp<AMessage> reply;
1441 CHECK(msg->findMessage("reply", &reply));
1442
1443 if ((audio && mFlushingAudio != NONE)
1444 || (!audio && mFlushingVideo != NONE)) {
1445 // We're currently attempting to flush the decoder, in order
1446 // to complete this, the decoder wants all its buffers back,
1447 // so we don't want any output buffers it sent us (from before
1448 // we initiated the flush) to be stuck in the renderer's queue.
1449
1450 ALOGV("we're still flushing the %s decoder, sending its output buffer"
1451 " right back.", audio ? "audio" : "video");
1452
1453 reply->post();
1454 return;
1455 }
1456
1457 sp<ABuffer> buffer;
1458 CHECK(msg->findBuffer("buffer", &buffer));
1459
1460 int64_t mediaTimeUs;
1461 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1462
1463 int64_t &skipUntilMediaTimeUs =
1464 audio
1465 ? mSkipRenderingAudioUntilMediaTimeUs
1466 : mSkipRenderingVideoUntilMediaTimeUs;
1467
1468 if (skipUntilMediaTimeUs >= 0) {
1469
1470 if (mediaTimeUs < skipUntilMediaTimeUs) {
1471 ALOGV("dropping %s buffer at time %lld as requested.",
1472 audio ? "audio" : "video",
1473 mediaTimeUs);
1474
1475 reply->post();
1476 return;
1477 }
1478
1479 skipUntilMediaTimeUs = -1;
1480 }
1481
1482 if (!audio && mCCDecoder->isSelected()) {
1483 mCCDecoder->display(mediaTimeUs);
1484 }
1485
1486 mRenderer->queueBuffer(audio, buffer, reply);
1487 }
1488
updateVideoSize(const sp<AMessage> & inputFormat,const sp<AMessage> & outputFormat)1489 void NuPlayer::updateVideoSize(
1490 const sp<AMessage> &inputFormat,
1491 const sp<AMessage> &outputFormat) {
1492 if (inputFormat == NULL) {
1493 ALOGW("Unknown video size, reporting 0x0!");
1494 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1495 return;
1496 }
1497
1498 int32_t displayWidth, displayHeight;
1499 int32_t cropLeft, cropTop, cropRight, cropBottom;
1500
1501 if (outputFormat != NULL) {
1502 int32_t width, height;
1503 CHECK(outputFormat->findInt32("width", &width));
1504 CHECK(outputFormat->findInt32("height", &height));
1505
1506 int32_t cropLeft, cropTop, cropRight, cropBottom;
1507 CHECK(outputFormat->findRect(
1508 "crop",
1509 &cropLeft, &cropTop, &cropRight, &cropBottom));
1510
1511 displayWidth = cropRight - cropLeft + 1;
1512 displayHeight = cropBottom - cropTop + 1;
1513
1514 ALOGV("Video output format changed to %d x %d "
1515 "(crop: %d x %d @ (%d, %d))",
1516 width, height,
1517 displayWidth,
1518 displayHeight,
1519 cropLeft, cropTop);
1520 } else {
1521 CHECK(inputFormat->findInt32("width", &displayWidth));
1522 CHECK(inputFormat->findInt32("height", &displayHeight));
1523
1524 ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1525 }
1526
1527 // Take into account sample aspect ratio if necessary:
1528 int32_t sarWidth, sarHeight;
1529 if (inputFormat->findInt32("sar-width", &sarWidth)
1530 && inputFormat->findInt32("sar-height", &sarHeight)) {
1531 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1532
1533 displayWidth = (displayWidth * sarWidth) / sarHeight;
1534
1535 ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
1536 }
1537
1538 int32_t rotationDegrees;
1539 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1540 rotationDegrees = 0;
1541 }
1542
1543 if (rotationDegrees == 90 || rotationDegrees == 270) {
1544 int32_t tmp = displayWidth;
1545 displayWidth = displayHeight;
1546 displayHeight = tmp;
1547 }
1548
1549 notifyListener(
1550 MEDIA_SET_VIDEO_SIZE,
1551 displayWidth,
1552 displayHeight);
1553 }
1554
notifyListener(int msg,int ext1,int ext2,const Parcel * in)1555 void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
1556 if (mDriver == NULL) {
1557 return;
1558 }
1559
1560 sp<NuPlayerDriver> driver = mDriver.promote();
1561
1562 if (driver == NULL) {
1563 return;
1564 }
1565
1566 driver->notifyListener(msg, ext1, ext2, in);
1567 }
1568
flushDecoder(bool audio,bool needShutdown,const sp<AMessage> & newFormat)1569 void NuPlayer::flushDecoder(
1570 bool audio, bool needShutdown, const sp<AMessage> &newFormat) {
1571 ALOGV("[%s] flushDecoder needShutdown=%d",
1572 audio ? "audio" : "video", needShutdown);
1573
1574 const sp<Decoder> &decoder = getDecoder(audio);
1575 if (decoder == NULL) {
1576 ALOGI("flushDecoder %s without decoder present",
1577 audio ? "audio" : "video");
1578 return;
1579 }
1580
1581 // Make sure we don't continue to scan sources until we finish flushing.
1582 ++mScanSourcesGeneration;
1583 mScanSourcesPending = false;
1584
1585 decoder->signalFlush(newFormat);
1586 mRenderer->flush(audio);
1587
1588 FlushStatus newStatus =
1589 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1590
1591 mFlushComplete[audio][false /* isDecoder */] = false;
1592 mFlushComplete[audio][true /* isDecoder */] = false;
1593 if (audio) {
1594 ALOGE_IF(mFlushingAudio != NONE,
1595 "audio flushDecoder() is called in state %d", mFlushingAudio);
1596 mFlushingAudio = newStatus;
1597 } else {
1598 ALOGE_IF(mFlushingVideo != NONE,
1599 "video flushDecoder() is called in state %d", mFlushingVideo);
1600 mFlushingVideo = newStatus;
1601
1602 if (mCCDecoder != NULL) {
1603 mCCDecoder->flush();
1604 }
1605 }
1606 }
1607
updateDecoderFormatWithoutFlush(bool audio,const sp<AMessage> & format)1608 void NuPlayer::updateDecoderFormatWithoutFlush(
1609 bool audio, const sp<AMessage> &format) {
1610 ALOGV("[%s] updateDecoderFormatWithoutFlush", audio ? "audio" : "video");
1611
1612 const sp<Decoder> &decoder = getDecoder(audio);
1613 if (decoder == NULL) {
1614 ALOGI("updateDecoderFormatWithoutFlush %s without decoder present",
1615 audio ? "audio" : "video");
1616 return;
1617 }
1618
1619 decoder->signalUpdateFormat(format);
1620 }
1621
queueDecoderShutdown(bool audio,bool video,const sp<AMessage> & reply)1622 void NuPlayer::queueDecoderShutdown(
1623 bool audio, bool video, const sp<AMessage> &reply) {
1624 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
1625
1626 mDeferredActions.push_back(
1627 new ShutdownDecoderAction(audio, video));
1628
1629 mDeferredActions.push_back(
1630 new SimpleAction(&NuPlayer::performScanSources));
1631
1632 mDeferredActions.push_back(new PostMessageAction(reply));
1633
1634 processDeferredActions();
1635 }
1636
setVideoScalingMode(int32_t mode)1637 status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1638 mVideoScalingMode = mode;
1639 if (mNativeWindow != NULL) {
1640 status_t ret = native_window_set_scaling_mode(
1641 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1642 if (ret != OK) {
1643 ALOGE("Failed to set scaling mode (%d): %s",
1644 -ret, strerror(-ret));
1645 return ret;
1646 }
1647 }
1648 return OK;
1649 }
1650
getTrackInfo(Parcel * reply) const1651 status_t NuPlayer::getTrackInfo(Parcel* reply) const {
1652 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
1653 msg->setPointer("reply", reply);
1654
1655 sp<AMessage> response;
1656 status_t err = msg->postAndAwaitResponse(&response);
1657 return err;
1658 }
1659
getSelectedTrack(int32_t type,Parcel * reply) const1660 status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
1661 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
1662 msg->setPointer("reply", reply);
1663 msg->setInt32("type", type);
1664
1665 sp<AMessage> response;
1666 status_t err = msg->postAndAwaitResponse(&response);
1667 if (err == OK && response != NULL) {
1668 CHECK(response->findInt32("err", &err));
1669 }
1670 return err;
1671 }
1672
selectTrack(size_t trackIndex,bool select)1673 status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
1674 sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
1675 msg->setSize("trackIndex", trackIndex);
1676 msg->setInt32("select", select);
1677
1678 sp<AMessage> response;
1679 status_t err = msg->postAndAwaitResponse(&response);
1680
1681 if (err != OK) {
1682 return err;
1683 }
1684
1685 if (!response->findInt32("err", &err)) {
1686 err = OK;
1687 }
1688
1689 return err;
1690 }
1691
getCurrentPosition(int64_t * mediaUs)1692 status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
1693 sp<Renderer> renderer = mRenderer;
1694 if (renderer == NULL) {
1695 return NO_INIT;
1696 }
1697
1698 return renderer->getCurrentPosition(mediaUs);
1699 }
1700
getStats(int64_t * numFramesTotal,int64_t * numFramesDropped)1701 void NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) {
1702 *numFramesTotal = mNumFramesTotal;
1703 *numFramesDropped = mNumFramesDropped;
1704 }
1705
getFileMeta()1706 sp<MetaData> NuPlayer::getFileMeta() {
1707 return mSource->getFileFormatMeta();
1708 }
1709
schedulePollDuration()1710 void NuPlayer::schedulePollDuration() {
1711 sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1712 msg->setInt32("generation", mPollDurationGeneration);
1713 msg->post();
1714 }
1715
cancelPollDuration()1716 void NuPlayer::cancelPollDuration() {
1717 ++mPollDurationGeneration;
1718 }
1719
processDeferredActions()1720 void NuPlayer::processDeferredActions() {
1721 while (!mDeferredActions.empty()) {
1722 // We won't execute any deferred actions until we're no longer in
1723 // an intermediate state, i.e. one more more decoders are currently
1724 // flushing or shutting down.
1725
1726 if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1727 // We're currently flushing, postpone the reset until that's
1728 // completed.
1729
1730 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1731 mFlushingAudio, mFlushingVideo);
1732
1733 break;
1734 }
1735
1736 sp<Action> action = *mDeferredActions.begin();
1737 mDeferredActions.erase(mDeferredActions.begin());
1738
1739 action->execute(this);
1740 }
1741 }
1742
performSeek(int64_t seekTimeUs,bool needNotify)1743 void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
1744 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), needNotify(%d)",
1745 seekTimeUs,
1746 seekTimeUs / 1E6,
1747 needNotify);
1748
1749 if (mSource == NULL) {
1750 // This happens when reset occurs right before the loop mode
1751 // asynchronously seeks to the start of the stream.
1752 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
1753 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
1754 mAudioDecoder.get(), mVideoDecoder.get());
1755 return;
1756 }
1757 mSource->seekTo(seekTimeUs);
1758 ++mTimedTextGeneration;
1759
1760 if (mDriver != NULL) {
1761 sp<NuPlayerDriver> driver = mDriver.promote();
1762 if (driver != NULL) {
1763 if (needNotify) {
1764 driver->notifySeekComplete();
1765 }
1766 }
1767 }
1768
1769 // everything's flushed, continue playback.
1770 }
1771
performDecoderFlush()1772 void NuPlayer::performDecoderFlush() {
1773 ALOGV("performDecoderFlush");
1774
1775 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1776 return;
1777 }
1778
1779 mTimeDiscontinuityPending = true;
1780
1781 if (mAudioDecoder != NULL) {
1782 flushDecoder(true /* audio */, false /* needShutdown */);
1783 }
1784
1785 if (mVideoDecoder != NULL) {
1786 flushDecoder(false /* audio */, false /* needShutdown */);
1787 }
1788 }
1789
performDecoderShutdown(bool audio,bool video)1790 void NuPlayer::performDecoderShutdown(bool audio, bool video) {
1791 ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video);
1792
1793 if ((!audio || mAudioDecoder == NULL)
1794 && (!video || mVideoDecoder == NULL)) {
1795 return;
1796 }
1797
1798 mTimeDiscontinuityPending = true;
1799
1800 if (audio && mAudioDecoder != NULL) {
1801 flushDecoder(true /* audio */, true /* needShutdown */);
1802 }
1803
1804 if (video && mVideoDecoder != NULL) {
1805 flushDecoder(false /* audio */, true /* needShutdown */);
1806 }
1807 }
1808
performReset()1809 void NuPlayer::performReset() {
1810 ALOGV("performReset");
1811
1812 CHECK(mAudioDecoder == NULL);
1813 CHECK(mVideoDecoder == NULL);
1814
1815 cancelPollDuration();
1816
1817 ++mScanSourcesGeneration;
1818 mScanSourcesPending = false;
1819
1820 if (mRendererLooper != NULL) {
1821 if (mRenderer != NULL) {
1822 mRendererLooper->unregisterHandler(mRenderer->id());
1823 }
1824 mRendererLooper->stop();
1825 mRendererLooper.clear();
1826 }
1827 mRenderer.clear();
1828 ++mRendererGeneration;
1829
1830 if (mSource != NULL) {
1831 mSource->stop();
1832
1833 mSource.clear();
1834 }
1835
1836 if (mDriver != NULL) {
1837 sp<NuPlayerDriver> driver = mDriver.promote();
1838 if (driver != NULL) {
1839 driver->notifyResetComplete();
1840 }
1841 }
1842
1843 mStarted = false;
1844 }
1845
performScanSources()1846 void NuPlayer::performScanSources() {
1847 ALOGV("performScanSources");
1848
1849 if (!mStarted) {
1850 return;
1851 }
1852
1853 if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1854 postScanSources();
1855 }
1856 }
1857
performSetSurface(const sp<NativeWindowWrapper> & wrapper)1858 void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1859 ALOGV("performSetSurface");
1860
1861 mNativeWindow = wrapper;
1862
1863 // XXX - ignore error from setVideoScalingMode for now
1864 setVideoScalingMode(mVideoScalingMode);
1865
1866 if (mDriver != NULL) {
1867 sp<NuPlayerDriver> driver = mDriver.promote();
1868 if (driver != NULL) {
1869 driver->notifySetSurfaceComplete();
1870 }
1871 }
1872 }
1873
onSourceNotify(const sp<AMessage> & msg)1874 void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1875 int32_t what;
1876 CHECK(msg->findInt32("what", &what));
1877
1878 switch (what) {
1879 case Source::kWhatPrepared:
1880 {
1881 if (mSource == NULL) {
1882 // This is a stale notification from a source that was
1883 // asynchronously preparing when the client called reset().
1884 // We handled the reset, the source is gone.
1885 break;
1886 }
1887
1888 int32_t err;
1889 CHECK(msg->findInt32("err", &err));
1890
1891 sp<NuPlayerDriver> driver = mDriver.promote();
1892 if (driver != NULL) {
1893 // notify duration first, so that it's definitely set when
1894 // the app received the "prepare complete" callback.
1895 int64_t durationUs;
1896 if (mSource->getDuration(&durationUs) == OK) {
1897 driver->notifyDuration(durationUs);
1898 }
1899 driver->notifyPrepareCompleted(err);
1900 }
1901
1902 break;
1903 }
1904
1905 case Source::kWhatFlagsChanged:
1906 {
1907 uint32_t flags;
1908 CHECK(msg->findInt32("flags", (int32_t *)&flags));
1909
1910 sp<NuPlayerDriver> driver = mDriver.promote();
1911 if (driver != NULL) {
1912 driver->notifyFlagsChanged(flags);
1913 }
1914
1915 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1916 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1917 cancelPollDuration();
1918 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1919 && (flags & Source::FLAG_DYNAMIC_DURATION)
1920 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1921 schedulePollDuration();
1922 }
1923
1924 mSourceFlags = flags;
1925 break;
1926 }
1927
1928 case Source::kWhatVideoSizeChanged:
1929 {
1930 sp<AMessage> format;
1931 CHECK(msg->findMessage("format", &format));
1932
1933 updateVideoSize(format);
1934 break;
1935 }
1936
1937 case Source::kWhatBufferingUpdate:
1938 {
1939 int32_t percentage;
1940 CHECK(msg->findInt32("percentage", &percentage));
1941
1942 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
1943 break;
1944 }
1945
1946 case Source::kWhatBufferingStart:
1947 {
1948 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1949 break;
1950 }
1951
1952 case Source::kWhatBufferingEnd:
1953 {
1954 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1955 break;
1956 }
1957
1958 case Source::kWhatSubtitleData:
1959 {
1960 sp<ABuffer> buffer;
1961 CHECK(msg->findBuffer("buffer", &buffer));
1962
1963 sendSubtitleData(buffer, 0 /* baseIndex */);
1964 break;
1965 }
1966
1967 case Source::kWhatTimedTextData:
1968 {
1969 int32_t generation;
1970 if (msg->findInt32("generation", &generation)
1971 && generation != mTimedTextGeneration) {
1972 break;
1973 }
1974
1975 sp<ABuffer> buffer;
1976 CHECK(msg->findBuffer("buffer", &buffer));
1977
1978 sp<NuPlayerDriver> driver = mDriver.promote();
1979 if (driver == NULL) {
1980 break;
1981 }
1982
1983 int posMs;
1984 int64_t timeUs, posUs;
1985 driver->getCurrentPosition(&posMs);
1986 posUs = posMs * 1000;
1987 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1988
1989 if (posUs < timeUs) {
1990 if (!msg->findInt32("generation", &generation)) {
1991 msg->setInt32("generation", mTimedTextGeneration);
1992 }
1993 msg->post(timeUs - posUs);
1994 } else {
1995 sendTimedTextData(buffer);
1996 }
1997 break;
1998 }
1999
2000 case Source::kWhatQueueDecoderShutdown:
2001 {
2002 int32_t audio, video;
2003 CHECK(msg->findInt32("audio", &audio));
2004 CHECK(msg->findInt32("video", &video));
2005
2006 sp<AMessage> reply;
2007 CHECK(msg->findMessage("reply", &reply));
2008
2009 queueDecoderShutdown(audio, video, reply);
2010 break;
2011 }
2012
2013 case Source::kWhatDrmNoLicense:
2014 {
2015 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2016 break;
2017 }
2018
2019 default:
2020 TRESPASS();
2021 }
2022 }
2023
onClosedCaptionNotify(const sp<AMessage> & msg)2024 void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2025 int32_t what;
2026 CHECK(msg->findInt32("what", &what));
2027
2028 switch (what) {
2029 case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2030 {
2031 sp<ABuffer> buffer;
2032 CHECK(msg->findBuffer("buffer", &buffer));
2033
2034 size_t inbandTracks = 0;
2035 if (mSource != NULL) {
2036 inbandTracks = mSource->getTrackCount();
2037 }
2038
2039 sendSubtitleData(buffer, inbandTracks);
2040 break;
2041 }
2042
2043 case NuPlayer::CCDecoder::kWhatTrackAdded:
2044 {
2045 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2046
2047 break;
2048 }
2049
2050 default:
2051 TRESPASS();
2052 }
2053
2054
2055 }
2056
sendSubtitleData(const sp<ABuffer> & buffer,int32_t baseIndex)2057 void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2058 int32_t trackIndex;
2059 int64_t timeUs, durationUs;
2060 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
2061 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2062 CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2063
2064 Parcel in;
2065 in.writeInt32(trackIndex + baseIndex);
2066 in.writeInt64(timeUs);
2067 in.writeInt64(durationUs);
2068 in.writeInt32(buffer->size());
2069 in.writeInt32(buffer->size());
2070 in.write(buffer->data(), buffer->size());
2071
2072 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2073 }
2074
sendTimedTextData(const sp<ABuffer> & buffer)2075 void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2076 const void *data;
2077 size_t size = 0;
2078 int64_t timeUs;
2079 int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
2080
2081 AString mime;
2082 CHECK(buffer->meta()->findString("mime", &mime));
2083 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2084
2085 data = buffer->data();
2086 size = buffer->size();
2087
2088 Parcel parcel;
2089 if (size > 0) {
2090 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2091 flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
2092 TextDescriptions::getParcelOfDescriptions(
2093 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2094 }
2095
2096 if ((parcel.dataSize() > 0)) {
2097 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2098 } else { // send an empty timed text
2099 notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2100 }
2101 }
2102 ////////////////////////////////////////////////////////////////////////////////
2103
getFormat(bool audio)2104 sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
2105 sp<MetaData> meta = getFormatMeta(audio);
2106
2107 if (meta == NULL) {
2108 return NULL;
2109 }
2110
2111 sp<AMessage> msg = new AMessage;
2112
2113 if(convertMetaDataToMessage(meta, &msg) == OK) {
2114 return msg;
2115 }
2116 return NULL;
2117 }
2118
notifyFlagsChanged(uint32_t flags)2119 void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
2120 sp<AMessage> notify = dupNotify();
2121 notify->setInt32("what", kWhatFlagsChanged);
2122 notify->setInt32("flags", flags);
2123 notify->post();
2124 }
2125
notifyVideoSizeChanged(const sp<AMessage> & format)2126 void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
2127 sp<AMessage> notify = dupNotify();
2128 notify->setInt32("what", kWhatVideoSizeChanged);
2129 notify->setMessage("format", format);
2130 notify->post();
2131 }
2132
notifyPrepared(status_t err)2133 void NuPlayer::Source::notifyPrepared(status_t err) {
2134 sp<AMessage> notify = dupNotify();
2135 notify->setInt32("what", kWhatPrepared);
2136 notify->setInt32("err", err);
2137 notify->post();
2138 }
2139
onMessageReceived(const sp<AMessage> &)2140 void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
2141 TRESPASS();
2142 }
2143
2144 } // namespace android
2145