Android 12(S) MultiMedia Learning(三)MediaPlayer Native
上一篇MediaPlayer中看到實現一個最簡單的播放器只需要5個介面,接下來會看看這些介面實現內容
/********************************************************** * Java -> C++ * 建構函式 建構函式 * setDataSource setDataSource * setDisPlay setVideoSurfaceTexture * prepareAsync prepareAsync * start start **********************************************************/
native mediaplayer 程式碼位置http://aospxref.com/android-12.0.0_r3/xref/frameworks/av/media/libmedia/mediaplayer.cpp
1、建構函式
建構函式主要是初始化了一些成員變數,獲取了一個audio_session_t,後面會利用這個session來建立audioSink
MediaPlayer::MediaPlayer(const AttributionSourceState& attributionSource) : mAttributionSource(attributionSource) { ALOGV("constructor"); mListener = NULL; mCookie = NULL; mStreamType = AUDIO_STREAM_MUSIC; mAudioAttributesParcel = NULL; mCurrentPosition = -1; mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; mSeekPosition = -1; mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC; mCurrentState= MEDIA_PLAYER_IDLE; mPrepareSync = false; mPrepareStatus = NO_ERROR; mLoop = false; mLeftVolume = mRightVolume = 1.0; mVideoWidth = mVideoHeight = 0; mLockThreadId = 0; mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION); AudioSystem::acquireAudioSessionId(mAudioSessionId, (pid_t)-1, (uid_t)-1); // always in client. mSendLevel = 0; mRetransmitEndpointValid = false; }
2、setDataSource
setDataSource做的內容相當重要:
a. getMediaPlayerService獲取media.player服務
b. 呼叫service的create方法例項化mPlayer
c. setDataSource
status_t MediaPlayer::setDataSource( const sp<IMediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers) { ALOGV("setDataSource(%s)", url); status_t err = BAD_VALUE; if (url != NULL) { const sp<IMediaPlayerService> service(getMediaPlayerService()); if (service != 0) { sp<IMediaPlayer> player(service->create(this, mAudioSessionId, mAttributionSource)); if ((NO_ERROR != doSetRetransmitEndpoint(player)) || (NO_ERROR != player->setDataSource(httpService, url, headers))) { player.clear(); } err = attachNewPlayer(player); } } return err; }
3、setVideoSurfaceTexture
這裡也很簡單,呼叫IMediaPlayer的setVideoSurfaceTexture
status_t MediaPlayer::setVideoSurfaceTexture( const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setVideoSurfaceTexture"); Mutex::Autolock _l(mLock); if (mPlayer == 0) return NO_INIT; return mPlayer->setVideoSurfaceTexture(bufferProducer); }
4、prepareAsync
prepareAsync做了兩件事:
a. 呼叫IMediaPlayer的setAudioStreamType方法,mStreamType在建構函式中被初始化為AUDIO_STREAM_MUSIC
b. 呼叫IMediaPlayer的prepareAsync方法
status_t MediaPlayer::prepareAsync() { ALOGV("prepareAsync"); Mutex::Autolock _l(mLock); return prepareAsync_l(); } status_t MediaPlayer::prepareAsync_l() { if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) { if (mAudioAttributesParcel != NULL) { mPlayer->setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel); } else { mPlayer->setAudioStreamType(mStreamType); } mCurrentState = MEDIA_PLAYER_PREPARING; return mPlayer->prepareAsync(); } ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); return INVALID_OPERATION; }
5、start/pause/stop/seekTo
在這裡做了三件事:
a. setLooping
b. setVolume
c. start
status_t MediaPlayer::start() { ALOGV("start"); status_t ret = NO_ERROR; Mutex::Autolock _l(mLock); mLockThreadId = getThreadId(); if (mCurrentState & MEDIA_PLAYER_STARTED) { ret = NO_ERROR; } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) { mPlayer->setLooping(mLoop); mPlayer->setVolume(mLeftVolume, mRightVolume); mPlayer->setAuxEffectSendLevel(mSendLevel); mCurrentState = MEDIA_PLAYER_STARTED; ret = mPlayer->start(); if (ret != NO_ERROR) { mCurrentState = MEDIA_PLAYER_STATE_ERROR; } else { if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) { ALOGV("playback completed immediately following start()"); } } } else { ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get()); ret = INVALID_OPERATION; } mLockThreadId = 0; return ret; }
看到這裡,Native MediaPlayer主要操作的是一個從mediaplayerservice中獲取到的IMediaPlayer物件,下面一節會看看mediaplayerservice以及IMediaPlayer中到底是什麼樣子的。