Android 13 - Media框架(25)- OMXNodeInstance(二)

全新系列文章已更新:


上一节我们了解了 OMXNodeInstance 的创建过程,以及 IOmx 服务和 OMXNodeInstance、OMX组件之间的联系。接下来我们将一起了解 ACodec 是如何通过 OMXNodeInstance 这个中间层进行端口定义设置,以及端口Buffer分配的。

OMXNodeInstance 的代码还是比较长的,我们需要重点抓住和 Buffer 相关的内容,也就是端口定义、Buffer分配以及 Buffer 传递,了解了 Buffer 那我们对 OpenMax 的学习就会很轻松了。

1、setPortMode

我们之前在学习 ACodec configureCodec 流程时看到有很多 portMode,端口类型确定之后就会调用 setPortMode 方法将端口模式设定给 OMXNode,最终设置给 OMX 组件。

status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
    status_t err = mOMXNode->setPortMode(portIndex, mode);
    if (err != OK) {
        ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
                mComponentName.c_str(),
                portIndex == kPortIndexInput ? "input" : "output",
                asString(mode),
                err);
        return err;
    }

    mPortMode[portIndex] = mode;
    return OK;
}

OMXNodeInstance 会根据设定的内容对 OMX 组件进行配置,我们这里暂时只研究解码的情况,一般解码流程可能会涉及到如下几种 port Mode:

  • in Port
    • non-secure:kPortModePresetByteBuffer,上层可以直接读写buffer;
    • secure:kPortModePresetSecureBuffer,上层需要用特殊的方式读写buffer;
  • out Port
    • has native window
      • tunnel mode:上层不需要接收 output buffer;
      • non tunnel mode:kPortModeDynamicANWBuffer,使用动态的native window;
    • no native window
      • non-secure: kPortModePresetByteBuffer,上层可以直接读写buffer;
      • secure:error,不允许这种情况。

1.1、kPortModePresetByteBuffer

之前我们讲过,Preset 是预设的意思,表示这块buffer是预先分配好的,之后使用过程中就不会发生变化了;ByteBuffer 指的是普通的buffer,我们通过指针就可以读写buffer中的内容。

kPortModePresetByteBuffer 会在两个情况下使用:

  • 普通解码的 input buffer;
  • 普通解码且无surface的 output buffer;

这两种情况下是可以通过指针读写 buffer 中内容的,也就意味着内容是不受保护的。

status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
    case IOMX::kPortModePresetByteBuffer:
    {
        // Disable secure buffer, native buffer and metadata.
        (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;
    }
}

从注释中我们可以看出来,需要关闭端口的 secure buffer,native buffer以及metadata功能,这里的native buffer指的应该就是graphic buffer。

从这里我们可以猜测,OMX 组件端口使用的buffer可能有3种,默认使用普通buffer:

  • 普通buffer;
  • secure buffer;
  • graphic buffer;

1.1.1、enableNativeBuffers_l

使用普通 buffer 就要把另外两个配置关闭,这里可以通过enableNativeBuffers_l方法来完成,之所以通过一个方法(并且方法名为 native buffer),是因为这些buffer本身都应该是由 native 层分配。由于OMXNodeInstance 把 secure buffer, graphic buffer的设置放到一起了,所以enableNativeBuffers_l容易把人看晕,把他拆成两部分:

先看 native buffer(graphic buffer)的配置部分,除了调用OMX_SetParameter对组件进行设定外,还将 mGraphicBufferEnabled 数组置为了 true/false,用于标记端口是否使用graphic buffer,如果使用了就置为true,没有使用就置为false。

		OMX_STRING name = "OMX.google.android.index.enableAndroidNativeBuffers"
        EnableAndroidNativeBuffersParams params;
        InitOMXParams(&params);
        params.nPortIndex = portIndex;
        params.enable = enable;

        err = OMX_SetParameter(mHandle, index, &params);
        CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
                      portString(portIndex), portIndex, enable);
        if (err == OMX_ErrorNone) {
            mGraphicBufferEnabled[portIndex] = enable;
        } else if (enable) {
            mGraphicBufferEnabled[portIndex] = false;
        }

再看 secure buffer 的配置部分,secure buffer 对应的配置名称为 native handle,这是因为native层分配的buffer会以handle的形式回传上层,从而保护buffer。

		OMX_STRING name = "OMX.google.android.index.allocateNativeHandle"
        EnableAndroidNativeBuffersParams params;
        InitOMXParams(&params);
        params.nPortIndex = portIndex;
        params.enable = enable;

        err = OMX_SetParameter(mHandle, index, &params);
        CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
                      portString(portIndex), portIndex, enable);
        if (!graphic) {
            if (err == OMX_ErrorNone) {
                mSecureBufferType[portIndex] =
                    enable ? kSecureBufferTypeNativeHandle : kSecureBufferTypeOpaque;
            } else if (mSecureBufferType[portIndex] == kSecureBufferTypeUnknown) {
                mSecureBufferType[portIndex] = kSecureBufferTypeOpaque;
            }
        }

如果 secure buffer 设置成功,那么 mSecureBufferType 会被设置为 kSecureBufferTypeNativeHandle,否则置为 kSecureBufferTypeOpaque。

我们这里大概知道:

  • secure buffer -> Native Handle;
  • graphic buffer -> Native Buffer;

1.1.2、storeMetaDataInBuffers_l


关注公众号《青山渺渺》阅读完整内容; 如有问题可在公众号后台私信,也可进入音视频开发技术分享群一起讨论!

在这里插入图片描述

  • 19
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山渺渺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值