通过多线程获取VENC的H264码流数据
我们这次要对RV1126进行CMOS摄像头采集,并进行VENC的视频编码处理,最终获取到H264码流。
一.RV1126 VI模块采集并进行VENC编码的流程
V1126多线程采集VI模块编码VENC并保存到文件,一般分为四个步骤:分别是初始化VI模块、初始化VENC模块、绑定VI和VENC模块、多线程获取每一帧H264码流数据
初始化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);
初始化VENC模块:
VENC模块的初始化实际上就是对VENC_CHN_ATTR_S的参数进行设置、然后调用RK_MPI_VENC_CreateChn创建编码器,伪代码如下:
VENC_CHN_ATTR_S venc_chn_attr;
venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
。。。。。。。。。。。。。。。。(这里是设置VENC的属性)
ret = RK_MPI_VENC_CreateChn(0, &venc_chn_attr);
绑定VI节点和VENC节点:
绑定VI节点和VENC节点,使其两个模块能够关联起来,使用的API是RK_MPI_SYS_Bind。关于这个API的定义,之前说过了,这里不在阐述。伪代码如下:
MPP_CHN_S vi_chn_s;
vi_chn_s.enModId = RK_ID_VI;
vi_chn_s.s32ChnId = 0;
MPP_CHN_S venc_chn_s;
venc_chn_s.enModId = RK_ID_VENC;
venc_chn_s.s32ChnId = 0;
ret = RK_MPI_SYS_Bind(&vi_chn_s, &venc_chn_s);
开启多线程采集VENC的数据
开启一个线程去采集每一帧VENC模块的数据,使用的API是RK_MPI_SYS_GetMediaBuffer, 模块ID是RK_ID_VENC,通道号ID是VENC创建的ID号。这个API的具体作用已经在之前的获取VI数据的课程里面已经讲解过,我们直接上伪代码:
while(1)
{
.........................
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, s32_chn_id, -1);
fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, h264_file);
.......................
}
二.代码编写
1.VI模块初始化
1.1参数填充
1.2设置,判断是否成功
1.3使能,判断
2.VENC模块初始化
2.1参数填充
VENC有三个结构体, 需要分别设置其中两个的其参数
第一个结构体
第二个结构体
1M = 1024KB
1KB=1024Byte(字节)
1Byte=8bit(比特),所以1M=1024*1024*8=8388608bit
2.2创建
3.节点绑定
在绑定之前,我们要给绑定的VI与VENC创建ID
3.1创建ID
3.2绑定
4.创建线程
4.1创建线程
4.2写子线程回调函数
5.释放资源
在退出线程之后要释放资源
到此代码就写完了,去编译一下看有没有什么错误