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

来源:互联网 发布:房地产经纪人网络教育 编辑:程序博客网 时间:2024/05/20 20:32

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;
    }

原创粉丝点击