1 /* 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 //#define LOG_NDEBUG 0 19 #define LOG_TAG "MediaPlayerNative" 20 21 #include <fcntl.h> 22 #include <inttypes.h> 23 #include <sys/stat.h> 24 #include <sys/types.h> 25 #include <unistd.h> 26 27 #include <utils/Log.h> 28 29 #include <binder/IServiceManager.h> 30 #include <binder/IPCThreadState.h> 31 32 #include <gui/Surface.h> 33 34 #include <media/mediaplayer.h> 35 #include <media/AudioResamplerPublic.h> 36 #include <media/AudioSystem.h> 37 #include <media/AVSyncSettings.h> 38 #include <media/IDataSource.h> 39 #include <media/MediaAnalyticsItem.h> 40 41 #include <binder/MemoryBase.h> 42 43 #include <utils/KeyedVector.h> 44 #include <utils/String8.h> 45 46 #include <system/audio.h> 47 #include <system/window.h> 48 49 namespace android { 50 51 using media::VolumeShaper; 52 53 MediaPlayer::MediaPlayer() 54 { 55 ALOGV("constructor"); 56 mListener = NULL; 57 mCookie = NULL; 58 mStreamType = AUDIO_STREAM_MUSIC; 59 mAudioAttributesParcel = NULL; 60 mCurrentPosition = -1; 61 mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; 62 mSeekPosition = -1; 63 mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; 64 mCurrentState = MEDIA_PLAYER_IDLE; 65 mPrepareSync = false; 66 mPrepareStatus = NO_ERROR; 67 mLoop = false; 68 mLeftVolume = mRightVolume = 1.0; 69 mVideoWidth = mVideoHeight = 0; 70 mLockThreadId = 0; 71 mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION); 72 AudioSystem::acquireAudioSessionId(mAudioSessionId, -1); 73 mSendLevel = 0; 74 mRetransmitEndpointValid = false; 75 } 76 77 MediaPlayer::~MediaPlayer() 78 { 79 ALOGV("destructor"); 80 if (mAudioAttributesParcel != NULL) { 81 delete mAudioAttributesParcel; 82 mAudioAttributesParcel = NULL; 83 } 84 AudioSystem::releaseAudioSessionId(mAudioSessionId, -1); 85 disconnect(); 86 IPCThreadState::self()->flushCommands(); 87 } 88 89 void MediaPlayer::disconnect() 90 { 91 ALOGV("disconnect"); 92 sp<IMediaPlayer> p; 93 { 94 Mutex::Autolock _l(mLock); 95 p = mPlayer; 96 mPlayer.clear(); 97 } 98 99 if (p != 0) { 100 p->disconnect(); 101 } 102 } 103 104 // always call with lock held 105 void MediaPlayer::clear_l() 106 { 107 mCurrentPosition = -1; 108 mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; 109 mSeekPosition = -1; 110 mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; 111 mVideoWidth = mVideoHeight = 0; 112 mRetransmitEndpointValid = false; 113 } 114 115 status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener) 116 { 117 ALOGV("setListener"); 118 Mutex::Autolock _l(mLock); 119 mListener = listener; 120 return NO_ERROR; 121 } 122 123 124 status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player) 125 { 126 status_t err = UNKNOWN_ERROR; 127 sp<IMediaPlayer> p; 128 { // scope for the lock 129 Mutex::Autolock _l(mLock); 130 131 if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) || 132 (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) { 133 ALOGE("attachNewPlayer called in state %d", mCurrentState); 134 return INVALID_OPERATION; 135 } 136 137 clear_l(); 138 p = mPlayer; 139 mPlayer = player; 140 if (player != 0) { 141 mCurrentState = MEDIA_PLAYER_INITIALIZED; 142 err = NO_ERROR; 143 } else { 144 ALOGE("Unable to create media player"); 145 } 146 } 147 148 if (p != 0) { 149 p->disconnect(); 150 } 151 152 return err; 153 } 154 155 status_t MediaPlayer::setDataSource( 156 const sp<IMediaHTTPService> &httpService, 157 const char *url, const KeyedVector<String8, String8> *headers) 158 { 159 ALOGV("setDataSource(%s)", url); 160 status_t err = BAD_VALUE; 161 if (url != NULL) { 162 const sp<IMediaPlayerService> service(getMediaPlayerService()); 163 if (service != 0) { 164 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); 165 if ((NO_ERROR != doSetRetransmitEndpoint(player)) || 166 (NO_ERROR != player->setDataSource(httpService, url, headers))) { 167 player.clear(); 168 } 169 err = attachNewPlayer(player); 170 } 171 } 172 return err; 173 } 174 175 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length) 176 { 177 ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length); 178 status_t err = UNKNOWN_ERROR; 179 const sp<IMediaPlayerService> service(getMediaPlayerService()); 180 if (service != 0) { 181 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); 182 if ((NO_ERROR != doSetRetransmitEndpoint(player)) || 183 (NO_ERROR != player->setDataSource(fd, offset, length))) { 184 player.clear(); 185 } 186 err = attachNewPlayer(player); 187 } 188 return err; 189 } 190 191 status_t MediaPlayer::setDataSource(const sp<IDataSource> &source) 192 { 193 ALOGV("setDataSource(IDataSource)"); 194 status_t err = UNKNOWN_ERROR; 195 const sp<IMediaPlayerService> service(getMediaPlayerService()); 196 if (service != 0) { 197 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); 198 if ((NO_ERROR != doSetRetransmitEndpoint(player)) || 199 (NO_ERROR != player->setDataSource(source))) { 200 player.clear(); 201 } 202 err = attachNewPlayer(player); 203 } 204 return err; 205 } 206 207 status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply) 208 { 209 Mutex::Autolock _l(mLock); 210 const bool hasBeenInitialized = 211 (mCurrentState != MEDIA_PLAYER_STATE_ERROR) && 212 ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE); 213 if ((mPlayer != NULL) && hasBeenInitialized) { 214 ALOGV("invoke %zu", request.dataSize()); 215 return mPlayer->invoke(request, reply); 216 } 217 ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get()); 218 return INVALID_OPERATION; 219 } 220 221 status_t MediaPlayer::setMetadataFilter(const Parcel& filter) 222 { 223 ALOGD("setMetadataFilter"); 224 Mutex::Autolock lock(mLock); 225 if (mPlayer == NULL) { 226 return NO_INIT; 227 } 228 return mPlayer->setMetadataFilter(filter); 229 } 230 231 status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata) 232 { 233 ALOGD("getMetadata"); 234 Mutex::Autolock lock(mLock); 235 if (mPlayer == NULL) { 236 return NO_INIT; 237 } 238 return mPlayer->getMetadata(update_only, apply_filter, metadata); 239 } 240 241 status_t MediaPlayer::setVideoSurfaceTexture( 242 const sp<IGraphicBufferProducer>& bufferProducer) 243 { 244 ALOGV("setVideoSurfaceTexture"); 245 Mutex::Autolock _l(mLock); 246 if (mPlayer == 0) return NO_INIT; 247 return mPlayer->setVideoSurfaceTexture(bufferProducer); 248 } 249 250 status_t MediaPlayer::getBufferingSettings(BufferingSettings* buffering /* nonnull */) 251 { 252 ALOGV("getBufferingSettings"); 253 254 Mutex::Autolock _l(mLock); 255 if (mPlayer == 0) { 256 return NO_INIT; 257 } 258 return mPlayer->getBufferingSettings(buffering); 259 } 260 261 status_t MediaPlayer::setBufferingSettings(const BufferingSettings& buffering) 262 { 263 ALOGV("setBufferingSettings"); 264 265 Mutex::Autolock _l(mLock); 266 if (mPlayer == 0) { 267 return NO_INIT; 268 } 269 return mPlayer->setBufferingSettings(buffering); 270 } 271 272 // must call with lock held 273 status_t MediaPlayer::prepareAsync_l() 274 { 275 if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) { 276 if (mAudioAttributesParcel != NULL) { 277 mPlayer->setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel); 278 } else { 279 mPlayer->setAudioStreamType(mStreamType); 280 } 281 mCurrentState = MEDIA_PLAYER_PREPARING; 282 return mPlayer->prepareAsync(); 283 } 284 ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 285 return INVALID_OPERATION; 286 } 287 288 // TODO: In case of error, prepareAsync provides the caller with 2 error codes, 289 // one defined in the Android framework and one provided by the implementation 290 // that generated the error. The sync version of prepare returns only 1 error 291 // code. 292 status_t MediaPlayer::prepare() 293 { 294 ALOGV("prepare"); 295 Mutex::Autolock _l(mLock); 296 mLockThreadId = getThreadId(); 297 if (mPrepareSync) { 298 mLockThreadId = 0; 299 return -EALREADY; 300 } 301 mPrepareSync = true; 302 status_t ret = prepareAsync_l(); 303 if (ret != NO_ERROR) { 304 mLockThreadId = 0; 305 return ret; 306 } 307 308 if (mPrepareSync) { 309 mSignal.wait(mLock); // wait for prepare done 310 mPrepareSync = false; 311 } 312 ALOGV("prepare complete - status=%d", mPrepareStatus); 313 mLockThreadId = 0; 314 return mPrepareStatus; 315 } 316 317 status_t MediaPlayer::prepareAsync() 318 { 319 ALOGV("prepareAsync"); 320 Mutex::Autolock _l(mLock); 321 return prepareAsync_l(); 322 } 323 324 status_t MediaPlayer::start() 325 { 326 ALOGV("start"); 327 328 status_t ret = NO_ERROR; 329 Mutex::Autolock _l(mLock); 330 331 mLockThreadId = getThreadId(); 332 333 if (mCurrentState & MEDIA_PLAYER_STARTED) { 334 ret = NO_ERROR; 335 } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED | 336 MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) { 337 mPlayer->setLooping(mLoop); 338 mPlayer->setVolume(mLeftVolume, mRightVolume); 339 mPlayer->setAuxEffectSendLevel(mSendLevel); 340 mCurrentState = MEDIA_PLAYER_STARTED; 341 ret = mPlayer->start(); 342 if (ret != NO_ERROR) { 343 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 344 } else { 345 if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) { 346 ALOGV("playback completed immediately following start()"); 347 } 348 } 349 } else { 350 ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 351 ret = INVALID_OPERATION; 352 } 353 354 mLockThreadId = 0; 355 356 return ret; 357 } 358 359 status_t MediaPlayer::stop() 360 { 361 ALOGV("stop"); 362 Mutex::Autolock _l(mLock); 363 if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR; 364 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | 365 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) { 366 status_t ret = mPlayer->stop(); 367 if (ret != NO_ERROR) { 368 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 369 } else { 370 mCurrentState = MEDIA_PLAYER_STOPPED; 371 } 372 return ret; 373 } 374 ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 375 return INVALID_OPERATION; 376 } 377 378 status_t MediaPlayer::pause() 379 { 380 ALOGV("pause"); 381 Mutex::Autolock _l(mLock); 382 if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE)) 383 return NO_ERROR; 384 if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) { 385 status_t ret = mPlayer->pause(); 386 if (ret != NO_ERROR) { 387 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 388 } else { 389 mCurrentState = MEDIA_PLAYER_PAUSED; 390 } 391 return ret; 392 } 393 ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 394 return INVALID_OPERATION; 395 } 396 397 bool MediaPlayer::isPlaying() 398 { 399 Mutex::Autolock _l(mLock); 400 if (mPlayer != 0) { 401 bool temp = false; 402 mPlayer->isPlaying(&temp); 403 ALOGV("isPlaying: %d", temp); 404 if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) { 405 ALOGE("internal/external state mismatch corrected"); 406 mCurrentState = MEDIA_PLAYER_PAUSED; 407 } else if ((mCurrentState & MEDIA_PLAYER_PAUSED) && temp) { 408 ALOGE("internal/external state mismatch corrected"); 409 mCurrentState = MEDIA_PLAYER_STARTED; 410 } 411 return temp; 412 } 413 ALOGV("isPlaying: no active player"); 414 return false; 415 } 416 417 status_t MediaPlayer::setPlaybackSettings(const AudioPlaybackRate& rate) 418 { 419 ALOGV("setPlaybackSettings: %f %f %d %d", 420 rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode); 421 // Negative speed and pitch does not make sense. Further validation will 422 // be done by the respective mediaplayers. 423 if (rate.mSpeed < 0.f || rate.mPitch < 0.f) { 424 return BAD_VALUE; 425 } 426 Mutex::Autolock _l(mLock); 427 if (mPlayer == 0 || (mCurrentState & MEDIA_PLAYER_STOPPED)) { 428 return INVALID_OPERATION; 429 } 430 431 if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER_STARTED) 432 && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED 433 | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 434 mPlayer->setLooping(mLoop); 435 mPlayer->setVolume(mLeftVolume, mRightVolume); 436 mPlayer->setAuxEffectSendLevel(mSendLevel); 437 } 438 439 status_t err = mPlayer->setPlaybackSettings(rate); 440 if (err == OK) { 441 if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER_STARTED) { 442 mCurrentState = MEDIA_PLAYER_PAUSED; 443 } else if (rate.mSpeed != 0.f 444 && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED 445 | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 446 mCurrentState = MEDIA_PLAYER_STARTED; 447 } 448 } 449 return err; 450 } 451 452 status_t MediaPlayer::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) 453 { 454 Mutex::Autolock _l(mLock); 455 if (mPlayer == 0) return INVALID_OPERATION; 456 return mPlayer->getPlaybackSettings(rate); 457 } 458 459 status_t MediaPlayer::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) 460 { 461 ALOGV("setSyncSettings: %u %u %f %f", 462 sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint); 463 Mutex::Autolock _l(mLock); 464 if (mPlayer == 0) return INVALID_OPERATION; 465 return mPlayer->setSyncSettings(sync, videoFpsHint); 466 } 467 468 status_t MediaPlayer::getSyncSettings( 469 AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) 470 { 471 Mutex::Autolock _l(mLock); 472 if (mPlayer == 0) return INVALID_OPERATION; 473 return mPlayer->getSyncSettings(sync, videoFps); 474 } 475 476 status_t MediaPlayer::getVideoWidth(int *w) 477 { 478 ALOGV("getVideoWidth"); 479 Mutex::Autolock _l(mLock); 480 if (mPlayer == 0) return INVALID_OPERATION; 481 *w = mVideoWidth; 482 return NO_ERROR; 483 } 484 485 status_t MediaPlayer::getVideoHeight(int *h) 486 { 487 ALOGV("getVideoHeight"); 488 Mutex::Autolock _l(mLock); 489 if (mPlayer == 0) return INVALID_OPERATION; 490 *h = mVideoHeight; 491 return NO_ERROR; 492 } 493 494 status_t MediaPlayer::getCurrentPosition(int *msec) 495 { 496 ALOGV("getCurrentPosition"); 497 Mutex::Autolock _l(mLock); 498 if (mPlayer != 0) { 499 if (mCurrentPosition >= 0) { 500 ALOGV("Using cached seek position: %d", mCurrentPosition); 501 *msec = mCurrentPosition; 502 return NO_ERROR; 503 } 504 return mPlayer->getCurrentPosition(msec); 505 } 506 return INVALID_OPERATION; 507 } 508 509 status_t MediaPlayer::getDuration_l(int *msec) 510 { 511 ALOGV("getDuration_l"); 512 bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 513 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE)); 514 if (mPlayer != 0 && isValidState) { 515 int durationMs; 516 status_t ret = mPlayer->getDuration(&durationMs); 517 518 if (ret != OK) { 519 // Do not enter error state just because no duration was available. 520 durationMs = -1; 521 ret = OK; 522 } 523 524 if (msec) { 525 *msec = durationMs; 526 } 527 return ret; 528 } 529 ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u", 530 mPlayer.get(), mCurrentState); 531 return INVALID_OPERATION; 532 } 533 534 status_t MediaPlayer::getDuration(int *msec) 535 { 536 Mutex::Autolock _l(mLock); 537 return getDuration_l(msec); 538 } 539 540 status_t MediaPlayer::seekTo_l(int msec, MediaPlayerSeekMode mode) 541 { 542 ALOGV("seekTo (%d, %d)", msec, mode); 543 if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | 544 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) { 545 if ( msec < 0 ) { 546 ALOGW("Attempt to seek to invalid position: %d", msec); 547 msec = 0; 548 } 549 550 int durationMs; 551 status_t err = mPlayer->getDuration(&durationMs); 552 553 if (err != OK) { 554 ALOGW("Stream has no duration and is therefore not seekable."); 555 return err; 556 } 557 558 if (msec > durationMs) { 559 ALOGW("Attempt to seek to past end of file: request = %d, " 560 "durationMs = %d", 561 msec, 562 durationMs); 563 564 msec = durationMs; 565 } 566 567 // cache duration 568 mCurrentPosition = msec; 569 mCurrentSeekMode = mode; 570 if (mSeekPosition < 0) { 571 mSeekPosition = msec; 572 mSeekMode = mode; 573 return mPlayer->seekTo(msec, mode); 574 } 575 else { 576 ALOGV("Seek in progress - queue up seekTo[%d, %d]", msec, mode); 577 return NO_ERROR; 578 } 579 } 580 ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), 581 mCurrentState); 582 return INVALID_OPERATION; 583 } 584 585 status_t MediaPlayer::seekTo(int msec, MediaPlayerSeekMode mode) 586 { 587 mLockThreadId = getThreadId(); 588 Mutex::Autolock _l(mLock); 589 status_t result = seekTo_l(msec, mode); 590 mLockThreadId = 0; 591 592 return result; 593 } 594 595 status_t MediaPlayer::notifyAt(int64_t mediaTimeUs) 596 { 597 Mutex::Autolock _l(mLock); 598 if (mPlayer != 0) { 599 return mPlayer->notifyAt(mediaTimeUs); 600 } 601 return INVALID_OPERATION; 602 } 603 604 status_t MediaPlayer::reset_l() 605 { 606 mLoop = false; 607 if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR; 608 mPrepareSync = false; 609 if (mPlayer != 0) { 610 status_t ret = mPlayer->reset(); 611 if (ret != NO_ERROR) { 612 ALOGE("reset() failed with return code (%d)", ret); 613 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 614 } else { 615 mPlayer->disconnect(); 616 mCurrentState = MEDIA_PLAYER_IDLE; 617 } 618 // setDataSource has to be called again to create a 619 // new mediaplayer. 620 mPlayer = 0; 621 return ret; 622 } 623 clear_l(); 624 return NO_ERROR; 625 } 626 627 status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) { 628 Mutex::Autolock _l(mLock); 629 630 if (player == NULL) { 631 return UNKNOWN_ERROR; 632 } 633 634 if (mRetransmitEndpointValid) { 635 return player->setRetransmitEndpoint(&mRetransmitEndpoint); 636 } 637 638 return OK; 639 } 640 641 status_t MediaPlayer::reset() 642 { 643 ALOGV("reset"); 644 mLockThreadId = getThreadId(); 645 Mutex::Autolock _l(mLock); 646 status_t result = reset_l(); 647 mLockThreadId = 0; 648 649 return result; 650 } 651 652 status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type) 653 { 654 ALOGV("MediaPlayer::setAudioStreamType"); 655 Mutex::Autolock _l(mLock); 656 if (mStreamType == type) return NO_ERROR; 657 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 658 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) { 659 // Can't change the stream type after prepare 660 ALOGE("setAudioStream called in state %d", mCurrentState); 661 return INVALID_OPERATION; 662 } 663 // cache 664 mStreamType = type; 665 return OK; 666 } 667 668 status_t MediaPlayer::getAudioStreamType(audio_stream_type_t *type) 669 { 670 ALOGV("getAudioStreamType"); 671 Mutex::Autolock _l(mLock); 672 *type = mStreamType; 673 return OK; 674 } 675 676 status_t MediaPlayer::setLooping(int loop) 677 { 678 ALOGV("MediaPlayer::setLooping"); 679 Mutex::Autolock _l(mLock); 680 mLoop = (loop != 0); 681 if (mPlayer != 0) { 682 return mPlayer->setLooping(loop); 683 } 684 return OK; 685 } 686 687 bool MediaPlayer::isLooping() { 688 ALOGV("isLooping"); 689 Mutex::Autolock _l(mLock); 690 if (mPlayer != 0) { 691 return mLoop; 692 } 693 ALOGV("isLooping: no active player"); 694 return false; 695 } 696 697 status_t MediaPlayer::setVolume(float leftVolume, float rightVolume) 698 { 699 ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume); 700 Mutex::Autolock _l(mLock); 701 mLeftVolume = leftVolume; 702 mRightVolume = rightVolume; 703 if (mPlayer != 0) { 704 return mPlayer->setVolume(leftVolume, rightVolume); 705 } 706 return OK; 707 } 708 709 status_t MediaPlayer::setAudioSessionId(audio_session_t sessionId) 710 { 711 ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId); 712 Mutex::Autolock _l(mLock); 713 if (!(mCurrentState & MEDIA_PLAYER_IDLE)) { 714 ALOGE("setAudioSessionId called in state %d", mCurrentState); 715 return INVALID_OPERATION; 716 } 717 if (sessionId < 0) { 718 return BAD_VALUE; 719 } 720 if (sessionId != mAudioSessionId) { 721 AudioSystem::acquireAudioSessionId(sessionId, -1); 722 AudioSystem::releaseAudioSessionId(mAudioSessionId, -1); 723 mAudioSessionId = sessionId; 724 } 725 return NO_ERROR; 726 } 727 728 audio_session_t MediaPlayer::getAudioSessionId() 729 { 730 Mutex::Autolock _l(mLock); 731 return mAudioSessionId; 732 } 733 734 status_t MediaPlayer::setAuxEffectSendLevel(float level) 735 { 736 ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level); 737 Mutex::Autolock _l(mLock); 738 mSendLevel = level; 739 if (mPlayer != 0) { 740 return mPlayer->setAuxEffectSendLevel(level); 741 } 742 return OK; 743 } 744 745 status_t MediaPlayer::attachAuxEffect(int effectId) 746 { 747 ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId); 748 Mutex::Autolock _l(mLock); 749 if (mPlayer == 0 || 750 (mCurrentState & MEDIA_PLAYER_IDLE) || 751 (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) { 752 ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 753 return INVALID_OPERATION; 754 } 755 756 return mPlayer->attachAuxEffect(effectId); 757 } 758 759 // always call with lock held 760 status_t MediaPlayer::checkStateForKeySet_l(int key) 761 { 762 switch(key) { 763 case KEY_PARAMETER_AUDIO_ATTRIBUTES: 764 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 765 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) { 766 // Can't change the audio attributes after prepare 767 ALOGE("trying to set audio attributes called in state %d", mCurrentState); 768 return INVALID_OPERATION; 769 } 770 break; 771 default: 772 // parameter doesn't require player state check 773 break; 774 } 775 return OK; 776 } 777 778 status_t MediaPlayer::setParameter(int key, const Parcel& request) 779 { 780 ALOGV("MediaPlayer::setParameter(%d)", key); 781 status_t status = INVALID_OPERATION; 782 Mutex::Autolock _l(mLock); 783 if (checkStateForKeySet_l(key) != OK) { 784 return status; 785 } 786 switch (key) { 787 case KEY_PARAMETER_AUDIO_ATTRIBUTES: 788 // save the marshalled audio attributes 789 if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; }; 790 mAudioAttributesParcel = new Parcel(); 791 mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize()); 792 status = OK; 793 break; 794 default: 795 ALOGV_IF(mPlayer == NULL, "setParameter: no active player"); 796 break; 797 } 798 799 if (mPlayer != NULL) { 800 status = mPlayer->setParameter(key, request); 801 } 802 return status; 803 } 804 805 status_t MediaPlayer::getParameter(int key, Parcel *reply) 806 { 807 ALOGV("MediaPlayer::getParameter(%d)", key); 808 Mutex::Autolock _l(mLock); 809 if (mPlayer != NULL) { 810 status_t status = mPlayer->getParameter(key, reply); 811 if (status != OK) { 812 ALOGD("getParameter returns %d", status); 813 } 814 return status; 815 } 816 ALOGV("getParameter: no active player"); 817 return INVALID_OPERATION; 818 } 819 820 status_t MediaPlayer::setRetransmitEndpoint(const char* addrString, 821 uint16_t port) { 822 ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)", 823 addrString ? addrString : "(null)", port); 824 825 Mutex::Autolock _l(mLock); 826 if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE)) 827 return INVALID_OPERATION; 828 829 if (NULL == addrString) { 830 mRetransmitEndpointValid = false; 831 return OK; 832 } 833 834 struct in_addr saddr; 835 if(!inet_aton(addrString, &saddr)) { 836 return BAD_VALUE; 837 } 838 839 memset(&mRetransmitEndpoint, 0, sizeof(mRetransmitEndpoint)); 840 mRetransmitEndpoint.sin_family = AF_INET; 841 mRetransmitEndpoint.sin_addr = saddr; 842 mRetransmitEndpoint.sin_port = htons(port); 843 mRetransmitEndpointValid = true; 844 845 return OK; 846 } 847 848 void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) 849 { 850 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); 851 bool send = true; 852 bool locked = false; 853 854 // TODO: In the future, we might be on the same thread if the app is 855 // running in the same process as the media server. In that case, 856 // this will deadlock. 857 // 858 // The threadId hack below works around this for the care of prepare, 859 // seekTo, start, and reset within the same process. 860 // FIXME: Remember, this is a hack, it's not even a hack that is applied 861 // consistently for all use-cases, this needs to be revisited. 862 if (mLockThreadId != getThreadId()) { 863 mLock.lock(); 864 locked = true; 865 } 866 867 // Allows calls from JNI in idle state to notify errors 868 if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) { 869 ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2); 870 if (locked) mLock.unlock(); // release the lock when done. 871 return; 872 } 873 874 switch (msg) { 875 case MEDIA_NOP: // interface test message 876 break; 877 case MEDIA_PREPARED: 878 ALOGV("MediaPlayer::notify() prepared"); 879 mCurrentState = MEDIA_PLAYER_PREPARED; 880 if (mPrepareSync) { 881 ALOGV("signal application thread"); 882 mPrepareSync = false; 883 mPrepareStatus = NO_ERROR; 884 mSignal.signal(); 885 } 886 break; 887 case MEDIA_DRM_INFO: 888 ALOGV("MediaPlayer::notify() MEDIA_DRM_INFO(%d, %d, %d, %p)", msg, ext1, ext2, obj); 889 break; 890 case MEDIA_PLAYBACK_COMPLETE: 891 ALOGV("playback complete"); 892 if (mCurrentState == MEDIA_PLAYER_IDLE) { 893 ALOGE("playback complete in idle state"); 894 } 895 if (!mLoop) { 896 mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE; 897 } 898 break; 899 case MEDIA_ERROR: 900 // Always log errors. 901 // ext1: Media framework error code. 902 // ext2: Implementation dependant error code. 903 ALOGE("error (%d, %d)", ext1, ext2); 904 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 905 if (mPrepareSync) 906 { 907 ALOGV("signal application thread"); 908 mPrepareSync = false; 909 mPrepareStatus = ext1; 910 mSignal.signal(); 911 send = false; 912 } 913 break; 914 case MEDIA_INFO: 915 // ext1: Media framework error code. 916 // ext2: Implementation dependant error code. 917 if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) { 918 ALOGW("info/warning (%d, %d)", ext1, ext2); 919 } 920 break; 921 case MEDIA_SEEK_COMPLETE: 922 ALOGV("Received seek complete"); 923 if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) { 924 ALOGV("Executing queued seekTo(%d, %d)", mCurrentPosition, mCurrentSeekMode); 925 mSeekPosition = -1; 926 mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; 927 seekTo_l(mCurrentPosition, mCurrentSeekMode); 928 } 929 else { 930 ALOGV("All seeks complete - return to regularly scheduled program"); 931 mCurrentPosition = mSeekPosition = -1; 932 mCurrentSeekMode = mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; 933 } 934 break; 935 case MEDIA_BUFFERING_UPDATE: 936 ALOGV("buffering %d", ext1); 937 break; 938 case MEDIA_SET_VIDEO_SIZE: 939 ALOGV("New video size %d x %d", ext1, ext2); 940 mVideoWidth = ext1; 941 mVideoHeight = ext2; 942 break; 943 case MEDIA_NOTIFY_TIME: 944 ALOGV("Received notify time message"); 945 break; 946 case MEDIA_TIMED_TEXT: 947 ALOGV("Received timed text message"); 948 break; 949 case MEDIA_SUBTITLE_DATA: 950 ALOGV("Received subtitle data message"); 951 break; 952 case MEDIA_META_DATA: 953 ALOGV("Received timed metadata message"); 954 break; 955 default: 956 ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); 957 break; 958 } 959 960 sp<MediaPlayerListener> listener = mListener; 961 if (locked) mLock.unlock(); 962 963 // this prevents re-entrant calls into client code 964 if ((listener != 0) && send) { 965 Mutex::Autolock _l(mNotifyLock); 966 ALOGV("callback application"); 967 listener->notify(msg, ext1, ext2, obj); 968 ALOGV("back from callback"); 969 } 970 } 971 972 void MediaPlayer::died() 973 { 974 ALOGV("died"); 975 notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0); 976 } 977 978 status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) { 979 Mutex::Autolock _l(mLock); 980 if (mPlayer == NULL) { 981 return NO_INIT; 982 } 983 984 if (next != NULL && !(next->mCurrentState & 985 (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 986 ALOGE("next player is not prepared"); 987 return INVALID_OPERATION; 988 } 989 990 return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer); 991 } 992 993 VolumeShaper::Status MediaPlayer::applyVolumeShaper( 994 const sp<VolumeShaper::Configuration>& configuration, 995 const sp<VolumeShaper::Operation>& operation) 996 { 997 Mutex::Autolock _l(mLock); 998 if (mPlayer == nullptr) { 999 return VolumeShaper::Status(NO_INIT); 1000 } 1001 VolumeShaper::Status status = mPlayer->applyVolumeShaper(configuration, operation); 1002 return status; 1003 } 1004 1005 sp<VolumeShaper::State> MediaPlayer::getVolumeShaperState(int id) 1006 { 1007 Mutex::Autolock _l(mLock); 1008 if (mPlayer == nullptr) { 1009 return nullptr; 1010 } 1011 return mPlayer->getVolumeShaperState(id); 1012 } 1013 1014 // Modular DRM 1015 status_t MediaPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) 1016 { 1017 // TODO change to ALOGV 1018 ALOGD("prepareDrm: uuid: %p drmSessionId: %p(%zu)", uuid, 1019 drmSessionId.array(), drmSessionId.size()); 1020 Mutex::Autolock _l(mLock); 1021 if (mPlayer == NULL) { 1022 return NO_INIT; 1023 } 1024 1025 // Only allowed it in player's preparing/prepared state. 1026 // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or 1027 // completed) so the state change to "prepared" might not have happened yet (e.g., buffering). 1028 // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener. 1029 if (!(mCurrentState & (MEDIA_PLAYER_PREPARING | MEDIA_PLAYER_PREPARED))) { 1030 ALOGE("prepareDrm is called in the wrong state (%d).", mCurrentState); 1031 return INVALID_OPERATION; 1032 } 1033 1034 if (drmSessionId.isEmpty()) { 1035 ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId."); 1036 return INVALID_OPERATION; 1037 } 1038 1039 // Passing down to mediaserver mainly for creating the crypto 1040 status_t status = mPlayer->prepareDrm(uuid, drmSessionId); 1041 ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status); 1042 1043 // TODO change to ALOGV 1044 ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status); 1045 1046 return status; 1047 } 1048 1049 status_t MediaPlayer::releaseDrm() 1050 { 1051 Mutex::Autolock _l(mLock); 1052 if (mPlayer == NULL) { 1053 return NO_INIT; 1054 } 1055 1056 // Not allowing releaseDrm in an active/resumable state 1057 if (mCurrentState & (MEDIA_PLAYER_STARTED | 1058 MEDIA_PLAYER_PAUSED | 1059 MEDIA_PLAYER_PLAYBACK_COMPLETE | 1060 MEDIA_PLAYER_STATE_ERROR)) { 1061 ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState); 1062 return INVALID_OPERATION; 1063 } 1064 1065 status_t status = mPlayer->releaseDrm(); 1066 // TODO change to ALOGV 1067 ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status); 1068 if (status != OK) { 1069 ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status); 1070 // Overriding to OK so the client proceed with its own cleanup 1071 // Client can't do more cleanup. mediaserver release its crypto at end of session anyway. 1072 status = OK; 1073 } 1074 1075 return status; 1076 } 1077 1078 status_t MediaPlayer::setOutputDevice(audio_port_handle_t deviceId) 1079 { 1080 Mutex::Autolock _l(mLock); 1081 if (mPlayer == NULL) { 1082 ALOGV("setOutputDevice: player not init"); 1083 return NO_INIT; 1084 } 1085 return mPlayer->setOutputDevice(deviceId); 1086 } 1087 1088 audio_port_handle_t MediaPlayer::getRoutedDeviceId() 1089 { 1090 Mutex::Autolock _l(mLock); 1091 if (mPlayer == NULL) { 1092 ALOGV("getRoutedDeviceId: player not init"); 1093 return AUDIO_PORT_HANDLE_NONE; 1094 } 1095 audio_port_handle_t deviceId; 1096 status_t status = mPlayer->getRoutedDeviceId(&deviceId); 1097 if (status != NO_ERROR) { 1098 return AUDIO_PORT_HANDLE_NONE; 1099 } 1100 return deviceId; 1101 } 1102 1103 status_t MediaPlayer::enableAudioDeviceCallback(bool enabled) 1104 { 1105 Mutex::Autolock _l(mLock); 1106 if (mPlayer == NULL) { 1107 ALOGV("addAudioDeviceCallback: player not init"); 1108 return NO_INIT; 1109 } 1110 return mPlayer->enableAudioDeviceCallback(enabled); 1111 } 1112 1113 } // namespace android 1114