AwesomePlayer.cpp revision fb50c0ba482dddfb030a2cff6874586949dc8ffe
1/* 2 * Copyright (C) 2009 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 DEBUG_HDCP 18 19//#define LOG_NDEBUG 0 20#define LOG_TAG "AwesomePlayer" 21#include <utils/Log.h> 22 23#include <dlfcn.h> 24 25#include "include/ARTSPController.h" 26#include "include/AwesomePlayer.h" 27#include "include/SoftwareRenderer.h" 28#include "include/NuCachedSource2.h" 29#include "include/ThrottledSource.h" 30#include "include/MPEG2TSExtractor.h" 31 32#include <binder/IPCThreadState.h> 33#include <binder/IServiceManager.h> 34#include <media/IMediaPlayerService.h> 35#include <media/stagefright/foundation/hexdump.h> 36#include <media/stagefright/foundation/ADebug.h> 37#include <media/stagefright/AudioPlayer.h> 38#include <media/stagefright/DataSource.h> 39#include <media/stagefright/FileSource.h> 40#include <media/stagefright/MediaBuffer.h> 41#include <media/stagefright/MediaDefs.h> 42#include <media/stagefright/MediaExtractor.h> 43#include <media/stagefright/MediaSource.h> 44#include <media/stagefright/MetaData.h> 45#include <media/stagefright/OMXCodec.h> 46 47#include <surfaceflinger/Surface.h> 48#include <gui/ISurfaceTexture.h> 49#include <gui/SurfaceTextureClient.h> 50#include <surfaceflinger/ISurfaceComposer.h> 51 52#include <media/stagefright/foundation/ALooper.h> 53#include <media/stagefright/foundation/AMessage.h> 54 55#include <cutils/properties.h> 56 57#define USE_SURFACE_ALLOC 1 58 59namespace android { 60 61static int64_t kLowWaterMarkUs = 2000000ll; // 2secs 62static int64_t kHighWaterMarkUs = 10000000ll; // 10secs 63static int64_t kHighWaterMarkRTSPUs = 4000000ll; // 4secs 64static const size_t kLowWaterMarkBytes = 40000; 65static const size_t kHighWaterMarkBytes = 200000; 66 67struct AwesomeEvent : public TimedEventQueue::Event { 68 AwesomeEvent( 69 AwesomePlayer *player, 70 void (AwesomePlayer::*method)()) 71 : mPlayer(player), 72 mMethod(method) { 73 } 74 75protected: 76 virtual ~AwesomeEvent() {} 77 78 virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) { 79 (mPlayer->*mMethod)(); 80 } 81 82private: 83 AwesomePlayer *mPlayer; 84 void (AwesomePlayer::*mMethod)(); 85 86 AwesomeEvent(const AwesomeEvent &); 87 AwesomeEvent &operator=(const AwesomeEvent &); 88}; 89 90struct AwesomeLocalRenderer : public AwesomeRenderer { 91 AwesomeLocalRenderer( 92 const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta) 93 : mTarget(new SoftwareRenderer(nativeWindow, meta)) { 94 } 95 96 virtual void render(MediaBuffer *buffer) { 97 render((const uint8_t *)buffer->data() + buffer->range_offset(), 98 buffer->range_length()); 99 } 100 101 void render(const void *data, size_t size) { 102 mTarget->render(data, size, NULL); 103 } 104 105protected: 106 virtual ~AwesomeLocalRenderer() { 107 delete mTarget; 108 mTarget = NULL; 109 } 110 111private: 112 SoftwareRenderer *mTarget; 113 114 AwesomeLocalRenderer(const AwesomeLocalRenderer &); 115 AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);; 116}; 117 118struct AwesomeNativeWindowRenderer : public AwesomeRenderer { 119 AwesomeNativeWindowRenderer( 120 const sp<ANativeWindow> &nativeWindow, 121 int32_t rotationDegrees) 122 : mNativeWindow(nativeWindow) { 123 applyRotation(rotationDegrees); 124 } 125 126 virtual void render(MediaBuffer *buffer) { 127 status_t err = mNativeWindow->queueBuffer( 128 mNativeWindow.get(), buffer->graphicBuffer().get()); 129 if (err != 0) { 130 LOGE("queueBuffer failed with error %s (%d)", strerror(-err), 131 -err); 132 return; 133 } 134 135 sp<MetaData> metaData = buffer->meta_data(); 136 metaData->setInt32(kKeyRendered, 1); 137 } 138 139protected: 140 virtual ~AwesomeNativeWindowRenderer() {} 141 142private: 143 sp<ANativeWindow> mNativeWindow; 144 145 void applyRotation(int32_t rotationDegrees) { 146 uint32_t transform; 147 switch (rotationDegrees) { 148 case 0: transform = 0; break; 149 case 90: transform = HAL_TRANSFORM_ROT_90; break; 150 case 180: transform = HAL_TRANSFORM_ROT_180; break; 151 case 270: transform = HAL_TRANSFORM_ROT_270; break; 152 default: transform = 0; break; 153 } 154 155 if (transform) { 156 CHECK_EQ(0, native_window_set_buffers_transform( 157 mNativeWindow.get(), transform)); 158 } 159 } 160 161 AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &); 162 AwesomeNativeWindowRenderer &operator=( 163 const AwesomeNativeWindowRenderer &); 164}; 165 166// To collect the decoder usage 167void addBatteryData(uint32_t params) { 168 sp<IBinder> binder = 169 defaultServiceManager()->getService(String16("media.player")); 170 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 171 CHECK(service.get() != NULL); 172 173 service->addBatteryData(params); 174} 175 176//////////////////////////////////////////////////////////////////////////////// 177AwesomePlayer::AwesomePlayer() 178 : mQueueStarted(false), 179 mTimeSource(NULL), 180 mVideoRendererIsPreview(false), 181 mAudioPlayer(NULL), 182 mDisplayWidth(0), 183 mDisplayHeight(0), 184 mFlags(0), 185 mExtractorFlags(0), 186 mVideoBuffer(NULL), 187 mDecryptHandle(NULL) { 188 CHECK_EQ(mClient.connect(), (status_t)OK); 189 190 DataSource::RegisterDefaultSniffers(); 191 192 mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent); 193 mVideoEventPending = false; 194 mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone); 195 mStreamDoneEventPending = false; 196 mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate); 197 mBufferingEventPending = false; 198 mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate); 199 mVideoEventPending = false; 200 201 mCheckAudioStatusEvent = new AwesomeEvent( 202 this, &AwesomePlayer::onCheckAudioStatus); 203 204 mAudioStatusEventPending = false; 205 206 reset(); 207} 208 209AwesomePlayer::~AwesomePlayer() { 210 if (mQueueStarted) { 211 mQueue.stop(); 212 } 213 214 reset(); 215 216 mClient.disconnect(); 217} 218 219void AwesomePlayer::cancelPlayerEvents(bool keepBufferingGoing) { 220 mQueue.cancelEvent(mVideoEvent->eventID()); 221 mVideoEventPending = false; 222 mQueue.cancelEvent(mStreamDoneEvent->eventID()); 223 mStreamDoneEventPending = false; 224 mQueue.cancelEvent(mCheckAudioStatusEvent->eventID()); 225 mAudioStatusEventPending = false; 226 mQueue.cancelEvent(mVideoLagEvent->eventID()); 227 mVideoLagEventPending = false; 228 229 if (!keepBufferingGoing) { 230 mQueue.cancelEvent(mBufferingEvent->eventID()); 231 mBufferingEventPending = false; 232 } 233} 234 235void AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) { 236 Mutex::Autolock autoLock(mLock); 237 mListener = listener; 238} 239 240status_t AwesomePlayer::setDataSource( 241 const char *uri, const KeyedVector<String8, String8> *headers) { 242 Mutex::Autolock autoLock(mLock); 243 return setDataSource_l(uri, headers); 244} 245 246status_t AwesomePlayer::setDataSource_l( 247 const char *uri, const KeyedVector<String8, String8> *headers) { 248 reset_l(); 249 250 mUri = uri; 251 252 if (headers) { 253 mUriHeaders = *headers; 254 255 ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log")); 256 if (index >= 0) { 257 // Browser is in "incognito" mode, suppress logging URLs. 258 259 // This isn't something that should be passed to the server. 260 mUriHeaders.removeItemsAt(index); 261 262 mFlags |= INCOGNITO; 263 } 264 } 265 266 if (!(mFlags & INCOGNITO)) { 267 LOGI("setDataSource_l('%s')", mUri.string()); 268 } else { 269 LOGI("setDataSource_l(URL suppressed)"); 270 } 271 272 // The actual work will be done during preparation in the call to 273 // ::finishSetDataSource_l to avoid blocking the calling thread in 274 // setDataSource for any significant time. 275 276 return OK; 277} 278 279status_t AwesomePlayer::setDataSource( 280 int fd, int64_t offset, int64_t length) { 281 Mutex::Autolock autoLock(mLock); 282 283 reset_l(); 284 285 sp<DataSource> dataSource = new FileSource(fd, offset, length); 286 287 status_t err = dataSource->initCheck(); 288 289 if (err != OK) { 290 return err; 291 } 292 293 mFileSource = dataSource; 294 295 return setDataSource_l(dataSource); 296} 297 298status_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) { 299 return INVALID_OPERATION; 300} 301 302status_t AwesomePlayer::setDataSource_l( 303 const sp<DataSource> &dataSource) { 304 sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 305 306 if (extractor == NULL) { 307 return UNKNOWN_ERROR; 308 } 309 310 dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); 311 if (mDecryptHandle != NULL) { 312 CHECK(mDrmManagerClient); 313 if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { 314 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE); 315 } 316 } 317 318 return setDataSource_l(extractor); 319} 320 321status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) { 322 // Attempt to approximate overall stream bitrate by summing all 323 // tracks' individual bitrates, if not all of them advertise bitrate, 324 // we have to fail. 325 326 int64_t totalBitRate = 0; 327 328 for (size_t i = 0; i < extractor->countTracks(); ++i) { 329 sp<MetaData> meta = extractor->getTrackMetaData(i); 330 331 int32_t bitrate; 332 if (!meta->findInt32(kKeyBitRate, &bitrate)) { 333 totalBitRate = -1; 334 break; 335 } 336 337 totalBitRate += bitrate; 338 } 339 340 mBitrate = totalBitRate; 341 342 LOGV("mBitrate = %lld bits/sec", mBitrate); 343 344 bool haveAudio = false; 345 bool haveVideo = false; 346 for (size_t i = 0; i < extractor->countTracks(); ++i) { 347 sp<MetaData> meta = extractor->getTrackMetaData(i); 348 349 const char *mime; 350 CHECK(meta->findCString(kKeyMIMEType, &mime)); 351 352 if (!haveVideo && !strncasecmp(mime, "video/", 6)) { 353 setVideoSource(extractor->getTrack(i)); 354 haveVideo = true; 355 356 // Set the presentation/display size 357 int32_t displayWidth, displayHeight; 358 bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth); 359 if (success) { 360 success = meta->findInt32(kKeyDisplayHeight, &displayHeight); 361 } 362 if (success) { 363 mDisplayWidth = displayWidth; 364 mDisplayHeight = displayHeight; 365 } 366 367 } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) { 368 setAudioSource(extractor->getTrack(i)); 369 haveAudio = true; 370 371 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 372 // Only do this for vorbis audio, none of the other audio 373 // formats even support this ringtone specific hack and 374 // retrieving the metadata on some extractors may turn out 375 // to be very expensive. 376 sp<MetaData> fileMeta = extractor->getMetaData(); 377 int32_t loop; 378 if (fileMeta != NULL 379 && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) { 380 mFlags |= AUTO_LOOPING; 381 } 382 } 383 } 384 385 if (haveAudio && haveVideo) { 386 break; 387 } 388 } 389 390 if (!haveAudio && !haveVideo) { 391 return UNKNOWN_ERROR; 392 } 393 394 mExtractorFlags = extractor->flags(); 395 396 return OK; 397} 398 399void AwesomePlayer::reset() { 400 Mutex::Autolock autoLock(mLock); 401 reset_l(); 402} 403 404void AwesomePlayer::reset_l() { 405 mDisplayWidth = 0; 406 mDisplayHeight = 0; 407 408 if (mDecryptHandle != NULL) { 409 mDrmManagerClient->setPlaybackStatus(mDecryptHandle, 410 Playback::STOP, 0); 411 mDecryptHandle = NULL; 412 mDrmManagerClient = NULL; 413 } 414 415 if (mFlags & PLAYING) { 416 uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder; 417 if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) { 418 params |= IMediaPlayerService::kBatteryDataTrackAudio; 419 } 420 if (mVideoSource != NULL) { 421 params |= IMediaPlayerService::kBatteryDataTrackVideo; 422 } 423 addBatteryData(params); 424 } 425 426 if (mFlags & PREPARING) { 427 mFlags |= PREPARE_CANCELLED; 428 if (mConnectingDataSource != NULL) { 429 LOGI("interrupting the connection process"); 430 mConnectingDataSource->disconnect(); 431 } else if (mConnectingRTSPController != NULL) { 432 LOGI("interrupting the connection process"); 433 mConnectingRTSPController->disconnect(); 434 } 435 436 if (mFlags & PREPARING_CONNECTED) { 437 // We are basically done preparing, we're just buffering 438 // enough data to start playback, we can safely interrupt that. 439 finishAsyncPrepare_l(); 440 } 441 } 442 443 while (mFlags & PREPARING) { 444 mPreparedCondition.wait(mLock); 445 } 446 447 cancelPlayerEvents(); 448 449 mCachedSource.clear(); 450 mAudioTrack.clear(); 451 mVideoTrack.clear(); 452 453 // Shutdown audio first, so that the respone to the reset request 454 // appears to happen instantaneously as far as the user is concerned 455 // If we did this later, audio would continue playing while we 456 // shutdown the video-related resources and the player appear to 457 // not be as responsive to a reset request. 458 if (mAudioPlayer == NULL && mAudioSource != NULL) { 459 // If we had an audio player, it would have effectively 460 // taken possession of the audio source and stopped it when 461 // _it_ is stopped. Otherwise this is still our responsibility. 462 mAudioSource->stop(); 463 } 464 mAudioSource.clear(); 465 466 mTimeSource = NULL; 467 468 delete mAudioPlayer; 469 mAudioPlayer = NULL; 470 471 mVideoRenderer.clear(); 472 473 if (mVideoBuffer) { 474 mVideoBuffer->release(); 475 mVideoBuffer = NULL; 476 } 477 478 if (mRTSPController != NULL) { 479 mRTSPController->disconnect(); 480 mRTSPController.clear(); 481 } 482 483 if (mVideoSource != NULL) { 484 mVideoSource->stop(); 485 486 // The following hack is necessary to ensure that the OMX 487 // component is completely released by the time we may try 488 // to instantiate it again. 489 wp<MediaSource> tmp = mVideoSource; 490 mVideoSource.clear(); 491 while (tmp.promote() != NULL) { 492 usleep(1000); 493 } 494 IPCThreadState::self()->flushCommands(); 495 } 496 497 mDurationUs = -1; 498 mFlags = 0; 499 mExtractorFlags = 0; 500 mTimeSourceDeltaUs = 0; 501 mVideoTimeUs = 0; 502 503 mSeeking = NO_SEEK; 504 mSeekNotificationSent = false; 505 mSeekTimeUs = 0; 506 507 mUri.setTo(""); 508 mUriHeaders.clear(); 509 510 mFileSource.clear(); 511 512 mBitrate = -1; 513} 514 515void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) { 516 if (mListener != NULL) { 517 sp<MediaPlayerBase> listener = mListener.promote(); 518 519 if (listener != NULL) { 520 listener->sendEvent(msg, ext1, ext2); 521 } 522 } 523} 524 525bool AwesomePlayer::getBitrate(int64_t *bitrate) { 526 off64_t size; 527 if (mDurationUs >= 0 && mCachedSource != NULL 528 && mCachedSource->getSize(&size) == OK) { 529 *bitrate = size * 8000000ll / mDurationUs; // in bits/sec 530 return true; 531 } 532 533 if (mBitrate >= 0) { 534 *bitrate = mBitrate; 535 return true; 536 } 537 538 *bitrate = 0; 539 540 return false; 541} 542 543// Returns true iff cached duration is available/applicable. 544bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) { 545 int64_t bitrate; 546 547 if (mRTSPController != NULL) { 548 *durationUs = mRTSPController->getQueueDurationUs(eos); 549 return true; 550 } else if (mCachedSource != NULL && getBitrate(&bitrate)) { 551 status_t finalStatus; 552 size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus); 553 *durationUs = cachedDataRemaining * 8000000ll / bitrate; 554 *eos = (finalStatus != OK); 555 return true; 556 } 557 558 return false; 559} 560 561void AwesomePlayer::ensureCacheIsFetching_l() { 562 if (mCachedSource != NULL) { 563 mCachedSource->resumeFetchingIfNecessary(); 564 } 565} 566 567void AwesomePlayer::onVideoLagUpdate() { 568 Mutex::Autolock autoLock(mLock); 569 if (!mVideoLagEventPending) { 570 return; 571 } 572 mVideoLagEventPending = false; 573 574 int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs(); 575 int64_t videoLateByUs = audioTimeUs - mVideoTimeUs; 576 577 if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) { 578 LOGV("video late by %lld ms.", videoLateByUs / 1000ll); 579 580 notifyListener_l( 581 MEDIA_INFO, 582 MEDIA_INFO_VIDEO_TRACK_LAGGING, 583 videoLateByUs / 1000ll); 584 } 585 586 postVideoLagEvent_l(); 587} 588 589void AwesomePlayer::onBufferingUpdate() { 590 Mutex::Autolock autoLock(mLock); 591 if (!mBufferingEventPending) { 592 return; 593 } 594 mBufferingEventPending = false; 595 596 if (mCachedSource != NULL) { 597 status_t finalStatus; 598 size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus); 599 bool eos = (finalStatus != OK); 600 601 if (eos) { 602 if (finalStatus == ERROR_END_OF_STREAM) { 603 notifyListener_l(MEDIA_BUFFERING_UPDATE, 100); 604 } 605 if (mFlags & PREPARING) { 606 LOGV("cache has reached EOS, prepare is done."); 607 finishAsyncPrepare_l(); 608 } 609 } else { 610 int64_t bitrate; 611 if (getBitrate(&bitrate)) { 612 size_t cachedSize = mCachedSource->cachedSize(); 613 int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate; 614 615 int percentage = 100.0 * (double)cachedDurationUs / mDurationUs; 616 if (percentage > 100) { 617 percentage = 100; 618 } 619 620 notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage); 621 } else { 622 // We don't know the bitrate of the stream, use absolute size 623 // limits to maintain the cache. 624 625 if ((mFlags & PLAYING) && !eos 626 && (cachedDataRemaining < kLowWaterMarkBytes)) { 627 LOGI("cache is running low (< %d) , pausing.", 628 kLowWaterMarkBytes); 629 mFlags |= CACHE_UNDERRUN; 630 pause_l(); 631 ensureCacheIsFetching_l(); 632 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START); 633 } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) { 634 if (mFlags & CACHE_UNDERRUN) { 635 LOGI("cache has filled up (> %d), resuming.", 636 kHighWaterMarkBytes); 637 mFlags &= ~CACHE_UNDERRUN; 638 play_l(); 639 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END); 640 } else if (mFlags & PREPARING) { 641 LOGV("cache has filled up (> %d), prepare is done", 642 kHighWaterMarkBytes); 643 finishAsyncPrepare_l(); 644 } 645 } 646 } 647 } 648 } 649 650 int64_t cachedDurationUs; 651 bool eos; 652 if (getCachedDuration_l(&cachedDurationUs, &eos)) { 653 LOGV("cachedDurationUs = %.2f secs, eos=%d", 654 cachedDurationUs / 1E6, eos); 655 656 int64_t highWaterMarkUs = 657 (mRTSPController != NULL) ? kHighWaterMarkRTSPUs : kHighWaterMarkUs; 658 659 if ((mFlags & PLAYING) && !eos 660 && (cachedDurationUs < kLowWaterMarkUs)) { 661 LOGI("cache is running low (%.2f secs) , pausing.", 662 cachedDurationUs / 1E6); 663 mFlags |= CACHE_UNDERRUN; 664 pause_l(); 665 ensureCacheIsFetching_l(); 666 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START); 667 } else if (eos || cachedDurationUs > highWaterMarkUs) { 668 if (mFlags & CACHE_UNDERRUN) { 669 LOGI("cache has filled up (%.2f secs), resuming.", 670 cachedDurationUs / 1E6); 671 mFlags &= ~CACHE_UNDERRUN; 672 play_l(); 673 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END); 674 } else if (mFlags & PREPARING) { 675 LOGV("cache has filled up (%.2f secs), prepare is done", 676 cachedDurationUs / 1E6); 677 finishAsyncPrepare_l(); 678 } 679 } 680 } 681 682 postBufferingEvent_l(); 683} 684 685void AwesomePlayer::onStreamDone() { 686 // Posted whenever any stream finishes playing. 687 688 Mutex::Autolock autoLock(mLock); 689 if (!mStreamDoneEventPending) { 690 return; 691 } 692 mStreamDoneEventPending = false; 693 694 if (mStreamDoneStatus != ERROR_END_OF_STREAM) { 695 LOGV("MEDIA_ERROR %d", mStreamDoneStatus); 696 697 notifyListener_l( 698 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus); 699 700 pause_l(true /* at eos */); 701 702 mFlags |= AT_EOS; 703 return; 704 } 705 706 const bool allDone = 707 (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS)) 708 && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS)); 709 710 if (!allDone) { 711 return; 712 } 713 714 if (mFlags & (LOOPING | AUTO_LOOPING)) { 715 seekTo_l(0); 716 717 if (mVideoSource != NULL) { 718 postVideoEvent_l(); 719 } 720 } else { 721 LOGV("MEDIA_PLAYBACK_COMPLETE"); 722 notifyListener_l(MEDIA_PLAYBACK_COMPLETE); 723 724 pause_l(true /* at eos */); 725 726 mFlags |= AT_EOS; 727 } 728} 729 730status_t AwesomePlayer::play() { 731 Mutex::Autolock autoLock(mLock); 732 733 mFlags &= ~CACHE_UNDERRUN; 734 735 return play_l(); 736} 737 738status_t AwesomePlayer::play_l() { 739 mFlags &= ~SEEK_PREVIEW; 740 741 if (mFlags & PLAYING) { 742 return OK; 743 } 744 745 if (!(mFlags & PREPARED)) { 746 status_t err = prepare_l(); 747 748 if (err != OK) { 749 return err; 750 } 751 } 752 753 mFlags |= PLAYING; 754 mFlags |= FIRST_FRAME; 755 756 if (mDecryptHandle != NULL) { 757 int64_t position; 758 getPosition(&position); 759 mDrmManagerClient->setPlaybackStatus(mDecryptHandle, 760 Playback::START, position / 1000); 761 } 762 763 if (mAudioSource != NULL) { 764 if (mAudioPlayer == NULL) { 765 if (mAudioSink != NULL) { 766 mAudioPlayer = new AudioPlayer(mAudioSink, this); 767 mAudioPlayer->setSource(mAudioSource); 768 769 mTimeSource = mAudioPlayer; 770 771 // If there was a seek request before we ever started, 772 // honor the request now. 773 // Make sure to do this before starting the audio player 774 // to avoid a race condition. 775 seekAudioIfNecessary_l(); 776 } 777 } 778 779 CHECK(!(mFlags & AUDIO_RUNNING)); 780 781 if (mVideoSource == NULL) { 782 status_t err = startAudioPlayer_l(); 783 784 if (err != OK) { 785 delete mAudioPlayer; 786 mAudioPlayer = NULL; 787 788 mFlags &= ~(PLAYING | FIRST_FRAME); 789 790 if (mDecryptHandle != NULL) { 791 mDrmManagerClient->setPlaybackStatus( 792 mDecryptHandle, Playback::STOP, 0); 793 } 794 795 return err; 796 } 797 } 798 } 799 800 if (mTimeSource == NULL && mAudioPlayer == NULL) { 801 mTimeSource = &mSystemTimeSource; 802 } 803 804 if (mVideoSource != NULL) { 805 // Kick off video playback 806 postVideoEvent_l(); 807 808 if (mAudioSource != NULL && mVideoSource != NULL) { 809 postVideoLagEvent_l(); 810 } 811 } 812 813 if (mFlags & AT_EOS) { 814 // Legacy behaviour, if a stream finishes playing and then 815 // is started again, we play from the start... 816 seekTo_l(0); 817 } 818 819 uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted 820 | IMediaPlayerService::kBatteryDataTrackDecoder; 821 if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) { 822 params |= IMediaPlayerService::kBatteryDataTrackAudio; 823 } 824 if (mVideoSource != NULL) { 825 params |= IMediaPlayerService::kBatteryDataTrackVideo; 826 } 827 addBatteryData(params); 828 829 return OK; 830} 831 832status_t AwesomePlayer::startAudioPlayer_l() { 833 CHECK(!(mFlags & AUDIO_RUNNING)); 834 835 if (mAudioSource == NULL || mAudioPlayer == NULL) { 836 return OK; 837 } 838 839 if (!(mFlags & AUDIOPLAYER_STARTED)) { 840 mFlags |= AUDIOPLAYER_STARTED; 841 842 // We've already started the MediaSource in order to enable 843 // the prefetcher to read its data. 844 status_t err = mAudioPlayer->start( 845 true /* sourceAlreadyStarted */); 846 847 if (err != OK) { 848 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 849 return err; 850 } 851 } else { 852 mAudioPlayer->resume(); 853 } 854 855 mFlags |= AUDIO_RUNNING; 856 857 mWatchForAudioEOS = true; 858 859 return OK; 860} 861 862void AwesomePlayer::notifyVideoSize_l() { 863 sp<MetaData> meta = mVideoSource->getFormat(); 864 865 int32_t cropLeft, cropTop, cropRight, cropBottom; 866 if (!meta->findRect( 867 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) { 868 int32_t width, height; 869 CHECK(meta->findInt32(kKeyWidth, &width)); 870 CHECK(meta->findInt32(kKeyHeight, &height)); 871 872 cropLeft = cropTop = 0; 873 cropRight = width - 1; 874 cropBottom = height - 1; 875 876 LOGV("got dimensions only %d x %d", width, height); 877 } else { 878 LOGV("got crop rect %d, %d, %d, %d", 879 cropLeft, cropTop, cropRight, cropBottom); 880 } 881 882 int32_t displayWidth; 883 if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) { 884 LOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth); 885 mDisplayWidth = displayWidth; 886 } 887 int32_t displayHeight; 888 if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) { 889 LOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight); 890 mDisplayHeight = displayHeight; 891 } 892 893 int32_t usableWidth = cropRight - cropLeft + 1; 894 int32_t usableHeight = cropBottom - cropTop + 1; 895 if (mDisplayWidth != 0) { 896 usableWidth = mDisplayWidth; 897 } 898 if (mDisplayHeight != 0) { 899 usableHeight = mDisplayHeight; 900 } 901 902 int32_t rotationDegrees; 903 if (!mVideoTrack->getFormat()->findInt32( 904 kKeyRotation, &rotationDegrees)) { 905 rotationDegrees = 0; 906 } 907 908 if (rotationDegrees == 90 || rotationDegrees == 270) { 909 notifyListener_l( 910 MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth); 911 } else { 912 notifyListener_l( 913 MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight); 914 } 915} 916 917void AwesomePlayer::initRenderer_l() { 918 if (mNativeWindow == NULL) { 919 return; 920 } 921 922 sp<MetaData> meta = mVideoSource->getFormat(); 923 924 int32_t format; 925 const char *component; 926 int32_t decodedWidth, decodedHeight; 927 CHECK(meta->findInt32(kKeyColorFormat, &format)); 928 CHECK(meta->findCString(kKeyDecoderComponent, &component)); 929 CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); 930 CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); 931 932 int32_t rotationDegrees; 933 if (!mVideoTrack->getFormat()->findInt32( 934 kKeyRotation, &rotationDegrees)) { 935 rotationDegrees = 0; 936 } 937 938 mVideoRenderer.clear(); 939 940 // Must ensure that mVideoRenderer's destructor is actually executed 941 // before creating a new one. 942 IPCThreadState::self()->flushCommands(); 943 944 if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) { 945 // Hardware decoders avoid the CPU color conversion by decoding 946 // directly to ANativeBuffers, so we must use a renderer that 947 // just pushes those buffers to the ANativeWindow. 948 mVideoRenderer = 949 new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees); 950 } else { 951 // Other decoders are instantiated locally and as a consequence 952 // allocate their buffers in local address space. This renderer 953 // then performs a color conversion and copy to get the data 954 // into the ANativeBuffer. 955 mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta); 956 } 957} 958 959status_t AwesomePlayer::pause() { 960 Mutex::Autolock autoLock(mLock); 961 962 mFlags &= ~CACHE_UNDERRUN; 963 964 return pause_l(); 965} 966 967status_t AwesomePlayer::pause_l(bool at_eos) { 968 if (!(mFlags & PLAYING)) { 969 return OK; 970 } 971 972 cancelPlayerEvents(true /* keepBufferingGoing */); 973 974 if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) { 975 if (at_eos) { 976 // If we played the audio stream to completion we 977 // want to make sure that all samples remaining in the audio 978 // track's queue are played out. 979 mAudioPlayer->pause(true /* playPendingSamples */); 980 } else { 981 mAudioPlayer->pause(); 982 } 983 984 mFlags &= ~AUDIO_RUNNING; 985 } 986 987 mFlags &= ~PLAYING; 988 989 if (mDecryptHandle != NULL) { 990 mDrmManagerClient->setPlaybackStatus(mDecryptHandle, 991 Playback::PAUSE, 0); 992 } 993 994 uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder; 995 if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) { 996 params |= IMediaPlayerService::kBatteryDataTrackAudio; 997 } 998 if (mVideoSource != NULL) { 999 params |= IMediaPlayerService::kBatteryDataTrackVideo; 1000 } 1001 1002 addBatteryData(params); 1003 1004 return OK; 1005} 1006 1007bool AwesomePlayer::isPlaying() const { 1008 return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN); 1009} 1010 1011void AwesomePlayer::setSurface(const sp<Surface> &surface) { 1012 Mutex::Autolock autoLock(mLock); 1013 1014 mSurface = surface; 1015 mNativeWindow = surface; 1016} 1017 1018void AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) { 1019 Mutex::Autolock autoLock(mLock); 1020 1021 mSurface.clear(); 1022 if (surfaceTexture != NULL) { 1023 mNativeWindow = new SurfaceTextureClient(surfaceTexture); 1024 } 1025 1026} 1027 1028void AwesomePlayer::setAudioSink( 1029 const sp<MediaPlayerBase::AudioSink> &audioSink) { 1030 Mutex::Autolock autoLock(mLock); 1031 1032 mAudioSink = audioSink; 1033} 1034 1035status_t AwesomePlayer::setLooping(bool shouldLoop) { 1036 Mutex::Autolock autoLock(mLock); 1037 1038 mFlags = mFlags & ~LOOPING; 1039 1040 if (shouldLoop) { 1041 mFlags |= LOOPING; 1042 } 1043 1044 return OK; 1045} 1046 1047status_t AwesomePlayer::getDuration(int64_t *durationUs) { 1048 Mutex::Autolock autoLock(mMiscStateLock); 1049 1050 if (mDurationUs < 0) { 1051 return UNKNOWN_ERROR; 1052 } 1053 1054 *durationUs = mDurationUs; 1055 1056 return OK; 1057} 1058 1059status_t AwesomePlayer::getPosition(int64_t *positionUs) { 1060 if (mRTSPController != NULL) { 1061 *positionUs = mRTSPController->getNormalPlayTimeUs(); 1062 } 1063 else if (mSeeking != NO_SEEK) { 1064 *positionUs = mSeekTimeUs; 1065 } else if (mVideoSource != NULL 1066 && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) { 1067 Mutex::Autolock autoLock(mMiscStateLock); 1068 *positionUs = mVideoTimeUs; 1069 } else if (mAudioPlayer != NULL) { 1070 *positionUs = mAudioPlayer->getMediaTimeUs(); 1071 } else { 1072 *positionUs = 0; 1073 } 1074 1075 return OK; 1076} 1077 1078status_t AwesomePlayer::seekTo(int64_t timeUs) { 1079 if (mExtractorFlags & MediaExtractor::CAN_SEEK) { 1080 Mutex::Autolock autoLock(mLock); 1081 return seekTo_l(timeUs); 1082 } 1083 1084 return OK; 1085} 1086 1087// static 1088void AwesomePlayer::OnRTSPSeekDoneWrapper(void *cookie) { 1089 static_cast<AwesomePlayer *>(cookie)->onRTSPSeekDone(); 1090} 1091 1092void AwesomePlayer::onRTSPSeekDone() { 1093 notifyListener_l(MEDIA_SEEK_COMPLETE); 1094 mSeekNotificationSent = true; 1095} 1096 1097status_t AwesomePlayer::seekTo_l(int64_t timeUs) { 1098 if (mRTSPController != NULL) { 1099 mRTSPController->seekAsync(timeUs, OnRTSPSeekDoneWrapper, this); 1100 return OK; 1101 } 1102 1103 if (mFlags & CACHE_UNDERRUN) { 1104 mFlags &= ~CACHE_UNDERRUN; 1105 play_l(); 1106 } 1107 1108 if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) { 1109 // Video playback completed before, there's no pending 1110 // video event right now. In order for this new seek 1111 // to be honored, we need to post one. 1112 1113 postVideoEvent_l(); 1114 } 1115 1116 mSeeking = SEEK; 1117 mSeekNotificationSent = false; 1118 mSeekTimeUs = timeUs; 1119 mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS); 1120 1121 seekAudioIfNecessary_l(); 1122 1123 if (!(mFlags & PLAYING)) { 1124 LOGV("seeking while paused, sending SEEK_COMPLETE notification" 1125 " immediately."); 1126 1127 notifyListener_l(MEDIA_SEEK_COMPLETE); 1128 mSeekNotificationSent = true; 1129 1130 if ((mFlags & PREPARED) && mVideoSource != NULL) { 1131 mFlags |= SEEK_PREVIEW; 1132 postVideoEvent_l(); 1133 } 1134 } 1135 1136 return OK; 1137} 1138 1139void AwesomePlayer::seekAudioIfNecessary_l() { 1140 if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) { 1141 mAudioPlayer->seekTo(mSeekTimeUs); 1142 1143 mWatchForAudioSeekComplete = true; 1144 mWatchForAudioEOS = true; 1145 1146 if (mDecryptHandle != NULL) { 1147 mDrmManagerClient->setPlaybackStatus(mDecryptHandle, 1148 Playback::PAUSE, 0); 1149 mDrmManagerClient->setPlaybackStatus(mDecryptHandle, 1150 Playback::START, mSeekTimeUs / 1000); 1151 } 1152 } 1153} 1154 1155void AwesomePlayer::setAudioSource(sp<MediaSource> source) { 1156 CHECK(source != NULL); 1157 1158 mAudioTrack = source; 1159} 1160 1161status_t AwesomePlayer::initAudioDecoder() { 1162 sp<MetaData> meta = mAudioTrack->getFormat(); 1163 1164 const char *mime; 1165 CHECK(meta->findCString(kKeyMIMEType, &mime)); 1166 1167 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 1168 mAudioSource = mAudioTrack; 1169 } else { 1170 mAudioSource = OMXCodec::Create( 1171 mClient.interface(), mAudioTrack->getFormat(), 1172 false, // createEncoder 1173 mAudioTrack); 1174 } 1175 1176 if (mAudioSource != NULL) { 1177 int64_t durationUs; 1178 if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) { 1179 Mutex::Autolock autoLock(mMiscStateLock); 1180 if (mDurationUs < 0 || durationUs > mDurationUs) { 1181 mDurationUs = durationUs; 1182 } 1183 } 1184 1185 status_t err = mAudioSource->start(); 1186 1187 if (err != OK) { 1188 mAudioSource.clear(); 1189 return err; 1190 } 1191 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) { 1192 // For legacy reasons we're simply going to ignore the absence 1193 // of an audio decoder for QCELP instead of aborting playback 1194 // altogether. 1195 return OK; 1196 } 1197 1198 return mAudioSource != NULL ? OK : UNKNOWN_ERROR; 1199} 1200 1201void AwesomePlayer::setVideoSource(sp<MediaSource> source) { 1202 CHECK(source != NULL); 1203 1204 mVideoTrack = source; 1205} 1206 1207status_t AwesomePlayer::initVideoDecoder(uint32_t flags) { 1208 1209 // Either the application or the DRM system can independently say 1210 // that there must be a hardware-protected path to an external video sink. 1211 // For now we always require a hardware-protected path to external video sink 1212 // if content is DRMed, but eventually this could be optional per DRM agent. 1213 // When the application wants protection, then 1214 // (USE_SURFACE_ALLOC && (mSurface != 0) && 1215 // (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp)) 1216 // will be true, but that part is already handled by SurfaceFlinger. 1217 1218#ifdef DEBUG_HDCP 1219 // For debugging, we allow a system property to control the protected usage. 1220 // In case of uninitialized or unexpected property, we default to "DRM only". 1221 bool setProtectionBit = false; 1222 char value[PROPERTY_VALUE_MAX]; 1223 if (property_get("persist.sys.hdcp_checking", value, NULL)) { 1224 if (!strcmp(value, "never")) { 1225 // nop 1226 } else if (!strcmp(value, "always")) { 1227 setProtectionBit = true; 1228 } else if (!strcmp(value, "drm-only")) { 1229 if (mDecryptHandle != NULL) { 1230 setProtectionBit = true; 1231 } 1232 // property value is empty, or unexpected value 1233 } else { 1234 if (mDecryptHandle != NULL) { 1235 setProtectionBit = true; 1236 } 1237 } 1238 // can' read property value 1239 } else { 1240 if (mDecryptHandle != NULL) { 1241 setProtectionBit = true; 1242 } 1243 } 1244 // note that usage bit is already cleared, so no need to clear it in the "else" case 1245 if (setProtectionBit) { 1246 flags |= OMXCodec::kEnableGrallocUsageProtected; 1247 } 1248#else 1249 if (mDecryptHandle != NULL) { 1250 flags |= OMXCodec::kEnableGrallocUsageProtected; 1251 } 1252#endif 1253 LOGV("initVideoDecoder flags=0x%x", flags); 1254 mVideoSource = OMXCodec::Create( 1255 mClient.interface(), mVideoTrack->getFormat(), 1256 false, // createEncoder 1257 mVideoTrack, 1258 NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL); 1259 1260 if (mVideoSource != NULL) { 1261 int64_t durationUs; 1262 if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) { 1263 Mutex::Autolock autoLock(mMiscStateLock); 1264 if (mDurationUs < 0 || durationUs > mDurationUs) { 1265 mDurationUs = durationUs; 1266 } 1267 } 1268 1269 status_t err = mVideoSource->start(); 1270 1271 if (err != OK) { 1272 mVideoSource.clear(); 1273 return err; 1274 } 1275 } 1276 1277 return mVideoSource != NULL ? OK : UNKNOWN_ERROR; 1278} 1279 1280void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) { 1281 if (mSeeking == SEEK_VIDEO_ONLY) { 1282 mSeeking = NO_SEEK; 1283 return; 1284 } 1285 1286 if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) { 1287 return; 1288 } 1289 1290 if (mAudioPlayer != NULL) { 1291 LOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6); 1292 1293 // If we don't have a video time, seek audio to the originally 1294 // requested seek time instead. 1295 1296 mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs); 1297 mWatchForAudioSeekComplete = true; 1298 mWatchForAudioEOS = true; 1299 } else if (!mSeekNotificationSent) { 1300 // If we're playing video only, report seek complete now, 1301 // otherwise audio player will notify us later. 1302 notifyListener_l(MEDIA_SEEK_COMPLETE); 1303 mSeekNotificationSent = true; 1304 } 1305 1306 mFlags |= FIRST_FRAME; 1307 mSeeking = NO_SEEK; 1308 1309 if (mDecryptHandle != NULL) { 1310 mDrmManagerClient->setPlaybackStatus(mDecryptHandle, 1311 Playback::PAUSE, 0); 1312 mDrmManagerClient->setPlaybackStatus(mDecryptHandle, 1313 Playback::START, videoTimeUs / 1000); 1314 } 1315} 1316 1317void AwesomePlayer::onVideoEvent() { 1318 Mutex::Autolock autoLock(mLock); 1319 if (!mVideoEventPending) { 1320 // The event has been cancelled in reset_l() but had already 1321 // been scheduled for execution at that time. 1322 return; 1323 } 1324 mVideoEventPending = false; 1325 1326 if (mSeeking != NO_SEEK) { 1327 if (mVideoBuffer) { 1328 mVideoBuffer->release(); 1329 mVideoBuffer = NULL; 1330 } 1331 1332 if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL 1333 && !(mFlags & SEEK_PREVIEW)) { 1334 // We're going to seek the video source first, followed by 1335 // the audio source. 1336 // In order to avoid jumps in the DataSource offset caused by 1337 // the audio codec prefetching data from the old locations 1338 // while the video codec is already reading data from the new 1339 // locations, we'll "pause" the audio source, causing it to 1340 // stop reading input data until a subsequent seek. 1341 1342 if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) { 1343 mAudioPlayer->pause(); 1344 1345 mFlags &= ~AUDIO_RUNNING; 1346 } 1347 mAudioSource->pause(); 1348 } 1349 } 1350 1351 if (!mVideoBuffer) { 1352 MediaSource::ReadOptions options; 1353 if (mSeeking != NO_SEEK) { 1354 LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6); 1355 1356 options.setSeekTo( 1357 mSeekTimeUs, 1358 mSeeking == SEEK_VIDEO_ONLY 1359 ? MediaSource::ReadOptions::SEEK_NEXT_SYNC 1360 : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC); 1361 } 1362 for (;;) { 1363 status_t err = mVideoSource->read(&mVideoBuffer, &options); 1364 options.clearSeekTo(); 1365 1366 if (err != OK) { 1367 CHECK(mVideoBuffer == NULL); 1368 1369 if (err == INFO_FORMAT_CHANGED) { 1370 LOGV("VideoSource signalled format change."); 1371 1372 notifyVideoSize_l(); 1373 1374 if (mVideoRenderer != NULL) { 1375 mVideoRendererIsPreview = false; 1376 initRenderer_l(); 1377 } 1378 continue; 1379 } 1380 1381 // So video playback is complete, but we may still have 1382 // a seek request pending that needs to be applied 1383 // to the audio track. 1384 if (mSeeking != NO_SEEK) { 1385 LOGV("video stream ended while seeking!"); 1386 } 1387 finishSeekIfNecessary(-1); 1388 1389 if (mAudioPlayer != NULL 1390 && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) { 1391 startAudioPlayer_l(); 1392 } 1393 1394 mFlags |= VIDEO_AT_EOS; 1395 postStreamDoneEvent_l(err); 1396 return; 1397 } 1398 1399 if (mVideoBuffer->range_length() == 0) { 1400 // Some decoders, notably the PV AVC software decoder 1401 // return spurious empty buffers that we just want to ignore. 1402 1403 mVideoBuffer->release(); 1404 mVideoBuffer = NULL; 1405 continue; 1406 } 1407 1408 break; 1409 } 1410 } 1411 1412 int64_t timeUs; 1413 CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 1414 1415 if (mSeeking == SEEK_VIDEO_ONLY) { 1416 if (mSeekTimeUs > timeUs) { 1417 LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us", 1418 mSeekTimeUs, timeUs); 1419 } 1420 } 1421 1422 { 1423 Mutex::Autolock autoLock(mMiscStateLock); 1424 mVideoTimeUs = timeUs; 1425 } 1426 1427 SeekType wasSeeking = mSeeking; 1428 finishSeekIfNecessary(timeUs); 1429 1430 if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) { 1431 status_t err = startAudioPlayer_l(); 1432 if (err != OK) { 1433 LOGE("Startung the audio player failed w/ err %d", err); 1434 return; 1435 } 1436 } 1437 1438 TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource; 1439 1440 if (mFlags & FIRST_FRAME) { 1441 mFlags &= ~FIRST_FRAME; 1442 mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs; 1443 } 1444 1445 int64_t realTimeUs, mediaTimeUs; 1446 if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL 1447 && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) { 1448 mTimeSourceDeltaUs = realTimeUs - mediaTimeUs; 1449 } 1450 1451 if (wasSeeking == SEEK_VIDEO_ONLY) { 1452 int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs; 1453 1454 int64_t latenessUs = nowUs - timeUs; 1455 1456 if (latenessUs > 0) { 1457 LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6); 1458 } 1459 } 1460 1461 if (wasSeeking == NO_SEEK) { 1462 // Let's display the first frame after seeking right away. 1463 1464 int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs; 1465 1466 int64_t latenessUs = nowUs - timeUs; 1467 1468 if (latenessUs > 500000ll 1469 && mRTSPController == NULL 1470 && mAudioPlayer != NULL 1471 && mAudioPlayer->getMediaTimeMapping( 1472 &realTimeUs, &mediaTimeUs)) { 1473 LOGI("we're much too late (%.2f secs), video skipping ahead", 1474 latenessUs / 1E6); 1475 1476 mVideoBuffer->release(); 1477 mVideoBuffer = NULL; 1478 1479 mSeeking = SEEK_VIDEO_ONLY; 1480 mSeekTimeUs = mediaTimeUs; 1481 1482 postVideoEvent_l(); 1483 return; 1484 } 1485 1486 if (latenessUs > 40000) { 1487 // We're more than 40ms late. 1488 LOGV("we're late by %lld us (%.2f secs), dropping frame", 1489 latenessUs, latenessUs / 1E6); 1490 mVideoBuffer->release(); 1491 mVideoBuffer = NULL; 1492 1493 postVideoEvent_l(); 1494 return; 1495 } 1496 1497 if (latenessUs < -10000) { 1498 // We're more than 10ms early. 1499 1500 postVideoEvent_l(10000); 1501 return; 1502 } 1503 } 1504 1505 if (mVideoRendererIsPreview || mVideoRenderer == NULL) { 1506 mVideoRendererIsPreview = false; 1507 1508 initRenderer_l(); 1509 } 1510 1511 if (mVideoRenderer != NULL) { 1512 mVideoRenderer->render(mVideoBuffer); 1513 } 1514 1515 mVideoBuffer->release(); 1516 mVideoBuffer = NULL; 1517 1518 if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) { 1519 mFlags &= ~SEEK_PREVIEW; 1520 return; 1521 } 1522 1523 postVideoEvent_l(); 1524} 1525 1526void AwesomePlayer::postVideoEvent_l(int64_t delayUs) { 1527 if (mVideoEventPending) { 1528 return; 1529 } 1530 1531 mVideoEventPending = true; 1532 mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs); 1533} 1534 1535void AwesomePlayer::postStreamDoneEvent_l(status_t status) { 1536 if (mStreamDoneEventPending) { 1537 return; 1538 } 1539 mStreamDoneEventPending = true; 1540 1541 mStreamDoneStatus = status; 1542 mQueue.postEvent(mStreamDoneEvent); 1543} 1544 1545void AwesomePlayer::postBufferingEvent_l() { 1546 if (mBufferingEventPending) { 1547 return; 1548 } 1549 mBufferingEventPending = true; 1550 mQueue.postEventWithDelay(mBufferingEvent, 1000000ll); 1551} 1552 1553void AwesomePlayer::postVideoLagEvent_l() { 1554 if (mVideoLagEventPending) { 1555 return; 1556 } 1557 mVideoLagEventPending = true; 1558 mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll); 1559} 1560 1561void AwesomePlayer::postCheckAudioStatusEvent_l(int64_t delayUs) { 1562 if (mAudioStatusEventPending) { 1563 return; 1564 } 1565 mAudioStatusEventPending = true; 1566 mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs); 1567} 1568 1569void AwesomePlayer::onCheckAudioStatus() { 1570 Mutex::Autolock autoLock(mLock); 1571 if (!mAudioStatusEventPending) { 1572 // Event was dispatched and while we were blocking on the mutex, 1573 // has already been cancelled. 1574 return; 1575 } 1576 1577 mAudioStatusEventPending = false; 1578 1579 if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) { 1580 mWatchForAudioSeekComplete = false; 1581 1582 if (!mSeekNotificationSent) { 1583 notifyListener_l(MEDIA_SEEK_COMPLETE); 1584 mSeekNotificationSent = true; 1585 } 1586 1587 mSeeking = NO_SEEK; 1588 } 1589 1590 status_t finalStatus; 1591 if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) { 1592 mWatchForAudioEOS = false; 1593 mFlags |= AUDIO_AT_EOS; 1594 mFlags |= FIRST_FRAME; 1595 postStreamDoneEvent_l(finalStatus); 1596 } 1597} 1598 1599status_t AwesomePlayer::prepare() { 1600 Mutex::Autolock autoLock(mLock); 1601 return prepare_l(); 1602} 1603 1604status_t AwesomePlayer::prepare_l() { 1605 if (mFlags & PREPARED) { 1606 return OK; 1607 } 1608 1609 if (mFlags & PREPARING) { 1610 return UNKNOWN_ERROR; 1611 } 1612 1613 mIsAsyncPrepare = false; 1614 status_t err = prepareAsync_l(); 1615 1616 if (err != OK) { 1617 return err; 1618 } 1619 1620 while (mFlags & PREPARING) { 1621 mPreparedCondition.wait(mLock); 1622 } 1623 1624 return mPrepareResult; 1625} 1626 1627status_t AwesomePlayer::prepareAsync() { 1628 Mutex::Autolock autoLock(mLock); 1629 1630 if (mFlags & PREPARING) { 1631 return UNKNOWN_ERROR; // async prepare already pending 1632 } 1633 1634 mIsAsyncPrepare = true; 1635 return prepareAsync_l(); 1636} 1637 1638status_t AwesomePlayer::prepareAsync_l() { 1639 if (mFlags & PREPARING) { 1640 return UNKNOWN_ERROR; // async prepare already pending 1641 } 1642 1643 if (!mQueueStarted) { 1644 mQueue.start(); 1645 mQueueStarted = true; 1646 } 1647 1648 mFlags |= PREPARING; 1649 mAsyncPrepareEvent = new AwesomeEvent( 1650 this, &AwesomePlayer::onPrepareAsyncEvent); 1651 1652 mQueue.postEvent(mAsyncPrepareEvent); 1653 1654 return OK; 1655} 1656 1657status_t AwesomePlayer::finishSetDataSource_l() { 1658 sp<DataSource> dataSource; 1659 1660 if (!strncasecmp("http://", mUri.string(), 7) 1661 || !strncasecmp("https://", mUri.string(), 8)) { 1662 mConnectingDataSource = HTTPBase::Create( 1663 (mFlags & INCOGNITO) 1664 ? HTTPBase::kFlagIncognito 1665 : 0); 1666 1667 mLock.unlock(); 1668 status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders); 1669 mLock.lock(); 1670 1671 if (err != OK) { 1672 mConnectingDataSource.clear(); 1673 1674 LOGI("mConnectingDataSource->connect() returned %d", err); 1675 return err; 1676 } 1677 1678#if 0 1679 mCachedSource = new NuCachedSource2( 1680 new ThrottledSource( 1681 mConnectingDataSource, 50 * 1024 /* bytes/sec */)); 1682#else 1683 mCachedSource = new NuCachedSource2(mConnectingDataSource); 1684#endif 1685 mConnectingDataSource.clear(); 1686 1687 dataSource = mCachedSource; 1688 1689 String8 contentType = dataSource->getMIMEType(); 1690 1691 if (strncasecmp(contentType.string(), "audio/", 6)) { 1692 // We're not doing this for streams that appear to be audio-only 1693 // streams to ensure that even low bandwidth streams start 1694 // playing back fairly instantly. 1695 1696 // We're going to prefill the cache before trying to instantiate 1697 // the extractor below, as the latter is an operation that otherwise 1698 // could block on the datasource for a significant amount of time. 1699 // During that time we'd be unable to abort the preparation phase 1700 // without this prefill. 1701 1702 mLock.unlock(); 1703 1704 for (;;) { 1705 status_t finalStatus; 1706 size_t cachedDataRemaining = 1707 mCachedSource->approxDataRemaining(&finalStatus); 1708 1709 if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes 1710 || (mFlags & PREPARE_CANCELLED)) { 1711 break; 1712 } 1713 1714 usleep(200000); 1715 } 1716 1717 mLock.lock(); 1718 } 1719 1720 if (mFlags & PREPARE_CANCELLED) { 1721 LOGI("Prepare cancelled while waiting for initial cache fill."); 1722 return UNKNOWN_ERROR; 1723 } 1724 } else if (!strncasecmp("rtsp://", mUri.string(), 7)) { 1725 if (mLooper == NULL) { 1726 mLooper = new ALooper; 1727 mLooper->setName("rtsp"); 1728 mLooper->start(); 1729 } 1730 mRTSPController = new ARTSPController(mLooper); 1731 mConnectingRTSPController = mRTSPController; 1732 1733 mLock.unlock(); 1734 status_t err = mRTSPController->connect(mUri.string()); 1735 mLock.lock(); 1736 1737 mConnectingRTSPController.clear(); 1738 1739 LOGI("ARTSPController::connect returned %d", err); 1740 1741 if (err != OK) { 1742 mRTSPController.clear(); 1743 return err; 1744 } 1745 1746 sp<MediaExtractor> extractor = mRTSPController.get(); 1747 return setDataSource_l(extractor); 1748 } else { 1749 dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders); 1750 } 1751 1752 if (dataSource == NULL) { 1753 return UNKNOWN_ERROR; 1754 } 1755 1756 sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 1757 1758 if (extractor == NULL) { 1759 return UNKNOWN_ERROR; 1760 } 1761 1762 dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); 1763 1764 if (mDecryptHandle != NULL) { 1765 CHECK(mDrmManagerClient); 1766 if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { 1767 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE); 1768 } 1769 } 1770 1771 return setDataSource_l(extractor); 1772} 1773 1774void AwesomePlayer::abortPrepare(status_t err) { 1775 CHECK(err != OK); 1776 1777 if (mIsAsyncPrepare) { 1778 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 1779 } 1780 1781 mPrepareResult = err; 1782 mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED); 1783 mAsyncPrepareEvent = NULL; 1784 mPreparedCondition.broadcast(); 1785} 1786 1787// static 1788bool AwesomePlayer::ContinuePreparation(void *cookie) { 1789 AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie); 1790 1791 return (me->mFlags & PREPARE_CANCELLED) == 0; 1792} 1793 1794void AwesomePlayer::onPrepareAsyncEvent() { 1795 Mutex::Autolock autoLock(mLock); 1796 1797 if (mFlags & PREPARE_CANCELLED) { 1798 LOGI("prepare was cancelled before doing anything"); 1799 abortPrepare(UNKNOWN_ERROR); 1800 return; 1801 } 1802 1803 if (mUri.size() > 0) { 1804 status_t err = finishSetDataSource_l(); 1805 1806 if (err != OK) { 1807 abortPrepare(err); 1808 return; 1809 } 1810 } 1811 1812 if (mVideoTrack != NULL && mVideoSource == NULL) { 1813 status_t err = initVideoDecoder(); 1814 1815 if (err != OK) { 1816 abortPrepare(err); 1817 return; 1818 } 1819 } 1820 1821 if (mAudioTrack != NULL && mAudioSource == NULL) { 1822 status_t err = initAudioDecoder(); 1823 1824 if (err != OK) { 1825 abortPrepare(err); 1826 return; 1827 } 1828 } 1829 1830 mFlags |= PREPARING_CONNECTED; 1831 1832 if (mCachedSource != NULL || mRTSPController != NULL) { 1833 postBufferingEvent_l(); 1834 } else { 1835 finishAsyncPrepare_l(); 1836 } 1837} 1838 1839void AwesomePlayer::finishAsyncPrepare_l() { 1840 if (mIsAsyncPrepare) { 1841 if (mVideoSource == NULL) { 1842 notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0); 1843 } else { 1844 notifyVideoSize_l(); 1845 } 1846 1847 notifyListener_l(MEDIA_PREPARED); 1848 } 1849 1850 mPrepareResult = OK; 1851 mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED); 1852 mFlags |= PREPARED; 1853 mAsyncPrepareEvent = NULL; 1854 mPreparedCondition.broadcast(); 1855} 1856 1857uint32_t AwesomePlayer::flags() const { 1858 return mExtractorFlags; 1859} 1860 1861void AwesomePlayer::postAudioEOS(int64_t delayUs) { 1862 Mutex::Autolock autoLock(mLock); 1863 postCheckAudioStatusEvent_l(delayUs); 1864} 1865 1866void AwesomePlayer::postAudioSeekComplete() { 1867 Mutex::Autolock autoLock(mLock); 1868 postCheckAudioStatusEvent_l(0 /* delayUs */); 1869} 1870 1871} // namespace android 1872