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