您的位置:首页 > 运维架构 > 网站架构

stagefright 架构分析(三) stagefright 功能和调用流程

2013-02-07 11:25 363 查看
stagefright继承于MediaPlayerInterface

通过VideoView对MediaPlayer的调用关系,分析一下MediaPlayer的接口层

VideoView:openVideo(){

mMediaPlayer = new MediaPlayer();

//设定回调函数

mMediaPlayer.setOnPreparedListener(mPreparedListener);

mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);

mMediaPlayer.setOnInfoListener(mInfoListener);

mDuration = -1;

mMediaPlayer.setOnCompletionListener(mCompletionListener);

mMediaPlayer.setOnErrorListener(mErrorListener);

mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);

mCurrentBufferPercentage = 0;

//传入URL

mMediaPlayer.setDataSource(mContext, mUri, mHeaders);

//与Surface建立链接

mMediaPlayer.setDisplay(mSurfaceHolder);

mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

mMediaPlayer.setScreenOnWhilePlaying(true);

//异步Prepare

mMediaPlayer.prepareAsync();

}

这里主要介绍setDataSource和prepareAsync,这是初始化的关键

注:创建Player,真正实现是MediaPlayerService创建的client,比较简单,不做介绍。

setDataSource有三种输入

const sp<IStreamSource> &source

int fd, int64_t offset, int64_t length

const char *uri, const KeyedVector<String8, String8> *headers

这里主要介绍URI方式,因为比较容易理解

setDataSource主要是保存URI

mStats.mFd = -1;

mStats.mURI = mUri;

prepareAsync:

status_t AwesomePlayer::prepareAsync_l() {

//创建onPrepareAsyncEvent事件,并post到TimedEventQueue中

mAsyncPrepareEvent = new AwesomeEvent(

this, &AwesomePlayer::onPrepareAsyncEvent);

mQueue.postEvent(mAsyncPrepareEvent);

}

AwesomePlayer::onPrepareAsyncEvent() {

//创建extractor

status_t err = finishSetDataSource_l();

//创建video decoder

status_t err = initVideoDecoder();

//创建audio decoder

status_t err = initAudioDecoder();

if (isStreamingHTTP()) {

//如果是网络流,调用onBufferingUpdate Event

postBufferingEvent_l();

} else {

//本地流,通知应用层,prepare完成

finishAsyncPrepare_l();

}

}

Prepare完成后,开始继续进入正常播放状态

当通知应用层prepare完成,最终调用

Videoview:mPreparedListener: onPrepared() {

//最主要的功能是调用

start();

}

后续在正常播放中,就会调用

virtual status_t start() = 0;

virtual status_t stop() = 0;

virtual status_t pause() = 0;

virtual status_t seekTo(int msec) = 0;

完成实际操作

下面是所有继承MediaPlayerInterface的接口

virtual status_t initCheck() = 0;

virtual bool hardwareOutput() = 0;

virtual status_t setUID(uid_t uid) {

return INVALID_OPERATION;

}

virtual status_t setDataSource(

const char *url,

const KeyedVector<String8, String8> *headers = NULL) = 0;

virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;

virtual status_t setDataSource(const sp<IStreamSource> &source) {

return INVALID_OPERATION;

}

// pass the buffered ISurfaceTexture to the media player service

virtual status_t setVideoSurfaceTexture(

const sp<ISurfaceTexture>& surfaceTexture) = 0;

virtual status_t prepare() = 0;

virtual status_t prepareAsync() = 0;

virtual status_t start() = 0;

virtual status_t stop() = 0;

virtual status_t pause() = 0;

virtual bool isPlaying() = 0;

virtual status_t seekTo(int msec) = 0;

virtual status_t getCurrentPosition(int *msec) = 0;

virtual status_t getDuration(int *msec) = 0;

virtual status_t reset() = 0;

virtual status_t setLooping(int loop) = 0;

virtual player_type playerType() = 0;

virtual status_t setParameter(int key, const Parcel &request) = 0;

virtual status_t getParameter(int key, Parcel *reply) = 0;

// Right now, only the AAX TX player supports this functionality. For now,

// provide a default implementation which indicates a lack of support for

// this functionality to make life easier for all of the other media player

// maintainers out there.

virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) {

return INVALID_OPERATION;

}

// Invoke a generic method on the player by using opaque parcels

// for the request and reply.

//

// @param request Parcel that is positioned at the start of the

// data sent by the java layer.

// @param[out] reply Parcel to hold the reply data. Cannot be null.

// @return OK if the call was successful.

virtual status_t invoke(const Parcel& request, Parcel *reply) = 0;

// The Client in the MetadataPlayerService calls this method on

// the native player to retrieve all or a subset of metadata.

//

// @param ids SortedList of metadata ID to be fetch. If empty, all

// the known metadata should be returned.

// @param[inout] records Parcel where the player appends its metadata.

// @return OK if the call was successful.

virtual status_t getMetadata(const media::Metadata::Filter& ids,

Parcel *records) {

return INVALID_OPERATION;

};

void setNotifyCallback(

void* cookie, notify_callback_f notifyFunc) {

Mutex::Autolock autoLock(mNotifyLock);

mCookie = cookie; mNotify = notifyFunc;

}

void sendEvent(int msg, int ext1=0, int ext2=0,

const Parcel *obj=NULL) {

Mutex::Autolock autoLock(mNotifyLock);

if (mNotify) mNotify(mCookie, msg, ext1, ext2, obj);

}

virtual status_t dump(int fd, const Vector<String16> &args) const {

return INVALID_OPERATION;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: