海思mpp之VDEC(视频解码)的接口调用流程分析

参考:https://blog.csdn.net/flaoter/article/details/92402685

一、初始化系统:
HI_MPI_SYS_Exit();
HI_MPI_VB_Exit();
HI_MPI_VB_SetConfig(pstVbConfig);//整个系统中可以容纳缓存池的个数,每个缓存池缓存块的个数,缓存块的大小
HI_MPI_VB_Init();
HI_MPI_SYS_Init();

二、VDEC初始化并获取VB:
1.根据每个解码通道的需要解码的视频的宽高,像素格式,位宽 以及不同的解码方式(如:h.264  h.265等)计算每个通道需要的VB大小。
2. 模块公共视频缓存池
HI_MPI_VB_ExitModCommPool(VB_UID_VDEC);
HI_MPI_VB_SetModPoolConfig(VB_UID_VDEC, &stVbConf);//设置模块公共视频缓存池属性
HI_MPI_VB_InitModCommPool(VB_UID_VDEC);

三、start VDEC:
HI_MPI_VDEC_SetModParam(&stModParam);//主要是设置VB 来源选择
以下的操作,在每个解码通道都需要操作一遍。
HI_MPI_VDEC_CreateChn(i, &stChnAttr[i])//创建视频解码的通道。
HI_MPI_VDEC_SetChnParam(i, &stChnParam)//设置解码通道i参数stChnParam
HI_MPI_VDEC_StartRecvStream(i)//使能解码通道i

四、start VPSS:
每个解码通道一个VPSSgroup,每个VPSSgroup中有4个phy通道
HI_MPI_VPSS_SetModParam(&stModParam);//hdr支持
以下的操作,在每个解码通道都需要操作一遍。
HI_MPI_VPSS_CreateGrp(VpssGrp, pstVpssGrpAttr);

for (j = 0; j < VPSS_MAX_PHY_CHN_NUM; j++)// VPSS_MAX_PHY_CHN_NUM = 4
VpssChn = j;
HI_MPI_VPSS_SetChnAttr(VpssGrp, VpssChn, &pastVpssChnAttr[VpssChn]);
HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn);

HI_MPI_VPSS_StartGrp(VpssGrp);

五、start VO:

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 上。

HI_MPI_VO_SetPubAttr(VoDev, pstPubAttr);// 配置视频输出设备VoDev(根据不同的芯片,有所不同)的公共属性(hdmi或者mipi,视频的输出格式如1080P60)。
HI_MPI_VO_Enable(VoDev);//使能视频输出设备

HI_MPI_VO_GetVideoLayerAttr(VoLayer, &stLayerAttr);// VoLayer(0.1.2即高清视频层0.1.2)获取视频层属性
HI_MPI_VO_SetChnAttr(VoLayer, i, &stChnAttr);//同一个图层VoLayer中,不同的视频输出通道i的属性
HI_MPI_VO_EnableChn(VoLayer, i);//使能同一个图层的不同的视频输出通道。

HI_MPI_VO_SetVideoLayerPartitionMode(VoLayer, enVoPartMode);// 设置当前视频层VoLayer的分割模式(VO_PART_MODE_MULTI,VO_PART_MODE_SINGLE)。
HI_MPI_VO_SetDisplayBufLen(VoLayer, pstVoConfig->u32DisBufLen);
HI_MPI_VO_SetVideoLayerAttr(VoLayer, pstLayerAttr);// 设备分辨率、显示分辨率和图像分辨率
HI_MPI_VO_EnableVideoLayer(VoLayer);

以下是视频输出的硬件接口的使能:
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);


MIPI:
fd = open("/dev/hi_mipi_tx", O_RDWR);
s32Ret = ioctl(fd, HI_MIPI_TX_SET_DEV_CFG, pstMipiTxConfig);//视频的输出格式。如:MIPI_TX_1080X1920_60_CONFIG。

/*中间部分为现实屏的初始化操作。主要区别和显示屏的分辨率有关。直接参考代码中的sample中的ioctl操作*/

s32Ret = ioctl(fd, HI_MIPI_TX_ENABLE);

六、VDEC bind VPSS:
stSrcChn.enModId   = HI_ID_VDEC;
stSrcChn.s32DevId  = 0;
stSrcChn.s32ChnId  = VdecChn;

stDestChn.enModId  = HI_ID_VPSS;
stDestChn.s32DevId = VpssGrp;
stDestChn.s32ChnId = 0;
HI_MPI_SYS_Bind(&stSrcChn, &stDestChn)

七、VPSS bind VO:
stSrcChn.enModId   = HI_ID_VPSS;
stSrcChn.s32DevId  = VpssGrp;
stSrcChn.s32ChnId  = VpssChn;//固定为0

stDestChn.enModId  = HI_ID_VO;
stDestChn.s32DevId = VoLayer;//Vodev
stDestChn.s32ChnId = VoChn;//对应于VpssGrp
HI_MPI_SYS_Bind(&stSrcChn, &stDestChn)

八、send stream to vdec(选定需要解码的文件路径和文件名)
每个解码通道创建一个相对应的线程,当应用程序退出时,直接退出线程即可。pthread_join(pVdecThread[i], HI_NULL);

pthread_create(&pVdecThread[i], 0, SAMPLE_COMM_VDEC_SendStream, (HI_VOID *)&pstVdecSend[i]);

SAMPLE_COMM_VDEC_SendStream:
fpStrm = fopen(cStreamFile, "rb");//打开视频文件
while(1)
{
        fseek(fpStrm, s32UsedBytes, SEEK_SET);
        s32ReadLen = fread(pu8Buf, 1, pstVdecThreadParam->s32MinBufSize, fpStrm);
        有区别于vdec,按stream和frame
        HI_MPI_VDEC_SendStream(pstVdecThreadParam->s32ChnId, &stStream, pstVdecThreadParam->s32MilliSec);
}
/* send the flag of stream end */
memset(&stStream, 0, sizeof(VDEC_STREAM_S) );
stStream.bEndOfStream = HI_TRUE;
HI_MPI_VDEC_SendStream(pstVdecThreadParam->s32ChnId, &stStream, -1); //在发送完所有码流后,可以发送 bEndOfStream 为 1 的空码流包,表示当前码流文件结束,解码器会把所有码流全部解完并输出全部图像。


九、应用退出:
pthread_join(pVdecThread[i], HI_NULL);
vpss vo unbind:HI_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
vdec vpss unbind

HI_MPI_HDMI_Stop(enHdmiId)
HI_MPI_HDMI_Close(enHdmiId)
HI_MPI_HDMI_DeInit()

HI_MPI_VO_DisableChn(VoLayer, i);
HI_MPI_VO_DisableVideoLayer(VoLayer);
HI_MPI_VO_Disable(VoDev);

HI_MPI_VPSS_StopGrp(VpssGrp);//停止每个vpssgroup
HI_MPI_VPSS_DisableChn(VpssGrp, VpssChn);//禁止vpss下的通道
HI_MPI_VPSS_DestroyGrp(VpssGrp);//销毁VpssGrp

//多个解码通道的话,每个通道都要分别执行
HI_MPI_VDEC_StopRecvStream(i)//解码通道i停止接收数据流
HI_MPI_VDEC_DestroyChn(i)//销毁解码通道i

HI_MPI_VB_ExitModCommPool(VB_UID_VDEC);//VDEC退出模块公共视频缓存池

HI_MPI_SYS_Exit();
HI_MPI_VB_Exit();

至此整个视频的解码流程就到此结束

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页