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