/* * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. * * File Name: sample/common/sample_common_vpss.c * Description: * Common sample code for video process. */ #include #include #include #include #include "sample_comm.h" /***************************************************************************** * function : Create Vpss group & enable channel. *****************************************************************************/ CVI_S32 SAMPLE_COMM_VPSS_Init(VPSS_GRP VpssGrp, CVI_BOOL *pabChnEnable, VPSS_GRP_ATTR_S *pstVpssGrpAttr, VPSS_CHN_ATTR_S *pastVpssChnAttr) { VPSS_CHN VpssChn; CVI_S32 s32Ret; CVI_S32 j; s32Ret = CVI_VPSS_CreateGrp(VpssGrp, pstVpssGrpAttr); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_VPSS_CreateGrp(grp:%d) failed with %#x!\n", VpssGrp, s32Ret); return CVI_FAILURE; } s32Ret = CVI_VPSS_ResetGrp(VpssGrp); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_VPSS_ResetGrp(grp:%d) failed with %#x!\n", VpssGrp, s32Ret); return CVI_FAILURE; } for (j = 0; j < VPSS_MAX_PHY_CHN_NUM; j++) { if (pabChnEnable[j]) { VpssChn = j; s32Ret = CVI_VPSS_SetChnAttr(VpssGrp, VpssChn, &pastVpssChnAttr[VpssChn]); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_VPSS_SetChnAttr failed with %#x\n", s32Ret); return CVI_FAILURE; } s32Ret = CVI_VPSS_EnableChn(VpssGrp, VpssChn); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_VPSS_EnableChn failed with %#x\n", s32Ret); return CVI_FAILURE; } } } return CVI_SUCCESS; } /***************************************************************************** * function : start vpss grp. *****************************************************************************/ CVI_S32 SAMPLE_COMM_VPSS_Start(VPSS_GRP VpssGrp, CVI_BOOL *pabChnEnable, VPSS_GRP_ATTR_S *pstVpssGrpAttr, VPSS_CHN_ATTR_S *pastVpssChnAttr) { CVI_S32 s32Ret; UNUSED(pabChnEnable); UNUSED(pstVpssGrpAttr); UNUSED(pastVpssChnAttr); s32Ret = CVI_VPSS_StartGrp(VpssGrp); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_VPSS_StartGrp failed with %#x\n", s32Ret); return CVI_FAILURE; } return CVI_SUCCESS; } /***************************************************************************** * function : start vpss grp, surport wrap. *****************************************************************************/ CVI_S32 SAMPLE_COMM_VPSS_WRAP_Start(VPSS_GRP VpssGrp, CVI_BOOL* pabChnEnable, VPSS_GRP_ATTR_S* pstVpssGrpAttr, VPSS_CHN_ATTR_S* pastVpssChnAttr, VPSS_CHN_BUF_WRAP_S* pstVpssChnBufWrap) { VPSS_CHN VpssChn; CVI_S32 s32Ret; CVI_S32 j; s32Ret = CVI_VPSS_CreateGrp(VpssGrp, pstVpssGrpAttr); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_MPI_VPSS_CreateGrp(grp:%d) failed with %#x!\n", VpssGrp, s32Ret); return CVI_FAILURE; } for (j = 0; j < VPSS_MAX_PHY_CHN_NUM; j++) { if (pabChnEnable[j] == CVI_TRUE) { VpssChn = j; s32Ret = CVI_VPSS_SetChnAttr(VpssGrp, VpssChn, &pastVpssChnAttr[VpssChn]); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_VPSS_SetChnAttr failed with %#x\n", s32Ret); return CVI_FAILURE; } if ((VpssChn == VPSS_CHN0) || (VpssChn == VPSS_CHN1)) { s32Ret = CVI_VPSS_SetChnBufWrapAttr(VpssGrp, VpssChn, pstVpssChnBufWrap); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_MPI_VPSS_SetChnBufWrapAttr failed with %#x\n", s32Ret); return CVI_FAILURE; } } s32Ret = CVI_VPSS_EnableChn(VpssGrp, VpssChn); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_MPI_VPSS_EnableChn failed with %#x\n", s32Ret); return CVI_FAILURE; } } } s32Ret = CVI_VPSS_StartGrp(VpssGrp); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("CVI_MPI_VPSS_StartGrp failed with %#x\n", s32Ret); return CVI_FAILURE; } return CVI_SUCCESS; } /* SAMPLE_COMM_VPSS_Stop: stop vpss grp * * VpssGrp: the VPSS Grp to control * pabChnEnable: array of VPSS CHN, stop if true. */ CVI_S32 SAMPLE_COMM_VPSS_Stop(VPSS_GRP VpssGrp, CVI_BOOL *pabChnEnable) { CVI_S32 j; CVI_S32 s32Ret = CVI_SUCCESS; VPSS_CHN VpssChn; for (j = 0; j < VPSS_MAX_PHY_CHN_NUM; j++) { if (pabChnEnable[j]) { VpssChn = j; s32Ret = CVI_VPSS_DisableChn(VpssGrp, VpssChn); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("Vpss stop Grp %d channel %d failed! Please check param\n", VpssGrp, VpssChn); return CVI_FAILURE; } } } s32Ret = CVI_VPSS_StopGrp(VpssGrp); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("Vpss Stop Grp %d failed! Please check param\n", VpssGrp); return CVI_FAILURE; } s32Ret = CVI_VPSS_DestroyGrp(VpssGrp); if (s32Ret != CVI_SUCCESS) { SAMPLE_PRT("Vpss Destroy Grp %d failed! Please check\n", VpssGrp); return CVI_FAILURE; } return CVI_SUCCESS; } /* SAMPLE_COMM_VPSS_SendFrame: * send frame, whose data loaded from given filename. * * VpssGrp: the VPSS Grp to control. * stSize: size of image. * enPixelFormat: format of image * filename: file to read. */ CVI_S32 SAMPLE_COMM_VPSS_SendFrame(VPSS_GRP VpssGrp, SIZE_S *stSize, PIXEL_FORMAT_E enPixelFormat, CVI_CHAR *filename) { VIDEO_FRAME_INFO_S stVideoFrame; VB_BLK blk; FILE *fp; CVI_U32 u32len; VB_CAL_CONFIG_S stVbCalConfig; COMMON_GetPicBufferConfig(stSize->u32Width, stSize->u32Height, enPixelFormat, DATA_BITWIDTH_8 , COMPRESS_MODE_NONE, DEFAULT_ALIGN, &stVbCalConfig); memset(&stVideoFrame, 0, sizeof(stVideoFrame)); stVideoFrame.stVFrame.enCompressMode = COMPRESS_MODE_NONE; stVideoFrame.stVFrame.enPixelFormat = enPixelFormat; stVideoFrame.stVFrame.enVideoFormat = VIDEO_FORMAT_LINEAR; stVideoFrame.stVFrame.enColorGamut = COLOR_GAMUT_BT709; stVideoFrame.stVFrame.u32Width = stSize->u32Width; stVideoFrame.stVFrame.u32Height = stSize->u32Height; stVideoFrame.stVFrame.u32Stride[0] = stVbCalConfig.u32MainStride; stVideoFrame.stVFrame.u32Stride[1] = stVbCalConfig.u32CStride; stVideoFrame.stVFrame.u32Stride[2] = stVbCalConfig.u32CStride; stVideoFrame.stVFrame.u32TimeRef = 0; stVideoFrame.stVFrame.u64PTS = 0; stVideoFrame.stVFrame.enDynamicRange = DYNAMIC_RANGE_SDR8; blk = CVI_VB_GetBlock(VB_INVALID_POOLID, stVbCalConfig.u32VBSize); if (blk == VB_INVALID_HANDLE) { SAMPLE_PRT("SAMPLE_COMM_VPSS_SendFrame: Can't acquire vb block\n"); return CVI_FAILURE; } //open data file & fread into the mmap address fp = fopen(filename, "r"); if (fp == CVI_NULL) { SAMPLE_PRT("open data file error\n"); CVI_VB_ReleaseBlock(blk); return CVI_FAILURE; } stVideoFrame.u32PoolId = CVI_VB_Handle2PoolId(blk); stVideoFrame.stVFrame.u32Length[0] = stVbCalConfig.u32MainYSize; stVideoFrame.stVFrame.u32Length[1] = stVbCalConfig.u32MainCSize; stVideoFrame.stVFrame.u64PhyAddr[0] = CVI_VB_Handle2PhysAddr(blk); stVideoFrame.stVFrame.u64PhyAddr[1] = stVideoFrame.stVFrame.u64PhyAddr[0] + ALIGN(stVbCalConfig.u32MainYSize, stVbCalConfig.u16AddrAlign); if (stVbCalConfig.plane_num == 3) { stVideoFrame.stVFrame.u32Length[2] = stVbCalConfig.u32MainCSize; stVideoFrame.stVFrame.u64PhyAddr[2] = stVideoFrame.stVFrame.u64PhyAddr[1] + ALIGN(stVbCalConfig.u32MainCSize, stVbCalConfig.u16AddrAlign); } for (int i = 0; i < stVbCalConfig.plane_num; ++i) { if (stVideoFrame.stVFrame.u32Length[i] == 0) continue; stVideoFrame.stVFrame.pu8VirAddr[i] = CVI_SYS_MmapCache(stVideoFrame.stVFrame.u64PhyAddr[i], stVideoFrame.stVFrame.u32Length[i]); u32len = fread(stVideoFrame.stVFrame.pu8VirAddr[i], stVideoFrame.stVFrame.u32Length[i], 1, fp); if (u32len <= 0) { SAMPLE_PRT("vpss send frame: fread plane%d error\n", i); fclose(fp); CVI_VB_ReleaseBlock(blk); return CVI_FAILURE; } CVI_SYS_IonInvalidateCache(stVideoFrame.stVFrame.u64PhyAddr[i], stVideoFrame.stVFrame.pu8VirAddr[i], stVideoFrame.stVFrame.u32Length[i]); } SAMPLE_PRT("length of buffer(%d, %d, %d)\n", stVideoFrame.stVFrame.u32Length[0] , stVideoFrame.stVFrame.u32Length[1], stVideoFrame.stVFrame.u32Length[2]); SAMPLE_PRT("phy addr(%#"PRIx64", %#"PRIx64", %#"PRIx64")\n", stVideoFrame.stVFrame.u64PhyAddr[0] , stVideoFrame.stVFrame.u64PhyAddr[1], stVideoFrame.stVFrame.u64PhyAddr[2]); SAMPLE_PRT("vir addr(%p, %p, %p)\n", stVideoFrame.stVFrame.pu8VirAddr[0] , stVideoFrame.stVFrame.pu8VirAddr[1], stVideoFrame.stVFrame.pu8VirAddr[2]); fclose(fp); SAMPLE_PRT("read file done and send out frame.\n"); CVI_VPSS_SendFrame(VpssGrp, &stVideoFrame, -1); CVI_VB_ReleaseBlock(blk); for (int i = 0; i < stVbCalConfig.plane_num; ++i) { if (stVideoFrame.stVFrame.u32Length[i] == 0) continue; CVI_SYS_Munmap(stVideoFrame.stVFrame.pu8VirAddr[i], stVideoFrame.stVFrame.u32Length[i]); } return CVI_SUCCESS; }