sample_vdec(视频解码)
(测试环境,在HI3531D开发板上运行,查看代码使用VSCode)
运行
/nfsroot/mpp/sample/vdec # ./sample_vdec
/************************************/
please choose the case which you want to run:
0: VDH H264
1: VDH H265
2: VDH MP4
3: JPEG decoding
4: PIP
q: quit the whole sample
sample command:
shell 说明:
0: VDEC解码器输入(H264的编码格式图片/视频)—>VPSS(视频输入缓存块)—>VO(图片/视频输出)
1: VDEC解码器输入(H265的编码格式图片/视频)—>VPSS(视频输入缓存块)—>VO(图片/视频输出)
2:
VDH H264
step1
init SYS and common VB
初始化HIMPP SYS和通用VB缓冲,包括设置缓冲区的大小,缓冲区块的数目。需要注意的是,在设置通用VB参数之前,必须确保HIMPP系统已经退出,否则设置失败。
1)视频缓存池属性
2)HI_MPI_SYS_Exit();//去初始化 MPP 系统
HI_MPI_VB_ExitModCommPool(i);//退出模块公共视频缓冲池
HI_MPI_VB_DestroyPool(i);//销毁一个视频缓存池。
HI_MPI_VB_Exit();//去初始化 MPP 视频缓存池。
HI_MPI_VB_SetConf(pstVbConf);//设置 MPP 视频缓存池属性。
HI_MPI_VB_Init();//初始化 MPP 视频缓存池。
HI_MPI_SYS_SetConf(&stSysConf);//配置系统控制参数。stride 字节对齐
HI_MPI_SYS_Init();初始化 MPP 系统
step2
init mod common VB
设置通用缓冲区的公共缓冲池属性。
1)根据每个解码通道的需要解码的视频的宽高,像素格式,位宽 以及不同的解码方式(如:h.264 h.265等)计算每个通道需要的VB大小。
2)HI_MPI_VB_ExitModCommPool(VB_UID_VDEC);
HI_MPI_VB_SetModPoolConf(VB_UID_VDEC, pstModVbConf)
HI_MPI_VB_InitModCommPool(VB_UID_VDEC)
step3
start VDEC
配置解码器,包括指定解码类型,这里是H264解码样例,选,然后指定视频大小、解码优先级等等。然后创建解码通道,并是能加收解码流。
1)配置视频解码通道属性
2)以下的操作,在每个解码通道都需要操作一遍:
创建视频解码通道
HI_MPI_VDEC_CreateChn(i, &pstAttr[i])
解码器开始接收用户发送的码流。
HI_MPI_VDEC_StartRecvStream(i)
step4
start VPSS
配置VPSS参数,VPSS是对VDEC解码后的流进行处理,如裁剪、降噪等,解码实例从简单应用出发,仅仅按默认的方式配置VPSS。
1)每个解码通道一个VPSSgroup,每个VPSSgroup中有4个phy通道
配置 VPSS GROUP 静态属性(每个通道都要配置)
2)以下的操作,在每个解码通道都需要操作一遍。
创建一个 VPSS GROUP。
HI_MPI_VPSS_CreateGrp(VpssGrp, &stGrpAttr)
获取 VPSS GRUOP 参数。
HI_MPI_VPSS_GetGrpParam
设置 VPSS GRUOP 参数。
HI_MPI_VPSS_SetGrpParam
3)
for(j=0; j<s32ChnCnt; j++)
{
设置 VPSS 通道属性。
HI_MPI_VPSS_SetChnAttr(VpssGrp, VpssChn, &stChnAttr)
启用 VPSS 通道。
HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn);
}
启用 VPSS GROUP。
HI_MPI_VPSS_StartGrp(VpssGrp)
step5
start VO
配置VO参数,这一步也很关键,因为它指定了画面输出,包括常见的HDMI和VGA,主要是配置输出显示,图层属性设置、输出位置等信息。
1)配置视频输出公共属性结构体
VO_PUB_ATTR_S stVoPubAttr
2)
DHD0: Device HD0, 超高清设备 0。
DHD1: Device HD1, 高清设备 1。
VHD0: Video layer of HD0, 超高清视频层 0, 隶属于 DHD0。
VHD1: Video layer of HD1,高清视频层 1,隶属于 DHD1。
VHD2: Video layer of HD 2, 高清视频层 2, Hi3559AV100 上隶属于 DHD0,
Hi3519AV100/Hi3556AV100 上可以绑定至 DHD0 或者 DHD1, 用作 PIP 层。
WD: Write Back Channel Device, 回写通道设备。
图形层 G3: Graphic layer 3, 用作鼠标层, DHD0 和 DHD1 中均有此项, 但只能绑定其中一个设备,
G3 默认绑定在 DHD1 上。
3)
HI_MPI_VO_SetPubAttr(VoDev, pstPubAttr)
配置视频输出设备VoDev(根据不同的芯片,有所不同)的公共属性(hdmi或者mipi,视频的输出格式如1080P60)。
HI_MPI_VO_Enable(VoDev)
使能视频输出设备
设置视频层信息…
4)以下是视频输出的硬件接口的使能:
HDMI:
HI_MPI_HDMI_Init();
HI_MPI_HDMI_Open(enHdmiId);
HI_MPI_HDMI_GetAttr(enHdmiId, &stAttr);
HI_MPI_HDMI_SetAttr(enHdmiId, &stAttr) ;//属性中比较重要的一点是输出的视频的格式。如:1080P60。
HI_MPI_HDMI_Start(enHdmiId);
step6
VDEC bind VPSS
绑定VDEC与VPSS,实现解码流程。
1)每个解码通道都要绑定
数据源到数据接收者绑定接口。
HI_MPI_SYS_Bind(&stSrcChn, &stDestChn)
setp7
VPSS bind VO
绑定VPSS与VO,实现解码流程。
1)每个解码通道都要绑定
数据源到数据接收者绑定接口。
HI_MPI_SYS_Bind(&stSrcChn, &stDestChn)
setp8
send stream to VDEC
推送视频流数据,这一步需要文件读写配合使用。
(选定需要解码的文件路径和文件名)
每个解码通道创建一个相对应的线程,当应用程序退出时,直接退出线程即可。
1)创建线程
pthread_create(&pVdecThread[i], 0, SAMPLE_COMM_VDEC_SendStream, (HI_VOID *)&pstVdecSend[i]);
2)HI_MPI_VDEC_SendStream(pstVdecThreadParam->s32ChnId, &stStream, -1); //在发送完所有码流后,可以发送 bEndOfStream 为 1 的空码流包,表示当前码流文件结束,解码器会把所有码流全部解完并输出全部图像。