海思mpp之VDEC(視頻解碼)的接口調用流程分析

原文鏈接:https://blog.csdn.net/oqqhutu12345678/article/details/82843617 https://blog.51cto.com/shugenyin/1851228

參考: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();

至此整個視頻的解碼流程就到此結束

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章