先来回顾下上篇文章所讲的MediaPlayerService的start过程。MediaPlayerService的start通过层层调用会调用到NuPlayer::onStart,onStart会先启动GenericSource,然后通过异步的方式调用到NuPlayer::instantiateDecoder。在instantiateDecoder中,会创建NuPlayer::Decoder(这个Decoder跟我标题里面的decoder是不一样的,标题里面的decoder指的是实际的解码器,而这里的NuPlayer::Decoder经过层层调用会调用到实际的解码器),然后会进行初始化和配置。从时序图中可以看出Decoder的配置过程会先去查找对应的解码器,然后为为解码器创建ACodec。上一节我们分析到了创建ACodec这里,没有分析ACodec的配置过程。这里我以自己集成的ffmpeg播放视频为场景,分析ACodec配置解码器的过程。
从时序图可以看出配置过程会调用到ACodec::configureCodec,这个configureCodec是配置过程的核心函数。
来看看配置的第一步SetComponentRole。
status_t ACodec::configureCodec(const char *mime, const sp<AMessage> &msg) {if (!msg->findInt32("encoder", &encoder)) { //从AMessage中取出encoder对应的值,如果不存在就认为是要初始化解码器。encoder = false;}......status_t err = setComponentRole(encoder /* isEncoder */, mime);
}
status_t ACodec::setComponentRole(bool isEncoder, const char *mime) {const char *role = GetComponentRole(isEncoder, mime);//根据mime找到组件的status_t err = SetComponentRole(mOMXNode, role);//把ComponentRole传递给解码器......
}
status_t SetComponentRole(const sp<IOMXNode> &omxNode, const char *role) {OMX_PARAM_COMPONENTROLETYPE roleParams;InitOMXParams(&roleParams);strncpy((char *)roleParams.cRole,role, OMX_MAX_STRINGNAME_SIZE - 1);roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '