mediaplayer.cpp revision a3f1fa308728976fc9ca1b4f37d26e633b32b9ac
1/* mediaplayer.cpp 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#include <utils/Log.h> 21 22#include <sys/types.h> 23#include <sys/stat.h> 24#include <unistd.h> 25#include <fcntl.h> 26 27#include <binder/IServiceManager.h> 28#include <binder/IPCThreadState.h> 29 30#include <gui/SurfaceTextureClient.h> 31 32#include <media/mediaplayer.h> 33#include <media/AudioSystem.h> 34 35#include <surfaceflinger/Surface.h> 36 37#include <binder/MemoryBase.h> 38 39#include <utils/KeyedVector.h> 40#include <utils/String8.h> 41 42#include <system/audio.h> 43#include <system/window.h> 44 45namespace android { 46 47MediaPlayer::MediaPlayer() 48{ 49 ALOGV("constructor"); 50 mListener = NULL; 51 mCookie = NULL; 52 mDuration = -1; 53 mStreamType = AUDIO_STREAM_MUSIC; 54 mCurrentPosition = -1; 55 mSeekPosition = -1; 56 mCurrentState = MEDIA_PLAYER_IDLE; 57 mPrepareSync = false; 58 mPrepareStatus = NO_ERROR; 59 mLoop = false; 60 mLeftVolume = mRightVolume = 1.0; 61 mVideoWidth = mVideoHeight = 0; 62 mLockThreadId = 0; 63 mAudioSessionId = AudioSystem::newAudioSessionId(); 64 AudioSystem::acquireAudioSessionId(mAudioSessionId); 65 mSendLevel = 0; 66} 67 68MediaPlayer::~MediaPlayer() 69{ 70 ALOGV("destructor"); 71 AudioSystem::releaseAudioSessionId(mAudioSessionId); 72 disconnect(); 73 IPCThreadState::self()->flushCommands(); 74} 75 76void MediaPlayer::disconnect() 77{ 78 ALOGV("disconnect"); 79 sp<IMediaPlayer> p; 80 { 81 Mutex::Autolock _l(mLock); 82 p = mPlayer; 83 mPlayer.clear(); 84 } 85 86 if (p != 0) { 87 p->disconnect(); 88 } 89} 90 91// always call with lock held 92void MediaPlayer::clear_l() 93{ 94 mDuration = -1; 95 mCurrentPosition = -1; 96 mSeekPosition = -1; 97 mVideoWidth = mVideoHeight = 0; 98} 99 100status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener) 101{ 102 ALOGV("setListener"); 103 Mutex::Autolock _l(mLock); 104 mListener = listener; 105 return NO_ERROR; 106} 107 108 109status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player) 110{ 111 status_t err = UNKNOWN_ERROR; 112 sp<IMediaPlayer> p; 113 { // scope for the lock 114 Mutex::Autolock _l(mLock); 115 116 if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) || 117 (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) { 118 ALOGE("attachNewPlayer called in state %d", mCurrentState); 119 return INVALID_OPERATION; 120 } 121 122 clear_l(); 123 p = mPlayer; 124 mPlayer = player; 125 if (player != 0) { 126 mCurrentState = MEDIA_PLAYER_INITIALIZED; 127 err = NO_ERROR; 128 } else { 129 ALOGE("Unable to to create media player"); 130 } 131 } 132 133 if (p != 0) { 134 p->disconnect(); 135 } 136 137 return err; 138} 139 140status_t MediaPlayer::setDataSource( 141 const char *url, const KeyedVector<String8, String8> *headers) 142{ 143 ALOGV("setDataSource(%s)", url); 144 status_t err = BAD_VALUE; 145 if (url != NULL) { 146 const sp<IMediaPlayerService>& service(getMediaPlayerService()); 147 if (service != 0) { 148 sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); 149 if (NO_ERROR != player->setDataSource(url, headers)) { 150 player.clear(); 151 } 152 err = attachNewPlayer(player); 153 } 154 } 155 return err; 156} 157 158status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length) 159{ 160 ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 161 status_t err = UNKNOWN_ERROR; 162 const sp<IMediaPlayerService>& service(getMediaPlayerService()); 163 if (service != 0) { 164 sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); 165 if (NO_ERROR != player->setDataSource(fd, offset, length)) { 166 player.clear(); 167 } 168 err = attachNewPlayer(player); 169 } 170 return err; 171} 172 173status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source) 174{ 175 ALOGV("setDataSource"); 176 status_t err = UNKNOWN_ERROR; 177 const sp<IMediaPlayerService>& service(getMediaPlayerService()); 178 if (service != 0) { 179 sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); 180 if (NO_ERROR != player->setDataSource(source)) { 181 player.clear(); 182 } 183 err = attachNewPlayer(player); 184 } 185 return err; 186} 187 188status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply) 189{ 190 Mutex::Autolock _l(mLock); 191 const bool hasBeenInitialized = 192 (mCurrentState != MEDIA_PLAYER_STATE_ERROR) && 193 ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE); 194 if ((mPlayer != NULL) && hasBeenInitialized) { 195 ALOGV("invoke %d", request.dataSize()); 196 return mPlayer->invoke(request, reply); 197 } 198 ALOGE("invoke failed: wrong state %X", mCurrentState); 199 return INVALID_OPERATION; 200} 201 202status_t MediaPlayer::setMetadataFilter(const Parcel& filter) 203{ 204 ALOGD("setMetadataFilter"); 205 Mutex::Autolock lock(mLock); 206 if (mPlayer == NULL) { 207 return NO_INIT; 208 } 209 return mPlayer->setMetadataFilter(filter); 210} 211 212status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata) 213{ 214 ALOGD("getMetadata"); 215 Mutex::Autolock lock(mLock); 216 if (mPlayer == NULL) { 217 return NO_INIT; 218 } 219 return mPlayer->getMetadata(update_only, apply_filter, metadata); 220} 221 222status_t MediaPlayer::setVideoSurfaceTexture( 223 const sp<ISurfaceTexture>& surfaceTexture) 224{ 225 ALOGV("setVideoSurfaceTexture"); 226 Mutex::Autolock _l(mLock); 227 if (mPlayer == 0) return NO_INIT; 228 return mPlayer->setVideoSurfaceTexture(surfaceTexture); 229} 230 231// must call with lock held 232status_t MediaPlayer::prepareAsync_l() 233{ 234 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) { 235 mPlayer->setAudioStreamType(mStreamType); 236 mCurrentState = MEDIA_PLAYER_PREPARING; 237 return mPlayer->prepareAsync(); 238 } 239 ALOGE("prepareAsync called in state %d", mCurrentState); 240 return INVALID_OPERATION; 241} 242 243// TODO: In case of error, prepareAsync provides the caller with 2 error codes, 244// one defined in the Android framework and one provided by the implementation 245// that generated the error. The sync version of prepare returns only 1 error 246// code. 247status_t MediaPlayer::prepare() 248{ 249 ALOGV("prepare"); 250 Mutex::Autolock _l(mLock); 251 mLockThreadId = getThreadId(); 252 if (mPrepareSync) { 253 mLockThreadId = 0; 254 return -EALREADY; 255 } 256 mPrepareSync = true; 257 status_t ret = prepareAsync_l(); 258 if (ret != NO_ERROR) { 259 mLockThreadId = 0; 260 return ret; 261 } 262 263 if (mPrepareSync) { 264 mSignal.wait(mLock); // wait for prepare done 265 mPrepareSync = false; 266 } 267 ALOGV("prepare complete - status=%d", mPrepareStatus); 268 mLockThreadId = 0; 269 return mPrepareStatus; 270} 271 272status_t MediaPlayer::prepareAsync() 273{ 274 ALOGV("prepareAsync"); 275 Mutex::Autolock _l(mLock); 276 return prepareAsync_l(); 277} 278 279status_t MediaPlayer::start() 280{ 281 ALOGV("start"); 282 Mutex::Autolock _l(mLock); 283 if (mCurrentState & MEDIA_PLAYER_STARTED) 284 return NO_ERROR; 285 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED | 286 MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) { 287 mPlayer->setLooping(mLoop); 288 mPlayer->setVolume(mLeftVolume, mRightVolume); 289 mPlayer->setAuxEffectSendLevel(mSendLevel); 290 mCurrentState = MEDIA_PLAYER_STARTED; 291 status_t ret = mPlayer->start(); 292 if (ret != NO_ERROR) { 293 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 294 } else { 295 if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) { 296 ALOGV("playback completed immediately following start()"); 297 } 298 } 299 return ret; 300 } 301 ALOGE("start called in state %d", mCurrentState); 302 return INVALID_OPERATION; 303} 304 305status_t MediaPlayer::stop() 306{ 307 ALOGV("stop"); 308 Mutex::Autolock _l(mLock); 309 if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR; 310 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | 311 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) { 312 status_t ret = mPlayer->stop(); 313 if (ret != NO_ERROR) { 314 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 315 } else { 316 mCurrentState = MEDIA_PLAYER_STOPPED; 317 } 318 return ret; 319 } 320 ALOGE("stop called in state %d", mCurrentState); 321 return INVALID_OPERATION; 322} 323 324status_t MediaPlayer::pause() 325{ 326 ALOGV("pause"); 327 Mutex::Autolock _l(mLock); 328 if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE)) 329 return NO_ERROR; 330 if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) { 331 status_t ret = mPlayer->pause(); 332 if (ret != NO_ERROR) { 333 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 334 } else { 335 mCurrentState = MEDIA_PLAYER_PAUSED; 336 } 337 return ret; 338 } 339 ALOGE("pause called in state %d", mCurrentState); 340 return INVALID_OPERATION; 341} 342 343bool MediaPlayer::isPlaying() 344{ 345 Mutex::Autolock _l(mLock); 346 if (mPlayer != 0) { 347 bool temp = false; 348 mPlayer->isPlaying(&temp); 349 ALOGV("isPlaying: %d", temp); 350 if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) { 351 ALOGE("internal/external state mismatch corrected"); 352 mCurrentState = MEDIA_PLAYER_PAUSED; 353 } 354 return temp; 355 } 356 ALOGV("isPlaying: no active player"); 357 return false; 358} 359 360status_t MediaPlayer::getVideoWidth(int *w) 361{ 362 ALOGV("getVideoWidth"); 363 Mutex::Autolock _l(mLock); 364 if (mPlayer == 0) return INVALID_OPERATION; 365 *w = mVideoWidth; 366 return NO_ERROR; 367} 368 369status_t MediaPlayer::getVideoHeight(int *h) 370{ 371 ALOGV("getVideoHeight"); 372 Mutex::Autolock _l(mLock); 373 if (mPlayer == 0) return INVALID_OPERATION; 374 *h = mVideoHeight; 375 return NO_ERROR; 376} 377 378status_t MediaPlayer::getCurrentPosition(int *msec) 379{ 380 ALOGV("getCurrentPosition"); 381 Mutex::Autolock _l(mLock); 382 if (mPlayer != 0) { 383 if (mCurrentPosition >= 0) { 384 ALOGV("Using cached seek position: %d", mCurrentPosition); 385 *msec = mCurrentPosition; 386 return NO_ERROR; 387 } 388 return mPlayer->getCurrentPosition(msec); 389 } 390 return INVALID_OPERATION; 391} 392 393status_t MediaPlayer::getDuration_l(int *msec) 394{ 395 ALOGV("getDuration"); 396 bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE)); 397 if (mPlayer != 0 && isValidState) { 398 status_t ret = NO_ERROR; 399 if (mDuration <= 0) 400 ret = mPlayer->getDuration(&mDuration); 401 if (msec) 402 *msec = mDuration; 403 return ret; 404 } 405 ALOGE("Attempt to call getDuration without a valid mediaplayer"); 406 return INVALID_OPERATION; 407} 408 409status_t MediaPlayer::getDuration(int *msec) 410{ 411 Mutex::Autolock _l(mLock); 412 return getDuration_l(msec); 413} 414 415status_t MediaPlayer::seekTo_l(int msec) 416{ 417 ALOGV("seekTo %d", msec); 418 if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) { 419 if ( msec < 0 ) { 420 ALOGW("Attempt to seek to invalid position: %d", msec); 421 msec = 0; 422 } else if ((mDuration > 0) && (msec > mDuration)) { 423 ALOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration); 424 msec = mDuration; 425 } 426 // cache duration 427 mCurrentPosition = msec; 428 if (mSeekPosition < 0) { 429 getDuration_l(NULL); 430 mSeekPosition = msec; 431 return mPlayer->seekTo(msec); 432 } 433 else { 434 ALOGV("Seek in progress - queue up seekTo[%d]", msec); 435 return NO_ERROR; 436 } 437 } 438 ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), mCurrentState); 439 return INVALID_OPERATION; 440} 441 442status_t MediaPlayer::seekTo(int msec) 443{ 444 mLockThreadId = getThreadId(); 445 Mutex::Autolock _l(mLock); 446 status_t result = seekTo_l(msec); 447 mLockThreadId = 0; 448 449 return result; 450} 451 452status_t MediaPlayer::reset_l() 453{ 454 mLoop = false; 455 if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR; 456 mPrepareSync = false; 457 if (mPlayer != 0) { 458 status_t ret = mPlayer->reset(); 459 if (ret != NO_ERROR) { 460 ALOGE("reset() failed with return code (%d)", ret); 461 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 462 } else { 463 mCurrentState = MEDIA_PLAYER_IDLE; 464 } 465 // setDataSource has to be called again to create a 466 // new mediaplayer. 467 mPlayer = 0; 468 return ret; 469 } 470 clear_l(); 471 return NO_ERROR; 472} 473 474status_t MediaPlayer::reset() 475{ 476 ALOGV("reset"); 477 Mutex::Autolock _l(mLock); 478 return reset_l(); 479} 480 481status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type) 482{ 483 ALOGV("MediaPlayer::setAudioStreamType"); 484 Mutex::Autolock _l(mLock); 485 if (mStreamType == type) return NO_ERROR; 486 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | 487 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) { 488 // Can't change the stream type after prepare 489 ALOGE("setAudioStream called in state %d", mCurrentState); 490 return INVALID_OPERATION; 491 } 492 // cache 493 mStreamType = type; 494 return OK; 495} 496 497status_t MediaPlayer::setLooping(int loop) 498{ 499 ALOGV("MediaPlayer::setLooping"); 500 Mutex::Autolock _l(mLock); 501 mLoop = (loop != 0); 502 if (mPlayer != 0) { 503 return mPlayer->setLooping(loop); 504 } 505 return OK; 506} 507 508bool MediaPlayer::isLooping() { 509 ALOGV("isLooping"); 510 Mutex::Autolock _l(mLock); 511 if (mPlayer != 0) { 512 return mLoop; 513 } 514 ALOGV("isLooping: no active player"); 515 return false; 516} 517 518status_t MediaPlayer::setVolume(float leftVolume, float rightVolume) 519{ 520 ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume); 521 Mutex::Autolock _l(mLock); 522 mLeftVolume = leftVolume; 523 mRightVolume = rightVolume; 524 if (mPlayer != 0) { 525 return mPlayer->setVolume(leftVolume, rightVolume); 526 } 527 return OK; 528} 529 530status_t MediaPlayer::setAudioSessionId(int sessionId) 531{ 532 ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId); 533 Mutex::Autolock _l(mLock); 534 if (!(mCurrentState & MEDIA_PLAYER_IDLE)) { 535 ALOGE("setAudioSessionId called in state %d", mCurrentState); 536 return INVALID_OPERATION; 537 } 538 if (sessionId < 0) { 539 return BAD_VALUE; 540 } 541 if (sessionId != mAudioSessionId) { 542 AudioSystem::releaseAudioSessionId(mAudioSessionId); 543 AudioSystem::acquireAudioSessionId(sessionId); 544 mAudioSessionId = sessionId; 545 } 546 return NO_ERROR; 547} 548 549int MediaPlayer::getAudioSessionId() 550{ 551 Mutex::Autolock _l(mLock); 552 return mAudioSessionId; 553} 554 555status_t MediaPlayer::setAuxEffectSendLevel(float level) 556{ 557 ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level); 558 Mutex::Autolock _l(mLock); 559 mSendLevel = level; 560 if (mPlayer != 0) { 561 return mPlayer->setAuxEffectSendLevel(level); 562 } 563 return OK; 564} 565 566status_t MediaPlayer::attachAuxEffect(int effectId) 567{ 568 ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId); 569 Mutex::Autolock _l(mLock); 570 if (mPlayer == 0 || 571 (mCurrentState & MEDIA_PLAYER_IDLE) || 572 (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) { 573 ALOGE("attachAuxEffect called in state %d", mCurrentState); 574 return INVALID_OPERATION; 575 } 576 577 return mPlayer->attachAuxEffect(effectId); 578} 579 580status_t MediaPlayer::setParameter(int key, const Parcel& request) 581{ 582 ALOGV("MediaPlayer::setParameter(%d)", key); 583 Mutex::Autolock _l(mLock); 584 if (mPlayer != NULL) { 585 return mPlayer->setParameter(key, request); 586 } 587 ALOGV("setParameter: no active player"); 588 return INVALID_OPERATION; 589} 590 591status_t MediaPlayer::getParameter(int key, Parcel *reply) 592{ 593 ALOGV("MediaPlayer::getParameter(%d)", key); 594 Mutex::Autolock _l(mLock); 595 if (mPlayer != NULL) { 596 return mPlayer->getParameter(key, reply); 597 } 598 ALOGV("getParameter: no active player"); 599 return INVALID_OPERATION; 600} 601 602void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) 603{ 604 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); 605 bool send = true; 606 bool locked = false; 607 608 // TODO: In the future, we might be on the same thread if the app is 609 // running in the same process as the media server. In that case, 610 // this will deadlock. 611 // 612 // The threadId hack below works around this for the care of prepare 613 // and seekTo within the same process. 614 // FIXME: Remember, this is a hack, it's not even a hack that is applied 615 // consistently for all use-cases, this needs to be revisited. 616 if (mLockThreadId != getThreadId()) { 617 mLock.lock(); 618 locked = true; 619 } 620 621 // Allows calls from JNI in idle state to notify errors 622 if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) { 623 ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2); 624 if (locked) mLock.unlock(); // release the lock when done. 625 return; 626 } 627 628 switch (msg) { 629 case MEDIA_NOP: // interface test message 630 break; 631 case MEDIA_PREPARED: 632 ALOGV("prepared"); 633 mCurrentState = MEDIA_PLAYER_PREPARED; 634 if (mPrepareSync) { 635 ALOGV("signal application thread"); 636 mPrepareSync = false; 637 mPrepareStatus = NO_ERROR; 638 mSignal.signal(); 639 } 640 break; 641 case MEDIA_PLAYBACK_COMPLETE: 642 ALOGV("playback complete"); 643 if (mCurrentState == MEDIA_PLAYER_IDLE) { 644 ALOGE("playback complete in idle state"); 645 } 646 if (!mLoop) { 647 mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE; 648 } 649 break; 650 case MEDIA_ERROR: 651 // Always log errors. 652 // ext1: Media framework error code. 653 // ext2: Implementation dependant error code. 654 ALOGE("error (%d, %d)", ext1, ext2); 655 mCurrentState = MEDIA_PLAYER_STATE_ERROR; 656 if (mPrepareSync) 657 { 658 ALOGV("signal application thread"); 659 mPrepareSync = false; 660 mPrepareStatus = ext1; 661 mSignal.signal(); 662 send = false; 663 } 664 break; 665 case MEDIA_INFO: 666 // ext1: Media framework error code. 667 // ext2: Implementation dependant error code. 668 if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) { 669 ALOGW("info/warning (%d, %d)", ext1, ext2); 670 } 671 break; 672 case MEDIA_SEEK_COMPLETE: 673 ALOGV("Received seek complete"); 674 if (mSeekPosition != mCurrentPosition) { 675 ALOGV("Executing queued seekTo(%d)", mSeekPosition); 676 mSeekPosition = -1; 677 seekTo_l(mCurrentPosition); 678 } 679 else { 680 ALOGV("All seeks complete - return to regularly scheduled program"); 681 mCurrentPosition = mSeekPosition = -1; 682 } 683 break; 684 case MEDIA_BUFFERING_UPDATE: 685 ALOGV("buffering %d", ext1); 686 break; 687 case MEDIA_SET_VIDEO_SIZE: 688 ALOGV("New video size %d x %d", ext1, ext2); 689 mVideoWidth = ext1; 690 mVideoHeight = ext2; 691 break; 692 case MEDIA_TIMED_TEXT: 693 ALOGV("Received timed text message"); 694 break; 695 default: 696 ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); 697 break; 698 } 699 700 sp<MediaPlayerListener> listener = mListener; 701 if (locked) mLock.unlock(); 702 703 // this prevents re-entrant calls into client code 704 if ((listener != 0) && send) { 705 Mutex::Autolock _l(mNotifyLock); 706 ALOGV("callback application"); 707 listener->notify(msg, ext1, ext2, obj); 708 ALOGV("back from callback"); 709 } 710} 711 712/*static*/ sp<IMemory> MediaPlayer::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) 713{ 714 ALOGV("decode(%s)", url); 715 sp<IMemory> p; 716 const sp<IMediaPlayerService>& service = getMediaPlayerService(); 717 if (service != 0) { 718 p = service->decode(url, pSampleRate, pNumChannels, pFormat); 719 } else { 720 ALOGE("Unable to locate media service"); 721 } 722 return p; 723 724} 725 726void MediaPlayer::died() 727{ 728 ALOGV("died"); 729 notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0); 730} 731 732/*static*/ sp<IMemory> MediaPlayer::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) 733{ 734 ALOGV("decode(%d, %lld, %lld)", fd, offset, length); 735 sp<IMemory> p; 736 const sp<IMediaPlayerService>& service = getMediaPlayerService(); 737 if (service != 0) { 738 p = service->decode(fd, offset, length, pSampleRate, pNumChannels, pFormat); 739 } else { 740 ALOGE("Unable to locate media service"); 741 } 742 return p; 743 744} 745 746}; // namespace android 747