Acodec是如何通过其维护的状态来处理AMessage的?

一、问题引言:
初读mediacodec的代码,分析了stagefright框架中大量使用的AHandler、ALooper和AMessage组成的消息机制,我们知道每个AHandler都会通过ALooper去发送消息,然后,最终通过ALooper的loop函数将AMessage分发到各自的AHandler进行处理,但在Acodec中,明明仅ACodec是一个AHandler,为什么处理消息的时候确是由各个状态的onMessageReceived来响应的呢?针对这个问题,分析了一下源码,找到了答案。
先直接给出答案:
ACodec通过调用AHierarchicalStateMachine类维护的成员变量mstate来进行消息处理的。

二、代码分析:

  1. mediacodec创建的逻辑时序图如下(create->start):
    在这里插入图片描述
    mediacodec实例化的时候会去实例化Acode,在Acode的构造函数中,我们可以看到创建了很多的state:
ACodec::ACodec()
...
{
	...
	mUninitializedState = new UninitializedState(this);
    mLoadedState = new LoadedState(this);
    mLoadedToIdleState = new LoadedToIdleState(this);
    mIdleToExecutingState = new IdleToExecutingState(this);
    mExecutingState = new ExecutingState(this);

    mOutputPortSettingsChangedState =
        new OutputPortSettingsChangedState(this);

    mExecutingToIdleState = new ExecutingToIdleState(this);
    mIdleToLoadedState = new IdleToLoadedState(this);
    mFlushingState = new FlushingState(this);

    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
    mInputEOSResult = OK;

	/* 首先将Acodec的状态改变为mUninitializedState */
    changeState(mUninitializedState);
}

这里注意一下每个state都是继承自ACodec中的类成员BaseState的,举例UninitializedState:

struct ACodec::UninitializedState : public ACodec::BaseState {
    UninitializedState(ACodec *codec);

我们先拓展看一下BaseState的继承关系:

struct ACodec::BaseState : public AState {
    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
    
struct AState : public RefBase {
    AState(const sp<AState> &parentState = NULL);

最终都是继承自Android的基类RefBase ,这里我们可以确定,Acodec中的各个状态都不是AHandler,是不具备拥有自主消息机制收发的权利的,那么是谁赋予的每个状态拥有onMessageReceived的消息处理权利呢?另外,以UninitializedState 为例看下每个状态构造是怎么玩的:

ACodec::UninitializedState::UninitializedState(ACodec *codec)
    : BaseState(codec) {
}

ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
    : AState(parentState),
      mCodec(codec) {
}

这里初始化参数列表是通过基类构造实现的,所以mCodec就是我们的Acodec对象。

  1. 假定Acodec发送了一个AMessage,经过ALooper之后,会最终调用对应AHandler的onMessageReceived来处理,因为Acodec就是一个AHandler,那么我们直接去找Acodec的onMessageReceived:
	ACodec.h
	
    // AHierarchicalStateMachine implements the message handling
    virtual void onMessageReceived(const sp<AMessage> &msg) {
        handleMessage(msg);
    }

因为ACodec继承自AHierarchicalStateMachine类,所以这里直接调用父类的handleMessage,来看一下这个函数做了什么:

AHierarchicalStateMachine.cpp

void AHierarchicalStateMachine::handleMessage(const sp<AMessage> &msg) {
	/* 先保存当前状态 */
    sp<AState> save = mState;

	/* 调用当前状态的onMessageReceived去处理消息 */
    sp<AState> cur = mState;
    while (cur != NULL && !cur->onMessageReceived(msg)) {	
        /* 确认状态是否有改变 */
        CHECK(save == mState);
		/* 将当前状态置为“上一个”状态 */
        cur = cur->parentState();
    }

    if (cur != NULL) {
        return;
    }

    ALOGW("Warning message %s unhandled in root state.",
         msg->debugString().c_str());
}

AHierarchicalStateMachine内部维护了一个成员变量叫mState,用来记录当前Acodec处于何种状态,当Acodec有消息要处理时,AHierarchicalStateMachine就会指派对应的状态去处理这个消息,注意,mediacodec中也维护了一个成员变量来mState来记录其所处的运行状态,只不过其类型为enum,不要弄混了,所以,在mediacodec和Acodec中,状态是非常重要的。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值