05、HI3518 自己写sample

05、HI3518 自己写sample

@(HI3518EV200学习)

文章目录

    • 05、HI3518 自己写sample
      • 新建工程
      • 配置VI
      • 附代码

目标

正确配置sensor -> VI -> Vpss -> Venc -> Save , 使其产生流文件,并保存

新建工程

①、拷贝mpp文件夹至新建工程文件夹中
②、在mpp文件夹下新建my_camera文件夹
③、拷贝mpp->sample->Makefile.param至my_camera文件夹
④、my_camera文件夹下新建一个my_vi文件夹
⑤、新建my_vi.c 拷贝mpp->sample->venc->Makefile至此文件夹中

配置VI

mipi使用

由于使用的是DC接口,所以配置mipi比较简单
MIPI Rx 提供对接 sensor 时序的功能。提供 ioctl 接口
hi3518ev200支持设置 MIPI Rx 设备属性HI_MIPI_SET_DEV_ATTR

配置步骤

1、根据sensor size 计算VB大小 配置VB参数 VB_CONF_S
2、初始化mpp系统
①、系统、VB 去初始化
②、根据一种的VB参数配置VB
③、VB初始化、系统配置、系统初始化

static HI_S32 MY_VI_MppSystemInit(VB_CONF_S* pstVbConf)
{
	MPP_SYS_CONF_S stSysConf = {0};
	HI_S32 s32Ret;
	HI_MPI_SYS_Exit();
	HI_MPI_VB_Exit();
    s32Ret = HI_MPI_VB_SetConf(pstVbConf);
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_VB_SetConf failed!\n");
        return HI_FAILURE;
    }
    s32Ret = HI_MPI_VB_Init();
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_VB_Init failed!\n");
        return HI_FAILURE;
    }
    stSysConf.u32AlignWidth = 64;
    s32Ret = HI_MPI_SYS_SetConf(&stSysConf);
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_SYS_SetConf failed\n");
        return HI_FAILURE;
    }
    s32Ret = HI_MPI_SYS_Init();
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_SYS_Init failed!\n");
        return HI_FAILURE;
    }
	return HI_SUCCESS;
}

3、启动VI设备和配置VI通道
①、配置sensor的硬件接口(设置mipi接口属性)ioctl(fd, HI_MIPI_SET_DEV_ATTR, pstcomboDevAttr)
②、sensor register callback
③、 register hisi ae、awb、af lib
④、 isp mem init (外部寄存器初始化)
⑤、isp set WDR mode
⑥、isp set pub attributes 设置公共属性
⑦、 isp init (HI_MPI_ISP_Init)
⑧、创建线程运行 ISP firmware (HI_MPI_ISP_Run)
⑨、设置VI设备属性(HI_MPI_VI_SetDevAttr)、WDR属性、开启VI设备(HI_MPI_VI_EnableDev)
4、开启VPSS并且绑定VI
①、创建一个 VPSS GROUP,在线模式仅支持一个0号GROUP,离线模式做大可创建VPSS_MAX_GRP_NUM个GROUP
②、set vpss 3DNR param
③、启用 VPSS GROUP
④、调用HI_MPI_SYS_Bind 将VI、VPSS绑定
⑤、设置VPSS通道属性(HI_MPI_VPSS_SetChnAttr)配置VPSS通道工作模式 (HI_MPI_VPSS_SetChnMode)
⑥、使能VPSS通道(HI_MPI_VPSS_SetChnAttr)
5、开启流编码
①、创建编码通道(HI_MPI_VENC_CreateChn)
②、开启编码通道接收输入图像(HI_MPI_VENC_StartRecvPic)
③、绑定 VPSS和VENC
6、获取流数据
①、获取编码通道对应的设备文件句柄(HI_MPI_VENC_GetFd)
②、使用fopen新建一个流文件
③、使用select来等待句柄可读,按帧获取码流?
④、使用HI_MPI_VENC_Query()查询当前编码通道状态(当前帧的码流包个数)
⑤、使用HI_MPI_VENC_GetStream()获取编码码流
⑥、使用fwrite()保存码流
⑦、使用HI_MPI_VENC_ReleaseStream()释放码流缓存,停止后,关闭文件

附代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "hi_common.h"
#include "hi_comm_sys.h"
#include "hi_comm_vb.h"
#include "hi_comm_isp.h"
#include "hi_comm_vi.h"
#include "hi_comm_vo.h"
#include "hi_comm_venc.h"
#include "hi_comm_vpss.h"
#include "hi_comm_vdec.h"
#include "hi_comm_region.h"
#include "hi_comm_adec.h"
#include "hi_comm_aenc.h"
#include "hi_comm_ai.h"
#include "hi_comm_ao.h"
#include "hi_comm_aio.h"
#include "hi_defines.h"

#include "mpi_sys.h"
#include "mpi_vb.h"
#include "mpi_vi.h"
#include "mpi_vo.h"
#include "mpi_venc.h"
#include "mpi_vpss.h"
#include "mpi_vdec.h"
#include "mpi_region.h"
#include "mpi_adec.h"
#include "mpi_aenc.h"
#include "mpi_ai.h"
#include "mpi_ao.h"
#include "mpi_isp.h"
#include "mpi_ae.h"
#include "mpi_awb.h"
#include "mpi_af.h"
#include "hi_vreg.h"
#include "hi_sns_ctrl.h"
#include "hi_mipi.h"


/*OV9732 DC 12bit input 720P@30fps*/
VI_DEV_ATTR_S DEV_ATTR_OV9732_DC_720P_BASE =
{
    /* interface mode */
    VI_MODE_DIGITAL_CAMERA,
    /* multiplex mode */
    VI_WORK_MODE_1Multiplex,
    /* r_mask    g_mask    b_mask*/
    {0xFFC0000,    0x0},
    /* progessive or interleaving */
    VI_SCAN_PROGRESSIVE,
    /*AdChnId*/
    {-1, -1, -1, -1},
    /*enDataSeq, only support yuv*/
    VI_INPUT_DATA_YUYV,

    /* synchronization information */
    {
    /*port_vsync   port_vsync_neg     port_hsync        port_hsync_neg        */
    VI_VSYNC_FIELD, VI_VSYNC_NEG_HIGH, VI_HSYNC_VALID_SINGNAL,VI_HSYNC_NEG_HIGH,VI_VSYNC_VALID_SINGAL,VI_VSYNC_VALID_NEG_HIGH,

    /*hsync_hfb    hsync_act    hsync_hhb*/
    {370,            1280,        0,
    /*vsync0_vhb vsync0_act vsync0_hhb*/
     6,            720,        6,
    /*vsync1_vhb vsync1_act vsync1_hhb*/
     0,            0,            0}
    },
    /* use interior ISP */
    VI_PATH_ISP,
    /* input data type */
    VI_DATA_TYPE_RGB,
    /* Data Reverse */
    HI_FALSE,
    {0, 0, 1280, 720}
};


static HI_BOOL gbIspInited = HI_FALSE;
static pthread_t gs_IspPid = 0;

static pthread_t gs_VencPid;

static HI_BOOL gs_VencPara;



HI_S32 MY_VI_Online_Mode(void);




int main(int argc, char* argv[])
{

	HI_S32 s32Ret = HI_SUCCESS;
	printf("11111111111111111\n");
	MY_VI_Online_Mode();
	
	printf("RUN OVER\n");
	exit(s32Ret);
}



static HI_S32 MY_VI_MppSystemInit(VB_CONF_S* pstVbConf)
{
	MPP_SYS_CONF_S stSysConf = {0};
	HI_S32 s32Ret;
	
	HI_MPI_SYS_Exit();
	HI_MPI_VB_Exit();
    s32Ret = HI_MPI_VB_SetConf(pstVbConf);
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_VB_SetConf failed!\n");
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_VB_Init();
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_VB_Init failed!\n");
        return HI_FAILURE;
    }

    stSysConf.u32AlignWidth = 64;
    s32Ret = HI_MPI_SYS_SetConf(&stSysConf);
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_SYS_SetConf failed\n");
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_SYS_Init();
    if (HI_SUCCESS != s32Ret)
    {
        printf("HI_MPI_SYS_Init failed!\n");
        return HI_FAILURE;
    }
	return HI_SUCCESS;

}


static HI_S32 MY_VI_SetMipiAttr(void)
{
	combo_dev_attr_t MIPI_CMOS3V3_ATTR =
	{
		/* input mode */
		.input_mode = INPUT_MODE_CMOS_33V,
		{
			
		}
	};


	HI_S32 fd;
	combo_dev_attr_t *pstcomboDevAttr = NULL;

	/* mipi reset unrest */
	fd = open("/dev/hi_mipi", O_RDWR);
	
	if (fd < 0)
	{
		printf("warning: open hi_mipi dev failed\n");
		return -1;
	}
	pstcomboDevAttr = &MIPI_CMOS3V3_ATTR;

	if (NULL == pstcomboDevAttr)
	{
		printf("Func %s() Line[%d], unsupported\n", __FUNCTION__, __LINE__);
		close(fd);
		return HI_FAILURE;	 
	}


	if (ioctl(fd, HI_MIPI_SET_DEV_ATTR, pstcomboDevAttr))
	{
		printf("set mipi attr failed\n");
		close(fd);
		return HI_FAILURE;
	}
	close(fd);
	return HI_SUCCESS;	
}


HI_S32 MY_VI_COMM_ISP_Init(void)

{
    ISP_DEV IspDev = 0;
    HI_S32 s32Ret;
    ISP_PUB_ATTR_S stPubAttr;
    ALG_LIB_S stLib;
    
    /* 1. sensor register callback */
    s32Ret = sensor_register_callback();
    if (s32Ret != HI_SUCCESS)
    {
        printf("%s: sensor_register_callback failed with %#x!\n", \
               __FUNCTION__, s32Ret);
        return s32Ret;
    }

    /* 2. register hisi ae lib */
    stLib.s32Id = 0;
    strcpy(stLib.acLibName, HI_AE_LIB_NAME);
    s32Ret = HI_MPI_AE_Register(IspDev, &stLib);
    if (s32Ret != HI_SUCCESS)
    {
        printf("%s: HI_MPI_AE_Register failed!\n", __FUNCTION__);
        return s32Ret;
    }

    /* 3. register hisi awb lib */
    stLib.s32Id = 0;
    strcpy(stLib.acLibName, HI_AWB_LIB_NAME);
    s32Ret = HI_MPI_AWB_Register(IspDev, &stLib);
    if (s32Ret != HI_SUCCESS)
    {
        printf("%s: HI_MPI_AWB_Register failed!\n", __FUNCTION__);
        return s32Ret;
    }

    /* 4. register hisi af lib */
    stLib.s32Id = 0;
    strcpy(stLib.acLibName, HI_AF_LIB_NAME);
    s32Ret = HI_MPI_AF_Register(IspDev, &stLib);
    if (s32Ret != HI_SUCCESS)
    {
        printf("%s: HI_MPI_AF_Register failed!\n", __FUNCTION__);
        return s32Ret;
    }

    /* 5. isp mem init */
    s32Ret = HI_MPI_ISP_MemInit(IspDev);
    if (s32Ret != HI_SUCCESS)
    {
        printf("%s: HI_MPI_ISP_Init failed!\n", __FUNCTION__);
        return s32Ret;
    }

    /* 6. isp set WDR mode */
    ISP_WDR_MODE_S stWdrMode;
    stWdrMode.enWDRMode  = WDR_MODE_NONE;
    s32Ret = HI_MPI_ISP_SetWDRMode(0, &stWdrMode);    
    if (HI_SUCCESS != s32Ret)
    {
        printf("start ISP WDR failed!\n");
        return s32Ret;
    }

    /* 7. isp set pub attributes */
    /* note : different sensor, different ISP_PUB_ATTR_S define.
              if the sensor you used is different, you can change
              ISP_PUB_ATTR_S definition */
    stPubAttr.enBayer               = BAYER_BGGR;
    stPubAttr.f32FrameRate          = 30;
    stPubAttr.stWndRect.s32X        = 0;
    stPubAttr.stWndRect.s32Y        = 0;
    stPubAttr.stWndRect.u32Width    = 1280;
    stPubAttr.stWndRect.u32Height   = 720;
 
    s32Ret = HI_MPI_ISP_SetPubAttr(IspDev, &stPubAttr);
    if (s32Ret != HI_SUCCESS)
    {
        printf("%s: HI_MPI_ISP_SetPubAttr failed with %#x!\n", __FUNCTION__, s32Ret);
        return s32Ret;
    }

    /* 8. isp init */
    s32Ret = HI_MPI_ISP_Init(IspDev);
    if (s32Ret != HI_SUCCESS)
    {
        printf("%s: HI_MPI_ISP_Init failed!\n", __FUNCTION__);
        return s32Ret;
    }

    gbIspInited = HI_TRUE;

    return HI_SUCCESS;
}




static HI_VOID* Test_ISP_Run(HI_VOID *param)
{
    ISP_DEV IspDev = 0;
    HI_MPI_ISP_Run(IspDev);

    return HI_NULL;
}


static HI_S32 MY_VI_COMM_ISP_Run(void)
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, 4096 * 1024);
    if (0 != pthread_create(&gs_IspPid, &attr, (void* (*)(void*))Test_ISP_Run, NULL))
    {
        printf("%s: create isp running thread failed!\n", __FUNCTION__);
        pthread_attr_destroy(&attr);
        return HI_FAILURE;
    }
    usleep(1000);
    pthread_attr_destroy(&attr);

	
    return HI_SUCCESS;
}


static void MY_VI_COMM_ISP_Stop(void)
{
	ISP_DEV IspDev = 0;
	HI_S32 s32Ret;
	ALG_LIB_S stLib;
	if (!gbIspInited)
	{
		return;
	}
	HI_MPI_ISP_Exit(IspDev);
	if (gs_IspPid)
	{
		pthread_join(gs_IspPid, 0);
		gs_IspPid = 0;
	}
	gbIspInited = HI_FALSE;
	/* unregister hisi af lib */
	stLib.s32Id = 0;
	strcpy(stLib.acLibName, HI_AF_LIB_NAME);
	s32Ret = HI_MPI_AF_UnRegister(IspDev, &stLib);
	if (s32Ret != HI_SUCCESS)
	{
		printf("%s: HI_MPI_AF_UnRegister failed!\n", __FUNCTION__);
		return;
	}

	/* unregister hisi awb lib */
	stLib.s32Id = 0;
	strcpy(stLib.acLibName, HI_AWB_LIB_NAME);
	s32Ret = HI_MPI_AWB_UnRegister(IspDev, &stLib);
	if (s32Ret != HI_SUCCESS)
	{
		printf("%s: HI_MPI_AWB_UnRegister failed!\n", __FUNCTION__);
		return;
	}

	/* unregister hisi ae lib */
	stLib.s32Id = 0;
	strcpy(stLib.acLibName, HI_AE_LIB_NAME);
	s32Ret = HI_MPI_AE_UnRegister(IspDev, &stLib);
	if (s32Ret != HI_SUCCESS)
	{
		printf("%s: HI_MPI_AE_UnRegister failed!\n", __FUNCTION__);
		return;
	}

	/* sensor unregister callback */
	s32Ret = sensor_unregister_callback();
	if (s32Ret != HI_SUCCESS)
	{
		printf("%s: sensor_unregister_callback failed with %#x!\n", \
		__FUNCTION__, s32Ret);
	    return;
	}

	return;
}




HI_S32 MY_VI_COMM_VI_StartDev(void)
{
    HI_S32 s32Ret;
    HI_S32 s32IspDev = 0;
    ISP_WDR_MODE_S stWdrMode;
    VI_DEV_ATTR_S  stViDevAttr;
	VI_DEV ViDev = 0;
    memset(&stViDevAttr,0,sizeof(stViDevAttr));

	memcpy(&stViDevAttr,&DEV_ATTR_OV9732_DC_720P_BASE,sizeof(stViDevAttr));
	stViDevAttr.stDevRect.s32X = 0;
	stViDevAttr.stDevRect.s32Y = 0;
	stViDevAttr.stDevRect.u32Width	= 1280;
	stViDevAttr.stDevRect.u32Height = 720;

    s32Ret = HI_MPI_VI_SetDevAttr(ViDev, &stViDevAttr);  //?置VI??属性
    if (s32Ret != HI_SUCCESS)
    {
        printf("HI_MPI_VI_SetDevAttr failed with %#x!\n", s32Ret);
        return HI_FAILURE;
    }

	s32Ret = HI_MPI_ISP_GetWDRMode(s32IspDev, &stWdrMode);
	if (s32Ret != HI_SUCCESS)
	{
		printf("HI_MPI_ISP_GetWDRMode failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}
	
	VI_WDR_ATTR_S stWdrAttr;
	stWdrAttr.enWDRMode = stWdrMode.enWDRMode;
	stWdrAttr.bCompress = HI_FALSE;
	
	s32Ret = HI_MPI_VI_SetWDRAttr(ViDev, &stWdrAttr);
	if (s32Ret)
	{
		printf("HI_MPI_VI_SetWDRAttr failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}

    s32Ret = HI_MPI_VI_EnableDev(ViDev);
    if (s32Ret != HI_SUCCESS)
    {
        printf("HI_MPI_VI_EnableDev failed with %#x!\n", s32Ret);
        return HI_FAILURE;
    }

    return HI_SUCCESS;


}

HI_S32 MY_VI_COMM_Config_Start_VicapChn(void)
{
	RECT_S stCapRect;
	SIZE_S stTargetSize;
	HI_S32 s32Ret = HI_SUCCESS;
    VI_CHN_ATTR_S stChnAttr;
    ROTATE_E enRotate = ROTATE_NONE;

	VI_CHN ViChn = 0;
	stCapRect.s32X = 0;
	stCapRect.s32Y = 0;
	stCapRect.u32Width = 1280;
	stCapRect.u32Height = 720;
	stTargetSize.u32Width = stCapRect.u32Width;
	stTargetSize.u32Height = stCapRect.u32Height;

	memcpy(&stChnAttr.stCapRect, &stCapRect, sizeof(RECT_S));
	stChnAttr.enCapSel = VI_CAPSEL_BOTH;
    /* to show scale. this is a sample only, we want to show dist_size = D1 only */
    stChnAttr.stDestSize.u32Width = stTargetSize.u32Width;
    stChnAttr.stDestSize.u32Height = stTargetSize.u32Height;
    stChnAttr.enPixFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420;   /* sp420 or sp422 */

    stChnAttr.bMirror = HI_FALSE;
    stChnAttr.bFlip = HI_FALSE;
    stChnAttr.s32SrcFrameRate = -1;
    stChnAttr.s32DstFrameRate = -1;
    stChnAttr.enCompressMode = COMPRESS_MODE_NONE;

    s32Ret = HI_MPI_VI_SetChnAttr(ViChn, &stChnAttr);
    if (s32Ret != HI_SUCCESS)
    {
        printf("failed with %#x!\n", s32Ret);
        return HI_FAILURE;
    }

	s32Ret = HI_MPI_VI_SetRotate(ViChn, enRotate);
	if (s32Ret != HI_SUCCESS)
	{
		printf("HI_MPI_VI_SetRotate failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}


	s32Ret = HI_MPI_VI_EnableChn(ViChn);
	if (s32Ret != HI_SUCCESS)
	{
		printf("failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}

	return HI_SUCCESS;




}


HI_S32 MY_VI_StartVpssAndViBindVpss(void)
{
	HI_S32 s32Ret;
	VPSS_GRP_ATTR_S stVpssGrpAttr;
	VPSS_CHN_MODE_S stVpssChnMode;	
	VPSS_GRP VpssGrp = 0;
	VPSS_CHN VpssChn = 0;		
	VPSS_CHN_ATTR_S stVpssChnAttr;
	VPSS_NR_PARAM_U unNrParam = {{0}};
	MPP_CHN_S stSrcChn;
	MPP_CHN_S stDestChn;

	stVpssGrpAttr.u32MaxW = 1280;
	stVpssGrpAttr.u32MaxH = 720;
	stVpssGrpAttr.bIeEn = HI_FALSE;
	stVpssGrpAttr.bNrEn = HI_TRUE;
	stVpssGrpAttr.bHistEn = HI_FALSE;
	stVpssGrpAttr.bDciEn = HI_FALSE;
	stVpssGrpAttr.enDieMode = VPSS_DIE_MODE_NODIE;
	stVpssGrpAttr.enPixFmt = PIXEL_FORMAT_YUV_SEMIPLANAR_420;

	/* start vpss grp */
	s32Ret = HI_MPI_VPSS_CreateGrp(VpssGrp, &stVpssGrpAttr);
	if (s32Ret != HI_SUCCESS)
	{
		printf("HI_MPI_VPSS_CreateGrp failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}

	/*** set vpss 3DNR param ***/
	s32Ret = HI_MPI_VPSS_GetNRParam(VpssGrp, &unNrParam);
	if (s32Ret != HI_SUCCESS)
	{
		printf("failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}

	s32Ret = HI_MPI_VPSS_SetNRParam(VpssGrp, &unNrParam);
	if (s32Ret != HI_SUCCESS)
	{
		printf("failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}

	s32Ret = HI_MPI_VPSS_StartGrp(VpssGrp);
	if (s32Ret != HI_SUCCESS)
	{
		printf("HI_MPI_VPSS_StartGrp failed with %#x\n", s32Ret);
		return HI_FAILURE;
	}

	/* Vi chn bind vpss group */
	stSrcChn.enModId  = HI_ID_VIU;
	stSrcChn.s32DevId = 0;
	stSrcChn.s32ChnId = 0;

	stDestChn.enModId  = HI_ID_VPSS;
	stDestChn.s32DevId = VpssGrp;
	stDestChn.s32ChnId = 0;	
	s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);
	if (s32Ret != HI_SUCCESS)
	{
		printf("failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}

	VpssChn = 0;
	stVpssChnMode.enChnMode 	 = VPSS_CHN_MODE_USER;
	stVpssChnMode.bDouble		 = HI_FALSE;
	stVpssChnMode.enPixelFormat  = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
	stVpssChnMode.u32Width		 = 1280;
	stVpssChnMode.u32Height 	 = 720;
	stVpssChnMode.enCompressMode = COMPRESS_MODE_SEG;
	memset(&stVpssChnAttr, 0, sizeof(stVpssChnAttr));
	stVpssChnAttr.s32SrcFrameRate = -1;
	stVpssChnAttr.s32DstFrameRate = -1;

	s32Ret = HI_MPI_VPSS_SetChnAttr(VpssGrp, VpssChn, &stVpssChnAttr);
	if (s32Ret != HI_SUCCESS)
	{
		printf("HI_MPI_VPSS_SetChnAttr failed with %#x\n", s32Ret);
		return HI_FAILURE;
	}

	s32Ret = HI_MPI_VPSS_SetChnMode(VpssGrp, VpssChn, &stVpssChnMode);
	if (s32Ret != HI_SUCCESS)
	{
		printf("%s failed with %#x\n", __FUNCTION__, s32Ret);
		return HI_FAILURE;
	} 

    s32Ret = HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn);
    if (s32Ret != HI_SUCCESS)
    {
        printf("HI_MPI_VPSS_EnableChn failed with %#x\n", s32Ret);
        return HI_FAILURE;
    }	
	return HI_SUCCESS;	
}


HI_S32 MY_VI_StartStreamVencAndVpssBindVenc(void)
{
	HI_S32 s32Ret;
	VENC_ATTR_H264_S stH264Attr;
	VENC_ATTR_H264_VBR_S stH264Vbr;
	VENC_CHN_ATTR_S stVencChnAttr;
	VIDEO_NORM_E enNorm = VIDEO_ENCODING_MODE_PAL;
	VENC_CHN VencChn = 0;
	MPP_CHN_S stSrcChn;
	MPP_CHN_S stDestChn;

	
	stVencChnAttr.stVeAttr.enType = PT_H264;

	stH264Attr.u32MaxPicWidth = 1280;
	stH264Attr.u32MaxPicHeight = 720;
	stH264Attr.u32PicWidth = 1280;/*the picture width*/
	stH264Attr.u32PicHeight = 720;/*the picture height*/
	stH264Attr.u32BufSize  = 1280 * 720;/*stream buffer size*/
	stH264Attr.u32Profile  = 0;/*0: baseline; 1:MP; 2:HP;	3:svc_t */
	stH264Attr.bByFrame = HI_TRUE;/*get stream mode is slice mode or frame mode?*/
	stH264Attr.u32BFrameNum = 0;/* 0: not support B frame; >=1: number of B frames */
	stH264Attr.u32RefNum = 1;/* 0: default; number of refrence frame*/
	memcpy(&stVencChnAttr.stVeAttr.stAttrH264e, &stH264Attr, sizeof(VENC_ATTR_H264_S));

	stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
	stH264Vbr.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
	stH264Vbr.u32StatTime = 1;
	stH264Vbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
	stH264Vbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
	stH264Vbr.u32MinQp = 10;
	stH264Vbr.u32MaxQp = 40;
	stH264Vbr.u32MaxBitRate = 1024*3;
	memcpy(&stVencChnAttr.stRcAttr.stAttrH264Vbr, &stH264Vbr, sizeof(VENC_ATTR_H264_VBR_S));



	s32Ret = HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr);
	if (HI_SUCCESS != s32Ret)
	{
		printf("HI_MPI_VENC_CreateChn [%d] faild with %#x!\n",\
		VencChn, s32Ret);
		return s32Ret;
	}

	s32Ret = HI_MPI_VENC_StartRecvPic(VencChn);
	if (HI_SUCCESS != s32Ret)
	{
		printf("HI_MPI_VENC_StartRecvPic faild with%#x!\n", s32Ret);
		return HI_FAILURE;
	}

	stSrcChn.enModId = HI_ID_VPSS;
	stSrcChn.s32DevId = 0;
	stSrcChn.s32ChnId = 0;

	stDestChn.enModId = HI_ID_VENC;
	stDestChn.s32DevId = 0;
	stDestChn.s32ChnId = 0;

	s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);
	if (s32Ret != HI_SUCCESS)
	{
		printf("failed with %#x!\n", s32Ret);
		return HI_FAILURE;
	}

	return HI_SUCCESS;

}

/******************************************************************************
* funciton : save H264 stream
******************************************************************************/
HI_S32 MY_VI__VENC_SaveH264(FILE* fpH264File, VENC_STREAM_S *pstStream)
{
    HI_S32 i;

    
    for (i = 0; i < pstStream->u32PackCount; i++)
    {
        fwrite(pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,
               pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset, 1, fpH264File);

        fflush(fpH264File);
    }
    

    return HI_SUCCESS;
}

static HI_VOID *MY_VI_VENC_GetVencStreamProc_Svc_t(void *p)

{
    HI_S32 i=0;
	HI_S32 s32Cnt=0;
    HI_S32 s32ChnTotal;
    VENC_CHN_ATTR_S stVencChnAttr;
    HI_S32 maxfd = 0;
    struct timeval TimeoutVal;
    fd_set read_fds;
    HI_S32 VencFd[VENC_MAX_CHN_NUM];
    HI_CHAR aszFileName[VENC_MAX_CHN_NUM][64];
    FILE *pFile[VENC_MAX_CHN_NUM];
    char szFilePostfix[10];
    VENC_CHN_STAT_S stStat;
    VENC_STREAM_S stStream;
    HI_S32 s32Ret;
    VENC_CHN VencChn;
    PAYLOAD_TYPE_E enPayLoadType[VENC_MAX_CHN_NUM];
    

	s32ChnTotal = 1;

	
    /******************************************
     step 1:  check & prepare save-file & venc-fd
    ******************************************/

    /* decide the stream file name, and open file to save stream */
    VencChn = 0;
    s32Ret = HI_MPI_VENC_GetChnAttr(VencChn, &stVencChnAttr);
    if(s32Ret != HI_SUCCESS)
    {
        printf("HI_MPI_VENC_GetChnAttr chn[%d] failed with %#x!\n", \
               VencChn, s32Ret);
        return NULL;
    }
    enPayLoadType[0] = stVencChnAttr.stVeAttr.enType;


	strcpy(szFilePostfix, ".h264");

	
	for(s32Cnt =0; s32Cnt<1; s32Cnt++)
    {
    	sprintf(aszFileName[i+s32Cnt], "Tid%d%s", i+s32Cnt, szFilePostfix);
        pFile[i+s32Cnt] = fopen(aszFileName[i+s32Cnt], "wb");
		
        if (!pFile[i+s32Cnt])
        {
            printf("open file[%s] failed!\n", 
                   aszFileName[i+s32Cnt]);
            return NULL;
        }
	}	

    /* Set Venc Fd. */
    VencFd[0] = HI_MPI_VENC_GetFd(0);		//?取文件句柄
    if (VencFd[0] < 0)
    {
        printf("HI_MPI_VENC_GetFd failed with %#x!\n", 
               VencFd[0]);
        return NULL;
    }
    if (maxfd <= VencFd[0])
    {
        maxfd = VencFd[0];
    }
    

    /******************************************
     step 2:  Start to get streams of each channel.
    ******************************************/
    while (HI_TRUE == (*((HI_BOOL*)p)))
    {
        FD_ZERO(&read_fds);
        for (i = 0; i < 1; i++)
        {
            FD_SET(VencFd[i], &read_fds);
        }

        TimeoutVal.tv_sec  = 2;
        TimeoutVal.tv_usec = 0;
        s32Ret = select(maxfd + 1, &read_fds, NULL, NULL, &TimeoutVal);
        if (s32Ret < 0)
        {
            printf("select failed!\n");
            break;
        }
        else if (s32Ret == 0)
        {
            printf("get venc stream time out, exit thread\n");
            continue;
        }
        else
        {
            for (i = 0; i < s32ChnTotal; i++)
            {
                if (FD_ISSET(VencFd[i], &read_fds))
                {
                    /*******************************************************
                     step 2.1 : query how many packs in one-frame stream.
                    *******************************************************/
                    memset(&stStream, 0, sizeof(stStream));
                    s32Ret = HI_MPI_VENC_Query(i, &stStat);
                    if (HI_SUCCESS != s32Ret)
                    {
                        printf("HI_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret);
                        break;
                    }
					
					/*******************************************************
					step 2.2 :suggest to check both u32CurPacks and u32LeftStreamFrames at the same time,for example:
					 if(0 == stStat.u32CurPacks || 0 == stStat.u32LeftStreamFrames)
					 {
						SAMPLE_PRT("NOTE: Current  frame is NULL!\n");
						continue;
					 }
					*******************************************************/
					if(0 == stStat.u32CurPacks)
					{
						  printf("NOTE: Current  frame is NULL!\n");
						  continue;
					}
                    /*******************************************************
                     step 2.3 : malloc corresponding number of pack nodes.
                    *******************************************************/
                    stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);
                    if (NULL == stStream.pstPack)
                    {
                        printf("malloc stream pack failed!\n");
                        break;
                    }
                    
                    /*******************************************************
                     step 2.4 : call mpi to get one-frame stream
                    *******************************************************/
                    stStream.u32PackCount = stStat.u32CurPacks;
                    s32Ret = HI_MPI_VENC_GetStream(i, &stStream, HI_TRUE);
                    if (HI_SUCCESS != s32Ret)
                    {
                        free(stStream.pstPack);
                        stStream.pstPack = NULL;
                        printf("HI_MPI_VENC_GetStream failed with %#x!\n", \
                               s32Ret);
                        break;
                    }

                    /*******************************************************
                     step 2.5 : save frame to file
                    *******************************************************/
					
					for(s32Cnt=0;s32Cnt<1;s32Cnt++)
					{
						
						switch(s32Cnt)
						{
							case 0:
								if(BASE_IDRSLICE == stStream.stH264Info.enRefType ||
				    				BASE_PSLICE_REFBYBASE == stStream.stH264Info.enRefType)
								{
									s32Ret = MY_VI__VENC_SaveH264(pFile[0], &stStream);
								}
							break;
						}
		
						if (HI_SUCCESS != s32Ret)
	                    {
	                        free(stStream.pstPack);
	                        stStream.pstPack = NULL;
	                        printf("save stream failed!\n");
	                        break;
	                    }
					}

    /******************************************************
                     step 2.6 : release stream
                    *******************************************************/
                    s32Ret = HI_MPI_VENC_ReleaseStream(0, &stStream);
                    if (HI_SUCCESS != s32Ret)
                    {
                        free(stStream.pstPack);
                        stStream.pstPack = NULL;
                        break;
                    }
                    /*******************************************************
                     step 2.7 : free pack nodes
                    *******************************************************/
                    free(stStream.pstPack);
                    stStream.pstPack = NULL;
                }
            }
        }
    }

    /*******************************************************
     step 3 : close save-file
    *******************************************************/
    for (i = 0; i < s32ChnTotal; i++)
    {
        for (s32Cnt = 0; s32Cnt < 3; s32Cnt++)
        {
            if (pFile[i+s32Cnt])
            {
                fclose(pFile[i+s32Cnt]);
            }
        }
    }

    return NULL;
}

HI_S32 MY_VI_VencStartGetStream(void)
{
	gs_VencPara = HI_TRUE;
	return pthread_create(&gs_VencPid, 0, MY_VI_VENC_GetVencStreamProc_Svc_t, (HI_VOID*)(&gs_VencPara));

}

HI_S32 MY_VI_Online_Mode(void)
{

	VB_CONF_S stVbConf;
	PIC_SIZE_E enPicSize = PIC_HD720;

    VPSS_EXT_CHN_ATTR_S stVpssExtChnAttr;
	
	HI_S32 s32Ret = HI_SUCCESS;
	HI_U32 u32HeaderSize;
    HI_U32 u32BlkSize;
    SIZE_S stSize;

    /******************************************
     step  1: init global  variable
    ******************************************/
	memset(&stVbConf, 0, sizeof(VB_CONF_S));

	VB_PIC_HEADER_SIZE(1280, 720, PIXEL_FORMAT_YUV_SEMIPLANAR_420, u32HeaderSize);
    u32BlkSize = (CEILING_2_POWER(1280, 64) * CEILING_2_POWER(720,64) * 1.5) + u32HeaderSize;

	stVbConf.u32MaxPoolCnt = 128;
    /*ddr0 video buffer*/
    stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;
    stVbConf.astCommPool[0].u32BlkCnt  = 6;
	
    /******************************************
     step 2: mpp system init. 
    ******************************************/
	MY_VI_MppSystemInit(&stVbConf);

    /******************************************
     step 3: start vi dev & chn to capture
    ******************************************/
	MY_VI_SetMipiAttr();		//硬件接口?置

	MY_VI_COMM_ISP_Init();		//ISP 相?

	MY_VI_COMM_ISP_Run();
	
	MY_VI_COMM_VI_StartDev();

	if(HI_SUCCESS != MY_VI_COMM_Config_Start_VicapChn())
	{
		MY_VI_COMM_ISP_Stop();
		return HI_FAILURE;
	}

    /******************************************
     step 4: start vpss and vi bind vpss
    ******************************************/
	MY_VI_StartVpssAndViBindVpss();

    /******************************************
     step 5: start stream venc
    ******************************************/
	MY_VI_StartStreamVencAndVpssBindVenc();

    /******************************************
     step 6: stream venc process -- get stream, then save it to file. 
    ******************************************/
	MY_VI_VencStartGetStream();

    printf("please press twice ENTER to exit this sample\n");
    getchar();
    getchar();

    /******************************************
     step 7: exit process
    ******************************************/

	gs_VencPara = HI_FALSE;
	pthread_join(gs_VencPid, 0);

	return s32Ret;
}

你可能感兴趣的:(HI3518)