rockit 学习、开发笔记(一)(VO)

在这里插入图片描述

什么是rockit MPI:(下面是rockchip给出官方解释)
Rockchip提供的媒体处理接口(Rockchip Media Process Interface,简称 RK MPI),可支持应用软件快速开发。该平台整合了RK的硬件资源,对应用软件屏蔽了芯片相关的复杂的底层处理,并对应用软件直接提供接口完成相应功能。该平台支持应用软件快速开发以下功能:输入视频捕获、H.265/H.264/JPEG 编码、H.265/H.264/JPEG 解码、视频输出显示、视频图像前处理(包括裁剪、缩放、旋转)、智能、音频捕获及输出、音频编解码等功能。
这是其中一些模块介绍
在这里插入图片描述

多的内容就不说了,本菜鸡目前只熟悉其中部分模块,在此之前也并未接触过相关流媒体处理的相关内容,所以有些知识并不完善,请多指教了。废话不多说,接下来开始正文内容。

说一下项目背景是需要在VO模块上叠加一层UI层,具体情况是有一个QT应用需要在最上层显示,即在切换屏幕画面后也要能够显示,因为之前这块信号源切换就是用的rockit所以在不更改之前的框架的基础上,解决方案是,将QT的UI实时显示rockit的UI层中,涉及的模块大致上有SYS,MB,VO,RGN等。

这里可以从rockchip官方给的一些demo入手可能理解起来会比较好一点。在rockchip给的SDK中,rockit相关代码的路径是在platform/external/rockit/。

目前(项目)现有的视频处理是外部视频流不进行处理直接给到显示设备,也就是VI -> VO,现在是需要加一层UI,也不需要去修改原先的视频流,只需要在原有的显示画面上叠加上我们的UI就行了,关于UI的显示模块有RGN,那就是RGN -> VO(虽然后续并没有使用RGN模块😅)。

那么我们先参考之前的demo代码以及结合rk提供的官方文档看一下大概的流程:

代码中main函数开始会进行参数的一些初始化工作,然后就进入相关模块的初始化。main函数中大部分东西不需要我们理解,可能会改到的地方就是一些参数的修改。

    switch (ctx->enMode) {
        case TEST_VI_MODE_VI_FRAME_ONLY:
            if (!ctx->stViChnAttr.u32Depth) {
                RK_LOGE("depth need > 0 when vi not bind any other module!");
                ctx->stViChnAttr.u32Depth = ctx->stViChnAttr.stIspOpt.u32BufCount;
            }
            s32Ret = test_vi_get_release_frame_loop(ctx);
        break;
        case TEST_VI_MODE_BIND_VO:
            s32Ret = test_vi_bind_vo_loop(ctx);
        break;
        case TEST_VI_MODE_VI_STREAM_ONLY:
            if (!ctx->stViChnAttr.u32Depth) {
                RK_LOGE("depth need > 0 when vi not bind any other module!");
                ctx->stViChnAttr.u32Depth = ctx->stViChnAttr.stIspOpt.u32BufCount;
            }
            s32Ret = test_vi_get_release_stream_loop(ctx);
        break;
        default:
            RK_LOGE("noC support such test mode:%d", ctx->enMode);
        break;
    }

进入到相关模块初始化函数,先进行的初始化的流程是VO,(其他模块的初始化流程可以去查看RK的官方文档有很详细的讲解,路径platform/external/rockit/mpi/doc),然后才是RGN,因为RGN模块是基于VO的区域管理。

首先失能图层和设备,不然修改和创建是不会生效的,然后获取原有视频输出设备的公共属性,在原有的基础上进行修改,然后重新设置回去,然后就可以使能设备了,然后再绑定图层到设备,绑定完设置图层的相关属性,然后设置图层的拼接模式,设置完成后就可以使能该图层了,最后就是对通道的设置,设置通道的相关属性然后使能就完成了整个VO的初始化流程。


    RK_MPI_VO_DisableLayer(VoLayer);
    RK_MPI_VO_Disable(VoDev);
  
    s32Ret = RK_MPI_VO_GetPubAttr(VoDev, &VoPubAttr);
    if (s32Ret != RK_SUCCESS) {
        return s32Ret;
    }
    s32Ret = RK_MPI_VO_SetPubAttr(VoDev, &VoPubAttr);
    if (s32Ret != RK_SUCCESS) {
        RK_LOGE("RK_MPI_VO_SetPubAttr failed,s32Ret:%#X\n", s32Ret);
        return s32Ret;
    }
    
    s32Ret = RK_MPI_VO_Enable(VoDev);
    if (s32Ret != RK_SUCCESS) {
        return s32Ret;
    }
    s32Ret = RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_GRAPHIC);
    if (s32Ret != RK_SUCCESS) {
        RK_LOGE("RK_MPI_VO_BindLayer failed,s32Ret:%#X\n", s32Ret);
        return RK_FAILURE;
    }
  

    s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer, &stLayerAttr);
    if (s32Ret != RK_SUCCESS) {
        RK_LOGE("RK_MPI_VO_SetLayerAttr failed,s32Ret:%#X\n", s32Ret);
        return RK_FAILURE;
    }
    
    RK_MPI_VO_SetLayerSpliceMode(VoLayer, VO_SPLICE_MODE_RGA);
    s32Ret = RK_MPI_VO_EnableLayer(VoLayer);
    if (s32Ret != RK_SUCCESS) {
        RK_LOGE("RK_MPI_VO_EnableLayer failed,s32Ret:%#X\n", s32Ret);
        return RK_FAILURE;
    }

    s32Ret = RK_MPI_VO_SetChnAttr(VoLayer, u32Ch, &stChnAttr);
    if (s32Ret != RK_SUCCESS) {
        RK_LOGE("set chn Attr failed,s32Ret:%#X\n", s32Ret);
        return RK_FAILURE;
    }

    // enable vo graph
    s32Ret = RK_MPI_VO_EnableChn(ctx->pstRgnCtx.vo_layer, ctx->pstRgnCtx.vo_chn);
    if (s32Ret != RK_SUCCESS) {
        RK_LOGE("Enalbe vo chn failed, s32Ret = %x\n", s32Ret);
        goto __FAILED;
    }

以上就是VO模块的大概的初始化流程,说得有点抽象😂,不过里面有三个关键字就是设备,图层,通道。这三者的关系与rockit内部视频输出链路是息息相关的,设备就是指的视频流的输出设备,一般就是你的显示器;图层就是你这个设备的图层,一个设备有三个图层视频层+图形层+鼠标层;通道是你这个视频流以什么方式到达对应设备的对应图层。

我们结合RK的文档详解一下相关函数

RK_MPI_VO_GetPubAttr

在失能设备后,获取设备属性便于后面进行修改。
在这里插入图片描述

RK_MPI_VO_SetPubAttr

获取设备的公共属性后,我们一般修改的是:

    VoPubAttr.enIntfType = VO_INTF_HDMI;
    VoPubAttr.enIntfSync = VO_OUTPUT_1080P60;

这两个参数指定了设备接口类型和设备的显示配置。修改完后就可以调用下面的函数设置。
在这里插入图片描述

RK_MPI_VO_Enable

然后关于设备修改完成后就可以对其进行使能。

在这里插入图片描述
在这里插入图片描述

RK_MPI_VO_BindLayer

然后就是对图层的操作了,在失能图层后首先就是要先绑定图层到设备上。

在这里插入图片描述
在这里插入图片描述
在这里选择的图层号有以下几种,具体区别可以参考官方文档

#define RK356X_VOP_LAYER_CLUSTER_0 0
#define RK356X_VOP_LAYER_CLUSTER_1 2
#define RK356X_VOP_LAYER_ESMART_0 4
#define RK356X_VOP_LAYER_ESMART_1 5
#define RK356X_VOP_LAYER_SMART_0 6
#define RK356X_VOP_LAYER_SMART_1 7

图层类型的话有下面几种,鼠标层,图形层,视频层,虚拟层,一般是用前三种,而且一个设备只能最多支持鼠标层,图形层,视频层各一个。

typedef enum rkVO_LAYER_MODE_E {
    VO_LAYER_MODE_CURSOR = 0,
    VO_LAYER_MODE_GRAPHIC,
    VO_LAYER_MODE_VIDEO,
    VO_LAYER_MODE_VIRTUAL,
    VO_LAYER_MODE_BUTT
} VO_LAYER_MODE_E;

RK_MPI_VO_SetLayerAttr

绑定对应图层到对应设备上后,可以配置图层属性。
在这里插入图片描述

该函数通过第二个参数 VO_VIDEO_LAYER_ATTR_S 来配置相关属性,相关参数的配置如下

    stLayerAttr.enCompressMode = ctx->enCompressMode;
    stLayerAttr.enPixFormat = static_cast<PIXEL_FORMAT_E>(ctx->s32VoPixFormat);
    stLayerAttr.stDispRect.s32X = ctx->stVoDispRect.s32X;
    stLayerAttr.stDispRect.s32Y = ctx->stVoDispRect.s32Y;
    stLayerAttr.u32DispFrmRt = ctx->u32VoDispFrmRt;
    stLayerAttr.stDispRect.u32Width = ctx->stVoDispRect.u32Width;
    stLayerAttr.stDispRect.u32Height = ctx->stVoDispRect.u32Height;
    stLayerAttr.stImageSize.u32Width = ctx->stVoImageSize.u32Width;
    stLayerAttr.stImageSize.u32Height = ctx->stVoImageSize.u32Height;
    stLayerAttr.bBypassFrame = RK_FALSE;

在这里插入图片描述

RK_MPI_VO_SetLayerSpliceMode

其中bBypassFrame属性需要为false,视频流才会在后面rgn进行拼接,不然视频会直接送到图层去,后续需要为其图层设置拼接的方式,如下。
在这里插入图片描述

也可以不调用该函数,因为默认图层使用GPU合成方式。
我这里只有当bBypassFrame属性需要为true时,设置GPU合成的方式才有效,否则就会报错create fance falied的错误,可能是不支持吧😥。

RK_MPI_VO_EnableLayer

这样我们图层就设置完成了,最后给图层使能即可。

在这里插入图片描述

RK_MPI_VO_SetChnAttr

然后就是设置通道属性了。
在这里插入图片描述

第三个参数设置通道属性,具体如下:
在这里插入图片描述
在这里插入图片描述

RK_MPI_VO_EnableChn

最后使能通道就可以了。
在这里插入图片描述

我感觉这个流程就好像你去到某个地方,你想去哪一栋楼(dev),然后想去哪一层(layer),具体怎么去坐电梯还是走楼梯(chn),一个只能自己理解的奇怪比喻😂。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值