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中到底是什么样子的。