MediaCodec(native)状态机分析

一、引入:
MediaCodec这条通路的调用逻辑是MediaCode->ACodec->OMX,因为OMX有自己的状态机,所以MediaCodec和ACodec也分别基于OMX组件的调用维护了其状态机,这篇博客就先分析MediaCodec的状态机是如何运转的。

二、MediaCodec与ACodec的联动:
1.MediaCodec的继承关系:

struct MediaCodec : public AHandler {
   
	...
}

MediaCodec实际上是一个AHandler ,用于维护native层的消息机制。

2.ACodec的继承关系:

struct ACodec : public AHierarchicalStateMachine, public CodecBase {
   
	...
}

ACodec继承自CodecBase ,而CodecBase 中含有一个内联函数:

inline void setCallback(std::unique_ptr<CodecCallback> &&callback) {
   
     mCallback = std::move(callback);
}

这表明,在实例化ACodec的时候,是可以设置一个回调函数下来的

3.MediaCodec与ACodec的关联:
看一下MediaCodec创建ACodec的场景:

status_t MediaCodec::init(const AString &name) {
   
	...
	/* 1.实例化Acodec */
	mCodec = GetCodecBase(name);
   	if (mCodec == NULL) {
   
       	return NAME_NOT_FOUND;
    }
    ...
    /* 2.设置ACodec的回调 */
    mCodec->setCallback(
            std::unique_ptr<CodecBase::CodecCallback>(
                    new CodecCallback(new AMessage(kWhatCodecNotify, this))));
    /* 3.创建buffer channel,为fillbuffer和emptybuffer做准备 */
    mBufferChannel = mCodec->getBufferChannel();
    mBufferChannel->setCallback(
            std::unique_ptr<CodecBase::BufferCallback>(
                    new BufferCallback(new AMessage(kWhatCodecNotify, this))));
    ...
}

在MediaCodec的init函数中,首先会去创建ACodec,然后创建CodecCallback对象,这个对象专门用于处理ACodec中回调回来的各种消息,然后根据不同的消息去设置MediaCodec的状态机。

三、MediaCodec的各状态机:
MediaCodec有如下状态机:

    enum State {
   
        UNINITIALIZED,
        INITIALIZING,
        INITIALIZED,
        CONFIGURING,
        CONFIGURED,
        STARTING,
        STARTED,
        FLUSHING,
        FLUSHED,
        STOPPING,
        RELEASING,
    };

1.UNINITIALIZED:
在构造MediaCodec对象的时候,会设置当前状态为UNINITIALIZED:

MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
    : mState(UNINITIALIZED),
      mReleasedByResourceManager(false),
      mLooper(looper),
      mCodec(NULL),
      ...
	  {
   
	  	...
}

当然,如果在其他的状态机中(INITIALIZING/STOPPING/FLUSHING),ACodec回调了kWhatError消息时,也会将MediaCodec设置为UNINITIALIZED

2.INITIALIZING:
MediaCodec的init函数中,会发送kWhatInit消息,而消息的处理阶段,将会设置此状态机:

        case kWhatInit:
        {
   
            sp<AReplyToken> replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            if (mState != UNINITIALIZED) {
   
                PostReplyWithError(replyID, INVALID_OPERATION);
                break;
            }

            mReplyID = replyID
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值