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

一、初始化系统:

*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");//打开视频文件
while1{
        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();

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


本文参考:小编是个爱分享的快乐青年,分享知识传播知识,如有侵权,请联系小编。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ltqshs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值