@(HI3518EV200学习)
正确配置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至此文件夹中
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;
}