NuPlayer.cpp revision b1e7cd156ca3e1747374e0d20cdd1ce467210453
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 51namespace android { 52 53struct NuPlayer::Action : public RefBase { 54 Action() {} 55 56 virtual void execute(NuPlayer *player) = 0; 57 58private: 59 DISALLOW_EVIL_CONSTRUCTORS(Action); 60}; 61 62struct 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 71private: 72 int64_t mSeekTimeUs; 73 74 DISALLOW_EVIL_CONSTRUCTORS(SeekAction); 75}; 76 77struct 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 86private: 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. 94struct 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 105private: 106 ActionFunc mFunc; 107 108 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction); 109}; 110 111//////////////////////////////////////////////////////////////////////////////// 112 113NuPlayer::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 134NuPlayer::~NuPlayer() { 135} 136 137void NuPlayer::setUID(uid_t uid) { 138 mUIDValid = true; 139 mUID = uid; 140} 141 142void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { 143 mDriver = driver; 144} 145 146void 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 162static bool IsHTTPLiveURL(const char *url) { 163 if (!strncasecmp("http://", url, 7) 164 || !strncasecmp("https://", url, 8)) { 165 size_t len = strlen(url); 166 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 167 return true; 168 } 169 170 if (strstr(url,"m3u8")) { 171 return true; 172 } 173 } 174 175 return false; 176} 177 178void NuPlayer::setDataSourceAsync( 179 const char *url, const KeyedVector<String8, String8> *headers) { 180 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 181 size_t len = strlen(url); 182 183 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 184 185 sp<Source> source; 186 if (IsHTTPLiveURL(url)) { 187 source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID); 188 } else if (!strncasecmp(url, "rtsp://", 7)) { 189 source = new RTSPSource(notify, url, headers, mUIDValid, mUID); 190 } else if ((!strncasecmp(url, "http://", 7) 191 || !strncasecmp(url, "https://", 8)) 192 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) 193 || strstr(url, ".sdp?"))) { 194 source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true); 195 } else { 196 source = new GenericSource(notify, url, headers, mUIDValid, mUID); 197 } 198 199 msg->setObject("source", source); 200 msg->post(); 201} 202 203void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { 204 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 205 206 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 207 208 sp<Source> source = new GenericSource(notify, fd, offset, length); 209 msg->setObject("source", source); 210 msg->post(); 211} 212 213void NuPlayer::prepareAsync() { 214 (new AMessage(kWhatPrepare, id()))->post(); 215} 216 217void NuPlayer::setVideoSurfaceTextureAsync( 218 const sp<IGraphicBufferProducer> &bufferProducer) { 219 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id()); 220 221 if (bufferProducer == NULL) { 222 msg->setObject("native-window", NULL); 223 } else { 224 msg->setObject( 225 "native-window", 226 new NativeWindowWrapper( 227 new Surface(bufferProducer))); 228 } 229 230 msg->post(); 231} 232 233void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) { 234 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id()); 235 msg->setObject("sink", sink); 236 msg->post(); 237} 238 239void NuPlayer::start() { 240 (new AMessage(kWhatStart, id()))->post(); 241} 242 243void NuPlayer::pause() { 244 (new AMessage(kWhatPause, id()))->post(); 245} 246 247void NuPlayer::resume() { 248 (new AMessage(kWhatResume, id()))->post(); 249} 250 251void NuPlayer::resetAsync() { 252 (new AMessage(kWhatReset, id()))->post(); 253} 254 255void NuPlayer::seekToAsync(int64_t seekTimeUs) { 256 sp<AMessage> msg = new AMessage(kWhatSeek, id()); 257 msg->setInt64("seekTimeUs", seekTimeUs); 258 msg->post(); 259} 260 261// static 262bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { 263 switch (state) { 264 case FLUSHING_DECODER: 265 if (needShutdown != NULL) { 266 *needShutdown = false; 267 } 268 return true; 269 270 case FLUSHING_DECODER_SHUTDOWN: 271 if (needShutdown != NULL) { 272 *needShutdown = true; 273 } 274 return true; 275 276 default: 277 return false; 278 } 279} 280 281void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 282 switch (msg->what()) { 283 case kWhatSetDataSource: 284 { 285 ALOGV("kWhatSetDataSource"); 286 287 CHECK(mSource == NULL); 288 289 sp<RefBase> obj; 290 CHECK(msg->findObject("source", &obj)); 291 292 mSource = static_cast<Source *>(obj.get()); 293 294 looper()->registerHandler(mSource); 295 296 CHECK(mDriver != NULL); 297 sp<NuPlayerDriver> driver = mDriver.promote(); 298 if (driver != NULL) { 299 driver->notifySetDataSourceCompleted(OK); 300 } 301 break; 302 } 303 304 case kWhatPrepare: 305 { 306 mSource->prepareAsync(); 307 break; 308 } 309 310 case kWhatPollDuration: 311 { 312 int32_t generation; 313 CHECK(msg->findInt32("generation", &generation)); 314 315 if (generation != mPollDurationGeneration) { 316 // stale 317 break; 318 } 319 320 int64_t durationUs; 321 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 322 sp<NuPlayerDriver> driver = mDriver.promote(); 323 if (driver != NULL) { 324 driver->notifyDuration(durationUs); 325 } 326 } 327 328 msg->post(1000000ll); // poll again in a second. 329 break; 330 } 331 332 case kWhatSetVideoNativeWindow: 333 { 334 ALOGV("kWhatSetVideoNativeWindow"); 335 336 mDeferredActions.push_back( 337 new SimpleAction(&NuPlayer::performDecoderShutdown)); 338 339 sp<RefBase> obj; 340 CHECK(msg->findObject("native-window", &obj)); 341 342 mDeferredActions.push_back( 343 new SetSurfaceAction( 344 static_cast<NativeWindowWrapper *>(obj.get()))); 345 346 if (obj != NULL) { 347 // If there is a new surface texture, instantiate decoders 348 // again if possible. 349 mDeferredActions.push_back( 350 new SimpleAction(&NuPlayer::performScanSources)); 351 } 352 353 processDeferredActions(); 354 break; 355 } 356 357 case kWhatSetAudioSink: 358 { 359 ALOGV("kWhatSetAudioSink"); 360 361 sp<RefBase> obj; 362 CHECK(msg->findObject("sink", &obj)); 363 364 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get()); 365 break; 366 } 367 368 case kWhatStart: 369 { 370 ALOGV("kWhatStart"); 371 372 mVideoIsAVC = false; 373 mAudioEOS = false; 374 mVideoEOS = false; 375 mSkipRenderingAudioUntilMediaTimeUs = -1; 376 mSkipRenderingVideoUntilMediaTimeUs = -1; 377 mVideoLateByUs = 0; 378 mNumFramesTotal = 0; 379 mNumFramesDropped = 0; 380 mStarted = true; 381 382 mSource->start(); 383 384 mRenderer = new Renderer( 385 mAudioSink, 386 new AMessage(kWhatRendererNotify, id())); 387 388 looper()->registerHandler(mRenderer); 389 390 postScanSources(); 391 break; 392 } 393 394 case kWhatScanSources: 395 { 396 int32_t generation; 397 CHECK(msg->findInt32("generation", &generation)); 398 if (generation != mScanSourcesGeneration) { 399 // Drop obsolete msg. 400 break; 401 } 402 403 mScanSourcesPending = false; 404 405 ALOGV("scanning sources haveAudio=%d, haveVideo=%d", 406 mAudioDecoder != NULL, mVideoDecoder != NULL); 407 408 bool mHadAnySourcesBefore = 409 (mAudioDecoder != NULL) || (mVideoDecoder != NULL); 410 411 if (mNativeWindow != NULL) { 412 instantiateDecoder(false, &mVideoDecoder); 413 } 414 415 if (mAudioSink != NULL) { 416 instantiateDecoder(true, &mAudioDecoder); 417 } 418 419 if (!mHadAnySourcesBefore 420 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 421 // This is the first time we've found anything playable. 422 423 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) { 424 schedulePollDuration(); 425 } 426 } 427 428 status_t err; 429 if ((err = mSource->feedMoreTSData()) != OK) { 430 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 431 // We're not currently decoding anything (no audio or 432 // video tracks found) and we just ran out of input data. 433 434 if (err == ERROR_END_OF_STREAM) { 435 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 436 } else { 437 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 438 } 439 } 440 break; 441 } 442 443 if ((mAudioDecoder == NULL && mAudioSink != NULL) 444 || (mVideoDecoder == NULL && mNativeWindow != NULL)) { 445 msg->post(100000ll); 446 mScanSourcesPending = true; 447 } 448 break; 449 } 450 451 case kWhatVideoNotify: 452 case kWhatAudioNotify: 453 { 454 bool audio = msg->what() == kWhatAudioNotify; 455 456 sp<AMessage> codecRequest; 457 CHECK(msg->findMessage("codec-request", &codecRequest)); 458 459 int32_t what; 460 CHECK(codecRequest->findInt32("what", &what)); 461 462 if (what == ACodec::kWhatFillThisBuffer) { 463 status_t err = feedDecoderInputData( 464 audio, codecRequest); 465 466 if (err == -EWOULDBLOCK) { 467 if (mSource->feedMoreTSData() == OK) { 468 msg->post(10000ll); 469 } 470 } 471 } else if (what == ACodec::kWhatEOS) { 472 int32_t err; 473 CHECK(codecRequest->findInt32("err", &err)); 474 475 if (err == ERROR_END_OF_STREAM) { 476 ALOGV("got %s decoder EOS", audio ? "audio" : "video"); 477 } else { 478 ALOGV("got %s decoder EOS w/ error %d", 479 audio ? "audio" : "video", 480 err); 481 } 482 483 mRenderer->queueEOS(audio, err); 484 } else if (what == ACodec::kWhatFlushCompleted) { 485 bool needShutdown; 486 487 if (audio) { 488 CHECK(IsFlushingState(mFlushingAudio, &needShutdown)); 489 mFlushingAudio = FLUSHED; 490 } else { 491 CHECK(IsFlushingState(mFlushingVideo, &needShutdown)); 492 mFlushingVideo = FLUSHED; 493 494 mVideoLateByUs = 0; 495 } 496 497 ALOGV("decoder %s flush completed", audio ? "audio" : "video"); 498 499 if (needShutdown) { 500 ALOGV("initiating %s decoder shutdown", 501 audio ? "audio" : "video"); 502 503 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); 504 505 if (audio) { 506 mFlushingAudio = SHUTTING_DOWN_DECODER; 507 } else { 508 mFlushingVideo = SHUTTING_DOWN_DECODER; 509 } 510 } 511 512 finishFlushIfPossible(); 513 } else if (what == ACodec::kWhatOutputFormatChanged) { 514 if (audio) { 515 int32_t numChannels; 516 CHECK(codecRequest->findInt32( 517 "channel-count", &numChannels)); 518 519 int32_t sampleRate; 520 CHECK(codecRequest->findInt32("sample-rate", &sampleRate)); 521 522 ALOGV("Audio output format changed to %d Hz, %d channels", 523 sampleRate, numChannels); 524 525 mAudioSink->close(); 526 527 audio_output_flags_t flags; 528 int64_t durationUs; 529 // FIXME: we should handle the case where the video decoder 530 // is created after we receive the format change indication. 531 // Current code will just make that we select deep buffer 532 // with video which should not be a problem as it should 533 // not prevent from keeping A/V sync. 534 if (mVideoDecoder == NULL && 535 mSource->getDuration(&durationUs) == OK && 536 durationUs 537 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 538 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 539 } else { 540 flags = AUDIO_OUTPUT_FLAG_NONE; 541 } 542 543 int32_t channelMask; 544 if (!codecRequest->findInt32("channel-mask", &channelMask)) { 545 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 546 } 547 548 CHECK_EQ(mAudioSink->open( 549 sampleRate, 550 numChannels, 551 (audio_channel_mask_t)channelMask, 552 AUDIO_FORMAT_PCM_16_BIT, 553 8 /* bufferCount */, 554 NULL, 555 NULL, 556 flags), 557 (status_t)OK); 558 mAudioSink->start(); 559 560 mRenderer->signalAudioSinkChanged(); 561 } else { 562 // video 563 564 int32_t width, height; 565 CHECK(codecRequest->findInt32("width", &width)); 566 CHECK(codecRequest->findInt32("height", &height)); 567 568 int32_t cropLeft, cropTop, cropRight, cropBottom; 569 CHECK(codecRequest->findRect( 570 "crop", 571 &cropLeft, &cropTop, &cropRight, &cropBottom)); 572 573 int32_t displayWidth = cropRight - cropLeft + 1; 574 int32_t displayHeight = cropBottom - cropTop + 1; 575 576 ALOGV("Video output format changed to %d x %d " 577 "(crop: %d x %d @ (%d, %d))", 578 width, height, 579 displayWidth, 580 displayHeight, 581 cropLeft, cropTop); 582 583 sp<AMessage> videoInputFormat = 584 mSource->getFormat(false /* audio */); 585 586 // Take into account sample aspect ratio if necessary: 587 int32_t sarWidth, sarHeight; 588 if (videoInputFormat->findInt32("sar-width", &sarWidth) 589 && videoInputFormat->findInt32( 590 "sar-height", &sarHeight)) { 591 ALOGV("Sample aspect ratio %d : %d", 592 sarWidth, sarHeight); 593 594 displayWidth = (displayWidth * sarWidth) / sarHeight; 595 596 ALOGV("display dimensions %d x %d", 597 displayWidth, displayHeight); 598 } 599 600 notifyListener( 601 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight); 602 } 603 } else if (what == ACodec::kWhatShutdownCompleted) { 604 ALOGV("%s shutdown completed", audio ? "audio" : "video"); 605 if (audio) { 606 mAudioDecoder.clear(); 607 608 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 609 mFlushingAudio = SHUT_DOWN; 610 } else { 611 mVideoDecoder.clear(); 612 613 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 614 mFlushingVideo = SHUT_DOWN; 615 } 616 617 finishFlushIfPossible(); 618 } else if (what == ACodec::kWhatError) { 619 ALOGE("Received error from %s decoder, aborting playback.", 620 audio ? "audio" : "video"); 621 622 mRenderer->queueEOS(audio, UNKNOWN_ERROR); 623 } else if (what == ACodec::kWhatDrainThisBuffer) { 624 renderBuffer(audio, codecRequest); 625 } else if (what != ACodec::kWhatComponentAllocated 626 && what != ACodec::kWhatComponentConfigured 627 && what != ACodec::kWhatBuffersAllocated) { 628 ALOGV("Unhandled codec notification %d '%c%c%c%c'.", 629 what, 630 what >> 24, 631 (what >> 16) & 0xff, 632 (what >> 8) & 0xff, 633 what & 0xff); 634 } 635 636 break; 637 } 638 639 case kWhatRendererNotify: 640 { 641 int32_t what; 642 CHECK(msg->findInt32("what", &what)); 643 644 if (what == Renderer::kWhatEOS) { 645 int32_t audio; 646 CHECK(msg->findInt32("audio", &audio)); 647 648 int32_t finalResult; 649 CHECK(msg->findInt32("finalResult", &finalResult)); 650 651 if (audio) { 652 mAudioEOS = true; 653 } else { 654 mVideoEOS = true; 655 } 656 657 if (finalResult == ERROR_END_OF_STREAM) { 658 ALOGV("reached %s EOS", audio ? "audio" : "video"); 659 } else { 660 ALOGE("%s track encountered an error (%d)", 661 audio ? "audio" : "video", finalResult); 662 663 notifyListener( 664 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 665 } 666 667 if ((mAudioEOS || mAudioDecoder == NULL) 668 && (mVideoEOS || mVideoDecoder == NULL)) { 669 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 670 } 671 } else if (what == Renderer::kWhatPosition) { 672 int64_t positionUs; 673 CHECK(msg->findInt64("positionUs", &positionUs)); 674 675 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs)); 676 677 if (mDriver != NULL) { 678 sp<NuPlayerDriver> driver = mDriver.promote(); 679 if (driver != NULL) { 680 driver->notifyPosition(positionUs); 681 682 driver->notifyFrameStats( 683 mNumFramesTotal, mNumFramesDropped); 684 } 685 } 686 } else if (what == Renderer::kWhatFlushComplete) { 687 int32_t audio; 688 CHECK(msg->findInt32("audio", &audio)); 689 690 ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 691 } else if (what == Renderer::kWhatVideoRenderingStart) { 692 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); 693 } 694 break; 695 } 696 697 case kWhatMoreDataQueued: 698 { 699 break; 700 } 701 702 case kWhatReset: 703 { 704 ALOGV("kWhatReset"); 705 706 mDeferredActions.push_back( 707 new SimpleAction(&NuPlayer::performDecoderShutdown)); 708 709 mDeferredActions.push_back( 710 new SimpleAction(&NuPlayer::performReset)); 711 712 processDeferredActions(); 713 break; 714 } 715 716 case kWhatSeek: 717 { 718 int64_t seekTimeUs; 719 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 720 721 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs); 722 723 mDeferredActions.push_back( 724 new SimpleAction(&NuPlayer::performDecoderFlush)); 725 726 mDeferredActions.push_back(new SeekAction(seekTimeUs)); 727 728 processDeferredActions(); 729 break; 730 } 731 732 case kWhatPause: 733 { 734 CHECK(mRenderer != NULL); 735 mSource->pause(); 736 mRenderer->pause(); 737 break; 738 } 739 740 case kWhatResume: 741 { 742 CHECK(mRenderer != NULL); 743 mSource->resume(); 744 mRenderer->resume(); 745 break; 746 } 747 748 case kWhatSourceNotify: 749 { 750 onSourceNotify(msg); 751 break; 752 } 753 754 default: 755 TRESPASS(); 756 break; 757 } 758} 759 760void NuPlayer::finishFlushIfPossible() { 761 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) { 762 return; 763 } 764 765 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) { 766 return; 767 } 768 769 ALOGV("both audio and video are flushed now."); 770 771 if (mTimeDiscontinuityPending) { 772 mRenderer->signalTimeDiscontinuity(); 773 mTimeDiscontinuityPending = false; 774 } 775 776 if (mAudioDecoder != NULL) { 777 mAudioDecoder->signalResume(); 778 } 779 780 if (mVideoDecoder != NULL) { 781 mVideoDecoder->signalResume(); 782 } 783 784 mFlushingAudio = NONE; 785 mFlushingVideo = NONE; 786 787 processDeferredActions(); 788} 789 790void NuPlayer::postScanSources() { 791 if (mScanSourcesPending) { 792 return; 793 } 794 795 sp<AMessage> msg = new AMessage(kWhatScanSources, id()); 796 msg->setInt32("generation", mScanSourcesGeneration); 797 msg->post(); 798 799 mScanSourcesPending = true; 800} 801 802status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { 803 if (*decoder != NULL) { 804 return OK; 805 } 806 807 sp<AMessage> format = mSource->getFormat(audio); 808 809 if (format == NULL) { 810 return -EWOULDBLOCK; 811 } 812 813 if (!audio) { 814 AString mime; 815 CHECK(format->findString("mime", &mime)); 816 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 817 } 818 819 sp<AMessage> notify = 820 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify, 821 id()); 822 823 *decoder = audio ? new Decoder(notify) : 824 new Decoder(notify, mNativeWindow); 825 looper()->registerHandler(*decoder); 826 827 (*decoder)->configure(format); 828 829 int64_t durationUs; 830 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 831 sp<NuPlayerDriver> driver = mDriver.promote(); 832 if (driver != NULL) { 833 driver->notifyDuration(durationUs); 834 } 835 } 836 837 return OK; 838} 839 840status_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 965void 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 1011void 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 1025void 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 1066sp<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 1081status_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 1095void NuPlayer::schedulePollDuration() { 1096 sp<AMessage> msg = new AMessage(kWhatPollDuration, id()); 1097 msg->setInt32("generation", mPollDurationGeneration); 1098 msg->post(); 1099} 1100 1101void NuPlayer::cancelPollDuration() { 1102 ++mPollDurationGeneration; 1103} 1104 1105void 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 1140void 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 1158void 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 1176void 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 1194void 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 1225void NuPlayer::performScanSources() { 1226 ALOGV("performScanSources"); 1227 1228 if (!mStarted) { 1229 return; 1230 } 1231 1232 if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 1233 postScanSources(); 1234 } 1235} 1236 1237void 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 1253void 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 int32_t err; 1261 CHECK(msg->findInt32("err", &err)); 1262 1263 sp<NuPlayerDriver> driver = mDriver.promote(); 1264 if (driver != NULL) { 1265 driver->notifyPrepareCompleted(err); 1266 } 1267 break; 1268 } 1269 1270 case Source::kWhatFlagsChanged: 1271 { 1272 uint32_t flags; 1273 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1274 1275 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1276 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { 1277 cancelPollDuration(); 1278 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1279 && (flags & Source::FLAG_DYNAMIC_DURATION) 1280 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 1281 schedulePollDuration(); 1282 } 1283 1284 mSourceFlags = flags; 1285 break; 1286 } 1287 1288 case Source::kWhatVideoSizeChanged: 1289 { 1290 int32_t width, height; 1291 CHECK(msg->findInt32("width", &width)); 1292 CHECK(msg->findInt32("height", &height)); 1293 1294 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height); 1295 break; 1296 } 1297 1298 case Source::kWhatBufferingStart: 1299 { 1300 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); 1301 break; 1302 } 1303 1304 case Source::kWhatBufferingEnd: 1305 { 1306 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0); 1307 break; 1308 } 1309 1310 default: 1311 TRESPASS(); 1312 } 1313} 1314 1315//////////////////////////////////////////////////////////////////////////////// 1316 1317void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { 1318 sp<AMessage> notify = dupNotify(); 1319 notify->setInt32("what", kWhatFlagsChanged); 1320 notify->setInt32("flags", flags); 1321 notify->post(); 1322} 1323 1324void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) { 1325 sp<AMessage> notify = dupNotify(); 1326 notify->setInt32("what", kWhatVideoSizeChanged); 1327 notify->setInt32("width", width); 1328 notify->setInt32("height", height); 1329 notify->post(); 1330} 1331 1332void NuPlayer::Source::notifyPrepared(status_t err) { 1333 sp<AMessage> notify = dupNotify(); 1334 notify->setInt32("what", kWhatPrepared); 1335 notify->setInt32("err", err); 1336 notify->post(); 1337} 1338 1339void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) { 1340 TRESPASS(); 1341} 1342 1343} // namespace android 1344