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 "NuPlayerDriver.h" 26 #include "NuPlayerRenderer.h" 27 #include "NuPlayerSource.h" 28 #include "RTSPSource.h" 29 #include "StreamingSource.h" 30 #include "GenericSource.h" 31 #include "mp4/MP4Source.h" 32 33 #include "ATSParser.h" 34 35 #include <cutils/properties.h> // for property_get 36 #include <media/stagefright/foundation/hexdump.h> 37 #include <media/stagefright/foundation/ABuffer.h> 38 #include <media/stagefright/foundation/ADebug.h> 39 #include <media/stagefright/foundation/AMessage.h> 40 #include <media/stagefright/ACodec.h> 41 #include <media/stagefright/MediaDefs.h> 42 #include <media/stagefright/MediaErrors.h> 43 #include <media/stagefright/MetaData.h> 44 #include <gui/IGraphicBufferProducer.h> 45 46 #include "avc_utils.h" 47 48 #include "ESDS.h" 49 #include <media/stagefright/Utils.h> 50 51 namespace android { 52 53 struct NuPlayer::Action : public RefBase { 54 Action() {} 55 56 virtual void execute(NuPlayer *player) = 0; 57 58 private: 59 DISALLOW_EVIL_CONSTRUCTORS(Action); 60 }; 61 62 struct NuPlayer::SeekAction : public Action { 63 SeekAction(int64_t seekTimeUs) 64 : mSeekTimeUs(seekTimeUs) { 65 } 66 67 virtual void execute(NuPlayer *player) { 68 player->performSeek(mSeekTimeUs); 69 } 70 71 private: 72 int64_t mSeekTimeUs; 73 74 DISALLOW_EVIL_CONSTRUCTORS(SeekAction); 75 }; 76 77 struct NuPlayer::SetSurfaceAction : public Action { 78 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper) 79 : mWrapper(wrapper) { 80 } 81 82 virtual void execute(NuPlayer *player) { 83 player->performSetSurface(mWrapper); 84 } 85 86 private: 87 sp<NativeWindowWrapper> mWrapper; 88 89 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction); 90 }; 91 92 // Use this if there's no state necessary to save in order to execute 93 // the action. 94 struct NuPlayer::SimpleAction : public Action { 95 typedef void (NuPlayer::*ActionFunc)(); 96 97 SimpleAction(ActionFunc func) 98 : mFunc(func) { 99 } 100 101 virtual void execute(NuPlayer *player) { 102 (player->*mFunc)(); 103 } 104 105 private: 106 ActionFunc mFunc; 107 108 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction); 109 }; 110 111 //////////////////////////////////////////////////////////////////////////////// 112 113 NuPlayer::NuPlayer() 114 : mUIDValid(false), 115 mSourceFlags(0), 116 mVideoIsAVC(false), 117 mAudioEOS(false), 118 mVideoEOS(false), 119 mScanSourcesPending(false), 120 mScanSourcesGeneration(0), 121 mPollDurationGeneration(0), 122 mTimeDiscontinuityPending(false), 123 mFlushingAudio(NONE), 124 mFlushingVideo(NONE), 125 mSkipRenderingAudioUntilMediaTimeUs(-1ll), 126 mSkipRenderingVideoUntilMediaTimeUs(-1ll), 127 mVideoLateByUs(0ll), 128 mNumFramesTotal(0ll), 129 mNumFramesDropped(0ll), 130 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), 131 mStarted(false) { 132 } 133 134 NuPlayer::~NuPlayer() { 135 } 136 137 void NuPlayer::setUID(uid_t uid) { 138 mUIDValid = true; 139 mUID = uid; 140 } 141 142 void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { 143 mDriver = driver; 144 } 145 146 void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) { 147 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 148 149 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 150 151 char prop[PROPERTY_VALUE_MAX]; 152 if (property_get("media.stagefright.use-mp4source", prop, NULL) 153 && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) { 154 msg->setObject("source", new MP4Source(notify, source)); 155 } else { 156 msg->setObject("source", new StreamingSource(notify, source)); 157 } 158 159 msg->post(); 160 } 161 162 static bool IsHTTPLiveURL(const char *url) { 163 if (!strncasecmp("http://", url, 7) 164 || !strncasecmp("https://", url, 8) 165 || !strncasecmp("file://", url, 7)) { 166 size_t len = strlen(url); 167 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 168 return true; 169 } 170 171 if (strstr(url,"m3u8")) { 172 return true; 173 } 174 } 175 176 return false; 177 } 178 179 void NuPlayer::setDataSourceAsync( 180 const char *url, const KeyedVector<String8, String8> *headers) { 181 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 182 size_t len = strlen(url); 183 184 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 185 186 sp<Source> source; 187 if (IsHTTPLiveURL(url)) { 188 source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID); 189 } else if (!strncasecmp(url, "rtsp://", 7)) { 190 source = new RTSPSource(notify, url, headers, mUIDValid, mUID); 191 } else if ((!strncasecmp(url, "http://", 7) 192 || !strncasecmp(url, "https://", 8)) 193 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) 194 || strstr(url, ".sdp?"))) { 195 source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true); 196 } else { 197 source = new GenericSource(notify, url, headers, mUIDValid, mUID); 198 } 199 200 msg->setObject("source", source); 201 msg->post(); 202 } 203 204 void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { 205 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 206 207 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 208 209 sp<Source> source = new GenericSource(notify, fd, offset, length); 210 msg->setObject("source", source); 211 msg->post(); 212 } 213 214 void NuPlayer::prepareAsync() { 215 (new AMessage(kWhatPrepare, id()))->post(); 216 } 217 218 void NuPlayer::setVideoSurfaceTextureAsync( 219 const sp<IGraphicBufferProducer> &bufferProducer) { 220 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id()); 221 222 if (bufferProducer == NULL) { 223 msg->setObject("native-window", NULL); 224 } else { 225 msg->setObject( 226 "native-window", 227 new NativeWindowWrapper( 228 new Surface(bufferProducer))); 229 } 230 231 msg->post(); 232 } 233 234 void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) { 235 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id()); 236 msg->setObject("sink", sink); 237 msg->post(); 238 } 239 240 void NuPlayer::start() { 241 (new AMessage(kWhatStart, id()))->post(); 242 } 243 244 void NuPlayer::pause() { 245 (new AMessage(kWhatPause, id()))->post(); 246 } 247 248 void NuPlayer::resume() { 249 (new AMessage(kWhatResume, id()))->post(); 250 } 251 252 void NuPlayer::resetAsync() { 253 (new AMessage(kWhatReset, id()))->post(); 254 } 255 256 void NuPlayer::seekToAsync(int64_t seekTimeUs) { 257 sp<AMessage> msg = new AMessage(kWhatSeek, id()); 258 msg->setInt64("seekTimeUs", seekTimeUs); 259 msg->post(); 260 } 261 262 // static 263 bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { 264 switch (state) { 265 case FLUSHING_DECODER: 266 if (needShutdown != NULL) { 267 *needShutdown = false; 268 } 269 return true; 270 271 case FLUSHING_DECODER_SHUTDOWN: 272 if (needShutdown != NULL) { 273 *needShutdown = true; 274 } 275 return true; 276 277 default: 278 return false; 279 } 280 } 281 282 void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 283 switch (msg->what()) { 284 case kWhatSetDataSource: 285 { 286 ALOGV("kWhatSetDataSource"); 287 288 CHECK(mSource == NULL); 289 290 sp<RefBase> obj; 291 CHECK(msg->findObject("source", &obj)); 292 293 mSource = static_cast<Source *>(obj.get()); 294 295 looper()->registerHandler(mSource); 296 297 CHECK(mDriver != NULL); 298 sp<NuPlayerDriver> driver = mDriver.promote(); 299 if (driver != NULL) { 300 driver->notifySetDataSourceCompleted(OK); 301 } 302 break; 303 } 304 305 case kWhatPrepare: 306 { 307 mSource->prepareAsync(); 308 break; 309 } 310 311 case kWhatPollDuration: 312 { 313 int32_t generation; 314 CHECK(msg->findInt32("generation", &generation)); 315 316 if (generation != mPollDurationGeneration) { 317 // stale 318 break; 319 } 320 321 int64_t durationUs; 322 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 323 sp<NuPlayerDriver> driver = mDriver.promote(); 324 if (driver != NULL) { 325 driver->notifyDuration(durationUs); 326 } 327 } 328 329 msg->post(1000000ll); // poll again in a second. 330 break; 331 } 332 333 case kWhatSetVideoNativeWindow: 334 { 335 ALOGV("kWhatSetVideoNativeWindow"); 336 337 mDeferredActions.push_back( 338 new SimpleAction(&NuPlayer::performDecoderShutdown)); 339 340 sp<RefBase> obj; 341 CHECK(msg->findObject("native-window", &obj)); 342 343 mDeferredActions.push_back( 344 new SetSurfaceAction( 345 static_cast<NativeWindowWrapper *>(obj.get()))); 346 347 if (obj != NULL) { 348 // If there is a new surface texture, instantiate decoders 349 // again if possible. 350 mDeferredActions.push_back( 351 new SimpleAction(&NuPlayer::performScanSources)); 352 } 353 354 processDeferredActions(); 355 break; 356 } 357 358 case kWhatSetAudioSink: 359 { 360 ALOGV("kWhatSetAudioSink"); 361 362 sp<RefBase> obj; 363 CHECK(msg->findObject("sink", &obj)); 364 365 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get()); 366 break; 367 } 368 369 case kWhatStart: 370 { 371 ALOGV("kWhatStart"); 372 373 mVideoIsAVC = false; 374 mAudioEOS = false; 375 mVideoEOS = false; 376 mSkipRenderingAudioUntilMediaTimeUs = -1; 377 mSkipRenderingVideoUntilMediaTimeUs = -1; 378 mVideoLateByUs = 0; 379 mNumFramesTotal = 0; 380 mNumFramesDropped = 0; 381 mStarted = true; 382 383 mSource->start(); 384 385 uint32_t flags = 0; 386 387 if (mSource->isRealTime()) { 388 flags |= Renderer::FLAG_REAL_TIME; 389 } 390 391 mRenderer = new Renderer( 392 mAudioSink, 393 new AMessage(kWhatRendererNotify, id()), 394 flags); 395 396 looper()->registerHandler(mRenderer); 397 398 postScanSources(); 399 break; 400 } 401 402 case kWhatScanSources: 403 { 404 int32_t generation; 405 CHECK(msg->findInt32("generation", &generation)); 406 if (generation != mScanSourcesGeneration) { 407 // Drop obsolete msg. 408 break; 409 } 410 411 mScanSourcesPending = false; 412 413 ALOGV("scanning sources haveAudio=%d, haveVideo=%d", 414 mAudioDecoder != NULL, mVideoDecoder != NULL); 415 416 bool mHadAnySourcesBefore = 417 (mAudioDecoder != NULL) || (mVideoDecoder != NULL); 418 419 if (mNativeWindow != NULL) { 420 instantiateDecoder(false, &mVideoDecoder); 421 } 422 423 if (mAudioSink != NULL) { 424 instantiateDecoder(true, &mAudioDecoder); 425 } 426 427 if (!mHadAnySourcesBefore 428 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 429 // This is the first time we've found anything playable. 430 431 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) { 432 schedulePollDuration(); 433 } 434 } 435 436 status_t err; 437 if ((err = mSource->feedMoreTSData()) != OK) { 438 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 439 // We're not currently decoding anything (no audio or 440 // video tracks found) and we just ran out of input data. 441 442 if (err == ERROR_END_OF_STREAM) { 443 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 444 } else { 445 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 446 } 447 } 448 break; 449 } 450 451 if ((mAudioDecoder == NULL && mAudioSink != NULL) 452 || (mVideoDecoder == NULL && mNativeWindow != NULL)) { 453 msg->post(100000ll); 454 mScanSourcesPending = true; 455 } 456 break; 457 } 458 459 case kWhatVideoNotify: 460 case kWhatAudioNotify: 461 { 462 bool audio = msg->what() == kWhatAudioNotify; 463 464 sp<AMessage> codecRequest; 465 CHECK(msg->findMessage("codec-request", &codecRequest)); 466 467 int32_t what; 468 CHECK(codecRequest->findInt32("what", &what)); 469 470 if (what == ACodec::kWhatFillThisBuffer) { 471 status_t err = feedDecoderInputData( 472 audio, codecRequest); 473 474 if (err == -EWOULDBLOCK) { 475 if (mSource->feedMoreTSData() == OK) { 476 msg->post(10000ll); 477 } 478 } 479 } else if (what == ACodec::kWhatEOS) { 480 int32_t err; 481 CHECK(codecRequest->findInt32("err", &err)); 482 483 if (err == ERROR_END_OF_STREAM) { 484 ALOGV("got %s decoder EOS", audio ? "audio" : "video"); 485 } else { 486 ALOGV("got %s decoder EOS w/ error %d", 487 audio ? "audio" : "video", 488 err); 489 } 490 491 mRenderer->queueEOS(audio, err); 492 } else if (what == ACodec::kWhatFlushCompleted) { 493 bool needShutdown; 494 495 if (audio) { 496 CHECK(IsFlushingState(mFlushingAudio, &needShutdown)); 497 mFlushingAudio = FLUSHED; 498 } else { 499 CHECK(IsFlushingState(mFlushingVideo, &needShutdown)); 500 mFlushingVideo = FLUSHED; 501 502 mVideoLateByUs = 0; 503 } 504 505 ALOGV("decoder %s flush completed", audio ? "audio" : "video"); 506 507 if (needShutdown) { 508 ALOGV("initiating %s decoder shutdown", 509 audio ? "audio" : "video"); 510 511 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); 512 513 if (audio) { 514 mFlushingAudio = SHUTTING_DOWN_DECODER; 515 } else { 516 mFlushingVideo = SHUTTING_DOWN_DECODER; 517 } 518 } 519 520 finishFlushIfPossible(); 521 } else if (what == ACodec::kWhatOutputFormatChanged) { 522 if (audio) { 523 int32_t numChannels; 524 CHECK(codecRequest->findInt32( 525 "channel-count", &numChannels)); 526 527 int32_t sampleRate; 528 CHECK(codecRequest->findInt32("sample-rate", &sampleRate)); 529 530 ALOGV("Audio output format changed to %d Hz, %d channels", 531 sampleRate, numChannels); 532 533 mAudioSink->close(); 534 535 audio_output_flags_t flags; 536 int64_t durationUs; 537 // FIXME: we should handle the case where the video decoder 538 // is created after we receive the format change indication. 539 // Current code will just make that we select deep buffer 540 // with video which should not be a problem as it should 541 // not prevent from keeping A/V sync. 542 if (mVideoDecoder == NULL && 543 mSource->getDuration(&durationUs) == OK && 544 durationUs 545 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 546 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 547 } else { 548 flags = AUDIO_OUTPUT_FLAG_NONE; 549 } 550 551 int32_t channelMask; 552 if (!codecRequest->findInt32("channel-mask", &channelMask)) { 553 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 554 } 555 556 CHECK_EQ(mAudioSink->open( 557 sampleRate, 558 numChannels, 559 (audio_channel_mask_t)channelMask, 560 AUDIO_FORMAT_PCM_16_BIT, 561 8 /* bufferCount */, 562 NULL, 563 NULL, 564 flags), 565 (status_t)OK); 566 mAudioSink->start(); 567 568 mRenderer->signalAudioSinkChanged(); 569 } else { 570 // video 571 572 int32_t width, height; 573 CHECK(codecRequest->findInt32("width", &width)); 574 CHECK(codecRequest->findInt32("height", &height)); 575 576 int32_t cropLeft, cropTop, cropRight, cropBottom; 577 CHECK(codecRequest->findRect( 578 "crop", 579 &cropLeft, &cropTop, &cropRight, &cropBottom)); 580 581 int32_t displayWidth = cropRight - cropLeft + 1; 582 int32_t displayHeight = cropBottom - cropTop + 1; 583 584 ALOGV("Video output format changed to %d x %d " 585 "(crop: %d x %d @ (%d, %d))", 586 width, height, 587 displayWidth, 588 displayHeight, 589 cropLeft, cropTop); 590 591 sp<AMessage> videoInputFormat = 592 mSource->getFormat(false /* audio */); 593 594 // Take into account sample aspect ratio if necessary: 595 int32_t sarWidth, sarHeight; 596 if (videoInputFormat->findInt32("sar-width", &sarWidth) 597 && videoInputFormat->findInt32( 598 "sar-height", &sarHeight)) { 599 ALOGV("Sample aspect ratio %d : %d", 600 sarWidth, sarHeight); 601 602 displayWidth = (displayWidth * sarWidth) / sarHeight; 603 604 ALOGV("display dimensions %d x %d", 605 displayWidth, displayHeight); 606 } 607 608 notifyListener( 609 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight); 610 } 611 } else if (what == ACodec::kWhatShutdownCompleted) { 612 ALOGV("%s shutdown completed", audio ? "audio" : "video"); 613 if (audio) { 614 mAudioDecoder.clear(); 615 616 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 617 mFlushingAudio = SHUT_DOWN; 618 } else { 619 mVideoDecoder.clear(); 620 621 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 622 mFlushingVideo = SHUT_DOWN; 623 } 624 625 finishFlushIfPossible(); 626 } else if (what == ACodec::kWhatError) { 627 ALOGE("Received error from %s decoder, aborting playback.", 628 audio ? "audio" : "video"); 629 630 mRenderer->queueEOS(audio, UNKNOWN_ERROR); 631 } else if (what == ACodec::kWhatDrainThisBuffer) { 632 renderBuffer(audio, codecRequest); 633 } else if (what != ACodec::kWhatComponentAllocated 634 && what != ACodec::kWhatComponentConfigured 635 && what != ACodec::kWhatBuffersAllocated) { 636 ALOGV("Unhandled codec notification %d '%c%c%c%c'.", 637 what, 638 what >> 24, 639 (what >> 16) & 0xff, 640 (what >> 8) & 0xff, 641 what & 0xff); 642 } 643 644 break; 645 } 646 647 case kWhatRendererNotify: 648 { 649 int32_t what; 650 CHECK(msg->findInt32("what", &what)); 651 652 if (what == Renderer::kWhatEOS) { 653 int32_t audio; 654 CHECK(msg->findInt32("audio", &audio)); 655 656 int32_t finalResult; 657 CHECK(msg->findInt32("finalResult", &finalResult)); 658 659 if (audio) { 660 mAudioEOS = true; 661 } else { 662 mVideoEOS = true; 663 } 664 665 if (finalResult == ERROR_END_OF_STREAM) { 666 ALOGV("reached %s EOS", audio ? "audio" : "video"); 667 } else { 668 ALOGE("%s track encountered an error (%d)", 669 audio ? "audio" : "video", finalResult); 670 671 notifyListener( 672 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 673 } 674 675 if ((mAudioEOS || mAudioDecoder == NULL) 676 && (mVideoEOS || mVideoDecoder == NULL)) { 677 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 678 } 679 } else if (what == Renderer::kWhatPosition) { 680 int64_t positionUs; 681 CHECK(msg->findInt64("positionUs", &positionUs)); 682 683 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs)); 684 685 if (mDriver != NULL) { 686 sp<NuPlayerDriver> driver = mDriver.promote(); 687 if (driver != NULL) { 688 driver->notifyPosition(positionUs); 689 690 driver->notifyFrameStats( 691 mNumFramesTotal, mNumFramesDropped); 692 } 693 } 694 } else if (what == Renderer::kWhatFlushComplete) { 695 int32_t audio; 696 CHECK(msg->findInt32("audio", &audio)); 697 698 ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 699 } else if (what == Renderer::kWhatVideoRenderingStart) { 700 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); 701 } 702 break; 703 } 704 705 case kWhatMoreDataQueued: 706 { 707 break; 708 } 709 710 case kWhatReset: 711 { 712 ALOGV("kWhatReset"); 713 714 mDeferredActions.push_back( 715 new SimpleAction(&NuPlayer::performDecoderShutdown)); 716 717 mDeferredActions.push_back( 718 new SimpleAction(&NuPlayer::performReset)); 719 720 processDeferredActions(); 721 break; 722 } 723 724 case kWhatSeek: 725 { 726 int64_t seekTimeUs; 727 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 728 729 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs); 730 731 mDeferredActions.push_back( 732 new SimpleAction(&NuPlayer::performDecoderFlush)); 733 734 mDeferredActions.push_back(new SeekAction(seekTimeUs)); 735 736 processDeferredActions(); 737 break; 738 } 739 740 case kWhatPause: 741 { 742 CHECK(mRenderer != NULL); 743 mSource->pause(); 744 mRenderer->pause(); 745 break; 746 } 747 748 case kWhatResume: 749 { 750 CHECK(mRenderer != NULL); 751 mSource->resume(); 752 mRenderer->resume(); 753 break; 754 } 755 756 case kWhatSourceNotify: 757 { 758 onSourceNotify(msg); 759 break; 760 } 761 762 default: 763 TRESPASS(); 764 break; 765 } 766 } 767 768 void NuPlayer::finishFlushIfPossible() { 769 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) { 770 return; 771 } 772 773 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) { 774 return; 775 } 776 777 ALOGV("both audio and video are flushed now."); 778 779 if (mTimeDiscontinuityPending) { 780 mRenderer->signalTimeDiscontinuity(); 781 mTimeDiscontinuityPending = false; 782 } 783 784 if (mAudioDecoder != NULL) { 785 mAudioDecoder->signalResume(); 786 } 787 788 if (mVideoDecoder != NULL) { 789 mVideoDecoder->signalResume(); 790 } 791 792 mFlushingAudio = NONE; 793 mFlushingVideo = NONE; 794 795 processDeferredActions(); 796 } 797 798 void NuPlayer::postScanSources() { 799 if (mScanSourcesPending) { 800 return; 801 } 802 803 sp<AMessage> msg = new AMessage(kWhatScanSources, id()); 804 msg->setInt32("generation", mScanSourcesGeneration); 805 msg->post(); 806 807 mScanSourcesPending = true; 808 } 809 810 status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { 811 if (*decoder != NULL) { 812 return OK; 813 } 814 815 sp<AMessage> format = mSource->getFormat(audio); 816 817 if (format == NULL) { 818 return -EWOULDBLOCK; 819 } 820 821 if (!audio) { 822 AString mime; 823 CHECK(format->findString("mime", &mime)); 824 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 825 } 826 827 sp<AMessage> notify = 828 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify, 829 id()); 830 831 *decoder = audio ? new Decoder(notify) : 832 new Decoder(notify, mNativeWindow); 833 looper()->registerHandler(*decoder); 834 835 (*decoder)->configure(format); 836 837 return OK; 838 } 839 840 status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { 841 sp<AMessage> reply; 842 CHECK(msg->findMessage("reply", &reply)); 843 844 if ((audio && IsFlushingState(mFlushingAudio)) 845 || (!audio && IsFlushingState(mFlushingVideo))) { 846 reply->setInt32("err", INFO_DISCONTINUITY); 847 reply->post(); 848 return OK; 849 } 850 851 sp<ABuffer> accessUnit; 852 853 bool dropAccessUnit; 854 do { 855 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit); 856 857 if (err == -EWOULDBLOCK) { 858 return err; 859 } else if (err != OK) { 860 if (err == INFO_DISCONTINUITY) { 861 int32_t type; 862 CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 863 864 bool formatChange = 865 (audio && 866 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 867 || (!audio && 868 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 869 870 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 871 872 ALOGI("%s discontinuity (formatChange=%d, time=%d)", 873 audio ? "audio" : "video", formatChange, timeChange); 874 875 if (audio) { 876 mSkipRenderingAudioUntilMediaTimeUs = -1; 877 } else { 878 mSkipRenderingVideoUntilMediaTimeUs = -1; 879 } 880 881 if (timeChange) { 882 sp<AMessage> extra; 883 if (accessUnit->meta()->findMessage("extra", &extra) 884 && extra != NULL) { 885 int64_t resumeAtMediaTimeUs; 886 if (extra->findInt64( 887 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { 888 ALOGI("suppressing rendering of %s until %lld us", 889 audio ? "audio" : "video", resumeAtMediaTimeUs); 890 891 if (audio) { 892 mSkipRenderingAudioUntilMediaTimeUs = 893 resumeAtMediaTimeUs; 894 } else { 895 mSkipRenderingVideoUntilMediaTimeUs = 896 resumeAtMediaTimeUs; 897 } 898 } 899 } 900 } 901 902 mTimeDiscontinuityPending = 903 mTimeDiscontinuityPending || timeChange; 904 905 if (formatChange || timeChange) { 906 if (mFlushingAudio == NONE && mFlushingVideo == NONE) { 907 // And we'll resume scanning sources once we're done 908 // flushing. 909 mDeferredActions.push_front( 910 new SimpleAction( 911 &NuPlayer::performScanSources)); 912 } 913 914 flushDecoder(audio, formatChange); 915 } else { 916 // This stream is unaffected by the discontinuity 917 918 if (audio) { 919 mFlushingAudio = FLUSHED; 920 } else { 921 mFlushingVideo = FLUSHED; 922 } 923 924 finishFlushIfPossible(); 925 926 return -EWOULDBLOCK; 927 } 928 } 929 930 reply->setInt32("err", err); 931 reply->post(); 932 return OK; 933 } 934 935 if (!audio) { 936 ++mNumFramesTotal; 937 } 938 939 dropAccessUnit = false; 940 if (!audio 941 && mVideoLateByUs > 100000ll 942 && mVideoIsAVC 943 && !IsAVCReferenceFrame(accessUnit)) { 944 dropAccessUnit = true; 945 ++mNumFramesDropped; 946 } 947 } while (dropAccessUnit); 948 949 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video"); 950 951 #if 0 952 int64_t mediaTimeUs; 953 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 954 ALOGV("feeding %s input buffer at media time %.2f secs", 955 audio ? "audio" : "video", 956 mediaTimeUs / 1E6); 957 #endif 958 959 reply->setBuffer("buffer", accessUnit); 960 reply->post(); 961 962 return OK; 963 } 964 965 void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { 966 // ALOGV("renderBuffer %s", audio ? "audio" : "video"); 967 968 sp<AMessage> reply; 969 CHECK(msg->findMessage("reply", &reply)); 970 971 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) { 972 // We're currently attempting to flush the decoder, in order 973 // to complete this, the decoder wants all its buffers back, 974 // so we don't want any output buffers it sent us (from before 975 // we initiated the flush) to be stuck in the renderer's queue. 976 977 ALOGV("we're still flushing the %s decoder, sending its output buffer" 978 " right back.", audio ? "audio" : "video"); 979 980 reply->post(); 981 return; 982 } 983 984 sp<ABuffer> buffer; 985 CHECK(msg->findBuffer("buffer", &buffer)); 986 987 int64_t &skipUntilMediaTimeUs = 988 audio 989 ? mSkipRenderingAudioUntilMediaTimeUs 990 : mSkipRenderingVideoUntilMediaTimeUs; 991 992 if (skipUntilMediaTimeUs >= 0) { 993 int64_t mediaTimeUs; 994 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs)); 995 996 if (mediaTimeUs < skipUntilMediaTimeUs) { 997 ALOGV("dropping %s buffer at time %lld as requested.", 998 audio ? "audio" : "video", 999 mediaTimeUs); 1000 1001 reply->post(); 1002 return; 1003 } 1004 1005 skipUntilMediaTimeUs = -1; 1006 } 1007 1008 mRenderer->queueBuffer(audio, buffer, reply); 1009 } 1010 1011 void NuPlayer::notifyListener(int msg, int ext1, int ext2) { 1012 if (mDriver == NULL) { 1013 return; 1014 } 1015 1016 sp<NuPlayerDriver> driver = mDriver.promote(); 1017 1018 if (driver == NULL) { 1019 return; 1020 } 1021 1022 driver->notifyListener(msg, ext1, ext2); 1023 } 1024 1025 void NuPlayer::flushDecoder(bool audio, bool needShutdown) { 1026 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { 1027 ALOGI("flushDecoder %s without decoder present", 1028 audio ? "audio" : "video"); 1029 } 1030 1031 // Make sure we don't continue to scan sources until we finish flushing. 1032 ++mScanSourcesGeneration; 1033 mScanSourcesPending = false; 1034 1035 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); 1036 mRenderer->flush(audio); 1037 1038 FlushStatus newStatus = 1039 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; 1040 1041 if (audio) { 1042 CHECK(mFlushingAudio == NONE 1043 || mFlushingAudio == AWAITING_DISCONTINUITY); 1044 1045 mFlushingAudio = newStatus; 1046 1047 if (mFlushingVideo == NONE) { 1048 mFlushingVideo = (mVideoDecoder != NULL) 1049 ? AWAITING_DISCONTINUITY 1050 : FLUSHED; 1051 } 1052 } else { 1053 CHECK(mFlushingVideo == NONE 1054 || mFlushingVideo == AWAITING_DISCONTINUITY); 1055 1056 mFlushingVideo = newStatus; 1057 1058 if (mFlushingAudio == NONE) { 1059 mFlushingAudio = (mAudioDecoder != NULL) 1060 ? AWAITING_DISCONTINUITY 1061 : FLUSHED; 1062 } 1063 } 1064 } 1065 1066 sp<AMessage> NuPlayer::Source::getFormat(bool audio) { 1067 sp<MetaData> meta = getFormatMeta(audio); 1068 1069 if (meta == NULL) { 1070 return NULL; 1071 } 1072 1073 sp<AMessage> msg = new AMessage; 1074 1075 if(convertMetaDataToMessage(meta, &msg) == OK) { 1076 return msg; 1077 } 1078 return NULL; 1079 } 1080 1081 status_t NuPlayer::setVideoScalingMode(int32_t mode) { 1082 mVideoScalingMode = mode; 1083 if (mNativeWindow != NULL) { 1084 status_t ret = native_window_set_scaling_mode( 1085 mNativeWindow->getNativeWindow().get(), mVideoScalingMode); 1086 if (ret != OK) { 1087 ALOGE("Failed to set scaling mode (%d): %s", 1088 -ret, strerror(-ret)); 1089 return ret; 1090 } 1091 } 1092 return OK; 1093 } 1094 1095 void NuPlayer::schedulePollDuration() { 1096 sp<AMessage> msg = new AMessage(kWhatPollDuration, id()); 1097 msg->setInt32("generation", mPollDurationGeneration); 1098 msg->post(); 1099 } 1100 1101 void NuPlayer::cancelPollDuration() { 1102 ++mPollDurationGeneration; 1103 } 1104 1105 void NuPlayer::processDeferredActions() { 1106 while (!mDeferredActions.empty()) { 1107 // We won't execute any deferred actions until we're no longer in 1108 // an intermediate state, i.e. one more more decoders are currently 1109 // flushing or shutting down. 1110 1111 if (mRenderer != NULL) { 1112 // There's an edge case where the renderer owns all output 1113 // buffers and is paused, therefore the decoder will not read 1114 // more input data and will never encounter the matching 1115 // discontinuity. To avoid this, we resume the renderer. 1116 1117 if (mFlushingAudio == AWAITING_DISCONTINUITY 1118 || mFlushingVideo == AWAITING_DISCONTINUITY) { 1119 mRenderer->resume(); 1120 } 1121 } 1122 1123 if (mFlushingAudio != NONE || mFlushingVideo != NONE) { 1124 // We're currently flushing, postpone the reset until that's 1125 // completed. 1126 1127 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d", 1128 mFlushingAudio, mFlushingVideo); 1129 1130 break; 1131 } 1132 1133 sp<Action> action = *mDeferredActions.begin(); 1134 mDeferredActions.erase(mDeferredActions.begin()); 1135 1136 action->execute(this); 1137 } 1138 } 1139 1140 void NuPlayer::performSeek(int64_t seekTimeUs) { 1141 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)", 1142 seekTimeUs, 1143 seekTimeUs / 1E6); 1144 1145 mSource->seekTo(seekTimeUs); 1146 1147 if (mDriver != NULL) { 1148 sp<NuPlayerDriver> driver = mDriver.promote(); 1149 if (driver != NULL) { 1150 driver->notifyPosition(seekTimeUs); 1151 driver->notifySeekComplete(); 1152 } 1153 } 1154 1155 // everything's flushed, continue playback. 1156 } 1157 1158 void NuPlayer::performDecoderFlush() { 1159 ALOGV("performDecoderFlush"); 1160 1161 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 1162 return; 1163 } 1164 1165 mTimeDiscontinuityPending = true; 1166 1167 if (mAudioDecoder != NULL) { 1168 flushDecoder(true /* audio */, false /* needShutdown */); 1169 } 1170 1171 if (mVideoDecoder != NULL) { 1172 flushDecoder(false /* audio */, false /* needShutdown */); 1173 } 1174 } 1175 1176 void NuPlayer::performDecoderShutdown() { 1177 ALOGV("performDecoderShutdown"); 1178 1179 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 1180 return; 1181 } 1182 1183 mTimeDiscontinuityPending = true; 1184 1185 if (mAudioDecoder != NULL) { 1186 flushDecoder(true /* audio */, true /* needShutdown */); 1187 } 1188 1189 if (mVideoDecoder != NULL) { 1190 flushDecoder(false /* audio */, true /* needShutdown */); 1191 } 1192 } 1193 1194 void NuPlayer::performReset() { 1195 ALOGV("performReset"); 1196 1197 CHECK(mAudioDecoder == NULL); 1198 CHECK(mVideoDecoder == NULL); 1199 1200 cancelPollDuration(); 1201 1202 ++mScanSourcesGeneration; 1203 mScanSourcesPending = false; 1204 1205 mRenderer.clear(); 1206 1207 if (mSource != NULL) { 1208 mSource->stop(); 1209 1210 looper()->unregisterHandler(mSource->id()); 1211 1212 mSource.clear(); 1213 } 1214 1215 if (mDriver != NULL) { 1216 sp<NuPlayerDriver> driver = mDriver.promote(); 1217 if (driver != NULL) { 1218 driver->notifyResetComplete(); 1219 } 1220 } 1221 1222 mStarted = false; 1223 } 1224 1225 void NuPlayer::performScanSources() { 1226 ALOGV("performScanSources"); 1227 1228 if (!mStarted) { 1229 return; 1230 } 1231 1232 if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 1233 postScanSources(); 1234 } 1235 } 1236 1237 void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) { 1238 ALOGV("performSetSurface"); 1239 1240 mNativeWindow = wrapper; 1241 1242 // XXX - ignore error from setVideoScalingMode for now 1243 setVideoScalingMode(mVideoScalingMode); 1244 1245 if (mDriver != NULL) { 1246 sp<NuPlayerDriver> driver = mDriver.promote(); 1247 if (driver != NULL) { 1248 driver->notifySetSurfaceComplete(); 1249 } 1250 } 1251 } 1252 1253 void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { 1254 int32_t what; 1255 CHECK(msg->findInt32("what", &what)); 1256 1257 switch (what) { 1258 case Source::kWhatPrepared: 1259 { 1260 if (mSource == NULL) { 1261 // This is a stale notification from a source that was 1262 // asynchronously preparing when the client called reset(). 1263 // We handled the reset, the source is gone. 1264 break; 1265 } 1266 1267 int32_t err; 1268 CHECK(msg->findInt32("err", &err)); 1269 1270 sp<NuPlayerDriver> driver = mDriver.promote(); 1271 if (driver != NULL) { 1272 driver->notifyPrepareCompleted(err); 1273 } 1274 1275 int64_t durationUs; 1276 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 1277 sp<NuPlayerDriver> driver = mDriver.promote(); 1278 if (driver != NULL) { 1279 driver->notifyDuration(durationUs); 1280 } 1281 } 1282 break; 1283 } 1284 1285 case Source::kWhatFlagsChanged: 1286 { 1287 uint32_t flags; 1288 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1289 1290 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1291 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { 1292 cancelPollDuration(); 1293 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1294 && (flags & Source::FLAG_DYNAMIC_DURATION) 1295 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 1296 schedulePollDuration(); 1297 } 1298 1299 mSourceFlags = flags; 1300 break; 1301 } 1302 1303 case Source::kWhatVideoSizeChanged: 1304 { 1305 int32_t width, height; 1306 CHECK(msg->findInt32("width", &width)); 1307 CHECK(msg->findInt32("height", &height)); 1308 1309 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height); 1310 break; 1311 } 1312 1313 case Source::kWhatBufferingStart: 1314 { 1315 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); 1316 break; 1317 } 1318 1319 case Source::kWhatBufferingEnd: 1320 { 1321 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0); 1322 break; 1323 } 1324 1325 default: 1326 TRESPASS(); 1327 } 1328 } 1329 1330 //////////////////////////////////////////////////////////////////////////////// 1331 1332 void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { 1333 sp<AMessage> notify = dupNotify(); 1334 notify->setInt32("what", kWhatFlagsChanged); 1335 notify->setInt32("flags", flags); 1336 notify->post(); 1337 } 1338 1339 void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) { 1340 sp<AMessage> notify = dupNotify(); 1341 notify->setInt32("what", kWhatVideoSizeChanged); 1342 notify->setInt32("width", width); 1343 notify->setInt32("height", height); 1344 notify->post(); 1345 } 1346 1347 void NuPlayer::Source::notifyPrepared(status_t err) { 1348 sp<AMessage> notify = dupNotify(); 1349 notify->setInt32("what", kWhatPrepared); 1350 notify->setInt32("err", err); 1351 notify->post(); 1352 } 1353 1354 void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) { 1355 TRESPASS(); 1356 } 1357 1358 } // namespace android 1359