Hi3559A 使用HI_MPI_VENC_SendFrame送yuv的例子
说明:
参考mpp中sample_venc.c添加如下代码,自行调用即可。
代码是向venc灌入同一帧yuv数据,仅供参考。
HI_VOID* SAMPLE_SendVencOneFrameProc(HI_VOID* p)
{
VENC_CHN VencChn = 0;
HI_S32 s32Ret = HI_SUCCESS;
HI_U64 u32Cnt = 0;
HI_U32 u32Profile = 0;
HI_U32 u32PhyAddr;
HI_U8 *pVirAddr=NULL;
HI_U32 milli_sec = 20000;
HI_U32 u32YSize = 3840*2160;
HI_U32 u32UVSize = 3840*2160/2;
HI_U32 u32YUVSize = 3840*2160*3/2;
VB_POOL poolID;
HI_U64 u64PhyAddrYuv;
HI_VOID *ppVirAddrYuv;
HI_U64 phyYaddr;
HI_U64* virYaddr;
FILE *fb = HI_NULL;
HI_BOOL isOneFrame = HI_FALSE;
VIDEO_FRAME_INFO_S stFrmInfo;
HI_U64 pu64CurPTS;
if (fb != HI_NULL)
{
fclose(fb);
fb = HI_NULL;
}
fb = fopen("./3840x2160.yuv", "rb" );
if (fb == HI_NULL)
{
SAMPLE_PRT("Open yuv file failed!Check if the file %s exit\n","./3840x2160.yuv");
return;
}
s32Ret = HI_MPI_SYS_MmzAlloc(&u64PhyAddrYuv, (HI_VOID**)&ppVirAddrYuv,"YUV420SP_3840_2160_FRAME_MEM", NULL, u32YUVSize);
if(HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_SYS_MmzAlloc err:0x%x",s32Ret);
HI_MPI_SYS_MmzFree(u64PhyAddrYuv, ppVirAddrYuv);
return;
}
fread(ppVirAddrYuv, u32YUVSize, 1, fb);
#if 0
int src_fd = open("YUV420SP_3840_2160_FRAME_MEM.yuv", O_RDWR+O_CREAT);
if (src_fd < 0)
{
printf("open YUV420SP_3840_2160_FRAME_MEM err\n");
return;
}
lseek(src_fd,0,SEEK_SET);
write(src_fd, ppVirAddrYuv, u32YUVSize);
#endif
printf("---->>>u64BlkSize=%d\n",u32YUVSize);
while(gs_stSendPara.bThreadStart)
{
// create venc buffer
VB_BLK handleY = HI_MPI_VB_GetBlock(VB_INVALID_POOLID, u32YUVSize, NULL);
if( handleY == VB_INVALID_HANDLE)
{
usleep(10);
printf("HI_MPI_VB_GetBlock for Block failed\n");
continue;
}
poolID = HI_MPI_VB_Handle2PoolId(handleY);
//printf("pool id %d\n", poolID);
phyYaddr = HI_MPI_VB_Handle2PhysAddr(handleY);
if( phyYaddr == 0)
{
printf("HI_MPI_VB_Handle2PhysAddr for handleY failed\n");
continue;
}
virYaddr = (HI_U64*) HI_MPI_SYS_Mmap(phyYaddr, u32YUVSize);
if(!isOneFrame)
{
memset(&stFrmInfo.stVFrame, 0, sizeof(VIDEO_FRAME_S));
stFrmInfo.enModId = HI_ID_VENC;
stFrmInfo.u32PoolId = poolID;
stFrmInfo.stVFrame.u64PhyAddr[0] = phyYaddr;
stFrmInfo.stVFrame.u64PhyAddr[1] = stFrmInfo.stVFrame.u64PhyAddr[0] + u32YSize;
//stFrmInfo.stVFrame.u64PhyAddr[2] = stFrmInfo.stVFrame.u64PhyAddr[1] + u32YSize;
stFrmInfo.stVFrame.u64VirAddr[0] = (HI_U64 *)virYaddr;
stFrmInfo.stVFrame.u64VirAddr[1] = (HI_U64 *)stFrmInfo.stVFrame.u64VirAddr[0] + u32YSize;
//stFrmInfo.stVFrame.u64VirAddr[2] = (HI_U8 *) stFrmInfo.stVFrame.u64VirAddr[1] + u32YSize;
stFrmInfo.stVFrame.u32Width = 3840;
stFrmInfo.stVFrame.u32Height = 2160;
stFrmInfo.stVFrame.u32Stride[0] = 3840;
stFrmInfo.stVFrame.u32Stride[1] = 3840;
//stFrmInfo.stVFrame.u32Stride[2] = 3840;
HI_MPI_SYS_GetCurPTS(&pu64CurPTS);
stFrmInfo.stVFrame.u64PTS = pu64CurPTS;
stFrmInfo.stVFrame.u32TimeRef = (u32Cnt * 2);//timeref need n*2 but you can't get the second frame
stFrmInfo.stVFrame.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
stFrmInfo.stVFrame.enField = VIDEO_FIELD_FRAME;
stFrmInfo.stVFrame.enCompressMode = COMPRESS_MODE_NONE;
stFrmInfo.stVFrame.enVideoFormat = VIDEO_FORMAT_LINEAR;
stFrmInfo.stVFrame.enDynamicRange = DYNAMIC_RANGE_SDR8;
//memcpy 4k about cost 95ms
memcpy(stFrmInfo.stVFrame.u64VirAddr[0], ppVirAddrYuv, u32YUVSize);
isOneFrame = HI_TRUE;
}
else
{
HI_MPI_SYS_GetCurPTS(&pu64CurPTS);
stFrmInfo.u32PoolId = poolID;
stFrmInfo.stVFrame.u64PTS = pu64CurPTS;
stFrmInfo.stVFrame.u32TimeRef = (u32Cnt * 2);//timeref need n*2 but you can't get the second frame
}
s32Ret = HI_MPI_VENC_SendFrame(VencChn, &stFrmInfo, milli_sec);
HI_MPI_SYS_Munmap(virYaddr, u32YUVSize);
HI_MPI_VB_ReleaseBlock(handleY);
u32Cnt ++;
}
//before destroy private pool,must stop venc
HI_MPI_VB_DestroyPool(poolID);
HI_MPI_SYS_MmzFree(u64PhyAddrYuv, ppVirAddrYuv);
//close YUV File
fclose(fb);
fb=HI_NULL;
}
HI_S32 SAMPLE_START_VENC_4K30_SaveES(HI_VOID)
{
HI_S32 s32Ret;
VENC_CHN VencChn = 0;
VENC_CHN_ATTR_S stVencChnAttr;
VENC_RECV_PIC_PARAM_S stRecvParam;
HI_U32 u32PicWidth = 3840;
HI_U32 u32PicHeigh = 2160;
HI_U64 u64BlkSize = u32PicWidth*u32PicHeigh*3/2;
HI_S32 s32ChnNum = 1;
VB_CONFIG_S stVbConf;
memset(&stVbConf, 0, sizeof(VB_CONFIG_S));
//u64BlkSize = COMMON_GetPicBufferSize(u32PicWidth, u32PicHeigh, PIXEL_FORMAT_YVU_SEMIPLANAR_420, DATA_BITWIDTH_10, COMPRESS_MODE_NONE,DEFAULT_ALIGN);
stVbConf.astCommPool[0].u64BlkSize = u64BlkSize;
stVbConf.astCommPool[0].u32BlkCnt = 15;
//u64BlkSize = COMMON_GetPicBufferSize(u32PicWidth, u32PicHeigh, PIXEL_FORMAT_YVU_SEMIPLANAR_422, DATA_BITWIDTH_10, COMPRESS_MODE_NONE,DEFAULT_ALIGN);
stVbConf.astCommPool[1].u64BlkSize = u64BlkSize;
stVbConf.astCommPool[1].u32BlkCnt = 15;
stVbConf.u32MaxPoolCnt = 2;
s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed!\n");
return s32Ret;
}
VENC_GOP_ATTR_S stGopAttr;
memset(&stGopAttr, 0x0, sizeof(stGopAttr));
stGopAttr.enGopMode = VENC_GOPMODE_NORMALP;
stGopAttr.stNormalP.s32IPQpDelta = 3;
/***encode h.264 **/
s32Ret = SAMPLE_COMM_VENC_Start(VencChn, PT_H264, PIC_3840x2160, SAMPLE_RC_CBR, 0, &stGopAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("Venc Start failed for %#x!\n", s32Ret);
SAMPLE_COMM_VENC_Stop(VencChn);
}
s32Ret = SAMPLE_COMM_VENC_StartGetStream(&VencChn, s32ChnNum);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("Start Venc failed!\n");
SAMPLE_COMM_VENC_Stop(VencChn);
}
gs_stSendPara.bThreadStart = HI_TRUE;
gs_stSendPara.VeChn = 0;
pthread_create(&gs_SendVencPid, 0, SAMPLE_SendVencOneFrameProc, (HI_VOID*)&gs_stSendPara);
return HI_SUCCESS;
}