在上一篇文章中,我们探讨了PortMode与BufferType之间的对应关系以及Metadata的概念,这一节对setPortMode来做一些分析。
1、setPortMode
PortMode是在ACodec解析配置参数的过程中确定的,而MetadataType则是由OMXNodeInstance根据ACodec设定下来的PortMode自行确定的。将setPortMode方法进行简化,以更清晰地展示其工作流程:
status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
status_t err = OK;
switch (mode) {
case IOMX::kPortModeDynamicANWBuffer:
{
if (portIndex == kPortIndexOutput) {
err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
}
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
break;
}
/* 此case未使用,暂时不做了解
case IOMX::kPortModeDynamicNativeHandle:
{
if (portIndex != kPortIndexInput) {
err = BAD_VALUE;
break;
}
(void)enableNativeBuffers_l(portIndex, OMX_TRUE, OMX_FALSE);
(void)enableNativeBuffers_l(portIndex, OMX_FALSE, OMX_FALSE);
MetadataBufferType metaType = kMetadataBufferTypeNativeHandleSource;
err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
break;
}*/
case IOMX::kPortModePresetSecureBuffer:
{
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
err = enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
break;
}
case IOMX::kPortModePresetANWBuffer:
{
if (portIndex != kPortIndexOutput) {
err = BAD_VALUE;
break;
}
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
if (err != OK) {
break;
}
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
break;
}
case IOMX::kPortModePresetByteBuffer:
{
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
break;
}
if (err == OK) {
mPortMode[portIndex] = mode;
}
return err;
}
对于每一种PortMode,都需要调用enableNativeBuffers_l两次,并调用storeMetaDataInBuffers_l一次,以完成相关的内容设定。为什么要调用enableNativeBuffers_l两次呢?这是因为enableNativeBuffers_l是把两个函数合并成了一个函数,Android希望要分别对两个不同的配置进行设定,因此需要调用两次。
观察代码会发现并不是每次调用enableNativeBuffers_l都会检查返回值,只有第三个参数为true时才会检查返回值。换言之,第三个参数为false时,OMX_SetParameter设定成功与否都不影响程序正常运行,因此笔者认为这些代码删掉也不影响程序运行,只要关注第三个参数为true时做了什么就可以了。
同样的,storeMetaDataInBuffers_l的调用也不是每次都会检查返回值,不检查返回值侧面说明可以不用做设定。结合以上说明对代码再做简化:
switch (mode) {
case IOMX::kPortModeDynamicANWBuffer:
{
if (portIndex == kPortIndexOutput) {
err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
}
err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
break;
}
case IOMX::kPortModePresetSecureBuffer:
{
err = enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
break;
}
case IOMX::kPortModePresetANWBuffer:
{
if (portIndex != kPortIndexOutput) {
err = BAD_VALUE;
break;
}
err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
if (err != OK) {
break;
}
break;
}
case IOMX::kPortModePresetByteBuffer:
{
break;
}
- kPortModePresetByteBuffer:在初始化状态下,组件的输入输出端口默认使用普通buffer,并且默认不使用Metadata,对应的PortMode为kPortModePresetByteBuffer。因此,如果setPortMode方法传入参数为kPortModePresetByteBuffer,实际上不需要执行任何额外的配置或操作。如果setPortMode传入参数为其他值,则需要对OMX组件做相应的配置;
- kPortModeDynamicANWBuffer:需要配置端口使用NativeBuffers,同时需要使用Metadata传输数据;
- kPortModePresetSecureBuffer:只要配置端口使用NativeBuffers即可;
- kPortModePresetANWBuffer:只要配置端口使用NativeBuffers即可;
2、enableNativeBuffers_l
将storeMetaDataInBuffers_l拆成两部分:
3、storeMetaDataInBuffers_l
关注公众号《青山渺渺》阅读全文