通過代碼的方式同時獲取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);
.......................
}