RV1126多线程获取SMARTP的GOP模式数据和普通GOP模式数据
通过代码的方式同时获取SMARTP模式的VENC码流数据和普通GOP模式的VENC码流数据,并进行对比画质。
一.RV1126 VI采集摄像头数据并同时编码SMARTP模式和普通GOP模式的编码码流流程
RV1126利用多线程同时获取普通GOP的VENC码流数据和SMARTP的码流数据一般如上图,分为8个步骤:分别是VI模块初始化、普通GOP的VENC模块初始化、智能SMARTP_GOP的VENC模块初始化、VI绑定普通GOP的VENC编码器节点、设置GOP属性为SMARTP属性、VI绑定SMARTP_GOP的VENC编码器节点、创建多线程获取普通GOP的VENC码流数据并保存、创建多线程获取SMART_GOP的VENC码流数据并保存。
1.初始化VI模块:
VI模块的初始化实际上就是对VI_CHN_ATTR_S的参数进行设置、然后调用RK_MPI_VI_SetChnAttr设置VI模块并使能RK_MPI_VI_EnableChn,伪代码如下:
VI_CHN_ATTR_S vi_chn_attr;
。。。。。。。。。。。。。。。(这里是设置VI的属性)
ret = RK_MPI_VI_SetChnAttr(CAMERA_ID, 0, &vi_chn_attr);
ret |= RK_MPI_VI_EnableChn(CAMERA_ID, 0);
2.两种GOP模式VENC模块初始化:
VENC_CHN_ATTR_S common_gop_venc_chn_attr;
..................................
RK_MPI_VENC_CreateChn(COMMON_GOP_VENC_CHN, &common_gop_venc_chn_attr);
VENC_CHN_ATTR_S smartp_gop_venc_chn_attr;
..................................
RK_MPI_VENC_CreateChn(SMARTP_VENC_CHN, &smartp_gop_venc_chn_attr);
注意:这里需要创建两个编码器层,分别是普通GOP模式编码器和SMART的GOP模式编码器。
3.设置SMARTP的VENC模块GOP参数调节
VENC_GOP_ATTR_S venc_gop_attr;
venc_gop_attr.enGopMode = VENC_GOPMODE_SMARTP; //设置GOP模式为SMARTP模式
venc_gop_attr.u32GopSize = 25; //设置短参考帧间隔是25
venc_gop_attr.s32IPQpDelta = 6; //设置I帧和P帧的差值是6
venc_gop_attr.s32ViQpDelta = 6;//设置虚拟I帧和P帧的差值是6
venc_gop_attr.u32BgInterval = 25 * 5; //设置长参考帧的长度是短参考帧的5倍
ret = RK_MPI_VENC_SetGopMode(SMARTP_GOP_VENC_CHN, &venc_gop_attr);
上面是SMARTP的GOP模式一些参数的设置,设置完成调用RK_MPI_VENC_SetGopMode去调用
4.VI模块绑定普通GOP的VENC模块和SMARTP_GOP的VENC模块,下面是伪代码:
//VI模块节点
MPP_CHN_S vi_chn_s;
vi_chn_s.enModId = RK_ID_VI;
vi_chn_s.s32ChnId = VI_CHN_ID;
//普通GOP的VENC模块节点
MPP_CHN_S common_gop_venc_chn_s;
common_gop_venc_chn_s.enModId = RK_ID_VENC;
common_gop_venc_chn_s.s32ChnId = COMMON_GOP_VENC_CHN;
ret = RK_MPI_SYS_Bind(&vi_chn_s, &common_gop_venc_chn_s);
//SMARTP_GOP的VENC模块
MPP_CHN_S smartp_gop_venc_chn_s;
smartp_gop_venc_chn_s_s.enModId = RK_ID_VENC;
smartp_gop_venc_chn_s.s32ChnId = SMARTP_GOP_VENC_CHN;
ret = RK_MPI_SYS_Bind(&vi_chn_s, &smartp_gop_venc_chn_s);
5.创建多线程获取普通GOP的VENC码流数据并保存:
开启一个线程去采集每一帧普通GOP的VENC模块数据,使用的API是RK_MPI_SYS_GetMediaBuffer, 模块ID是RK_ID_VENC,通道号ID是普通GOP的 VENC创建ID号。这个API伪代码如下:
while(1)
{
.........................
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, COMMON_GOP_VENC_CHN, -1);
fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, common_gop_h264_file);
.......................
}
6.多线程获取SMARTP_GOP的VENC模块数据:
开启一个线程去采集每一帧SMARTP_GOP的VENC模块数据,使用的API是RK_MPI_SYS_GetMediaBuffer, 模块ID是RK_ID_VENC,通道号ID是SMARTP_GOP的VENC层。这个API伪代码如下:
while(1)
{
.........................
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, SMARTP_GOP_VENC_CHN, -1);
fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, smartp_gop_h264_file);
.......................
}