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 "MediaPlayer" 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 40 #include <binder/MemoryBase.h> 41 42 #include <utils/KeyedVector.h> 43 #include <utils/String8.h> 44 45 #include <system/audio.h> 46 #include <system/window.h> 47 48 namespace android { 49 50 MediaPlayer::MediaPlayer() 51 { 52 ALOGV("constructor"); 53 mListener = NULL; 54 mCookie = NULL; 55 mStreamType = AUDIO_STREAM_MUSIC; 56 mAudioAttributesParcel = NULL; 57 mCurrentPosition = -1; 58 mSeekPosition = -1; 59 mCurrentState = MEDIA_PLAYER_IDLE; 60 mPrepareSync = false; 61 mPrepareStatus = NO_ERROR; 62 mLoop = false; 63 mLeftVolume = mRightVolume = 1.0; 64 mVideoWidth = mVideoHeight = 0; 65 mLockThreadId = 0; 66 mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION); 67 AudioSystem::acquireAudioSessionId(mAudioSessionId, -1); 68 mSendLevel = 0; 69 mRetransmitEndpointValid = false; 70 } 71 72 MediaPlayer::~MediaPlayer() 73 { 74 ALOGV("destructor"); 75 if (mAudioAttributesParcel != NULL) { 76 delete mAudioAttributesParcel; 77 mAudioAttributesParcel = NULL; 78 } 79 AudioSystem::releaseAudioSessionId(mAudioSessionId, -1); 80 disconnect(); 81 IPCThreadState::self()->flushCommands(); 82 } 83 84 void MediaPlayer::disconnect() 85 { 86 ALOGV("disconnect"); 87 sp<IMediaPlayer> p; 88 { 89 Mutex::Autolock _l(mLock); 90 p = mPlayer; 91 mPlayer.clear(); 92 } 93 94 if (p != 0) { 95 p->disconnect(); 96 } 97 } 98 99 // always call with lock held 100 void MediaPlayer::clear_l() 101 { 102 mCurrentPosition = -1; 103 mSeekPosition = -1; 104 mVideoWidth = mVideoHeight = 0; 105 mRetransmitEndpointValid = false; 106 } 107 108 status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener) 109 { 110 ALOGV("setListener"); 111 Mutex::Autolock _l(mLock); 112 mListener = listener; 113 return NO_ERROR; 114 } 115 116 117 status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player) 118 { 119 status_t err = UNKNOWN_ERROR; 120 sp<IMediaPlayer> p; 121 { // scope for the lock 122 Mutex::Autolock _l(mLock); 123 124 if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) || 125 (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) { 126 ALOGE("attachNewPlayer called in state %d", mCurrentState); 127 return INVALID_OPERATION; 128 } 129 130 clear_l(); 131 p = mPlayer; 132 mPlayer = player; 133 if (player != 0) { 134 mCurrentState = MEDIA_PLAYER_INITIALIZED; 135 err = NO_ERROR; 136 } else { 137 ALOGE("Unable to create media player"); 138 } 139 } 140 141 if (p != 0) { 142 p->disconnect(); 143 } 144 145 return err; 146 } 147 148 status_t MediaPlayer::setDataSource( 149 const sp<IMediaHTTPService> &httpService, 150 const char *url, const KeyedVector<String8, String8> *headers) 151 { 152 ALOGV("setDataSource(%s)", url); 153 status_t err = BAD_VALUE; 154 if (url != NULL) { 155 const sp<IMediaPlayerService> service(getMediaPlayerService()); 156 if (service != 0) { 157 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); 158 if ((NO_ERROR != doSetRetransmitEndpoint(player)) || 159 (NO_ERROR != player->setDataSource(httpService, url, headers))) { 160 player.clear(); 161 } 162 err = attachNewPlayer(player); 163 } 164 } 165 return err; 166 } 167 168 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length) 169 { 170 ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length); 171 status_t err = UNKNOWN_ERROR; 172 const sp<IMediaPlayerService> service(getMediaPlayerService()); 173 if (service != 0) { 174 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); 175 if ((NO_ERROR != doSetRetransmitEndpoint(player)) || 176 (NO_ERROR != player->setDataSource(fd, offset, length))) { 177 player.clear(); 178 } 179 err = attachNewPlayer(player); 180 } 181 return err; 182 } 183 184 status_t MediaPlayer::setDataSource(const sp<IDataSource> &source) 185 { 186 ALOGV("setDataSource(IDataSource)"); 187 status_t err = UNKNOWN_ERROR; 188 const sp<IMediaPlayerService> service(getMediaPlayerService()); 189 if (service != 0) { 190 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); 191 if ((NO_ERROR != doSetRetransmitEndpoint(player)) || 192 (NO_ERROR != player->setDataSource(source))) { 193 player.clear(); 194 } 195 err = attachNewPlayer(player); 196 } 197 return err; 198 } 199 200 status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply) 201 { 202 Mutex::Autolock _l(mLock); 203 const bool hasBeenInitialized = 204 (mCurrentState != MEDIA_PLAYER_STATE_ERROR) && 205 ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE); 206 if ((mPlayer != NULL) && hasBeenInitialized) { 207 ALOGV("invoke %zu", request.dataSize()); 208 return mPlayer->invoke(request, reply); 209 } 210 ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get()); 211 return INVALID_OPERATION; 212 } 213 214 status_t MediaPlayer::setMetadataFilter(const Parcel& filter) 215 { 216 ALOGD("setMetadataFilter"); 217 Mutex::Autolock lock(mLock); 218 if (mPlayer == NULL) { 219 return NO_INIT; 220 } 221 return mPlayer->setMetadataFilter(filter); 222 } 223 224 status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata) 225 { 226 ALOGD("getMetadata"); 227 Mutex::Autolock lock(mLock); 228 if (mPlayer == NULL) { 229 return NO_INIT; 230 } 231 return mPlayer->getMetadata(update_only, apply_filter, metadata); 232 } 233 234 status_t MediaPlayer::setVideoSurfaceTexture( 235 const sp<IGraphicBufferProducer>& bufferProducer) 236 { 237 ALOGV("setVideoSurfaceTexture"); 238 Mutex::Autolock _l(mLock); 239 if (mPlayer == 0) return NO_INIT; 240 return mPlayer->setVideoSurfaceTexture(bufferProducer); 241 } 242 243 // must call with lock held 244 status_t MediaPlayer::prepareAsync_l() 245 { 246 if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) { 247 if (mAudioAttributesParcel != NULL) { 248 mPlayer->setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel); 249 } else { 250 mPlayer->setAudioStreamType(mStreamType); 251 } 252 mCurrentState = MEDIA_PLAYER_PREPARING; 253 return mPlayer->prepareAsync(); 254 } 255 ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 256 return INVALID_OPERATION; 257 } 258 259 // TODO: In case of error, prepareAsync provides the caller with 2 error codes, 260 // one defined in the Android framework and one provided by the implementation 261 // that generated the error. The sync version of prepare returns only 1 error 262 // code. 263 status_t MediaPlayer::prepare() 264 { 265 ALOGV("prepare"); 266 Mutex::Autolock _l(mLock); 267 mLockThreadId = getThreadId(); 268 if (mPrepareSync) { 269 mLockThreadId = 0; 270 return -EALREADY; 271 } 272 mPrepareSync = true; 273 status_t ret = prepareAsync_l(); 274 if (ret != NO_ERROR) { 275 mLockThreadId = 0; 276 return ret; 277 } 278 279 if (mPrepareSync) { 280 mSignal.wait(mLock); // wait for prepare done 281 mPrepareSync = false; 282 } 283 ALOGV("prepare complete - status=%d", mPrepareStatus); 284 mLockThreadId = 0; 285 return mPrepareStatus; 286 } 287 288 status_t MediaPlayer::prepareAsync() 289 { 290 ALOGV("prepareAsync"); 291 Mutex::Autolock _l(mLock); 292 return prepareAsync_l(); 293 } 294 295 status_t MediaPlayer::start() 296 { 297 ALOGV("start"); 298 299 status_t ret = NO_ERROR; 300 Mutex::Autolock _l(mLock); 301 302 mLockThreadId = getThreadId(); 303 304 if (mCurrentState & MEDIA_PLAYER_STARTED) { 305 ret = NO_ERROR; 306 } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED | 307 MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) { 308 mPlayer->setLooping(mLoop); 309 mPlayer->setVolume(mLeftVolume, mRightVolume); 310 mPlayer->setAuxEffectSendLevel(mSendLevel); 311 mCurrentState = MEDIA_PLAYER_STARTED; 312 ret = mPlayer->start(); 313 if (ret != NO_ERROR) { 314 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 315 } else { 316 if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) { 317 ALOGV("playback completed immediately following start()"); 318 } 319 } 320 } else { 321 ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 322 ret = INVALID_OPERATION; 323 } 324 325 mLockThreadId = 0; 326 327 return ret; 328 } 329 330 status_t MediaPlayer::stop() 331 { 332 ALOGV("stop"); 333 Mutex::Autolock _l(mLock); 334 if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR; 335 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | 336 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) { 337 status_t ret = mPlayer->stop(); 338 if (ret != NO_ERROR) { 339 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 340 } else { 341 mCurrentState = MEDIA_PLAYER_STOPPED; 342 } 343 return ret; 344 } 345 ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 346 return INVALID_OPERATION; 347 } 348 349 status_t MediaPlayer::pause() 350 { 351 ALOGV("pause"); 352 Mutex::Autolock _l(mLock); 353 if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE)) 354 return NO_ERROR; 355 if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) { 356 status_t ret = mPlayer->pause(); 357 if (ret != NO_ERROR) { 358 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 359 } else { 360 mCurrentState = MEDIA_PLAYER_PAUSED; 361 } 362 return ret; 363 } 364 ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 365 return INVALID_OPERATION; 366 } 367 368 bool MediaPlayer::isPlaying() 369 { 370 Mutex::Autolock _l(mLock); 371 if (mPlayer != 0) { 372 bool temp = false; 373 mPlayer->isPlaying(&temp); 374 ALOGV("isPlaying: %d", temp); 375 if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) { 376 ALOGE("internal/external state mismatch corrected"); 377 mCurrentState = MEDIA_PLAYER_PAUSED; 378 } else if ((mCurrentState & MEDIA_PLAYER_PAUSED) && temp) { 379 ALOGE("internal/external state mismatch corrected"); 380 mCurrentState = MEDIA_PLAYER_STARTED; 381 } 382 return temp; 383 } 384 ALOGV("isPlaying: no active player"); 385 return false; 386 } 387 388 status_t MediaPlayer::setPlaybackSettings(const AudioPlaybackRate& rate) 389 { 390 ALOGV("setPlaybackSettings: %f %f %d %d", 391 rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode); 392 // Negative speed and pitch does not make sense. Further validation will 393 // be done by the respective mediaplayers. 394 if (rate.mSpeed < 0.f || rate.mPitch < 0.f) { 395 return BAD_VALUE; 396 } 397 Mutex::Autolock _l(mLock); 398 if (mPlayer == 0) return INVALID_OPERATION; 399 400 if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER_STARTED) 401 && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED 402 | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 403 mPlayer->setLooping(mLoop); 404 mPlayer->setVolume(mLeftVolume, mRightVolume); 405 mPlayer->setAuxEffectSendLevel(mSendLevel); 406 } 407 408 status_t err = mPlayer->setPlaybackSettings(rate); 409 if (err == OK) { 410 if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER_STARTED) { 411 mCurrentState = MEDIA_PLAYER_PAUSED; 412 } else if (rate.mSpeed != 0.f 413 && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED 414 | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 415 mCurrentState = MEDIA_PLAYER_STARTED; 416 } 417 } 418 return err; 419 } 420 421 status_t MediaPlayer::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) 422 { 423 Mutex::Autolock _l(mLock); 424 if (mPlayer == 0) return INVALID_OPERATION; 425 return mPlayer->getPlaybackSettings(rate); 426 } 427 428 status_t MediaPlayer::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) 429 { 430 ALOGV("setSyncSettings: %u %u %f %f", 431 sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint); 432 Mutex::Autolock _l(mLock); 433 if (mPlayer == 0) return INVALID_OPERATION; 434 return mPlayer->setSyncSettings(sync, videoFpsHint); 435 } 436 437 status_t MediaPlayer::getSyncSettings( 438 AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) 439 { 440 Mutex::Autolock _l(mLock); 441 if (mPlayer == 0) return INVALID_OPERATION; 442 return mPlayer->getSyncSettings(sync, videoFps); 443 } 444 445 status_t MediaPlayer::getVideoWidth(int *w) 446 { 447 ALOGV("getVideoWidth"); 448 Mutex::Autolock _l(mLock); 449 if (mPlayer == 0) return INVALID_OPERATION; 450 *w = mVideoWidth; 451 return NO_ERROR; 452 } 453 454 status_t MediaPlayer::getVideoHeight(int *h) 455 { 456 ALOGV("getVideoHeight"); 457 Mutex::Autolock _l(mLock); 458 if (mPlayer == 0) return INVALID_OPERATION; 459 *h = mVideoHeight; 460 return NO_ERROR; 461 } 462 463 status_t MediaPlayer::getCurrentPosition(int *msec) 464 { 465 ALOGV("getCurrentPosition"); 466 Mutex::Autolock _l(mLock); 467 if (mPlayer != 0) { 468 if (mCurrentPosition >= 0) { 469 ALOGV("Using cached seek position: %d", mCurrentPosition); 470 *msec = mCurrentPosition; 471 return NO_ERROR; 472 } 473 return mPlayer->getCurrentPosition(msec); 474 } 475 return INVALID_OPERATION; 476 } 477 478 status_t MediaPlayer::getDuration_l(int *msec) 479 { 480 ALOGV("getDuration_l"); 481 bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 482 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE)); 483 if (mPlayer != 0 && isValidState) { 484 int durationMs; 485 status_t ret = mPlayer->getDuration(&durationMs); 486 487 if (ret != OK) { 488 // Do not enter error state just because no duration was available. 489 durationMs = -1; 490 ret = OK; 491 } 492 493 if (msec) { 494 *msec = durationMs; 495 } 496 return ret; 497 } 498 ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u", 499 mPlayer.get(), mCurrentState); 500 return INVALID_OPERATION; 501 } 502 503 status_t MediaPlayer::getDuration(int *msec) 504 { 505 Mutex::Autolock _l(mLock); 506 return getDuration_l(msec); 507 } 508 509 status_t MediaPlayer::seekTo_l(int msec) 510 { 511 ALOGV("seekTo %d", msec); 512 if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | 513 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) { 514 if ( msec < 0 ) { 515 ALOGW("Attempt to seek to invalid position: %d", msec); 516 msec = 0; 517 } 518 519 int durationMs; 520 status_t err = mPlayer->getDuration(&durationMs); 521 522 if (err != OK) { 523 ALOGW("Stream has no duration and is therefore not seekable."); 524 return err; 525 } 526 527 if (msec > durationMs) { 528 ALOGW("Attempt to seek to past end of file: request = %d, " 529 "durationMs = %d", 530 msec, 531 durationMs); 532 533 msec = durationMs; 534 } 535 536 // cache duration 537 mCurrentPosition = msec; 538 if (mSeekPosition < 0) { 539 mSeekPosition = msec; 540 return mPlayer->seekTo(msec); 541 } 542 else { 543 ALOGV("Seek in progress - queue up seekTo[%d]", msec); 544 return NO_ERROR; 545 } 546 } 547 ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), 548 mCurrentState); 549 return INVALID_OPERATION; 550 } 551 552 status_t MediaPlayer::seekTo(int msec) 553 { 554 mLockThreadId = getThreadId(); 555 Mutex::Autolock _l(mLock); 556 status_t result = seekTo_l(msec); 557 mLockThreadId = 0; 558 559 return result; 560 } 561 562 status_t MediaPlayer::reset_l() 563 { 564 mLoop = false; 565 if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR; 566 mPrepareSync = false; 567 if (mPlayer != 0) { 568 status_t ret = mPlayer->reset(); 569 if (ret != NO_ERROR) { 570 ALOGE("reset() failed with return code (%d)", ret); 571 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 572 } else { 573 mPlayer->disconnect(); 574 mCurrentState = MEDIA_PLAYER_IDLE; 575 } 576 // setDataSource has to be called again to create a 577 // new mediaplayer. 578 mPlayer = 0; 579 return ret; 580 } 581 clear_l(); 582 return NO_ERROR; 583 } 584 585 status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) { 586 Mutex::Autolock _l(mLock); 587 588 if (player == NULL) { 589 return UNKNOWN_ERROR; 590 } 591 592 if (mRetransmitEndpointValid) { 593 return player->setRetransmitEndpoint(&mRetransmitEndpoint); 594 } 595 596 return OK; 597 } 598 599 status_t MediaPlayer::reset() 600 { 601 ALOGV("reset"); 602 Mutex::Autolock _l(mLock); 603 return reset_l(); 604 } 605 606 status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type) 607 { 608 ALOGV("MediaPlayer::setAudioStreamType"); 609 Mutex::Autolock _l(mLock); 610 if (mStreamType == type) return NO_ERROR; 611 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 612 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) { 613 // Can't change the stream type after prepare 614 ALOGE("setAudioStream called in state %d", mCurrentState); 615 return INVALID_OPERATION; 616 } 617 // cache 618 mStreamType = type; 619 return OK; 620 } 621 622 status_t MediaPlayer::getAudioStreamType(audio_stream_type_t *type) 623 { 624 ALOGV("getAudioStreamType"); 625 Mutex::Autolock _l(mLock); 626 *type = mStreamType; 627 return OK; 628 } 629 630 status_t MediaPlayer::setLooping(int loop) 631 { 632 ALOGV("MediaPlayer::setLooping"); 633 Mutex::Autolock _l(mLock); 634 mLoop = (loop != 0); 635 if (mPlayer != 0) { 636 return mPlayer->setLooping(loop); 637 } 638 return OK; 639 } 640 641 bool MediaPlayer::isLooping() { 642 ALOGV("isLooping"); 643 Mutex::Autolock _l(mLock); 644 if (mPlayer != 0) { 645 return mLoop; 646 } 647 ALOGV("isLooping: no active player"); 648 return false; 649 } 650 651 status_t MediaPlayer::setVolume(float leftVolume, float rightVolume) 652 { 653 ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume); 654 Mutex::Autolock _l(mLock); 655 mLeftVolume = leftVolume; 656 mRightVolume = rightVolume; 657 if (mPlayer != 0) { 658 return mPlayer->setVolume(leftVolume, rightVolume); 659 } 660 return OK; 661 } 662 663 status_t MediaPlayer::setAudioSessionId(audio_session_t sessionId) 664 { 665 ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId); 666 Mutex::Autolock _l(mLock); 667 if (!(mCurrentState & MEDIA_PLAYER_IDLE)) { 668 ALOGE("setAudioSessionId called in state %d", mCurrentState); 669 return INVALID_OPERATION; 670 } 671 if (sessionId < 0) { 672 return BAD_VALUE; 673 } 674 if (sessionId != mAudioSessionId) { 675 AudioSystem::acquireAudioSessionId(sessionId, -1); 676 AudioSystem::releaseAudioSessionId(mAudioSessionId, -1); 677 mAudioSessionId = sessionId; 678 } 679 return NO_ERROR; 680 } 681 682 audio_session_t MediaPlayer::getAudioSessionId() 683 { 684 Mutex::Autolock _l(mLock); 685 return mAudioSessionId; 686 } 687 688 status_t MediaPlayer::setAuxEffectSendLevel(float level) 689 { 690 ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level); 691 Mutex::Autolock _l(mLock); 692 mSendLevel = level; 693 if (mPlayer != 0) { 694 return mPlayer->setAuxEffectSendLevel(level); 695 } 696 return OK; 697 } 698 699 status_t MediaPlayer::attachAuxEffect(int effectId) 700 { 701 ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId); 702 Mutex::Autolock _l(mLock); 703 if (mPlayer == 0 || 704 (mCurrentState & MEDIA_PLAYER_IDLE) || 705 (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) { 706 ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 707 return INVALID_OPERATION; 708 } 709 710 return mPlayer->attachAuxEffect(effectId); 711 } 712 713 // always call with lock held 714 status_t MediaPlayer::checkStateForKeySet_l(int key) 715 { 716 switch(key) { 717 case KEY_PARAMETER_AUDIO_ATTRIBUTES: 718 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 719 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) { 720 // Can't change the audio attributes after prepare 721 ALOGE("trying to set audio attributes called in state %d", mCurrentState); 722 return INVALID_OPERATION; 723 } 724 break; 725 default: 726 // parameter doesn't require player state check 727 break; 728 } 729 return OK; 730 } 731 732 status_t MediaPlayer::setParameter(int key, const Parcel& request) 733 { 734 ALOGV("MediaPlayer::setParameter(%d)", key); 735 status_t status = INVALID_OPERATION; 736 Mutex::Autolock _l(mLock); 737 if (checkStateForKeySet_l(key) != OK) { 738 return status; 739 } 740 switch (key) { 741 case KEY_PARAMETER_AUDIO_ATTRIBUTES: 742 // save the marshalled audio attributes 743 if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; }; 744 mAudioAttributesParcel = new Parcel(); 745 mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize()); 746 status = OK; 747 break; 748 default: 749 ALOGV_IF(mPlayer == NULL, "setParameter: no active player"); 750 break; 751 } 752 753 if (mPlayer != NULL) { 754 status = mPlayer->setParameter(key, request); 755 } 756 return status; 757 } 758 759 status_t MediaPlayer::getParameter(int key, Parcel *reply) 760 { 761 ALOGV("MediaPlayer::getParameter(%d)", key); 762 Mutex::Autolock _l(mLock); 763 if (mPlayer != NULL) { 764 return mPlayer->getParameter(key, reply); 765 } 766 ALOGV("getParameter: no active player"); 767 return INVALID_OPERATION; 768 } 769 770 status_t MediaPlayer::setRetransmitEndpoint(const char* addrString, 771 uint16_t port) { 772 ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)", 773 addrString ? addrString : "(null)", port); 774 775 Mutex::Autolock _l(mLock); 776 if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE)) 777 return INVALID_OPERATION; 778 779 if (NULL == addrString) { 780 mRetransmitEndpointValid = false; 781 return OK; 782 } 783 784 struct in_addr saddr; 785 if(!inet_aton(addrString, &saddr)) { 786 return BAD_VALUE; 787 } 788 789 memset(&mRetransmitEndpoint, 0, sizeof(mRetransmitEndpoint)); 790 mRetransmitEndpoint.sin_family = AF_INET; 791 mRetransmitEndpoint.sin_addr = saddr; 792 mRetransmitEndpoint.sin_port = htons(port); 793 mRetransmitEndpointValid = true; 794 795 return OK; 796 } 797 798 void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) 799 { 800 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); 801 bool send = true; 802 bool locked = false; 803 804 // TODO: In the future, we might be on the same thread if the app is 805 // running in the same process as the media server. In that case, 806 // this will deadlock. 807 // 808 // The threadId hack below works around this for the care of prepare, 809 // seekTo and start within the same process. 810 // FIXME: Remember, this is a hack, it's not even a hack that is applied 811 // consistently for all use-cases, this needs to be revisited. 812 if (mLockThreadId != getThreadId()) { 813 mLock.lock(); 814 locked = true; 815 } 816 817 // Allows calls from JNI in idle state to notify errors 818 if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) { 819 ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2); 820 if (locked) mLock.unlock(); // release the lock when done. 821 return; 822 } 823 824 switch (msg) { 825 case MEDIA_NOP: // interface test message 826 break; 827 case MEDIA_PREPARED: 828 ALOGV("prepared"); 829 mCurrentState = MEDIA_PLAYER_PREPARED; 830 if (mPrepareSync) { 831 ALOGV("signal application thread"); 832 mPrepareSync = false; 833 mPrepareStatus = NO_ERROR; 834 mSignal.signal(); 835 } 836 break; 837 case MEDIA_PLAYBACK_COMPLETE: 838 ALOGV("playback complete"); 839 if (mCurrentState == MEDIA_PLAYER_IDLE) { 840 ALOGE("playback complete in idle state"); 841 } 842 if (!mLoop) { 843 mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE; 844 } 845 break; 846 case MEDIA_ERROR: 847 // Always log errors. 848 // ext1: Media framework error code. 849 // ext2: Implementation dependant error code. 850 ALOGE("error (%d, %d)", ext1, ext2); 851 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 852 if (mPrepareSync) 853 { 854 ALOGV("signal application thread"); 855 mPrepareSync = false; 856 mPrepareStatus = ext1; 857 mSignal.signal(); 858 send = false; 859 } 860 break; 861 case MEDIA_INFO: 862 // ext1: Media framework error code. 863 // ext2: Implementation dependant error code. 864 if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) { 865 ALOGW("info/warning (%d, %d)", ext1, ext2); 866 } 867 break; 868 case MEDIA_SEEK_COMPLETE: 869 ALOGV("Received seek complete"); 870 if (mSeekPosition != mCurrentPosition) { 871 ALOGV("Executing queued seekTo(%d)", mSeekPosition); 872 mSeekPosition = -1; 873 seekTo_l(mCurrentPosition); 874 } 875 else { 876 ALOGV("All seeks complete - return to regularly scheduled program"); 877 mCurrentPosition = mSeekPosition = -1; 878 } 879 break; 880 case MEDIA_BUFFERING_UPDATE: 881 ALOGV("buffering %d", ext1); 882 break; 883 case MEDIA_SET_VIDEO_SIZE: 884 ALOGV("New video size %d x %d", ext1, ext2); 885 mVideoWidth = ext1; 886 mVideoHeight = ext2; 887 break; 888 case MEDIA_TIMED_TEXT: 889 ALOGV("Received timed text message"); 890 break; 891 case MEDIA_SUBTITLE_DATA: 892 ALOGV("Received subtitle data message"); 893 break; 894 case MEDIA_META_DATA: 895 ALOGV("Received timed metadata message"); 896 break; 897 default: 898 ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); 899 break; 900 } 901 902 sp<MediaPlayerListener> listener = mListener; 903 if (locked) mLock.unlock(); 904 905 // this prevents re-entrant calls into client code 906 if ((listener != 0) && send) { 907 Mutex::Autolock _l(mNotifyLock); 908 ALOGV("callback application"); 909 listener->notify(msg, ext1, ext2, obj); 910 ALOGV("back from callback"); 911 } 912 } 913 914 void MediaPlayer::died() 915 { 916 ALOGV("died"); 917 notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0); 918 } 919 920 status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) { 921 Mutex::Autolock _l(mLock); 922 if (mPlayer == NULL) { 923 return NO_INIT; 924 } 925 926 if (next != NULL && !(next->mCurrentState & 927 (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 928 ALOGE("next player is not prepared"); 929 return INVALID_OPERATION; 930 } 931 932 return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer); 933 } 934 935 } // namespace android 936