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 || (mCurrentState & MEDIA_PLAYER_STOPPED)) { 399 return INVALID_OPERATION; 400 } 401 402 if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER_STARTED) 403 && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED 404 | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 405 mPlayer->setLooping(mLoop); 406 mPlayer->setVolume(mLeftVolume, mRightVolume); 407 mPlayer->setAuxEffectSendLevel(mSendLevel); 408 } 409 410 status_t err = mPlayer->setPlaybackSettings(rate); 411 if (err == OK) { 412 if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER_STARTED) { 413 mCurrentState = MEDIA_PLAYER_PAUSED; 414 } else if (rate.mSpeed != 0.f 415 && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED 416 | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 417 mCurrentState = MEDIA_PLAYER_STARTED; 418 } 419 } 420 return err; 421 } 422 423 status_t MediaPlayer::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) 424 { 425 Mutex::Autolock _l(mLock); 426 if (mPlayer == 0) return INVALID_OPERATION; 427 return mPlayer->getPlaybackSettings(rate); 428 } 429 430 status_t MediaPlayer::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) 431 { 432 ALOGV("setSyncSettings: %u %u %f %f", 433 sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint); 434 Mutex::Autolock _l(mLock); 435 if (mPlayer == 0) return INVALID_OPERATION; 436 return mPlayer->setSyncSettings(sync, videoFpsHint); 437 } 438 439 status_t MediaPlayer::getSyncSettings( 440 AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) 441 { 442 Mutex::Autolock _l(mLock); 443 if (mPlayer == 0) return INVALID_OPERATION; 444 return mPlayer->getSyncSettings(sync, videoFps); 445 } 446 447 status_t MediaPlayer::getVideoWidth(int *w) 448 { 449 ALOGV("getVideoWidth"); 450 Mutex::Autolock _l(mLock); 451 if (mPlayer == 0) return INVALID_OPERATION; 452 *w = mVideoWidth; 453 return NO_ERROR; 454 } 455 456 status_t MediaPlayer::getVideoHeight(int *h) 457 { 458 ALOGV("getVideoHeight"); 459 Mutex::Autolock _l(mLock); 460 if (mPlayer == 0) return INVALID_OPERATION; 461 *h = mVideoHeight; 462 return NO_ERROR; 463 } 464 465 status_t MediaPlayer::getCurrentPosition(int *msec) 466 { 467 ALOGV("getCurrentPosition"); 468 Mutex::Autolock _l(mLock); 469 if (mPlayer != 0) { 470 if (mCurrentPosition >= 0) { 471 ALOGV("Using cached seek position: %d", mCurrentPosition); 472 *msec = mCurrentPosition; 473 return NO_ERROR; 474 } 475 return mPlayer->getCurrentPosition(msec); 476 } 477 return INVALID_OPERATION; 478 } 479 480 status_t MediaPlayer::getDuration_l(int *msec) 481 { 482 ALOGV("getDuration_l"); 483 bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 484 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE)); 485 if (mPlayer != 0 && isValidState) { 486 int durationMs; 487 status_t ret = mPlayer->getDuration(&durationMs); 488 489 if (ret != OK) { 490 // Do not enter error state just because no duration was available. 491 durationMs = -1; 492 ret = OK; 493 } 494 495 if (msec) { 496 *msec = durationMs; 497 } 498 return ret; 499 } 500 ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u", 501 mPlayer.get(), mCurrentState); 502 return INVALID_OPERATION; 503 } 504 505 status_t MediaPlayer::getDuration(int *msec) 506 { 507 Mutex::Autolock _l(mLock); 508 return getDuration_l(msec); 509 } 510 511 status_t MediaPlayer::seekTo_l(int msec) 512 { 513 ALOGV("seekTo %d", msec); 514 if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | 515 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) { 516 if ( msec < 0 ) { 517 ALOGW("Attempt to seek to invalid position: %d", msec); 518 msec = 0; 519 } 520 521 int durationMs; 522 status_t err = mPlayer->getDuration(&durationMs); 523 524 if (err != OK) { 525 ALOGW("Stream has no duration and is therefore not seekable."); 526 return err; 527 } 528 529 if (msec > durationMs) { 530 ALOGW("Attempt to seek to past end of file: request = %d, " 531 "durationMs = %d", 532 msec, 533 durationMs); 534 535 msec = durationMs; 536 } 537 538 // cache duration 539 mCurrentPosition = msec; 540 if (mSeekPosition < 0) { 541 mSeekPosition = msec; 542 return mPlayer->seekTo(msec); 543 } 544 else { 545 ALOGV("Seek in progress - queue up seekTo[%d]", msec); 546 return NO_ERROR; 547 } 548 } 549 ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), 550 mCurrentState); 551 return INVALID_OPERATION; 552 } 553 554 status_t MediaPlayer::seekTo(int msec) 555 { 556 mLockThreadId = getThreadId(); 557 Mutex::Autolock _l(mLock); 558 status_t result = seekTo_l(msec); 559 mLockThreadId = 0; 560 561 return result; 562 } 563 564 status_t MediaPlayer::reset_l() 565 { 566 mLoop = false; 567 if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR; 568 mPrepareSync = false; 569 if (mPlayer != 0) { 570 status_t ret = mPlayer->reset(); 571 if (ret != NO_ERROR) { 572 ALOGE("reset() failed with return code (%d)", ret); 573 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 574 } else { 575 mPlayer->disconnect(); 576 mCurrentState = MEDIA_PLAYER_IDLE; 577 } 578 // setDataSource has to be called again to create a 579 // new mediaplayer. 580 mPlayer = 0; 581 return ret; 582 } 583 clear_l(); 584 return NO_ERROR; 585 } 586 587 status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) { 588 Mutex::Autolock _l(mLock); 589 590 if (player == NULL) { 591 return UNKNOWN_ERROR; 592 } 593 594 if (mRetransmitEndpointValid) { 595 return player->setRetransmitEndpoint(&mRetransmitEndpoint); 596 } 597 598 return OK; 599 } 600 601 status_t MediaPlayer::reset() 602 { 603 ALOGV("reset"); 604 Mutex::Autolock _l(mLock); 605 return reset_l(); 606 } 607 608 status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type) 609 { 610 ALOGV("MediaPlayer::setAudioStreamType"); 611 Mutex::Autolock _l(mLock); 612 if (mStreamType == type) return NO_ERROR; 613 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 614 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) { 615 // Can't change the stream type after prepare 616 ALOGE("setAudioStream called in state %d", mCurrentState); 617 return INVALID_OPERATION; 618 } 619 // cache 620 mStreamType = type; 621 return OK; 622 } 623 624 status_t MediaPlayer::getAudioStreamType(audio_stream_type_t *type) 625 { 626 ALOGV("getAudioStreamType"); 627 Mutex::Autolock _l(mLock); 628 *type = mStreamType; 629 return OK; 630 } 631 632 status_t MediaPlayer::setLooping(int loop) 633 { 634 ALOGV("MediaPlayer::setLooping"); 635 Mutex::Autolock _l(mLock); 636 mLoop = (loop != 0); 637 if (mPlayer != 0) { 638 return mPlayer->setLooping(loop); 639 } 640 return OK; 641 } 642 643 bool MediaPlayer::isLooping() { 644 ALOGV("isLooping"); 645 Mutex::Autolock _l(mLock); 646 if (mPlayer != 0) { 647 return mLoop; 648 } 649 ALOGV("isLooping: no active player"); 650 return false; 651 } 652 653 status_t MediaPlayer::setVolume(float leftVolume, float rightVolume) 654 { 655 ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume); 656 Mutex::Autolock _l(mLock); 657 mLeftVolume = leftVolume; 658 mRightVolume = rightVolume; 659 if (mPlayer != 0) { 660 return mPlayer->setVolume(leftVolume, rightVolume); 661 } 662 return OK; 663 } 664 665 status_t MediaPlayer::setAudioSessionId(audio_session_t sessionId) 666 { 667 ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId); 668 Mutex::Autolock _l(mLock); 669 if (!(mCurrentState & MEDIA_PLAYER_IDLE)) { 670 ALOGE("setAudioSessionId called in state %d", mCurrentState); 671 return INVALID_OPERATION; 672 } 673 if (sessionId < 0) { 674 return BAD_VALUE; 675 } 676 if (sessionId != mAudioSessionId) { 677 AudioSystem::acquireAudioSessionId(sessionId, -1); 678 AudioSystem::releaseAudioSessionId(mAudioSessionId, -1); 679 mAudioSessionId = sessionId; 680 } 681 return NO_ERROR; 682 } 683 684 audio_session_t MediaPlayer::getAudioSessionId() 685 { 686 Mutex::Autolock _l(mLock); 687 return mAudioSessionId; 688 } 689 690 status_t MediaPlayer::setAuxEffectSendLevel(float level) 691 { 692 ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level); 693 Mutex::Autolock _l(mLock); 694 mSendLevel = level; 695 if (mPlayer != 0) { 696 return mPlayer->setAuxEffectSendLevel(level); 697 } 698 return OK; 699 } 700 701 status_t MediaPlayer::attachAuxEffect(int effectId) 702 { 703 ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId); 704 Mutex::Autolock _l(mLock); 705 if (mPlayer == 0 || 706 (mCurrentState & MEDIA_PLAYER_IDLE) || 707 (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) { 708 ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); 709 return INVALID_OPERATION; 710 } 711 712 return mPlayer->attachAuxEffect(effectId); 713 } 714 715 // always call with lock held 716 status_t MediaPlayer::checkStateForKeySet_l(int key) 717 { 718 switch(key) { 719 case KEY_PARAMETER_AUDIO_ATTRIBUTES: 720 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 721 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) { 722 // Can't change the audio attributes after prepare 723 ALOGE("trying to set audio attributes called in state %d", mCurrentState); 724 return INVALID_OPERATION; 725 } 726 break; 727 default: 728 // parameter doesn't require player state check 729 break; 730 } 731 return OK; 732 } 733 734 status_t MediaPlayer::setParameter(int key, const Parcel& request) 735 { 736 ALOGV("MediaPlayer::setParameter(%d)", key); 737 status_t status = INVALID_OPERATION; 738 Mutex::Autolock _l(mLock); 739 if (checkStateForKeySet_l(key) != OK) { 740 return status; 741 } 742 switch (key) { 743 case KEY_PARAMETER_AUDIO_ATTRIBUTES: 744 // save the marshalled audio attributes 745 if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; }; 746 mAudioAttributesParcel = new Parcel(); 747 mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize()); 748 status = OK; 749 break; 750 default: 751 ALOGV_IF(mPlayer == NULL, "setParameter: no active player"); 752 break; 753 } 754 755 if (mPlayer != NULL) { 756 status = mPlayer->setParameter(key, request); 757 } 758 return status; 759 } 760 761 status_t MediaPlayer::getParameter(int key, Parcel *reply) 762 { 763 ALOGV("MediaPlayer::getParameter(%d)", key); 764 Mutex::Autolock _l(mLock); 765 if (mPlayer != NULL) { 766 return mPlayer->getParameter(key, reply); 767 } 768 ALOGV("getParameter: no active player"); 769 return INVALID_OPERATION; 770 } 771 772 status_t MediaPlayer::setRetransmitEndpoint(const char* addrString, 773 uint16_t port) { 774 ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)", 775 addrString ? addrString : "(null)", port); 776 777 Mutex::Autolock _l(mLock); 778 if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE)) 779 return INVALID_OPERATION; 780 781 if (NULL == addrString) { 782 mRetransmitEndpointValid = false; 783 return OK; 784 } 785 786 struct in_addr saddr; 787 if(!inet_aton(addrString, &saddr)) { 788 return BAD_VALUE; 789 } 790 791 memset(&mRetransmitEndpoint, 0, sizeof(mRetransmitEndpoint)); 792 mRetransmitEndpoint.sin_family = AF_INET; 793 mRetransmitEndpoint.sin_addr = saddr; 794 mRetransmitEndpoint.sin_port = htons(port); 795 mRetransmitEndpointValid = true; 796 797 return OK; 798 } 799 800 void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) 801 { 802 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); 803 bool send = true; 804 bool locked = false; 805 806 // TODO: In the future, we might be on the same thread if the app is 807 // running in the same process as the media server. In that case, 808 // this will deadlock. 809 // 810 // The threadId hack below works around this for the care of prepare, 811 // seekTo and start within the same process. 812 // FIXME: Remember, this is a hack, it's not even a hack that is applied 813 // consistently for all use-cases, this needs to be revisited. 814 if (mLockThreadId != getThreadId()) { 815 mLock.lock(); 816 locked = true; 817 } 818 819 // Allows calls from JNI in idle state to notify errors 820 if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) { 821 ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2); 822 if (locked) mLock.unlock(); // release the lock when done. 823 return; 824 } 825 826 switch (msg) { 827 case MEDIA_NOP: // interface test message 828 break; 829 case MEDIA_PREPARED: 830 ALOGV("prepared"); 831 mCurrentState = MEDIA_PLAYER_PREPARED; 832 if (mPrepareSync) { 833 ALOGV("signal application thread"); 834 mPrepareSync = false; 835 mPrepareStatus = NO_ERROR; 836 mSignal.signal(); 837 } 838 break; 839 case MEDIA_PLAYBACK_COMPLETE: 840 ALOGV("playback complete"); 841 if (mCurrentState == MEDIA_PLAYER_IDLE) { 842 ALOGE("playback complete in idle state"); 843 } 844 if (!mLoop) { 845 mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE; 846 } 847 break; 848 case MEDIA_ERROR: 849 // Always log errors. 850 // ext1: Media framework error code. 851 // ext2: Implementation dependant error code. 852 ALOGE("error (%d, %d)", ext1, ext2); 853 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 854 if (mPrepareSync) 855 { 856 ALOGV("signal application thread"); 857 mPrepareSync = false; 858 mPrepareStatus = ext1; 859 mSignal.signal(); 860 send = false; 861 } 862 break; 863 case MEDIA_INFO: 864 // ext1: Media framework error code. 865 // ext2: Implementation dependant error code. 866 if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) { 867 ALOGW("info/warning (%d, %d)", ext1, ext2); 868 } 869 break; 870 case MEDIA_SEEK_COMPLETE: 871 ALOGV("Received seek complete"); 872 if (mSeekPosition != mCurrentPosition) { 873 ALOGV("Executing queued seekTo(%d)", mSeekPosition); 874 mSeekPosition = -1; 875 seekTo_l(mCurrentPosition); 876 } 877 else { 878 ALOGV("All seeks complete - return to regularly scheduled program"); 879 mCurrentPosition = mSeekPosition = -1; 880 } 881 break; 882 case MEDIA_BUFFERING_UPDATE: 883 ALOGV("buffering %d", ext1); 884 break; 885 case MEDIA_SET_VIDEO_SIZE: 886 ALOGV("New video size %d x %d", ext1, ext2); 887 mVideoWidth = ext1; 888 mVideoHeight = ext2; 889 break; 890 case MEDIA_TIMED_TEXT: 891 ALOGV("Received timed text message"); 892 break; 893 case MEDIA_SUBTITLE_DATA: 894 ALOGV("Received subtitle data message"); 895 break; 896 case MEDIA_META_DATA: 897 ALOGV("Received timed metadata message"); 898 break; 899 default: 900 ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); 901 break; 902 } 903 904 sp<MediaPlayerListener> listener = mListener; 905 if (locked) mLock.unlock(); 906 907 // this prevents re-entrant calls into client code 908 if ((listener != 0) && send) { 909 Mutex::Autolock _l(mNotifyLock); 910 ALOGV("callback application"); 911 listener->notify(msg, ext1, ext2, obj); 912 ALOGV("back from callback"); 913 } 914 } 915 916 void MediaPlayer::died() 917 { 918 ALOGV("died"); 919 notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0); 920 } 921 922 status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) { 923 Mutex::Autolock _l(mLock); 924 if (mPlayer == NULL) { 925 return NO_INIT; 926 } 927 928 if (next != NULL && !(next->mCurrentState & 929 (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 930 ALOGE("next player is not prepared"); 931 return INVALID_OPERATION; 932 } 933 934 return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer); 935 } 936 937 } // namespace android 938