【Hi3559A 使用HI_MPI_VENC_SendFrame送yuv的例子】

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;
}

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值