1. 程式人生 > 其它 >Android 12(S) MultiMedia Learning(三)MediaPlayer Native

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