NuPlayer.cpp revision 3a2956d148d81194e297408179e84a47a309ef48
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 33#include "ATSParser.h" 34 35#include <media/stagefright/foundation/hexdump.h> 36#include <media/stagefright/foundation/ABuffer.h> 37#include <media/stagefright/foundation/ADebug.h> 38#include <media/stagefright/foundation/AMessage.h> 39#include <media/stagefright/MediaBuffer.h> 40#include <media/stagefright/MediaDefs.h> 41#include <media/stagefright/MediaErrors.h> 42#include <media/stagefright/MetaData.h> 43#include <gui/IGraphicBufferProducer.h> 44 45#include "avc_utils.h" 46 47#include "ESDS.h" 48#include <media/stagefright/Utils.h> 49 50namespace android { 51 52struct NuPlayer::Action : public RefBase { 53 Action() {} 54 55 virtual void execute(NuPlayer *player) = 0; 56 57private: 58 DISALLOW_EVIL_CONSTRUCTORS(Action); 59}; 60 61struct NuPlayer::SeekAction : public Action { 62 SeekAction(int64_t seekTimeUs) 63 : mSeekTimeUs(seekTimeUs) { 64 } 65 66 virtual void execute(NuPlayer *player) { 67 player->performSeek(mSeekTimeUs); 68 } 69 70private: 71 int64_t mSeekTimeUs; 72 73 DISALLOW_EVIL_CONSTRUCTORS(SeekAction); 74}; 75 76struct NuPlayer::SetSurfaceAction : public Action { 77 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper) 78 : mWrapper(wrapper) { 79 } 80 81 virtual void execute(NuPlayer *player) { 82 player->performSetSurface(mWrapper); 83 } 84 85private: 86 sp<NativeWindowWrapper> mWrapper; 87 88 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction); 89}; 90 91struct NuPlayer::ShutdownDecoderAction : public Action { 92 ShutdownDecoderAction(bool audio, bool video) 93 : mAudio(audio), 94 mVideo(video) { 95 } 96 97 virtual void execute(NuPlayer *player) { 98 player->performDecoderShutdown(mAudio, mVideo); 99 } 100 101private: 102 bool mAudio; 103 bool mVideo; 104 105 DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction); 106}; 107 108struct NuPlayer::PostMessageAction : public Action { 109 PostMessageAction(const sp<AMessage> &msg) 110 : mMessage(msg) { 111 } 112 113 virtual void execute(NuPlayer *) { 114 mMessage->post(); 115 } 116 117private: 118 sp<AMessage> mMessage; 119 120 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction); 121}; 122 123// Use this if there's no state necessary to save in order to execute 124// the action. 125struct NuPlayer::SimpleAction : public Action { 126 typedef void (NuPlayer::*ActionFunc)(); 127 128 SimpleAction(ActionFunc func) 129 : mFunc(func) { 130 } 131 132 virtual void execute(NuPlayer *player) { 133 (player->*mFunc)(); 134 } 135 136private: 137 ActionFunc mFunc; 138 139 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction); 140}; 141 142//////////////////////////////////////////////////////////////////////////////// 143 144NuPlayer::NuPlayer() 145 : mUIDValid(false), 146 mSourceFlags(0), 147 mVideoIsAVC(false), 148 mOffloadAudio(false), 149 mAudioEOS(false), 150 mVideoEOS(false), 151 mScanSourcesPending(false), 152 mScanSourcesGeneration(0), 153 mPollDurationGeneration(0), 154 mTimeDiscontinuityPending(false), 155 mFlushingAudio(NONE), 156 mFlushingVideo(NONE), 157 mSkipRenderingAudioUntilMediaTimeUs(-1ll), 158 mSkipRenderingVideoUntilMediaTimeUs(-1ll), 159 mVideoLateByUs(0ll), 160 mNumFramesTotal(0ll), 161 mNumFramesDropped(0ll), 162 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), 163 mStarted(false) { 164} 165 166NuPlayer::~NuPlayer() { 167} 168 169void NuPlayer::setUID(uid_t uid) { 170 mUIDValid = true; 171 mUID = uid; 172} 173 174void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { 175 mDriver = driver; 176} 177 178void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) { 179 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 180 181 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 182 183 msg->setObject("source", new StreamingSource(notify, source)); 184 msg->post(); 185} 186 187static bool IsHTTPLiveURL(const char *url) { 188 if (!strncasecmp("http://", url, 7) 189 || !strncasecmp("https://", url, 8) 190 || !strncasecmp("file://", url, 7)) { 191 size_t len = strlen(url); 192 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 193 return true; 194 } 195 196 if (strstr(url,"m3u8")) { 197 return true; 198 } 199 } 200 201 return false; 202} 203 204void NuPlayer::setDataSourceAsync( 205 const sp<IMediaHTTPService> &httpService, 206 const char *url, 207 const KeyedVector<String8, String8> *headers) { 208 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 209 size_t len = strlen(url); 210 211 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 212 213 sp<Source> source; 214 if (IsHTTPLiveURL(url)) { 215 source = new HTTPLiveSource(notify, httpService, url, headers); 216 } else if (!strncasecmp(url, "rtsp://", 7)) { 217 source = new RTSPSource( 218 notify, httpService, url, headers, mUIDValid, mUID); 219 } else if ((!strncasecmp(url, "http://", 7) 220 || !strncasecmp(url, "https://", 8)) 221 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) 222 || strstr(url, ".sdp?"))) { 223 source = new RTSPSource( 224 notify, httpService, url, headers, mUIDValid, mUID, true); 225 } else if ((!strncasecmp(url, "widevine://", 11))) { 226 source = new GenericSource(notify, httpService, url, headers, 227 true /* isWidevine */, mUIDValid, mUID); 228 mSourceFlags |= Source::FLAG_SECURE; 229 } else { 230 source = new GenericSource(notify, httpService, url, headers); 231 } 232 233 msg->setObject("source", source); 234 msg->post(); 235} 236 237void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { 238 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 239 240 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 241 242 sp<Source> source = new GenericSource(notify, fd, offset, length); 243 msg->setObject("source", source); 244 msg->post(); 245} 246 247void NuPlayer::prepareAsync() { 248 (new AMessage(kWhatPrepare, id()))->post(); 249} 250 251void NuPlayer::setVideoSurfaceTextureAsync( 252 const sp<IGraphicBufferProducer> &bufferProducer) { 253 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id()); 254 255 if (bufferProducer == NULL) { 256 msg->setObject("native-window", NULL); 257 } else { 258 msg->setObject( 259 "native-window", 260 new NativeWindowWrapper( 261 new Surface(bufferProducer))); 262 } 263 264 msg->post(); 265} 266 267void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) { 268 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id()); 269 msg->setObject("sink", sink); 270 msg->post(); 271} 272 273void NuPlayer::start() { 274 (new AMessage(kWhatStart, id()))->post(); 275} 276 277void NuPlayer::pause() { 278 (new AMessage(kWhatPause, id()))->post(); 279} 280 281void NuPlayer::resume() { 282 (new AMessage(kWhatResume, id()))->post(); 283} 284 285void NuPlayer::resetAsync() { 286 (new AMessage(kWhatReset, id()))->post(); 287} 288 289void NuPlayer::seekToAsync(int64_t seekTimeUs) { 290 sp<AMessage> msg = new AMessage(kWhatSeek, id()); 291 msg->setInt64("seekTimeUs", seekTimeUs); 292 msg->post(); 293} 294 295// static 296bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { 297 switch (state) { 298 case FLUSHING_DECODER: 299 if (needShutdown != NULL) { 300 *needShutdown = false; 301 } 302 return true; 303 304 case FLUSHING_DECODER_SHUTDOWN: 305 if (needShutdown != NULL) { 306 *needShutdown = true; 307 } 308 return true; 309 310 default: 311 return false; 312 } 313} 314 315void NuPlayer::writeTrackInfo( 316 Parcel* reply, const sp<AMessage> format) const { 317 int32_t trackType; 318 CHECK(format->findInt32("type", &trackType)); 319 320 AString lang; 321 CHECK(format->findString("language", &lang)); 322 323 reply->writeInt32(2); // write something non-zero 324 reply->writeInt32(trackType); 325 reply->writeString16(String16(lang.c_str())); 326 327 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) { 328 AString mime; 329 CHECK(format->findString("mime", &mime)); 330 331 int32_t isAuto, isDefault, isForced; 332 CHECK(format->findInt32("auto", &isAuto)); 333 CHECK(format->findInt32("default", &isDefault)); 334 CHECK(format->findInt32("forced", &isForced)); 335 336 reply->writeString16(String16(mime.c_str())); 337 reply->writeInt32(isAuto); 338 reply->writeInt32(isDefault); 339 reply->writeInt32(isForced); 340 } 341} 342 343void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 344 switch (msg->what()) { 345 case kWhatSetDataSource: 346 { 347 ALOGV("kWhatSetDataSource"); 348 349 CHECK(mSource == NULL); 350 351 sp<RefBase> obj; 352 CHECK(msg->findObject("source", &obj)); 353 354 mSource = static_cast<Source *>(obj.get()); 355 356 looper()->registerHandler(mSource); 357 358 CHECK(mDriver != NULL); 359 sp<NuPlayerDriver> driver = mDriver.promote(); 360 if (driver != NULL) { 361 driver->notifySetDataSourceCompleted(OK); 362 } 363 break; 364 } 365 366 case kWhatPrepare: 367 { 368 mSource->prepareAsync(); 369 break; 370 } 371 372 case kWhatGetTrackInfo: 373 { 374 uint32_t replyID; 375 CHECK(msg->senderAwaitsResponse(&replyID)); 376 377 Parcel* reply; 378 CHECK(msg->findPointer("reply", (void**)&reply)); 379 380 size_t inbandTracks = 0; 381 if (mSource != NULL) { 382 inbandTracks = mSource->getTrackCount(); 383 } 384 385 size_t ccTracks = 0; 386 if (mCCDecoder != NULL) { 387 ccTracks = mCCDecoder->getTrackCount(); 388 } 389 390 // total track count 391 reply->writeInt32(inbandTracks + ccTracks); 392 393 // write inband tracks 394 for (size_t i = 0; i < inbandTracks; ++i) { 395 writeTrackInfo(reply, mSource->getTrackInfo(i)); 396 } 397 398 // write CC track 399 for (size_t i = 0; i < ccTracks; ++i) { 400 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i)); 401 } 402 403 sp<AMessage> response = new AMessage; 404 response->postReply(replyID); 405 break; 406 } 407 408 case kWhatSelectTrack: 409 { 410 uint32_t replyID; 411 CHECK(msg->senderAwaitsResponse(&replyID)); 412 413 size_t trackIndex; 414 int32_t select; 415 CHECK(msg->findSize("trackIndex", &trackIndex)); 416 CHECK(msg->findInt32("select", &select)); 417 418 status_t err = INVALID_OPERATION; 419 420 size_t inbandTracks = 0; 421 if (mSource != NULL) { 422 inbandTracks = mSource->getTrackCount(); 423 } 424 size_t ccTracks = 0; 425 if (mCCDecoder != NULL) { 426 ccTracks = mCCDecoder->getTrackCount(); 427 } 428 429 if (trackIndex < inbandTracks) { 430 err = mSource->selectTrack(trackIndex, select); 431 } else { 432 trackIndex -= inbandTracks; 433 434 if (trackIndex < ccTracks) { 435 err = mCCDecoder->selectTrack(trackIndex, select); 436 } 437 } 438 439 sp<AMessage> response = new AMessage; 440 response->setInt32("err", err); 441 442 response->postReply(replyID); 443 break; 444 } 445 446 case kWhatPollDuration: 447 { 448 int32_t generation; 449 CHECK(msg->findInt32("generation", &generation)); 450 451 if (generation != mPollDurationGeneration) { 452 // stale 453 break; 454 } 455 456 int64_t durationUs; 457 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 458 sp<NuPlayerDriver> driver = mDriver.promote(); 459 if (driver != NULL) { 460 driver->notifyDuration(durationUs); 461 } 462 } 463 464 msg->post(1000000ll); // poll again in a second. 465 break; 466 } 467 468 case kWhatSetVideoNativeWindow: 469 { 470 ALOGV("kWhatSetVideoNativeWindow"); 471 472 mDeferredActions.push_back( 473 new ShutdownDecoderAction( 474 false /* audio */, true /* video */)); 475 476 sp<RefBase> obj; 477 CHECK(msg->findObject("native-window", &obj)); 478 479 mDeferredActions.push_back( 480 new SetSurfaceAction( 481 static_cast<NativeWindowWrapper *>(obj.get()))); 482 483 if (obj != NULL) { 484 // If there is a new surface texture, instantiate decoders 485 // again if possible. 486 mDeferredActions.push_back( 487 new SimpleAction(&NuPlayer::performScanSources)); 488 } 489 490 processDeferredActions(); 491 break; 492 } 493 494 case kWhatSetAudioSink: 495 { 496 ALOGV("kWhatSetAudioSink"); 497 498 sp<RefBase> obj; 499 CHECK(msg->findObject("sink", &obj)); 500 501 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get()); 502 break; 503 } 504 505 case kWhatStart: 506 { 507 ALOGV("kWhatStart"); 508 509 mVideoIsAVC = false; 510 mOffloadAudio = false; 511 mAudioEOS = false; 512 mVideoEOS = false; 513 mSkipRenderingAudioUntilMediaTimeUs = -1; 514 mSkipRenderingVideoUntilMediaTimeUs = -1; 515 mVideoLateByUs = 0; 516 mNumFramesTotal = 0; 517 mNumFramesDropped = 0; 518 mStarted = true; 519 520 /* instantiate decoders now for secure playback */ 521 if (mSourceFlags & Source::FLAG_SECURE) { 522 if (mNativeWindow != NULL) { 523 instantiateDecoder(false, &mVideoDecoder); 524 } 525 526 if (mAudioSink != NULL) { 527 instantiateDecoder(true, &mAudioDecoder); 528 } 529 } 530 531 mSource->start(); 532 533 uint32_t flags = 0; 534 535 if (mSource->isRealTime()) { 536 flags |= Renderer::FLAG_REAL_TIME; 537 } 538 539 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); 540 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; 541 if (mAudioSink != NULL) { 542 streamType = mAudioSink->getAudioStreamType(); 543 } 544 545 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); 546 547 mOffloadAudio = 548 canOffloadStream(audioMeta, (videoFormat != NULL), 549 true /* is_streaming */, streamType); 550 if (mOffloadAudio) { 551 flags |= Renderer::FLAG_OFFLOAD_AUDIO; 552 } 553 554 mRenderer = new Renderer( 555 mAudioSink, 556 new AMessage(kWhatRendererNotify, id()), 557 flags); 558 559 mRendererLooper = new ALooper; 560 mRendererLooper->setName("NuPlayerRenderer"); 561 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 562 mRendererLooper->registerHandler(mRenderer); 563 564 postScanSources(); 565 break; 566 } 567 568 case kWhatScanSources: 569 { 570 int32_t generation; 571 CHECK(msg->findInt32("generation", &generation)); 572 if (generation != mScanSourcesGeneration) { 573 // Drop obsolete msg. 574 break; 575 } 576 577 mScanSourcesPending = false; 578 579 ALOGV("scanning sources haveAudio=%d, haveVideo=%d", 580 mAudioDecoder != NULL, mVideoDecoder != NULL); 581 582 bool mHadAnySourcesBefore = 583 (mAudioDecoder != NULL) || (mVideoDecoder != NULL); 584 585 if (mNativeWindow != NULL) { 586 instantiateDecoder(false, &mVideoDecoder); 587 } 588 589 if (mAudioSink != NULL) { 590 instantiateDecoder(true, &mAudioDecoder); 591 } 592 593 if (!mHadAnySourcesBefore 594 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 595 // This is the first time we've found anything playable. 596 597 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) { 598 schedulePollDuration(); 599 } 600 } 601 602 status_t err; 603 if ((err = mSource->feedMoreTSData()) != OK) { 604 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 605 // We're not currently decoding anything (no audio or 606 // video tracks found) and we just ran out of input data. 607 608 if (err == ERROR_END_OF_STREAM) { 609 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 610 } else { 611 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 612 } 613 } 614 break; 615 } 616 617 if ((mAudioDecoder == NULL && mAudioSink != NULL) 618 || (mVideoDecoder == NULL && mNativeWindow != NULL)) { 619 msg->post(100000ll); 620 mScanSourcesPending = true; 621 } 622 break; 623 } 624 625 case kWhatVideoNotify: 626 case kWhatAudioNotify: 627 { 628 bool audio = msg->what() == kWhatAudioNotify; 629 630 int32_t what; 631 CHECK(msg->findInt32("what", &what)); 632 633 if (what == Decoder::kWhatFillThisBuffer) { 634 status_t err = feedDecoderInputData( 635 audio, msg); 636 637 if (err == -EWOULDBLOCK) { 638 if (mSource->feedMoreTSData() == OK) { 639 msg->post(10000ll); 640 } 641 } 642 } else if (what == Decoder::kWhatEOS) { 643 int32_t err; 644 CHECK(msg->findInt32("err", &err)); 645 646 if (err == ERROR_END_OF_STREAM) { 647 ALOGV("got %s decoder EOS", audio ? "audio" : "video"); 648 } else { 649 ALOGV("got %s decoder EOS w/ error %d", 650 audio ? "audio" : "video", 651 err); 652 } 653 654 mRenderer->queueEOS(audio, err); 655 } else if (what == Decoder::kWhatFlushCompleted) { 656 bool needShutdown; 657 658 if (audio) { 659 CHECK(IsFlushingState(mFlushingAudio, &needShutdown)); 660 mFlushingAudio = FLUSHED; 661 } else { 662 CHECK(IsFlushingState(mFlushingVideo, &needShutdown)); 663 mFlushingVideo = FLUSHED; 664 665 mVideoLateByUs = 0; 666 } 667 668 ALOGV("decoder %s flush completed", audio ? "audio" : "video"); 669 670 if (needShutdown) { 671 ALOGV("initiating %s decoder shutdown", 672 audio ? "audio" : "video"); 673 674 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); 675 676 if (audio) { 677 mFlushingAudio = SHUTTING_DOWN_DECODER; 678 } else { 679 mFlushingVideo = SHUTTING_DOWN_DECODER; 680 } 681 } 682 683 finishFlushIfPossible(); 684 } else if (what == Decoder::kWhatOutputFormatChanged) { 685 sp<AMessage> format; 686 CHECK(msg->findMessage("format", &format)); 687 688 if (audio) { 689 int32_t numChannels; 690 CHECK(format->findInt32( 691 "channel-count", &numChannels)); 692 693 int32_t sampleRate; 694 CHECK(format->findInt32("sample-rate", &sampleRate)); 695 696 ALOGV("Audio output format changed to %d Hz, %d channels", 697 sampleRate, numChannels); 698 699 mAudioSink->close(); 700 701 uint32_t flags; 702 int64_t durationUs; 703 // FIXME: we should handle the case where the video decoder 704 // is created after we receive the format change indication. 705 // Current code will just make that we select deep buffer 706 // with video which should not be a problem as it should 707 // not prevent from keeping A/V sync. 708 if (mVideoDecoder == NULL && 709 mSource->getDuration(&durationUs) == OK && 710 durationUs 711 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 712 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 713 } else { 714 flags = AUDIO_OUTPUT_FLAG_NONE; 715 } 716 717 int32_t channelMask; 718 if (!format->findInt32("channel-mask", &channelMask)) { 719 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 720 } 721 722 if (mOffloadAudio) { 723 audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT; 724 audio_offload_info_t offloadInfo = 725 AUDIO_INFO_INITIALIZER; 726 727 AString mime; 728 CHECK(format->findString("mime", &mime)); 729 730 status_t err = 731 mapMimeToAudioFormat(audioFormat, mime.c_str()); 732 if (err != OK) { 733 ALOGE("Couldn't map mime \"%s\" to a valid " 734 "audio_format", mime.c_str()); 735 mOffloadAudio = false; 736 } else { 737 ALOGV("Mime \"%s\" mapped to audio_format 0x%x", 738 mime.c_str(), audioFormat); 739 740 flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 741 742 offloadInfo.duration_us = -1; 743 format->findInt64( 744 "durationUs", &offloadInfo.duration_us); 745 746 int avgBitRate = -1; 747 format->findInt32("bit-rate", &avgBitRate); 748 749 offloadInfo.sample_rate = sampleRate; 750 offloadInfo.channel_mask = channelMask; 751 offloadInfo.format = audioFormat; 752 offloadInfo.stream_type = AUDIO_STREAM_MUSIC; 753 offloadInfo.bit_rate = avgBitRate; 754 offloadInfo.has_video = (mVideoDecoder != NULL); 755 offloadInfo.is_streaming = true; 756 757 ALOGV("try to open AudioSink in offload mode"); 758 err = mAudioSink->open( 759 sampleRate, 760 numChannels, 761 (audio_channel_mask_t)channelMask, 762 audioFormat, 763 8 /* bufferCount */, 764 &NuPlayer::Renderer::AudioSinkCallback, 765 mRenderer.get(), 766 (audio_output_flags_t)flags, 767 &offloadInfo); 768 769 if (err == OK) { 770 // If the playback is offloaded to h/w, we pass 771 // the HAL some metadata information. 772 // We don't want to do this for PCM because it 773 // will be going through the AudioFlinger mixer 774 // before reaching the hardware. 775 sp<MetaData> audioMeta = 776 mSource->getFormatMeta(true /* audio */); 777 sendMetaDataToHal(mAudioSink, audioMeta); 778 779 err = mAudioSink->start(); 780 } 781 } 782 783 if (err != OK) { 784 // Clean up, fall back to non offload mode. 785 mAudioSink->close(); 786 mAudioDecoder.clear(); 787 mRenderer->signalDisableOffloadAudio(); 788 mOffloadAudio = false; 789 790 instantiateDecoder( 791 true /* audio */, &mAudioDecoder); 792 } 793 } 794 795 if (!mOffloadAudio) { 796 flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 797 ALOGV("open AudioSink in NON-offload mode"); 798 CHECK_EQ(mAudioSink->open( 799 sampleRate, 800 numChannels, 801 (audio_channel_mask_t)channelMask, 802 AUDIO_FORMAT_PCM_16_BIT, 803 8 /* bufferCount */, 804 NULL, 805 NULL, 806 (audio_output_flags_t)flags), 807 (status_t)OK); 808 mAudioSink->start(); 809 } 810 811 mRenderer->signalAudioSinkChanged(); 812 } else { 813 // video 814 815 int32_t width, height; 816 CHECK(format->findInt32("width", &width)); 817 CHECK(format->findInt32("height", &height)); 818 819 int32_t cropLeft, cropTop, cropRight, cropBottom; 820 CHECK(format->findRect( 821 "crop", 822 &cropLeft, &cropTop, &cropRight, &cropBottom)); 823 824 int32_t displayWidth = cropRight - cropLeft + 1; 825 int32_t displayHeight = cropBottom - cropTop + 1; 826 827 ALOGV("Video output format changed to %d x %d " 828 "(crop: %d x %d @ (%d, %d))", 829 width, height, 830 displayWidth, 831 displayHeight, 832 cropLeft, cropTop); 833 834 sp<AMessage> videoInputFormat = 835 mSource->getFormat(false /* audio */); 836 837 // Take into account sample aspect ratio if necessary: 838 int32_t sarWidth, sarHeight; 839 if (videoInputFormat->findInt32("sar-width", &sarWidth) 840 && videoInputFormat->findInt32( 841 "sar-height", &sarHeight)) { 842 ALOGV("Sample aspect ratio %d : %d", 843 sarWidth, sarHeight); 844 845 displayWidth = (displayWidth * sarWidth) / sarHeight; 846 847 ALOGV("display dimensions %d x %d", 848 displayWidth, displayHeight); 849 } 850 851 notifyListener( 852 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight); 853 } 854 } else if (what == Decoder::kWhatShutdownCompleted) { 855 ALOGV("%s shutdown completed", audio ? "audio" : "video"); 856 if (audio) { 857 mAudioDecoder.clear(); 858 859 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 860 mFlushingAudio = SHUT_DOWN; 861 } else { 862 mVideoDecoder.clear(); 863 864 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 865 mFlushingVideo = SHUT_DOWN; 866 } 867 868 finishFlushIfPossible(); 869 } else if (what == Decoder::kWhatError) { 870 ALOGE("Received error from %s decoder, aborting playback.", 871 audio ? "audio" : "video"); 872 873 mRenderer->queueEOS(audio, UNKNOWN_ERROR); 874 } else if (what == Decoder::kWhatDrainThisBuffer) { 875 renderBuffer(audio, msg); 876 } else { 877 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.", 878 what, 879 what >> 24, 880 (what >> 16) & 0xff, 881 (what >> 8) & 0xff, 882 what & 0xff); 883 } 884 885 break; 886 } 887 888 case kWhatRendererNotify: 889 { 890 int32_t what; 891 CHECK(msg->findInt32("what", &what)); 892 893 if (what == Renderer::kWhatEOS) { 894 int32_t audio; 895 CHECK(msg->findInt32("audio", &audio)); 896 897 int32_t finalResult; 898 CHECK(msg->findInt32("finalResult", &finalResult)); 899 900 if (audio) { 901 mAudioEOS = true; 902 } else { 903 mVideoEOS = true; 904 } 905 906 if (finalResult == ERROR_END_OF_STREAM) { 907 ALOGV("reached %s EOS", audio ? "audio" : "video"); 908 } else { 909 ALOGE("%s track encountered an error (%d)", 910 audio ? "audio" : "video", finalResult); 911 912 notifyListener( 913 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 914 } 915 916 if ((mAudioEOS || mAudioDecoder == NULL) 917 && (mVideoEOS || mVideoDecoder == NULL)) { 918 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 919 } 920 } else if (what == Renderer::kWhatPosition) { 921 int64_t positionUs; 922 CHECK(msg->findInt64("positionUs", &positionUs)); 923 924 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs)); 925 926 if (mDriver != NULL) { 927 sp<NuPlayerDriver> driver = mDriver.promote(); 928 if (driver != NULL) { 929 driver->notifyPosition(positionUs); 930 931 driver->notifyFrameStats( 932 mNumFramesTotal, mNumFramesDropped); 933 } 934 } 935 } else if (what == Renderer::kWhatFlushComplete) { 936 int32_t audio; 937 CHECK(msg->findInt32("audio", &audio)); 938 939 ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 940 } else if (what == Renderer::kWhatVideoRenderingStart) { 941 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); 942 } else if (what == Renderer::kWhatMediaRenderingStart) { 943 ALOGV("media rendering started"); 944 notifyListener(MEDIA_STARTED, 0, 0); 945 } else if (what == Renderer::kWhatAudioOffloadTearDown) { 946 ALOGV("Tear down audio offload, fall back to s/w path"); 947 int64_t positionUs; 948 CHECK(msg->findInt64("positionUs", &positionUs)); 949 mAudioSink->close(); 950 mAudioDecoder.clear(); 951 mRenderer->flush(true /* audio */); 952 if (mVideoDecoder != NULL) { 953 mRenderer->flush(false /* audio */); 954 } 955 mRenderer->signalDisableOffloadAudio(); 956 mOffloadAudio = false; 957 958 performSeek(positionUs); 959 instantiateDecoder(true /* audio */, &mAudioDecoder); 960 } 961 break; 962 } 963 964 case kWhatMoreDataQueued: 965 { 966 break; 967 } 968 969 case kWhatReset: 970 { 971 ALOGV("kWhatReset"); 972 973 mDeferredActions.push_back( 974 new ShutdownDecoderAction( 975 true /* audio */, true /* video */)); 976 977 mDeferredActions.push_back( 978 new SimpleAction(&NuPlayer::performReset)); 979 980 processDeferredActions(); 981 break; 982 } 983 984 case kWhatSeek: 985 { 986 int64_t seekTimeUs; 987 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 988 989 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs); 990 991 mDeferredActions.push_back( 992 new SimpleAction(&NuPlayer::performDecoderFlush)); 993 994 mDeferredActions.push_back(new SeekAction(seekTimeUs)); 995 996 processDeferredActions(); 997 break; 998 } 999 1000 case kWhatPause: 1001 { 1002 CHECK(mRenderer != NULL); 1003 mSource->pause(); 1004 mRenderer->pause(); 1005 break; 1006 } 1007 1008 case kWhatResume: 1009 { 1010 CHECK(mRenderer != NULL); 1011 mSource->resume(); 1012 mRenderer->resume(); 1013 break; 1014 } 1015 1016 case kWhatSourceNotify: 1017 { 1018 onSourceNotify(msg); 1019 break; 1020 } 1021 1022 case kWhatClosedCaptionNotify: 1023 { 1024 onClosedCaptionNotify(msg); 1025 break; 1026 } 1027 1028 default: 1029 TRESPASS(); 1030 break; 1031 } 1032} 1033 1034void NuPlayer::finishFlushIfPossible() { 1035 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) { 1036 return; 1037 } 1038 1039 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) { 1040 return; 1041 } 1042 1043 ALOGV("both audio and video are flushed now."); 1044 1045 if (mTimeDiscontinuityPending) { 1046 mRenderer->signalTimeDiscontinuity(); 1047 mTimeDiscontinuityPending = false; 1048 } 1049 1050 if (mAudioDecoder != NULL) { 1051 mAudioDecoder->signalResume(); 1052 } 1053 1054 if (mVideoDecoder != NULL) { 1055 mVideoDecoder->signalResume(); 1056 } 1057 1058 mFlushingAudio = NONE; 1059 mFlushingVideo = NONE; 1060 1061 processDeferredActions(); 1062} 1063 1064void NuPlayer::postScanSources() { 1065 if (mScanSourcesPending) { 1066 return; 1067 } 1068 1069 sp<AMessage> msg = new AMessage(kWhatScanSources, id()); 1070 msg->setInt32("generation", mScanSourcesGeneration); 1071 msg->post(); 1072 1073 mScanSourcesPending = true; 1074} 1075 1076status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { 1077 if (*decoder != NULL) { 1078 return OK; 1079 } 1080 1081 sp<AMessage> format = mSource->getFormat(audio); 1082 1083 if (format == NULL) { 1084 return -EWOULDBLOCK; 1085 } 1086 1087 if (!audio) { 1088 AString mime; 1089 CHECK(format->findString("mime", &mime)); 1090 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 1091 1092 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id()); 1093 mCCDecoder = new CCDecoder(ccNotify); 1094 1095 if (mSourceFlags & Source::FLAG_SECURE) { 1096 format->setInt32("secure", true); 1097 } 1098 } 1099 1100 sp<AMessage> notify = 1101 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify, 1102 id()); 1103 1104 if (audio) { 1105 if (mOffloadAudio) { 1106 *decoder = new DecoderPassThrough(notify); 1107 } else { 1108 *decoder = new Decoder(notify); 1109 } 1110 } else { 1111 *decoder = new Decoder(notify, mNativeWindow); 1112 } 1113 (*decoder)->init(); 1114 (*decoder)->configure(format); 1115 1116 // allocate buffers to decrypt widevine source buffers 1117 if (!audio && (mSourceFlags & Source::FLAG_SECURE)) { 1118 Vector<sp<ABuffer> > inputBufs; 1119 CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK); 1120 1121 Vector<MediaBuffer *> mediaBufs; 1122 for (size_t i = 0; i < inputBufs.size(); i++) { 1123 const sp<ABuffer> &buffer = inputBufs[i]; 1124 MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size()); 1125 mediaBufs.push(mbuf); 1126 } 1127 1128 status_t err = mSource->setBuffers(audio, mediaBufs); 1129 if (err != OK) { 1130 for (size_t i = 0; i < mediaBufs.size(); ++i) { 1131 mediaBufs[i]->release(); 1132 } 1133 mediaBufs.clear(); 1134 ALOGE("Secure source didn't support secure mediaBufs."); 1135 return err; 1136 } 1137 } 1138 return OK; 1139} 1140 1141status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { 1142 sp<AMessage> reply; 1143 CHECK(msg->findMessage("reply", &reply)); 1144 1145 if ((audio && IsFlushingState(mFlushingAudio)) 1146 || (!audio && IsFlushingState(mFlushingVideo))) { 1147 reply->setInt32("err", INFO_DISCONTINUITY); 1148 reply->post(); 1149 return OK; 1150 } 1151 1152 sp<ABuffer> accessUnit; 1153 1154 bool dropAccessUnit; 1155 do { 1156 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit); 1157 1158 if (err == -EWOULDBLOCK) { 1159 return err; 1160 } else if (err != OK) { 1161 if (err == INFO_DISCONTINUITY) { 1162 int32_t type; 1163 CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 1164 1165 bool formatChange = 1166 (audio && 1167 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 1168 || (!audio && 1169 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 1170 1171 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 1172 1173 ALOGI("%s discontinuity (formatChange=%d, time=%d)", 1174 audio ? "audio" : "video", formatChange, timeChange); 1175 1176 if (audio) { 1177 mSkipRenderingAudioUntilMediaTimeUs = -1; 1178 } else { 1179 mSkipRenderingVideoUntilMediaTimeUs = -1; 1180 } 1181 1182 if (timeChange) { 1183 sp<AMessage> extra; 1184 if (accessUnit->meta()->findMessage("extra", &extra) 1185 && extra != NULL) { 1186 int64_t resumeAtMediaTimeUs; 1187 if (extra->findInt64( 1188 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { 1189 ALOGI("suppressing rendering of %s until %lld us", 1190 audio ? "audio" : "video", resumeAtMediaTimeUs); 1191 1192 if (audio) { 1193 mSkipRenderingAudioUntilMediaTimeUs = 1194 resumeAtMediaTimeUs; 1195 } else { 1196 mSkipRenderingVideoUntilMediaTimeUs = 1197 resumeAtMediaTimeUs; 1198 } 1199 } 1200 } 1201 } 1202 1203 mTimeDiscontinuityPending = 1204 mTimeDiscontinuityPending || timeChange; 1205 1206 if (formatChange || timeChange) { 1207 if (mFlushingAudio == NONE && mFlushingVideo == NONE) { 1208 // And we'll resume scanning sources once we're done 1209 // flushing. 1210 mDeferredActions.push_front( 1211 new SimpleAction( 1212 &NuPlayer::performScanSources)); 1213 } 1214 1215 sp<AMessage> newFormat = mSource->getFormat(audio); 1216 sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder; 1217 if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) { 1218 flushDecoder(audio, /* needShutdown = */ true); 1219 } else { 1220 flushDecoder(audio, /* needShutdown = */ false); 1221 err = OK; 1222 } 1223 } else { 1224 // This stream is unaffected by the discontinuity 1225 1226 if (audio) { 1227 mFlushingAudio = FLUSHED; 1228 } else { 1229 mFlushingVideo = FLUSHED; 1230 } 1231 1232 finishFlushIfPossible(); 1233 1234 return -EWOULDBLOCK; 1235 } 1236 } 1237 1238 reply->setInt32("err", err); 1239 reply->post(); 1240 return OK; 1241 } 1242 1243 if (!audio) { 1244 ++mNumFramesTotal; 1245 } 1246 1247 dropAccessUnit = false; 1248 if (!audio 1249 && !(mSourceFlags & Source::FLAG_SECURE) 1250 && mVideoLateByUs > 100000ll 1251 && mVideoIsAVC 1252 && !IsAVCReferenceFrame(accessUnit)) { 1253 dropAccessUnit = true; 1254 ++mNumFramesDropped; 1255 } 1256 } while (dropAccessUnit); 1257 1258 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video"); 1259 1260#if 0 1261 int64_t mediaTimeUs; 1262 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 1263 ALOGV("feeding %s input buffer at media time %.2f secs", 1264 audio ? "audio" : "video", 1265 mediaTimeUs / 1E6); 1266#endif 1267 1268 if (!audio) { 1269 mCCDecoder->decode(accessUnit); 1270 } 1271 1272 reply->setBuffer("buffer", accessUnit); 1273 reply->post(); 1274 1275 return OK; 1276} 1277 1278void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { 1279 // ALOGV("renderBuffer %s", audio ? "audio" : "video"); 1280 1281 sp<AMessage> reply; 1282 CHECK(msg->findMessage("reply", &reply)); 1283 1284 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) { 1285 // We're currently attempting to flush the decoder, in order 1286 // to complete this, the decoder wants all its buffers back, 1287 // so we don't want any output buffers it sent us (from before 1288 // we initiated the flush) to be stuck in the renderer's queue. 1289 1290 ALOGV("we're still flushing the %s decoder, sending its output buffer" 1291 " right back.", audio ? "audio" : "video"); 1292 1293 reply->post(); 1294 return; 1295 } 1296 1297 sp<ABuffer> buffer; 1298 CHECK(msg->findBuffer("buffer", &buffer)); 1299 1300 int64_t mediaTimeUs; 1301 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1302 1303 int64_t &skipUntilMediaTimeUs = 1304 audio 1305 ? mSkipRenderingAudioUntilMediaTimeUs 1306 : mSkipRenderingVideoUntilMediaTimeUs; 1307 1308 if (skipUntilMediaTimeUs >= 0) { 1309 1310 if (mediaTimeUs < skipUntilMediaTimeUs) { 1311 ALOGV("dropping %s buffer at time %lld as requested.", 1312 audio ? "audio" : "video", 1313 mediaTimeUs); 1314 1315 reply->post(); 1316 return; 1317 } 1318 1319 skipUntilMediaTimeUs = -1; 1320 } 1321 1322 if (!audio && mCCDecoder->isSelected()) { 1323 mCCDecoder->display(mediaTimeUs); 1324 } 1325 1326 mRenderer->queueBuffer(audio, buffer, reply); 1327} 1328 1329void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) { 1330 if (mDriver == NULL) { 1331 return; 1332 } 1333 1334 sp<NuPlayerDriver> driver = mDriver.promote(); 1335 1336 if (driver == NULL) { 1337 return; 1338 } 1339 1340 driver->notifyListener(msg, ext1, ext2, in); 1341} 1342 1343void NuPlayer::flushDecoder(bool audio, bool needShutdown) { 1344 ALOGV("[%s] flushDecoder needShutdown=%d", 1345 audio ? "audio" : "video", needShutdown); 1346 1347 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { 1348 ALOGI("flushDecoder %s without decoder present", 1349 audio ? "audio" : "video"); 1350 } 1351 1352 // Make sure we don't continue to scan sources until we finish flushing. 1353 ++mScanSourcesGeneration; 1354 mScanSourcesPending = false; 1355 1356 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); 1357 mRenderer->flush(audio); 1358 1359 FlushStatus newStatus = 1360 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; 1361 1362 if (audio) { 1363 CHECK(mFlushingAudio == NONE 1364 || mFlushingAudio == AWAITING_DISCONTINUITY); 1365 1366 mFlushingAudio = newStatus; 1367 1368 if (mFlushingVideo == NONE) { 1369 mFlushingVideo = (mVideoDecoder != NULL) 1370 ? AWAITING_DISCONTINUITY 1371 : FLUSHED; 1372 } 1373 } else { 1374 CHECK(mFlushingVideo == NONE 1375 || mFlushingVideo == AWAITING_DISCONTINUITY); 1376 1377 mFlushingVideo = newStatus; 1378 1379 if (mFlushingAudio == NONE) { 1380 mFlushingAudio = (mAudioDecoder != NULL) 1381 ? AWAITING_DISCONTINUITY 1382 : FLUSHED; 1383 } 1384 } 1385} 1386 1387sp<AMessage> NuPlayer::Source::getFormat(bool audio) { 1388 sp<MetaData> meta = getFormatMeta(audio); 1389 1390 if (meta == NULL) { 1391 return NULL; 1392 } 1393 1394 sp<AMessage> msg = new AMessage; 1395 1396 if(convertMetaDataToMessage(meta, &msg) == OK) { 1397 return msg; 1398 } 1399 return NULL; 1400} 1401 1402status_t NuPlayer::setVideoScalingMode(int32_t mode) { 1403 mVideoScalingMode = mode; 1404 if (mNativeWindow != NULL) { 1405 status_t ret = native_window_set_scaling_mode( 1406 mNativeWindow->getNativeWindow().get(), mVideoScalingMode); 1407 if (ret != OK) { 1408 ALOGE("Failed to set scaling mode (%d): %s", 1409 -ret, strerror(-ret)); 1410 return ret; 1411 } 1412 } 1413 return OK; 1414} 1415 1416status_t NuPlayer::getTrackInfo(Parcel* reply) const { 1417 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id()); 1418 msg->setPointer("reply", reply); 1419 1420 sp<AMessage> response; 1421 status_t err = msg->postAndAwaitResponse(&response); 1422 return err; 1423} 1424 1425status_t NuPlayer::selectTrack(size_t trackIndex, bool select) { 1426 sp<AMessage> msg = new AMessage(kWhatSelectTrack, id()); 1427 msg->setSize("trackIndex", trackIndex); 1428 msg->setInt32("select", select); 1429 1430 sp<AMessage> response; 1431 status_t err = msg->postAndAwaitResponse(&response); 1432 1433 if (err != OK) { 1434 return err; 1435 } 1436 1437 if (!response->findInt32("err", &err)) { 1438 err = OK; 1439 } 1440 1441 return err; 1442} 1443 1444void NuPlayer::schedulePollDuration() { 1445 sp<AMessage> msg = new AMessage(kWhatPollDuration, id()); 1446 msg->setInt32("generation", mPollDurationGeneration); 1447 msg->post(); 1448} 1449 1450void NuPlayer::cancelPollDuration() { 1451 ++mPollDurationGeneration; 1452} 1453 1454void NuPlayer::processDeferredActions() { 1455 while (!mDeferredActions.empty()) { 1456 // We won't execute any deferred actions until we're no longer in 1457 // an intermediate state, i.e. one more more decoders are currently 1458 // flushing or shutting down. 1459 1460 if (mRenderer != NULL) { 1461 // There's an edge case where the renderer owns all output 1462 // buffers and is paused, therefore the decoder will not read 1463 // more input data and will never encounter the matching 1464 // discontinuity. To avoid this, we resume the renderer. 1465 1466 if (mFlushingAudio == AWAITING_DISCONTINUITY 1467 || mFlushingVideo == AWAITING_DISCONTINUITY) { 1468 mRenderer->resume(); 1469 } 1470 } 1471 1472 if (mFlushingAudio != NONE || mFlushingVideo != NONE) { 1473 // We're currently flushing, postpone the reset until that's 1474 // completed. 1475 1476 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d", 1477 mFlushingAudio, mFlushingVideo); 1478 1479 break; 1480 } 1481 1482 sp<Action> action = *mDeferredActions.begin(); 1483 mDeferredActions.erase(mDeferredActions.begin()); 1484 1485 action->execute(this); 1486 } 1487} 1488 1489void NuPlayer::performSeek(int64_t seekTimeUs) { 1490 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)", 1491 seekTimeUs, 1492 seekTimeUs / 1E6); 1493 1494 mSource->seekTo(seekTimeUs); 1495 1496 if (mDriver != NULL) { 1497 sp<NuPlayerDriver> driver = mDriver.promote(); 1498 if (driver != NULL) { 1499 driver->notifyPosition(seekTimeUs); 1500 driver->notifySeekComplete(); 1501 } 1502 } 1503 1504 // everything's flushed, continue playback. 1505} 1506 1507void NuPlayer::performDecoderFlush() { 1508 ALOGV("performDecoderFlush"); 1509 1510 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 1511 return; 1512 } 1513 1514 mTimeDiscontinuityPending = true; 1515 1516 if (mAudioDecoder != NULL) { 1517 flushDecoder(true /* audio */, false /* needShutdown */); 1518 } 1519 1520 if (mVideoDecoder != NULL) { 1521 flushDecoder(false /* audio */, false /* needShutdown */); 1522 } 1523} 1524 1525void NuPlayer::performDecoderShutdown(bool audio, bool video) { 1526 ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video); 1527 1528 if ((!audio || mAudioDecoder == NULL) 1529 && (!video || mVideoDecoder == NULL)) { 1530 return; 1531 } 1532 1533 mTimeDiscontinuityPending = true; 1534 1535 if (mFlushingAudio == NONE && (!audio || mAudioDecoder == NULL)) { 1536 mFlushingAudio = FLUSHED; 1537 } 1538 1539 if (mFlushingVideo == NONE && (!video || mVideoDecoder == NULL)) { 1540 mFlushingVideo = FLUSHED; 1541 } 1542 1543 if (audio && mAudioDecoder != NULL) { 1544 flushDecoder(true /* audio */, true /* needShutdown */); 1545 } 1546 1547 if (video && mVideoDecoder != NULL) { 1548 flushDecoder(false /* audio */, true /* needShutdown */); 1549 } 1550} 1551 1552void NuPlayer::performReset() { 1553 ALOGV("performReset"); 1554 1555 CHECK(mAudioDecoder == NULL); 1556 CHECK(mVideoDecoder == NULL); 1557 1558 cancelPollDuration(); 1559 1560 ++mScanSourcesGeneration; 1561 mScanSourcesPending = false; 1562 1563 if (mRendererLooper != NULL) { 1564 if (mRenderer != NULL) { 1565 mRendererLooper->unregisterHandler(mRenderer->id()); 1566 } 1567 mRendererLooper->stop(); 1568 mRendererLooper.clear(); 1569 } 1570 mRenderer.clear(); 1571 1572 if (mSource != NULL) { 1573 mSource->stop(); 1574 1575 looper()->unregisterHandler(mSource->id()); 1576 1577 mSource.clear(); 1578 } 1579 1580 if (mDriver != NULL) { 1581 sp<NuPlayerDriver> driver = mDriver.promote(); 1582 if (driver != NULL) { 1583 driver->notifyResetComplete(); 1584 } 1585 } 1586 1587 mStarted = false; 1588} 1589 1590void NuPlayer::performScanSources() { 1591 ALOGV("performScanSources"); 1592 1593 if (!mStarted) { 1594 return; 1595 } 1596 1597 if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 1598 postScanSources(); 1599 } 1600} 1601 1602void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) { 1603 ALOGV("performSetSurface"); 1604 1605 mNativeWindow = wrapper; 1606 1607 // XXX - ignore error from setVideoScalingMode for now 1608 setVideoScalingMode(mVideoScalingMode); 1609 1610 if (mDriver != NULL) { 1611 sp<NuPlayerDriver> driver = mDriver.promote(); 1612 if (driver != NULL) { 1613 driver->notifySetSurfaceComplete(); 1614 } 1615 } 1616} 1617 1618void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { 1619 int32_t what; 1620 CHECK(msg->findInt32("what", &what)); 1621 1622 switch (what) { 1623 case Source::kWhatPrepared: 1624 { 1625 if (mSource == NULL) { 1626 // This is a stale notification from a source that was 1627 // asynchronously preparing when the client called reset(). 1628 // We handled the reset, the source is gone. 1629 break; 1630 } 1631 1632 int32_t err; 1633 CHECK(msg->findInt32("err", &err)); 1634 1635 sp<NuPlayerDriver> driver = mDriver.promote(); 1636 if (driver != NULL) { 1637 // notify duration first, so that it's definitely set when 1638 // the app received the "prepare complete" callback. 1639 int64_t durationUs; 1640 if (mSource->getDuration(&durationUs) == OK) { 1641 driver->notifyDuration(durationUs); 1642 } 1643 driver->notifyPrepareCompleted(err); 1644 } 1645 1646 break; 1647 } 1648 1649 case Source::kWhatFlagsChanged: 1650 { 1651 uint32_t flags; 1652 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1653 1654 sp<NuPlayerDriver> driver = mDriver.promote(); 1655 if (driver != NULL) { 1656 driver->notifyFlagsChanged(flags); 1657 } 1658 1659 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1660 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { 1661 cancelPollDuration(); 1662 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1663 && (flags & Source::FLAG_DYNAMIC_DURATION) 1664 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 1665 schedulePollDuration(); 1666 } 1667 1668 mSourceFlags = flags; 1669 break; 1670 } 1671 1672 case Source::kWhatVideoSizeChanged: 1673 { 1674 int32_t width, height; 1675 CHECK(msg->findInt32("width", &width)); 1676 CHECK(msg->findInt32("height", &height)); 1677 1678 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height); 1679 break; 1680 } 1681 1682 case Source::kWhatBufferingStart: 1683 { 1684 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); 1685 break; 1686 } 1687 1688 case Source::kWhatBufferingEnd: 1689 { 1690 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0); 1691 break; 1692 } 1693 1694 case Source::kWhatSubtitleData: 1695 { 1696 sp<ABuffer> buffer; 1697 CHECK(msg->findBuffer("buffer", &buffer)); 1698 1699 sendSubtitleData(buffer, 0 /* baseIndex */); 1700 break; 1701 } 1702 1703 case Source::kWhatQueueDecoderShutdown: 1704 { 1705 int32_t audio, video; 1706 CHECK(msg->findInt32("audio", &audio)); 1707 CHECK(msg->findInt32("video", &video)); 1708 1709 sp<AMessage> reply; 1710 CHECK(msg->findMessage("reply", &reply)); 1711 1712 queueDecoderShutdown(audio, video, reply); 1713 break; 1714 } 1715 1716 default: 1717 TRESPASS(); 1718 } 1719} 1720 1721void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) { 1722 int32_t what; 1723 CHECK(msg->findInt32("what", &what)); 1724 1725 switch (what) { 1726 case NuPlayer::CCDecoder::kWhatClosedCaptionData: 1727 { 1728 sp<ABuffer> buffer; 1729 CHECK(msg->findBuffer("buffer", &buffer)); 1730 1731 size_t inbandTracks = 0; 1732 if (mSource != NULL) { 1733 inbandTracks = mSource->getTrackCount(); 1734 } 1735 1736 sendSubtitleData(buffer, inbandTracks); 1737 break; 1738 } 1739 1740 case NuPlayer::CCDecoder::kWhatTrackAdded: 1741 { 1742 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0); 1743 1744 break; 1745 } 1746 1747 default: 1748 TRESPASS(); 1749 } 1750 1751 1752} 1753 1754void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) { 1755 int32_t trackIndex; 1756 int64_t timeUs, durationUs; 1757 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex)); 1758 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 1759 CHECK(buffer->meta()->findInt64("durationUs", &durationUs)); 1760 1761 Parcel in; 1762 in.writeInt32(trackIndex + baseIndex); 1763 in.writeInt64(timeUs); 1764 in.writeInt64(durationUs); 1765 in.writeInt32(buffer->size()); 1766 in.writeInt32(buffer->size()); 1767 in.write(buffer->data(), buffer->size()); 1768 1769 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in); 1770} 1771//////////////////////////////////////////////////////////////////////////////// 1772 1773void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { 1774 sp<AMessage> notify = dupNotify(); 1775 notify->setInt32("what", kWhatFlagsChanged); 1776 notify->setInt32("flags", flags); 1777 notify->post(); 1778} 1779 1780void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) { 1781 sp<AMessage> notify = dupNotify(); 1782 notify->setInt32("what", kWhatVideoSizeChanged); 1783 notify->setInt32("width", width); 1784 notify->setInt32("height", height); 1785 notify->post(); 1786} 1787 1788void NuPlayer::Source::notifyPrepared(status_t err) { 1789 sp<AMessage> notify = dupNotify(); 1790 notify->setInt32("what", kWhatPrepared); 1791 notify->setInt32("err", err); 1792 notify->post(); 1793} 1794 1795void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { 1796 TRESPASS(); 1797} 1798 1799void NuPlayer::queueDecoderShutdown( 1800 bool audio, bool video, const sp<AMessage> &reply) { 1801 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video); 1802 1803 mDeferredActions.push_back( 1804 new ShutdownDecoderAction(audio, video)); 1805 1806 mDeferredActions.push_back( 1807 new SimpleAction(&NuPlayer::performScanSources)); 1808 1809 mDeferredActions.push_back(new PostMessageAction(reply)); 1810 1811 processDeferredActions(); 1812} 1813 1814} // namespace android 1815