NuPlayer.cpp revision 095248375e29adde961ec2a44989ecb3a6dda6a2
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 err = mAudioSink->open( 758 sampleRate, 759 numChannels, 760 (audio_channel_mask_t)channelMask, 761 audioFormat, 762 8 /* bufferCount */, 763 &NuPlayer::Renderer::AudioSinkCallback, 764 mRenderer.get(), 765 (audio_output_flags_t)flags, 766 &offloadInfo); 767 768 if (err == OK) { 769 // If the playback is offloaded to h/w, we pass 770 // the HAL some metadata information. 771 // We don't want to do this for PCM because it 772 // will be going through the AudioFlinger mixer 773 // before reaching the hardware. 774 sp<MetaData> audioMeta = 775 mSource->getFormatMeta(true /* audio */); 776 sendMetaDataToHal(mAudioSink, audioMeta); 777 778 err = mAudioSink->start(); 779 } 780 } 781 782 if (err != OK) { 783 // Clean up, fall back to non offload mode. 784 mAudioSink->close(); 785 mAudioDecoder.clear(); 786 mRenderer->signalDisableOffloadAudio(); 787 mOffloadAudio = false; 788 789 instantiateDecoder( 790 true /* audio */, &mAudioDecoder); 791 } 792 } 793 794 if (!mOffloadAudio) { 795 flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 796 CHECK_EQ(mAudioSink->open( 797 sampleRate, 798 numChannels, 799 (audio_channel_mask_t)channelMask, 800 AUDIO_FORMAT_PCM_16_BIT, 801 8 /* bufferCount */, 802 NULL, 803 NULL, 804 (audio_output_flags_t)flags), 805 (status_t)OK); 806 mAudioSink->start(); 807 } 808 809 mRenderer->signalAudioSinkChanged(); 810 } else { 811 // video 812 813 int32_t width, height; 814 CHECK(format->findInt32("width", &width)); 815 CHECK(format->findInt32("height", &height)); 816 817 int32_t cropLeft, cropTop, cropRight, cropBottom; 818 CHECK(format->findRect( 819 "crop", 820 &cropLeft, &cropTop, &cropRight, &cropBottom)); 821 822 int32_t displayWidth = cropRight - cropLeft + 1; 823 int32_t displayHeight = cropBottom - cropTop + 1; 824 825 ALOGV("Video output format changed to %d x %d " 826 "(crop: %d x %d @ (%d, %d))", 827 width, height, 828 displayWidth, 829 displayHeight, 830 cropLeft, cropTop); 831 832 sp<AMessage> videoInputFormat = 833 mSource->getFormat(false /* audio */); 834 835 // Take into account sample aspect ratio if necessary: 836 int32_t sarWidth, sarHeight; 837 if (videoInputFormat->findInt32("sar-width", &sarWidth) 838 && videoInputFormat->findInt32( 839 "sar-height", &sarHeight)) { 840 ALOGV("Sample aspect ratio %d : %d", 841 sarWidth, sarHeight); 842 843 displayWidth = (displayWidth * sarWidth) / sarHeight; 844 845 ALOGV("display dimensions %d x %d", 846 displayWidth, displayHeight); 847 } 848 849 notifyListener( 850 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight); 851 } 852 } else if (what == Decoder::kWhatShutdownCompleted) { 853 ALOGV("%s shutdown completed", audio ? "audio" : "video"); 854 if (audio) { 855 mAudioDecoder.clear(); 856 857 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 858 mFlushingAudio = SHUT_DOWN; 859 } else { 860 mVideoDecoder.clear(); 861 862 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 863 mFlushingVideo = SHUT_DOWN; 864 } 865 866 finishFlushIfPossible(); 867 } else if (what == Decoder::kWhatError) { 868 ALOGE("Received error from %s decoder, aborting playback.", 869 audio ? "audio" : "video"); 870 871 mRenderer->queueEOS(audio, UNKNOWN_ERROR); 872 } else if (what == Decoder::kWhatDrainThisBuffer) { 873 renderBuffer(audio, msg); 874 } else { 875 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.", 876 what, 877 what >> 24, 878 (what >> 16) & 0xff, 879 (what >> 8) & 0xff, 880 what & 0xff); 881 } 882 883 break; 884 } 885 886 case kWhatRendererNotify: 887 { 888 int32_t what; 889 CHECK(msg->findInt32("what", &what)); 890 891 if (what == Renderer::kWhatEOS) { 892 int32_t audio; 893 CHECK(msg->findInt32("audio", &audio)); 894 895 int32_t finalResult; 896 CHECK(msg->findInt32("finalResult", &finalResult)); 897 898 if (audio) { 899 mAudioEOS = true; 900 } else { 901 mVideoEOS = true; 902 } 903 904 if (finalResult == ERROR_END_OF_STREAM) { 905 ALOGV("reached %s EOS", audio ? "audio" : "video"); 906 } else { 907 ALOGE("%s track encountered an error (%d)", 908 audio ? "audio" : "video", finalResult); 909 910 notifyListener( 911 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 912 } 913 914 if ((mAudioEOS || mAudioDecoder == NULL) 915 && (mVideoEOS || mVideoDecoder == NULL)) { 916 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 917 } 918 } else if (what == Renderer::kWhatPosition) { 919 int64_t positionUs; 920 CHECK(msg->findInt64("positionUs", &positionUs)); 921 922 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs)); 923 924 if (mDriver != NULL) { 925 sp<NuPlayerDriver> driver = mDriver.promote(); 926 if (driver != NULL) { 927 driver->notifyPosition(positionUs); 928 929 driver->notifyFrameStats( 930 mNumFramesTotal, mNumFramesDropped); 931 } 932 } 933 } else if (what == Renderer::kWhatFlushComplete) { 934 int32_t audio; 935 CHECK(msg->findInt32("audio", &audio)); 936 937 ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 938 } else if (what == Renderer::kWhatVideoRenderingStart) { 939 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); 940 } else if (what == Renderer::kWhatMediaRenderingStart) { 941 ALOGV("media rendering started"); 942 notifyListener(MEDIA_STARTED, 0, 0); 943 } 944 break; 945 } 946 947 case kWhatMoreDataQueued: 948 { 949 break; 950 } 951 952 case kWhatReset: 953 { 954 ALOGV("kWhatReset"); 955 956 mDeferredActions.push_back( 957 new ShutdownDecoderAction( 958 true /* audio */, true /* video */)); 959 960 mDeferredActions.push_back( 961 new SimpleAction(&NuPlayer::performReset)); 962 963 processDeferredActions(); 964 break; 965 } 966 967 case kWhatSeek: 968 { 969 int64_t seekTimeUs; 970 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 971 972 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs); 973 974 mDeferredActions.push_back( 975 new SimpleAction(&NuPlayer::performDecoderFlush)); 976 977 mDeferredActions.push_back(new SeekAction(seekTimeUs)); 978 979 processDeferredActions(); 980 break; 981 } 982 983 case kWhatPause: 984 { 985 CHECK(mRenderer != NULL); 986 mSource->pause(); 987 mRenderer->pause(); 988 break; 989 } 990 991 case kWhatResume: 992 { 993 CHECK(mRenderer != NULL); 994 mSource->resume(); 995 mRenderer->resume(); 996 break; 997 } 998 999 case kWhatSourceNotify: 1000 { 1001 onSourceNotify(msg); 1002 break; 1003 } 1004 1005 case kWhatClosedCaptionNotify: 1006 { 1007 onClosedCaptionNotify(msg); 1008 break; 1009 } 1010 1011 default: 1012 TRESPASS(); 1013 break; 1014 } 1015} 1016 1017void NuPlayer::finishFlushIfPossible() { 1018 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) { 1019 return; 1020 } 1021 1022 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) { 1023 return; 1024 } 1025 1026 ALOGV("both audio and video are flushed now."); 1027 1028 if (mTimeDiscontinuityPending) { 1029 mRenderer->signalTimeDiscontinuity(); 1030 mTimeDiscontinuityPending = false; 1031 } 1032 1033 if (mAudioDecoder != NULL) { 1034 mAudioDecoder->signalResume(); 1035 } 1036 1037 if (mVideoDecoder != NULL) { 1038 mVideoDecoder->signalResume(); 1039 } 1040 1041 mFlushingAudio = NONE; 1042 mFlushingVideo = NONE; 1043 1044 processDeferredActions(); 1045} 1046 1047void NuPlayer::postScanSources() { 1048 if (mScanSourcesPending) { 1049 return; 1050 } 1051 1052 sp<AMessage> msg = new AMessage(kWhatScanSources, id()); 1053 msg->setInt32("generation", mScanSourcesGeneration); 1054 msg->post(); 1055 1056 mScanSourcesPending = true; 1057} 1058 1059status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { 1060 if (*decoder != NULL) { 1061 return OK; 1062 } 1063 1064 sp<AMessage> format = mSource->getFormat(audio); 1065 1066 if (format == NULL) { 1067 return -EWOULDBLOCK; 1068 } 1069 1070 if (!audio) { 1071 AString mime; 1072 CHECK(format->findString("mime", &mime)); 1073 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 1074 1075 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id()); 1076 mCCDecoder = new CCDecoder(ccNotify); 1077 1078 if (mSourceFlags & Source::FLAG_SECURE) { 1079 format->setInt32("secure", true); 1080 } 1081 } 1082 1083 sp<AMessage> notify = 1084 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify, 1085 id()); 1086 1087 if (audio) { 1088 if (mOffloadAudio) { 1089 *decoder = new DecoderPassThrough(notify); 1090 } else { 1091 *decoder = new Decoder(notify); 1092 } 1093 } else { 1094 *decoder = new Decoder(notify, mNativeWindow); 1095 } 1096 (*decoder)->init(); 1097 (*decoder)->configure(format); 1098 1099 // allocate buffers to decrypt widevine source buffers 1100 if (!audio && (mSourceFlags & Source::FLAG_SECURE)) { 1101 Vector<sp<ABuffer> > inputBufs; 1102 CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK); 1103 1104 Vector<MediaBuffer *> mediaBufs; 1105 for (size_t i = 0; i < inputBufs.size(); i++) { 1106 const sp<ABuffer> &buffer = inputBufs[i]; 1107 MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size()); 1108 mediaBufs.push(mbuf); 1109 } 1110 1111 status_t err = mSource->setBuffers(audio, mediaBufs); 1112 if (err != OK) { 1113 for (size_t i = 0; i < mediaBufs.size(); ++i) { 1114 mediaBufs[i]->release(); 1115 } 1116 mediaBufs.clear(); 1117 ALOGE("Secure source didn't support secure mediaBufs."); 1118 return err; 1119 } 1120 } 1121 return OK; 1122} 1123 1124status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { 1125 sp<AMessage> reply; 1126 CHECK(msg->findMessage("reply", &reply)); 1127 1128 if ((audio && IsFlushingState(mFlushingAudio)) 1129 || (!audio && IsFlushingState(mFlushingVideo))) { 1130 reply->setInt32("err", INFO_DISCONTINUITY); 1131 reply->post(); 1132 return OK; 1133 } 1134 1135 sp<ABuffer> accessUnit; 1136 1137 bool dropAccessUnit; 1138 do { 1139 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit); 1140 1141 if (err == -EWOULDBLOCK) { 1142 return err; 1143 } else if (err != OK) { 1144 if (err == INFO_DISCONTINUITY) { 1145 int32_t type; 1146 CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 1147 1148 bool formatChange = 1149 (audio && 1150 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 1151 || (!audio && 1152 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 1153 1154 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 1155 1156 ALOGI("%s discontinuity (formatChange=%d, time=%d)", 1157 audio ? "audio" : "video", formatChange, timeChange); 1158 1159 if (audio) { 1160 mSkipRenderingAudioUntilMediaTimeUs = -1; 1161 } else { 1162 mSkipRenderingVideoUntilMediaTimeUs = -1; 1163 } 1164 1165 if (timeChange) { 1166 sp<AMessage> extra; 1167 if (accessUnit->meta()->findMessage("extra", &extra) 1168 && extra != NULL) { 1169 int64_t resumeAtMediaTimeUs; 1170 if (extra->findInt64( 1171 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { 1172 ALOGI("suppressing rendering of %s until %lld us", 1173 audio ? "audio" : "video", resumeAtMediaTimeUs); 1174 1175 if (audio) { 1176 mSkipRenderingAudioUntilMediaTimeUs = 1177 resumeAtMediaTimeUs; 1178 } else { 1179 mSkipRenderingVideoUntilMediaTimeUs = 1180 resumeAtMediaTimeUs; 1181 } 1182 } 1183 } 1184 } 1185 1186 mTimeDiscontinuityPending = 1187 mTimeDiscontinuityPending || timeChange; 1188 1189 if (formatChange || timeChange) { 1190 if (mFlushingAudio == NONE && mFlushingVideo == NONE) { 1191 // And we'll resume scanning sources once we're done 1192 // flushing. 1193 mDeferredActions.push_front( 1194 new SimpleAction( 1195 &NuPlayer::performScanSources)); 1196 } 1197 1198 sp<AMessage> newFormat = mSource->getFormat(audio); 1199 sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder; 1200 if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) { 1201 flushDecoder(audio, /* needShutdown = */ true); 1202 } else { 1203 flushDecoder(audio, /* needShutdown = */ false); 1204 err = OK; 1205 } 1206 } else { 1207 // This stream is unaffected by the discontinuity 1208 1209 if (audio) { 1210 mFlushingAudio = FLUSHED; 1211 } else { 1212 mFlushingVideo = FLUSHED; 1213 } 1214 1215 finishFlushIfPossible(); 1216 1217 return -EWOULDBLOCK; 1218 } 1219 } 1220 1221 reply->setInt32("err", err); 1222 reply->post(); 1223 return OK; 1224 } 1225 1226 if (!audio) { 1227 ++mNumFramesTotal; 1228 } 1229 1230 dropAccessUnit = false; 1231 if (!audio 1232 && !(mSourceFlags & Source::FLAG_SECURE) 1233 && mVideoLateByUs > 100000ll 1234 && mVideoIsAVC 1235 && !IsAVCReferenceFrame(accessUnit)) { 1236 dropAccessUnit = true; 1237 ++mNumFramesDropped; 1238 } 1239 } while (dropAccessUnit); 1240 1241 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video"); 1242 1243#if 0 1244 int64_t mediaTimeUs; 1245 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 1246 ALOGV("feeding %s input buffer at media time %.2f secs", 1247 audio ? "audio" : "video", 1248 mediaTimeUs / 1E6); 1249#endif 1250 1251 if (!audio) { 1252 mCCDecoder->decode(accessUnit); 1253 } 1254 1255 reply->setBuffer("buffer", accessUnit); 1256 reply->post(); 1257 1258 return OK; 1259} 1260 1261void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { 1262 // ALOGV("renderBuffer %s", audio ? "audio" : "video"); 1263 1264 sp<AMessage> reply; 1265 CHECK(msg->findMessage("reply", &reply)); 1266 1267 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) { 1268 // We're currently attempting to flush the decoder, in order 1269 // to complete this, the decoder wants all its buffers back, 1270 // so we don't want any output buffers it sent us (from before 1271 // we initiated the flush) to be stuck in the renderer's queue. 1272 1273 ALOGV("we're still flushing the %s decoder, sending its output buffer" 1274 " right back.", audio ? "audio" : "video"); 1275 1276 reply->post(); 1277 return; 1278 } 1279 1280 sp<ABuffer> buffer; 1281 CHECK(msg->findBuffer("buffer", &buffer)); 1282 1283 int64_t mediaTimeUs; 1284 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1285 1286 int64_t &skipUntilMediaTimeUs = 1287 audio 1288 ? mSkipRenderingAudioUntilMediaTimeUs 1289 : mSkipRenderingVideoUntilMediaTimeUs; 1290 1291 if (skipUntilMediaTimeUs >= 0) { 1292 1293 if (mediaTimeUs < skipUntilMediaTimeUs) { 1294 ALOGV("dropping %s buffer at time %lld as requested.", 1295 audio ? "audio" : "video", 1296 mediaTimeUs); 1297 1298 reply->post(); 1299 return; 1300 } 1301 1302 skipUntilMediaTimeUs = -1; 1303 } 1304 1305 if (!audio && mCCDecoder->isSelected()) { 1306 mCCDecoder->display(mediaTimeUs); 1307 } 1308 1309 mRenderer->queueBuffer(audio, buffer, reply); 1310} 1311 1312void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) { 1313 if (mDriver == NULL) { 1314 return; 1315 } 1316 1317 sp<NuPlayerDriver> driver = mDriver.promote(); 1318 1319 if (driver == NULL) { 1320 return; 1321 } 1322 1323 driver->notifyListener(msg, ext1, ext2, in); 1324} 1325 1326void NuPlayer::flushDecoder(bool audio, bool needShutdown) { 1327 ALOGV("[%s] flushDecoder needShutdown=%d", 1328 audio ? "audio" : "video", needShutdown); 1329 1330 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { 1331 ALOGI("flushDecoder %s without decoder present", 1332 audio ? "audio" : "video"); 1333 } 1334 1335 // Make sure we don't continue to scan sources until we finish flushing. 1336 ++mScanSourcesGeneration; 1337 mScanSourcesPending = false; 1338 1339 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); 1340 mRenderer->flush(audio); 1341 1342 FlushStatus newStatus = 1343 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; 1344 1345 if (audio) { 1346 CHECK(mFlushingAudio == NONE 1347 || mFlushingAudio == AWAITING_DISCONTINUITY); 1348 1349 mFlushingAudio = newStatus; 1350 1351 if (mFlushingVideo == NONE) { 1352 mFlushingVideo = (mVideoDecoder != NULL) 1353 ? AWAITING_DISCONTINUITY 1354 : FLUSHED; 1355 } 1356 } else { 1357 CHECK(mFlushingVideo == NONE 1358 || mFlushingVideo == AWAITING_DISCONTINUITY); 1359 1360 mFlushingVideo = newStatus; 1361 1362 if (mFlushingAudio == NONE) { 1363 mFlushingAudio = (mAudioDecoder != NULL) 1364 ? AWAITING_DISCONTINUITY 1365 : FLUSHED; 1366 } 1367 } 1368} 1369 1370sp<AMessage> NuPlayer::Source::getFormat(bool audio) { 1371 sp<MetaData> meta = getFormatMeta(audio); 1372 1373 if (meta == NULL) { 1374 return NULL; 1375 } 1376 1377 sp<AMessage> msg = new AMessage; 1378 1379 if(convertMetaDataToMessage(meta, &msg) == OK) { 1380 return msg; 1381 } 1382 return NULL; 1383} 1384 1385status_t NuPlayer::setVideoScalingMode(int32_t mode) { 1386 mVideoScalingMode = mode; 1387 if (mNativeWindow != NULL) { 1388 status_t ret = native_window_set_scaling_mode( 1389 mNativeWindow->getNativeWindow().get(), mVideoScalingMode); 1390 if (ret != OK) { 1391 ALOGE("Failed to set scaling mode (%d): %s", 1392 -ret, strerror(-ret)); 1393 return ret; 1394 } 1395 } 1396 return OK; 1397} 1398 1399status_t NuPlayer::getTrackInfo(Parcel* reply) const { 1400 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id()); 1401 msg->setPointer("reply", reply); 1402 1403 sp<AMessage> response; 1404 status_t err = msg->postAndAwaitResponse(&response); 1405 return err; 1406} 1407 1408status_t NuPlayer::selectTrack(size_t trackIndex, bool select) { 1409 sp<AMessage> msg = new AMessage(kWhatSelectTrack, id()); 1410 msg->setSize("trackIndex", trackIndex); 1411 msg->setInt32("select", select); 1412 1413 sp<AMessage> response; 1414 status_t err = msg->postAndAwaitResponse(&response); 1415 1416 if (err != OK) { 1417 return err; 1418 } 1419 1420 if (!response->findInt32("err", &err)) { 1421 err = OK; 1422 } 1423 1424 return err; 1425} 1426 1427void NuPlayer::schedulePollDuration() { 1428 sp<AMessage> msg = new AMessage(kWhatPollDuration, id()); 1429 msg->setInt32("generation", mPollDurationGeneration); 1430 msg->post(); 1431} 1432 1433void NuPlayer::cancelPollDuration() { 1434 ++mPollDurationGeneration; 1435} 1436 1437void NuPlayer::processDeferredActions() { 1438 while (!mDeferredActions.empty()) { 1439 // We won't execute any deferred actions until we're no longer in 1440 // an intermediate state, i.e. one more more decoders are currently 1441 // flushing or shutting down. 1442 1443 if (mRenderer != NULL) { 1444 // There's an edge case where the renderer owns all output 1445 // buffers and is paused, therefore the decoder will not read 1446 // more input data and will never encounter the matching 1447 // discontinuity. To avoid this, we resume the renderer. 1448 1449 if (mFlushingAudio == AWAITING_DISCONTINUITY 1450 || mFlushingVideo == AWAITING_DISCONTINUITY) { 1451 mRenderer->resume(); 1452 } 1453 } 1454 1455 if (mFlushingAudio != NONE || mFlushingVideo != NONE) { 1456 // We're currently flushing, postpone the reset until that's 1457 // completed. 1458 1459 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d", 1460 mFlushingAudio, mFlushingVideo); 1461 1462 break; 1463 } 1464 1465 sp<Action> action = *mDeferredActions.begin(); 1466 mDeferredActions.erase(mDeferredActions.begin()); 1467 1468 action->execute(this); 1469 } 1470} 1471 1472void NuPlayer::performSeek(int64_t seekTimeUs) { 1473 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)", 1474 seekTimeUs, 1475 seekTimeUs / 1E6); 1476 1477 mSource->seekTo(seekTimeUs); 1478 1479 if (mDriver != NULL) { 1480 sp<NuPlayerDriver> driver = mDriver.promote(); 1481 if (driver != NULL) { 1482 driver->notifyPosition(seekTimeUs); 1483 driver->notifySeekComplete(); 1484 } 1485 } 1486 1487 // everything's flushed, continue playback. 1488} 1489 1490void NuPlayer::performDecoderFlush() { 1491 ALOGV("performDecoderFlush"); 1492 1493 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 1494 return; 1495 } 1496 1497 mTimeDiscontinuityPending = true; 1498 1499 if (mAudioDecoder != NULL) { 1500 flushDecoder(true /* audio */, false /* needShutdown */); 1501 } 1502 1503 if (mVideoDecoder != NULL) { 1504 flushDecoder(false /* audio */, false /* needShutdown */); 1505 } 1506} 1507 1508void NuPlayer::performDecoderShutdown(bool audio, bool video) { 1509 ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video); 1510 1511 if ((!audio || mAudioDecoder == NULL) 1512 && (!video || mVideoDecoder == NULL)) { 1513 return; 1514 } 1515 1516 mTimeDiscontinuityPending = true; 1517 1518 if (mFlushingAudio == NONE && (!audio || mAudioDecoder == NULL)) { 1519 mFlushingAudio = FLUSHED; 1520 } 1521 1522 if (mFlushingVideo == NONE && (!video || mVideoDecoder == NULL)) { 1523 mFlushingVideo = FLUSHED; 1524 } 1525 1526 if (audio && mAudioDecoder != NULL) { 1527 flushDecoder(true /* audio */, true /* needShutdown */); 1528 } 1529 1530 if (video && mVideoDecoder != NULL) { 1531 flushDecoder(false /* audio */, true /* needShutdown */); 1532 } 1533} 1534 1535void NuPlayer::performReset() { 1536 ALOGV("performReset"); 1537 1538 CHECK(mAudioDecoder == NULL); 1539 CHECK(mVideoDecoder == NULL); 1540 1541 cancelPollDuration(); 1542 1543 ++mScanSourcesGeneration; 1544 mScanSourcesPending = false; 1545 1546 if (mRendererLooper != NULL) { 1547 if (mRenderer != NULL) { 1548 mRendererLooper->unregisterHandler(mRenderer->id()); 1549 } 1550 mRendererLooper->stop(); 1551 mRendererLooper.clear(); 1552 } 1553 mRenderer.clear(); 1554 1555 if (mSource != NULL) { 1556 mSource->stop(); 1557 1558 looper()->unregisterHandler(mSource->id()); 1559 1560 mSource.clear(); 1561 } 1562 1563 if (mDriver != NULL) { 1564 sp<NuPlayerDriver> driver = mDriver.promote(); 1565 if (driver != NULL) { 1566 driver->notifyResetComplete(); 1567 } 1568 } 1569 1570 mStarted = false; 1571} 1572 1573void NuPlayer::performScanSources() { 1574 ALOGV("performScanSources"); 1575 1576 if (!mStarted) { 1577 return; 1578 } 1579 1580 if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 1581 postScanSources(); 1582 } 1583} 1584 1585void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) { 1586 ALOGV("performSetSurface"); 1587 1588 mNativeWindow = wrapper; 1589 1590 // XXX - ignore error from setVideoScalingMode for now 1591 setVideoScalingMode(mVideoScalingMode); 1592 1593 if (mDriver != NULL) { 1594 sp<NuPlayerDriver> driver = mDriver.promote(); 1595 if (driver != NULL) { 1596 driver->notifySetSurfaceComplete(); 1597 } 1598 } 1599} 1600 1601void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { 1602 int32_t what; 1603 CHECK(msg->findInt32("what", &what)); 1604 1605 switch (what) { 1606 case Source::kWhatPrepared: 1607 { 1608 if (mSource == NULL) { 1609 // This is a stale notification from a source that was 1610 // asynchronously preparing when the client called reset(). 1611 // We handled the reset, the source is gone. 1612 break; 1613 } 1614 1615 int32_t err; 1616 CHECK(msg->findInt32("err", &err)); 1617 1618 sp<NuPlayerDriver> driver = mDriver.promote(); 1619 if (driver != NULL) { 1620 // notify duration first, so that it's definitely set when 1621 // the app received the "prepare complete" callback. 1622 int64_t durationUs; 1623 if (mSource->getDuration(&durationUs) == OK) { 1624 driver->notifyDuration(durationUs); 1625 } 1626 driver->notifyPrepareCompleted(err); 1627 } 1628 1629 break; 1630 } 1631 1632 case Source::kWhatFlagsChanged: 1633 { 1634 uint32_t flags; 1635 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1636 1637 sp<NuPlayerDriver> driver = mDriver.promote(); 1638 if (driver != NULL) { 1639 driver->notifyFlagsChanged(flags); 1640 } 1641 1642 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1643 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { 1644 cancelPollDuration(); 1645 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1646 && (flags & Source::FLAG_DYNAMIC_DURATION) 1647 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 1648 schedulePollDuration(); 1649 } 1650 1651 mSourceFlags = flags; 1652 break; 1653 } 1654 1655 case Source::kWhatVideoSizeChanged: 1656 { 1657 int32_t width, height; 1658 CHECK(msg->findInt32("width", &width)); 1659 CHECK(msg->findInt32("height", &height)); 1660 1661 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height); 1662 break; 1663 } 1664 1665 case Source::kWhatBufferingStart: 1666 { 1667 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); 1668 break; 1669 } 1670 1671 case Source::kWhatBufferingEnd: 1672 { 1673 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0); 1674 break; 1675 } 1676 1677 case Source::kWhatSubtitleData: 1678 { 1679 sp<ABuffer> buffer; 1680 CHECK(msg->findBuffer("buffer", &buffer)); 1681 1682 sendSubtitleData(buffer, 0 /* baseIndex */); 1683 break; 1684 } 1685 1686 case Source::kWhatQueueDecoderShutdown: 1687 { 1688 int32_t audio, video; 1689 CHECK(msg->findInt32("audio", &audio)); 1690 CHECK(msg->findInt32("video", &video)); 1691 1692 sp<AMessage> reply; 1693 CHECK(msg->findMessage("reply", &reply)); 1694 1695 queueDecoderShutdown(audio, video, reply); 1696 break; 1697 } 1698 1699 default: 1700 TRESPASS(); 1701 } 1702} 1703 1704void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) { 1705 int32_t what; 1706 CHECK(msg->findInt32("what", &what)); 1707 1708 switch (what) { 1709 case NuPlayer::CCDecoder::kWhatClosedCaptionData: 1710 { 1711 sp<ABuffer> buffer; 1712 CHECK(msg->findBuffer("buffer", &buffer)); 1713 1714 size_t inbandTracks = 0; 1715 if (mSource != NULL) { 1716 inbandTracks = mSource->getTrackCount(); 1717 } 1718 1719 sendSubtitleData(buffer, inbandTracks); 1720 break; 1721 } 1722 1723 case NuPlayer::CCDecoder::kWhatTrackAdded: 1724 { 1725 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0); 1726 1727 break; 1728 } 1729 1730 default: 1731 TRESPASS(); 1732 } 1733 1734 1735} 1736 1737void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) { 1738 int32_t trackIndex; 1739 int64_t timeUs, durationUs; 1740 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex)); 1741 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 1742 CHECK(buffer->meta()->findInt64("durationUs", &durationUs)); 1743 1744 Parcel in; 1745 in.writeInt32(trackIndex + baseIndex); 1746 in.writeInt64(timeUs); 1747 in.writeInt64(durationUs); 1748 in.writeInt32(buffer->size()); 1749 in.writeInt32(buffer->size()); 1750 in.write(buffer->data(), buffer->size()); 1751 1752 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in); 1753} 1754//////////////////////////////////////////////////////////////////////////////// 1755 1756void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { 1757 sp<AMessage> notify = dupNotify(); 1758 notify->setInt32("what", kWhatFlagsChanged); 1759 notify->setInt32("flags", flags); 1760 notify->post(); 1761} 1762 1763void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) { 1764 sp<AMessage> notify = dupNotify(); 1765 notify->setInt32("what", kWhatVideoSizeChanged); 1766 notify->setInt32("width", width); 1767 notify->setInt32("height", height); 1768 notify->post(); 1769} 1770 1771void NuPlayer::Source::notifyPrepared(status_t err) { 1772 sp<AMessage> notify = dupNotify(); 1773 notify->setInt32("what", kWhatPrepared); 1774 notify->setInt32("err", err); 1775 notify->post(); 1776} 1777 1778void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { 1779 TRESPASS(); 1780} 1781 1782void NuPlayer::queueDecoderShutdown( 1783 bool audio, bool video, const sp<AMessage> &reply) { 1784 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video); 1785 1786 mDeferredActions.push_back( 1787 new ShutdownDecoderAction(audio, video)); 1788 1789 mDeferredActions.push_back( 1790 new SimpleAction(&NuPlayer::performScanSources)); 1791 1792 mDeferredActions.push_back(new PostMessageAction(reply)); 1793 1794 processDeferredActions(); 1795} 1796 1797} // namespace android 1798