介绍完了VO模块的用法,接下来就是RGN模块的用法。
对于RGN模块的用例可以参考 platform/external/rockit/ 路径下的相关目录中的rgn demo。
rgn的概述:(rockchip官方文档)
用户一般都需要在视频中叠加 OSD 用于显示一些特定的信息(如:通道号、时间戳等),必要时还会填充色块。这些叠加在视频上的 OSD 和遮挡在视频上的色块统称为区域。REGION 模块,用于统一管理这些区域资源。区域管理可以实现区域的创建,并叠加到视频中或对视频进行遮挡。例如,实际应用中,用户通过创建一个区域,通过RK_MPI_RGN_AttachToChn,将该区域叠加到某个通道(如 VENC 通道)中。在通道进行调度时,则会将 OSD 叠加在视频中。一个区域支持通过设置通道显示属性接口指定到多个通道中(如:多个 VENC 通道),且支持在每个通道的显示属性(如位置、层次、透明度等)都不同。
从上面这段话我们大概知道rgn是用来进行区域管理的,一般用于UI显示。
rgn中有多种区域管理的形式,如OVERLAY,COVER,MOSAIC,LINE等等。
这里我主要用到的是OVERLAY的,所以其他方式可以参考RK官方的文档(platform/external/rockit/mpi/doc)。
前置条件
RK_MPI_VO_CreateGraphicsFrameBuffer
在真正进行rgn模块的实现之前,需要有在对应的图层有FrameBuffer,这里可以参考rgn的demo中是先在TEST_RGN_VoSendFrame函数中调用了 RK_MPI_VO_CreateGraphicsFrameBuffer 函数来创建一个图形层Framebuffer。
其中最后一个参数是图像的数据地址,用于后续存放图像数据。
RK_MPI_VO_SendFrame
在调用完 RK_MPI_VO_CreateGraphicsFrameBuffer 创建了FrameBuffer后需要调用RK_MPI_VO_SendFrame将其发送到相应图层上,这样该图层才会有原始的画面。
选定与VO模块一样的图层的通道才有效,否则可能会报错。
总结一下就是在要想使用rgn模块,得首先保证最少有一个图层有画面,要么就是绑定了VI模块到VO模块上,或者有framebuffer被发送到图层上,我对于这里的理解是毕竟rgn模块是区域管理,你得先有一个可以被管理的区域吧,不然怎么管理😂。
RGN模块
好了,接下来就是rgn模块的OVERLAY的使用步骤了。大家也可以参考官方的文档,里面也有详细的步骤。
s32Ret = RK_MPI_RGN_Create(RgnHandle, &stRgnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("RK_MPI_RGN_Create (%d) failed with %#x!", RgnHandle, s32Ret);
RK_MPI_RGN_Destroy(RgnHandle);
return RK_FAILURE;
}
s32Ret = RK_MPI_RGN_AttachToChn(RgnHandle, pstMppChn, &stRgnChnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("RK_MPI_RGN_AttachToChn (%d) failed with %#x!", RgnHandle, s32Ret);
return RK_FAILURE;
}
//方式 1
s32Ret = RK_MPI_RGN_SetBitMap(RgnHandle, &stBitmap);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_RGN_SetBitMap failed with %#x!", s32Ret);
return RK_FAILURE;
}
//方式 2
s32Ret = RK_MPI_RGN_GetCanvasInfo(RgnHandle, &stCanvasInfo);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_RGN_GetCanvasInfo failed with %#x!", s32Ret);
return RK_FAILURE;
}
s32Ret = RK_MPI_RGN_UpdateCanvas(RgnHandle);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_RGN_UpdateCanvas failed with %#x!", s32Ret);
return RK_FAILURE;
}
RK_MPI_RGN_Create
通过该函数创建一个rgn区域,该函数限制了可管理的rgn区域大小,区域的像素格式,区域类型等等。
RK_MPI_RGN_AttachToChn
该函数将创建好的区域叠加到通道上,其中pstChnAttr参数中定义了区域通道显示的属性
其中区域通道显示属性中的stOverlayChn成员较为重要,显示的坐标,透明度,rgn图层等等都在该成员中配置。
stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = pstRgnCtx->stRegion.s32X + 48 * i;
stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = pstRgnCtx->stRegion.s32Y + 48 * i;
stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 255;
stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 0;
stRgnChnAttr.unChnAttr.stOverlayChn.u32Layer = 7;
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bEnable = pstRgnCtx->bRgnQp;
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bForceIntra = RK_TRUE;
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = RK_FALSE;
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp = RK_FALSE;
RK_MPI_RGN_SetBitMap
该函数用于设置区域位图,就是用来填充区域的。
其中参数pstBitmap是用来设置位图属性的,其中有像素格式,图像大小,图像数据。
RK_MPI_RGN_GetCanvasInfo
这个函数是用来获取区域的显示画布信息。创建一个空的RGN_CANVAS_INFO_S类型的变量传入以获取画布信息。
同时该参数还需要将图像的信息写入该成员u64VirAddr中。
RK_MPI_RGN_UpdateCanvas
该函数用于更新区域的显示画布数据,这个函数与RK_MPI_RGN_SetBitMap类似都是用于rgn的图像绘制。不同的是该函数将绘制的信息绑定到了RGN_HANDLE上,可能在效率上有所提升。
到这里基本上就rgn模块的步骤就基本结束了,应该是可以在创建好的图层上显示rgn区域画面了。