Hi3518EV300-venc例程分析

Hi3518EV300-venc例程分析

  • 前言:
  • MAPI 层业务流程
  • VENC录像
  • 流程:
    • 1、定义要绑定的VCap,VProc,VENC变量
    • 2、start vcap
    • 3、start vproc(vpss)
    • 4、start venc

前言:

第一次搞海思的嵌入式芯片,买的海思单板给的资料pack很多很多,花了一个月磕文档熟悉代码、框架。海思定义了reference层,middleware层,mpp层 一堆堆,reference 连产品形态都定义好了,比如行车记录仪,通过配置就可以已经实现如循环录像,紧急录像,WIFI+RTSP视频流。

海思的东东像其它文章说的那样它有自己一套理念,我们的目标就是说服自己接受这套理念然后装进大脑运用它,然后快速造出自己的ID产品。

MAPI 层业务流程

MAPI 层内部处理流程如下图 所示,主要分为视频捕获(VCap)、视频处理
(VProc)、视频编码(VENC)、显示预览(DISP)、音频输入(AI)、音频输出(AO)、音
频编码(AENC)等模块。主要的处理流程介绍如下:
Hi3518EV300-venc例程分析_第1张图片

  1. VCap 模块捕获视频图像,可对其做 bayer 缩放,叠加 OSD 等处理,并输出 YUV 图像数据。
  2. VProc 模块接收 VCap 发送过来的图像,可对图像进行去噪、缩放、旋转、拍照算法合成等处理,并实现同源输出多路不同分辨率的图像数据用于编码、预览或抓 拍。
  3. VENC 模块接收 VProc 处理后输出的图像数据,然后按不同协议 H.264/H.265/JPEGE等进行编码并输出相应码流或者照片。
  4. DISP 模块接收 VProc 处理后的图像输出到显示设备。
  5. AI 模块捕获音频数据,然后 AENC 模块支持按多种音频协议对其进行编码,最后 输出音频码流。

现在回过头来分析middleware/ndk/sample_venc.c 的代码。

VENC录像

function :SAMPLE_VENC_Record(HI_VOID)
实现功能:1080p30fps H.264 record
PS:启动VENC录像对于应用层来说其实就是一堆绑定再启动,绑定包括:DEV和VCAP的绑定,VCAP和VPSS的绑定,VPSS和VENC的绑定。

流程:

1、定义要绑定的VCap,VProc,VENC变量

VCap { pipe { channel } }
Vpss { vport }
Venc { .0 .1 .2 .3 }

//------------------Vcap----------------------//	
    HI_HANDLE VcapDev0 = SAMPLE_MAPI_VCAP_DEV_0;
    HI_HANDLE VcapPipe0 = SAMPLE_MAPI_VCAP_PIPE_0;
    HI_HANDLE PipeChn0 = SAMPLE_MAPI_PIPE_CHN_0;
    HI_MAPI_VCAP_ATTR_S stVcapAttr;               //定义 VCAP 通路的属性
    HI_MAPI_SENSOR_ATTR_S stVcapSensorAttr;       //定义 Sensor 的模式(时序)属性。
    SAMPLE_COMM_INITATTR_S stSampleCommAttr;		
    FILE* pFd[HI_MAPI_VENC_MAX_CHN_NUM] = {NULL};
//-----------------Vpss----------------------//
    HI_HANDLE VpssHdl0 = 0;
    HI_HANDLE VPortHdl0 = 0;
    HI_BOOL bStitch = HI_FALSE;				
    HI_MAPI_VPSS_ATTR_S stVpssAttr;            	//定义 VPSS 输入属性的结构体。		    
    HI_MAPI_VPORT_ATTR_S stVPortAttr;			//VPort 输出图像信息
//----------------Venc-----------------------//
    HI_HANDLE VencHdl0 = 0;
    HI_HANDLE VencHdl1 = 1;
    HI_S32 s32FrameCnt = -1;
    HI_MAPI_VENC_ATTR_S stVencAttr;				//定义视频编码属性结构体。
    HI_MAPI_VENC_CALLBACK_S stVencBigStreamCb;   //定义视频编码回调函数结构体。 

2、start vcap

2.1 sensor0 属性结构体的相关参数赋值 。

//-----------获取SAMPLE_SENSOR_1080P30模式的参数------------------//
SAMPLE_CHECK_GOTO(SAMPLE_COMM_GetSensorCfg(SAMPLE_SENSOR_1080P30, &stVcapSensorAttr)); //镜头采集配置模式 
//---------------------------------------------------------------//
Sensor 的模式(时序)属性结构体:
typedef struct hiMAPI_SENSOR_ATTR_S {
    HI_U32 u32SnsMode;//Sensor 的模式参数,用以区分不同时序。
    WDR_MODE_E enWdrMode;//WDR 模式枚举,详情参考《HiMPP V4.0 媒体处理软件开发参考.pdf》 3518ev300不支持此参数。
    SIZE_S stSize; //Sensor 的分辨率结构体
    HI_MAPI_INPUT_DEV_ATTR_S stInputDevAttr;//前端输入设备的属性。
} HI_MAPI_SENSOR_ATTR_S;

//Sensor 所有模式下的序列通过配置文件 sensor_interface_cfg_params.c 中配置.
//----------SAMPLE_SENSOR_1080P30-----结构体成员赋值如下--------------------------//
const HI_MAPI_SENSOR_ATTR_S g_stSensor1080PMode0 = {
    .u32SnsMode = 0,
    .enWdrMode = WDR_MODE_NONE,
    .stSize = {
        .u32Width = 1920,
        .u32Height = 1080,
    }
};

2.2、[vcap.dev]结构体属性成员 赋值

SAMPLE_CHECK_GOTO(memcpy_s(&stVcapAttr.stVcapDevAttr, sizeof(HI_MAPI_VCAP_DEV_ATTR_S), &g_stDev1080P,
        sizeof(HI_MAPI_VCAP_DEV_ATTR_S)));
        
相关结构体:
 typedef struct hiMAPI_VCAP_ATTR_S {
    HI_MAPI_VCAP_DEV_ATTR_S stVcapDevAttr; /*   //VCAP DEV 的属性

    HI_U32 u32PipeBindNum;  //与 VCAP DEV 绑定的 VCAP PIPE 的总个数。           /* 
    HI_HANDLE aPipeIdBind[HI_MAPI_VCAP_MAX_PIPE_NUM]; //该 VCAP DEV 锁绑定的 PIPE 号        /* 
    HI_MAPI_VCAP_PIPE_ATTR_S
    astVcapPipeAttr[HI_MAPI_VCAP_MAX_PIPE_NUM]; /* 与 VCAP PIPE 相关的属性 
} HI_MAPI_VCAP_ATTR_S;       
//定义 VCAP DEV 的属性。
typedef struct hiMAPI_VCAP_DEV_ATTR_S { 
    SIZE_S stBasSize;     /* 
						//Bayer 域缩放之后的宽、高。BAS 只支持 1 倍,2 倍或者 3 倍缩小。静态属性。   
//不过文档提了       Hi3559V200/Hi3518EV300 不支持 BAS。				 		
    VI_WDR_ATTR_S stWDRAttr;//WDR 属性,详情参考《HiMPP V4.0 媒体处理软件开发参考.pdf》
    VI_INTF_MODE_E enIntfMode;  /*   //视频设备的接口模式
    HI_U32 au32ComponentMask[VI_COMPMASK_NUM]; /*   //分量掩码配置详情参考
    VI_YUV_DATA_SEQ_E enDataSeq; /*   //输入数据顺序(仅支持 yuv 格式) 详情参考《HiMPP V4.0 媒体处理软件开发参考.pdf》
    VI_DATA_TYPE_E      enInputDataType; /* //输入数据类型,Sensor 输入一般为 RGB,AD 输入一般为 YUV,详情参考《HiMPP V4.0 媒体处理软件开发参考.pdf》
} HI_MAPI_VCAP_DEV_ATTR_S; 

//---------------------结构体变量赋值如下--------------------------//
const HI_MAPI_VCAP_DEV_ATTR_S g_stDev1080P = {
    .stBasSize = {            //估计这里没用的。。因为3518EV300不支持BAS。
        .u32Width = 1920,
        .u32Height = 1080,
    },
    .stWDRAttr = {
        .enWDRMode = WDR_MODE_NONE,
    }
};

2.3、[vcap.pipe.0] 理解为pipe输入结构体属性赋值

    SAMPLE_CHECK_GOTO(memcpy_s(&stVcapAttr.astVcapPipeAttr[VcapPipe0], sizeof(HI_MAPI_VCAP_PIPE_ATTR_S),
        &g_stPipe1080P30Fps, sizeof(HI_MAPI_VCAP_PIPE_ATTR_S)));

//----------------相关相关结构体-------------------------------//
typedef struct hiMAPI_VCAP_PIPE_ATTR_S {
    HI_MAPI_PIPE_TYPE_E enPipeType;         /* 
    FRAME_RATE_CTRL_S stFrameRate;          /* 
    COMPRESS_MODE_E enCompressMode;         /* 
    HI_BOOL bIspBypass;                     /* 
    VI_PIPE_BYPASS_MODE_E enPipeBypassMode; /* 
#ifndef __HI3559AV100__
    /* the attr is not support in current version */
    FRAME_INTERRUPT_ATTR_S stFrameIntAttr; /* 
#endif
    HI_MAPI_PIPE_ISP_ATTR_S stIspPubAttr;                             /* 
    HI_MAPI_PIPE_CHN_ATTR_S astPipeChnAttr[HI_MAPI_PIPE_MAX_CHN_NUM]; /* 
} HI_MAPI_VCAP_PIPE_ATTR_S;

//---------------------结构体变量赋值如下--------------------------//
const HI_MAPI_VCAP_PIPE_ATTR_S g_stPipe1080P30Fps = {
    .stFrameRate = {//VCAP PIPE 的帧率控制结构体,详见《HiMPPV4.0 媒体处理软件开发参考》
        .s32SrcFrameRate = -1,
        .s32DstFrameRate = -1,
    },
    .enCompressMode = COMPRESS_MODE_NONE, //VCAP PIPE 的数据压缩格式
    .bIspBypass = HI_FALSE,
    .enPipeBypassMode = VI_PIPE_BYPASS_NONE,
    .stIspPubAttr = {
        .f32FrameRate = 30.0f, //!!!输入图像帧率。低于 sensor 时序最大帧率。动态属性。
        .stSize = {//ISP 裁剪后的宽高,结构体详见《HiMPPV4.0 媒体处理软件开发参考.pdf》静态属性。
            .u32Width = 1920,
            .u32Height = 1080,
        },
        .enBayer = BAYER_RGGB,//Bayer 数据格式。枚举详见《Hi ISP 开发参考.pdf》静态属性。
    }
};

2.4 、[vcap.pipe.0.chn.0] 理解为channel输出结构体属性赋值

 SAMPLE_CHECK_GOTO(memcpy_s(&stVcapAttr.astVcapPipeAttr[VcapPipe0].astPipeChnAttr[PipeChn0],
        sizeof(HI_MAPI_PIPE_CHN_ATTR_S), &g_stChn1080P30Fps, sizeof(HI_MAPI_PIPE_CHN_ATTR_S)));

//----------------相关相关结构体-------------------------------//
typedef struct hiMAPI_PIPE_CHN_ATTR_S {
    SIZE_S stDestSize;              /* 
    FRAME_RATE_CTRL_S stFrameRate;  /* 
    COMPRESS_MODE_E enCompressMode; /* 
    PIXEL_FORMAT_E enPixelFormat;   /* 
} HI_MAPI_PIPE_CHN_ATTR_S;

//---------------------结构体变量赋值如下--------------------------//
const HI_MAPI_PIPE_CHN_ATTR_S g_stChn1080P30Fps = {        
    .stDestSize = {  //目标分辨率
        .u32Width = 1920,
        .u32Height = 1080,
    },
    .stFrameRate = {  //帧率控制结构体
        .s32SrcFrameRate = 30,
        .s32DstFrameRate = 30,
    },
    .enCompressMode = COMPRESS_MODE_NONE,//不压缩
    .enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420, //像素格式
};

2.5、 VB and media Attr 赋值

    /* VB and media Attr */
    SAMPLE_CHECK_GOTO(memset_s(&stSampleCommAttr, sizeof(SAMPLE_COMM_INITATTR_S), 0, sizeof(SAMPLE_COMM_INITATTR_S)));//清空结构体
    SAMPLE_CHECK_GOTO(memset_s(&stSampleCommAttr.stViVpssMode, sizeof(VI_VPSS_MODE_S), 0, sizeof(VI_VPSS_MODE_S)));//清空结构体
	 //--------------------------------共用初始化属性赋值-------------------------------------------------------------//
    stSampleCommAttr.stResolution.u32Width = stVcapSensorAttr.stSize.u32Width;    //将sensor的分辨率给 stResolution分辨率  
    stSampleCommAttr.stResolution.u32Height = stVcapSensorAttr.stSize.u32Height;  //			
    stSampleCommAttr.stViVpssMode.aenMode[VcapPipe0] = VI_ONLINE_VPSS_ONLINE;	  //PIPE 在线指的是 VI_ONLINE_VPSS_OFFLINE 
    stSampleCommAttr.u8SnsCnt = u8SnsCnt;

    /* init VB and media */
	//VB_MODE_1:not stitch Stitch 是对多路图像拼接,有四种拼接模式 3518EV300 不支持
    SAMPLE_CHECK_GOTO(SAMPLE_COMM_InitBufWrap(stSampleCommAttr, VB_MODE_1, NULL));
   //--------------函数内部------------------------//
HI_S32 SAMPLE_COMM_InitBufWrap(SAMPLE_COMM_INITATTR_S stSampleCommAttr, SAMPLE_VB_CFG_MODE_E enVbMode,
    VPSS_CHN_BUF_WRAP_S *pstVpssChnBufWrap)
{
    HI_S32 s32Ret = HI_SUCCESS;

    /* start media */
    HI_MAPI_MEDIA_ATTR_S stMediaAttr;   //定义媒体配置属性结构体。
    HI_U32 u32BlkSize;

    SAMPLE_CHECK_RET(memset_s(&stMediaAttr, sizeof(HI_MAPI_MEDIA_ATTR_S), 0, sizeof(HI_MAPI_MEDIA_ATTR_S)));//清空stMediaAttr
    SAMPLE_CHECK_RET(memset_s(&stMediaAttr.stMediaConfig.stVIVPSSMode, sizeof(VI_VPSS_MODE_S), 0,/*清空stMediaAttr.stMediaConfig.stVIVPSSMode*/
        sizeof(VI_VPSS_MODE_S)));

    SAMPLE_CHECK_RET(memcpy_s(&stMediaAttr.stMediaConfig.stVIVPSSMode, sizeof(VI_VPSS_MODE_S),
        &stSampleCommAttr.stViVpssMode, sizeof(VI_VPSS_MODE_S)));   //赋值 VIVPSS模式 
	//--------------------------VB 配置参数------------------------------------------------------//
/*		typedef struct hiVB_CONFIG_S
		{
		HI_U32 u32MaxPoolCnt; // max count of pools, (0,VB_MAX_POOLS]  整个系统中可容纳的缓存池个数。
		VB_POOL_CONFIG_S astCommPool[VB_MAX_COMM_POOLS];  公共缓存池属性结构体。
		} VB_CONFIG_S;
*/
    stMediaAttr.stMediaConfig.stVbConfig.u32MaxPoolCnt = 32;   //整个系统中可容纳的缓存池个数。
    if (VB_MODE_1 == enVbMode) {
//视频缓存池大小计算接口 				 					接口简介		
//VI_GetRawBufferSize						VI 写出的 Raw 数据缓存池
//COMMON_GetPicBufferSize					一般 linear(线性存储)) 格式的 YUV 各部分数据大小		
        u32BlkSize = VI_GetRawBufferSize(stSampleCommAttr.stResolution.u32Width,   /* 原始数据RGB*/
            stSampleCommAttr.stResolution.u32Height, PIXEL_FORMAT_RGB_BAYER_12BPP, COMPRESS_MODE_NONE, DEFAULT_ALIGN);
        stMediaAttr.stMediaConfig.stVbConfig.astCommPool[0].u64BlkSize = u32BlkSize; //缓存块 大小,以 Byte 位单位。
        stMediaAttr.stMediaConfig.stVbConfig.astCommPool[0].u32BlkCnt = 2;  //每个缓存池的 缓存块 个数。
       
        u32BlkSize = COMMON_GetPicBufferSize(stSampleCommAttr.stResolution.u32Width,
                                             stSampleCommAttr.stResolution.u32Height, PIXEL_FORMAT_YVU_SEMIPLANAR_420,
                                             DATA_BITWIDTH, COMPRESS_MODE_NONE, DEFAULT_ALIGN);
        stMediaAttr.stMediaConfig.stVbConfig.astCommPool[1].u64BlkSize = u32BlkSize;
        stMediaAttr.stMediaConfig.stVbConfig.astCommPool[1].u32BlkCnt = 2;
        u32BlkSize = COMMON_GetPicBufferSize(640, 480, PIXEL_FORMAT_YVU_SEMIPLANAR_420, DATA_BITWIDTH,
                                             COMPRESS_MODE_NONE, DEFAULT_ALIGN);
        stMediaAttr.stMediaConfig.stVbConfig.astCommPool[2].u64BlkSize = u32BlkSize;
        stMediaAttr.stMediaConfig.stVbConfig.astCommPool[2].u32BlkCnt = 3;
    }
    stMediaAttr.stVencModPara.u32H264eLowPowerMode = 1;     //H264 低功耗模式
    stMediaAttr.stVencModPara.u32H265eLowPowerMode = 1;		//H265 低功耗模式
//初始化媒体相关各模块的资源。 
//包括:读取 Sensor,DIS 相关配置文件,设置 VI 和 VPSS 在线离线模式、VB 个数和大小、VENC 相关模块低功耗模式,然后做媒体业务的初始化工作
    s32Ret = HI_MAPI_Media_Init(&stMediaAttr);   
    if (s32Ret != HI_SUCCESS) {
        printf("HI_MAPI_Media_Init error:%#x.\n", s32Ret);
        return HI_FAILURE;
    }

    return HI_SUCCESS;
}


2.6、vcap通路属性的参数通过上面的赋值,现在开始初始化和启动 vcap!

//----------------venc调用的接口--------------------------------------//
SAMPLE_VCAP_CreateSingle(VcapDev0, VcapPipe0, PipeChn0, &stVcapSensorAttr, &stVcapAttr)
//--------------- 函数内部功能----------------------------------------------//
HI_S32 SAMPLE_VCAP_CreateSingle(HI_HANDLE VcapDevHdl, HI_HANDLE VcapPipeHdl, HI_HANDLE PipeChnHdl,
    HI_MAPI_SENSOR_ATTR_S* pstVcapSensorAttr, HI_MAPI_VCAP_ATTR_S* pstVcapAttr)
{
    HI_S32 s32Ret = HI_SUCCESS; 
//功能:初始化 sensor,包含以什么样的 sensor 属性(时序)进行 sensor 的初始化。其中,Sensor 所有模式下的序列通过配置文件 sensor_interface_cfg_params.c 中配置	.
//VcapDevHdl:Sensor 所在的 VCAP DEV 的 Handle 号。pstSensorAttr:Sensor 属性(或称时序)。bResetSensor:是否需要复位 Sensor 时钟标志位。bResetSensor 只有在 IPC 业务下置为 False,正常流程下传入 True。
    SAMPLE_CHECK_RET(HI_MAPI_VCAP_InitSensor(VcapDevHdl, pstVcapSensorAttr, HI_TRUE));
//功能:设置 VCAP 通路属性。 
//注意:1、必须先初始化 Sensor 才能设置 VCAP 属性。
//		2、这个接口将设置 VCAP 整个通路的属性以及绑定关系包括:VCAP DEV 属性、VCAP PIPE 属性、ISP PUB 属性、VCAP CHN 属性、VCAP DEV 与 VCAP PIPE的绑定关系
//VcapDevHdl :VCAP DEV 的 Handle 号。  pstVCapAttr:VCAP 属性。  
    SAMPLE_CHECK_RET(HI_MAPI_VCAP_SetAttr(VcapDevHdl, pstVcapAttr));
//启动 VCAP DEV
    SAMPLE_CHECK_RET(HI_MAPI_VCAP_StartDev(VcapDevHdl));
//启动 VCAP CHN
    SAMPLE_CHECK_RET(HI_MAPI_VCAP_StartChn(VcapPipeHdl, PipeChnHdl));
//初始化 ISP
    SAMPLE_CHECK_RET(HI_MAPI_VCAP_InitISP(VcapPipeHdl));
//启动 VCAP PIPE
    SAMPLE_CHECK_RET(HI_MAPI_VCAP_StartPipe(VcapPipeHdl));
//启动 ISP 处理单元
    SAMPLE_CHECK_RET(HI_MAPI_VCAP_StartISP(VcapPipeHdl));
    return s32Ret;
}

这里其实我有点蒙圈的,stVcapSensorAttr理解为给sensor的初始化用, stVcapAttr.stVcapDevAttr 理解为 给 Vcap(通路属性这个抽象概念)定义的dev对象用。 通过 VcapDevHdl 把它们链接了起来。

3、start vproc(vpss)

typedef struct hiMAPI_VPSS_ATTR_S {
    HI_U32 u32MaxW;   //	需要处理的 VPSS 输入数据的最大宽度。
    HI_U32 u32MaxH;    //	需要处理的 VPSS 输入数据的最大高度。
    FRAME_RATE_CTRL_S stFrameRate;  //帧率控制结构体,其中-1 代表不做帧率控制,详情请参考《HiMPP V4.0 媒体处理软件开发参考》
    PIXEL_FORMAT_E enPixelFormat;  //输入图像的像素格式
    HI_BOOL bNrEn;//NR 去噪开关。
    VPSS_NR_ATTR_S stNrAttr;//NR 属性结构体,详情请参考《HiMPP V4.0 媒体处理软件开发参考》。
} HI_MAPI_VPSS_ATTR_S;

######################配置VPSS 输入数据######################
const HI_MAPI_VPSS_ATTR_S g_stVpss1080P30Fps = {
    .u32MaxW = 1920,
    .u32MaxH = 1080,
    .stFrameRate = {
        .s32SrcFrameRate = 30,
        .s32DstFrameRate = 30,
    },
    .enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420,
    .bNrEn = HI_TRUE,
    .stNrAttr = {
        .enCompressMode = COMPRESS_MODE_NONE,
        .enNrMotionMode = NR_MOTION_MODE_NORMAL,
    },
};

typedef struct hiMAPI_VPORT_ATTR_S {
    HI_U32 u32Width;//VPort 输出宽度取值范围:[32, 8192]。
    HI_U32 u32Height;//VPort 输出高度取值范围:[32, 8192]。
    HI_BOOL bSupportBufferShare;//是否支持输入输出复用 buffer。
//只有 Hi3559V200 与 Hi3518EV300 支持 bSupportBufferShare。
    FRAME_RATE_CTRL_S stFrameRate;//帧率控制结构体,其中-1 代表不做帧率控制,详情请参考《HiMPP V4.0 媒体处理软件开发参考》。
    VIDEO_FORMAT_E enVideoFormat;//VPort 输出的视频存储格式,详情请参考《HiMPPV4.0 媒体处理软件开发参考》。
    PIXEL_FORMAT_E enPixelFormat;//VPort 输出的像素格式,详情请参考《HiMPP V4.0媒体处理软件开发参考》。
    COMPRESS_MODE_E enCompressMode;//VPort 输出的压缩格式。支持HI_COMPRESS_MODE_NONE 和HI_COMPRESS_MODE_SEG,详情请参考《HiMPP V4.0 媒体处理软件开发参考》
    ASPECT_RATIO_S stAspectRatio;//视频层内视频的幅型比,详情请参考《HiMPP V4.0媒体处理软件开发参考》。
} HI_MAPI_VPORT_ATTR_S;

######################配置VPSS的 vport输出######################
const HI_MAPI_VPORT_ATTR_S g_stVport1080P30Fps = {
    .u32Width = 1920,
    .u32Height = 1080,
    .stFrameRate = {
        .s32SrcFrameRate = 30,
        .s32DstFrameRate = 30,
    },
    .enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420,
    .enVideoFormat = VIDEO_FORMAT_LINEAR,  //线性存储的视频格式
    .enCompressMode = COMPRESS_MODE_NONE,  //非压缩的视频格式
};
 图像模式 YUV 数据 enVideoFormat 必须为 VIDEO_FORMAT_LINEAR。
 图像模式 YUV 数据 enCompressMode 必须为非压 COMPRESS_MODE_NONE。

初始化、绑定和启动工作( 绑定是后者(vpss)绑定前者(vcap)).

//初始化一个 vpss 处理单元  VpssHdl:vpss handle 号,pstVpssAttr:vpss 属性指针。 
    SAMPLE_CHECK_GOTO(HI_MAPI_VPROC_InitVpss(VpssHdl0, &stVpssAttr));
//将 VPROC 和 Vcap 绑定,用于接收 Vcap 的图像。VcapPipeHdl:capPipe handle 号
//PipeChnHdl:PipeChn handle 号。   VpssHdl :vpss handle 号
    SAMPLE_CHECK_GOTO(HI_MAPI_VPROC_BindVcap(VcapPipe0, PipeChn0, VpssHdl0));
//配置 VPort 输出的图像属性。	VpssHdl:vpss handle 号.
//VPortHdl :VPort handle 号。	pstVPortAttr:VPort 输出图像属性信息结构体。
    SAMPLE_CHECK_GOTO(HI_MAPI_VPROC_SetPortAttr(VpssHdl0, VPortHdl0, &stVPortAttr));
//启动 VPort,输出图像。VpssHdl:vpss handle 号。  VPortHdl: VPort handle 号。  
    SAMPLE_CHECK_GOTO(HI_MAPI_VPROC_StartPort(VpssHdl0, VPortHdl0));

4、start venc

相关结构体如下:
/* the attribute of video encode */
typedef struct hiMAPI_VENC_ATTR_S {
    HI_MAPI_VENC_TYPE_ATTR_S stVencPloadTypeAttr; /*  
    HI_MAPI_VENC_RC_ATTR_S stRcAttr;              /* 
} HI_MAPI_VENC_ATTR_S;

/*
 the attribute of encoder type */
typedef struct hiMAPI_VENC_TYPE_ATTR_S {
    HI_MAPI_PAYLOAD_TYPE_E enType;         /*   //编码类型
    HI_U32 u32Width;                       /* 
    HI_U32 u32Height;                      /* 
    HI_U32 u32BufSize;                     /* 
    HI_U32 u32Profile;                     /* 
    HI_MAPI_VENC_SCENE_MODE_E enSceneMode; /* 
    union {
        HI_MAPI_VENC_ATTR_H264_S stAttrH264e;  /* 
        HI_MAPI_VENC_ATTR_H265_S stAttrH265e;  /* 
        HI_MAPI_VENC_ATTR_JPEG_S stAttrJpege;  /* 
        HI_MAPI_VENC_ATTR_MJPEG_S stAttrMjpeg; /* 
    };

} HI_MAPI_VENC_TYPE_ATTR_S;
/* the attribute of rate control */
typedef struct hiMAPI_VENC_RC_ATTR_S {
    HI_MAPI_VENC_RC_MODE_E enRcMode; /* 
    union {
        HI_MAPI_VENC_ATTR_CBR_S stAttrCbr;   /* 
        HI_MAPI_VENC_ATTR_VBR_S stAttrVbr;   /* 
        HI_MAPI_VENC_ATTR_QVBR_S stAttrQVbr; /* 
        HI_MAPI_VENC_ATTR_CVBR_S stAttrCVbr; /* 
        HI_MAPI_VENC_ATTR_AVBR_S stAttrAVbr; /* 
    };
} HI_MAPI_VENC_RC_ATTR_S;

typedef struct hiVENC_H264_CBR_S
    HI_MAPI_VENC_ATTR_CBR_S; 
    
/* the attribute of h264e cbr */
typedef struct hiVENC_H264_CBR_S {
    HI_U32      u32Gop;                    /* RW; Range:[1, 65536]; the interval of I Frame. */
    HI_U32      u32StatTime;               /* RW; Range:[1, 60]; the rate statistic time, the unit is senconds(s) *///CBR 码率统计时间,以秒为单位。
    HI_U32      u32SrcFrameRate;           /* RW; Range:[1, 240]; the input frame rate of the venc chnnel */
    HI_FR32     fr32DstFrameRate ;         /* RW; Range:[0.015625, 240]; the target frame rate of the venc chnnel,can not be larger than u32SrcFrameRate */
    HI_U32      u32BitRate;                /* RW; Range:[2, 614400]; average bitrate */
} VENC_H264_CBR_S;

typedef enum hiMAPI_VENC_SCENE_MODE_E
{
HI_MAPI_VENC_SCENE_MODE_NORMAL, /**
HI_MAPI_VENC_SCENE_MODE_DV, /**
HI_MAPI_VENC_SCENE_MODE_CAR, /**
HI_MAPI_VENC_SCENE_MODE_BUTT,
}HI_MAPI_VENC_SCENE_MODE_E;

//-------HI_MAPI_VENC_ATTR_S 视频编码属性结构体:定义H264参数配置。-----------//
const HI_MAPI_VENC_ATTR_S g_stVenc1080P30FpsVideoH264 = {
    .stVencPloadTypeAttr = {
        .enType = HI_MAPI_PAYLOAD_TYPE_H264,
        .u32Width = 1920,
        .u32Height = 1080,
        .u32BufSize = 1920 * 1080 * 3 / 2,
        .u32Profile = 0,
        .enSceneMode = HI_MAPI_VENC_SCENE_MODE_DV,//dv scene mode
    },
    .stRcAttr = {
        .enRcMode = HI_MAPI_VENC_RC_MODE_CBR,  //constant bit rate
            .stAttrCbr = {
            .u32Gop = 30,
            .u32StatTime = 2,
            .u32SrcFrameRate = 30,
            .fr32DstFrameRate = 30,
            .u32BitRate = 4096,
        }
    }
};

    /* venc 0 H264 big stream */
    SAMPLE_CHECK_GOTO(memcpy_s(&stVencAttr, sizeof(HI_MAPI_VENC_ATTR_S), &g_stVenc1080P30FpsVideoH264,
        sizeof(HI_MAPI_VENC_ATTR_S)));

初始化、绑定和启动工作( 绑定是后者(VENC)绑定前者(vpss)).

//aFilePath :  /sharefs/SAMPLE_VENC_Record_chn0.h264
    pFd[VencHdl0] = SAMPLE_AUDIO_OpenVideoFile(aFilePath);  //返回已经打开文件的句柄
    stVencBigStreamCb.pfnDataCB = SMAPLE_COMM_VENC_DataProc;//回调处理函数。用于获取编码数据。
    stVencBigStreamCb.pPrivateData = pFd[VencHdl0];  //私有数据指针。作为参数,在 PFN_VENC_DataProc 中被调用。

//初始化编码通道。 VencHdl:VENC 通道号。 pstVencAttr:  VENC 通道属性指针。
    SAMPLE_CHECK_GOTO(HI_MAPI_VENC_Init(VencHdl0, &stVencAttr));
//注册编码通道回调函数,用于编码数据的获取(stVencBigStreamCb会将.h264数据流写到文件)。
//VencHdl:VENC 通道号。        pstVencCB:编码器回调函数结构体指针。
    SAMPLE_CHECK_GOTO(HI_MAPI_VENC_RegisterCallback(VencHdl0, &stVencBigStreamCb));
//绑定 VProc 输入端。                               bStitch=0 非拼接
    SAMPLE_CHECK_GOTO(HI_MAPI_VENC_BindVProc(VpssHdl0, VPortHdl0, VencHdl0, bStitch));
//启动编码通道。
    SAMPLE_CHECK_GOTO(HI_MAPI_VENC_Start(VencHdl0, s32FrameCnt));

至此启动步骤就分析得7788了;在单板上运行例程,成功运行情况下文件存储路径就会看到生成的SAMPLE_VENC_Record_chn0.h264文件。

END!

你可能感兴趣的:(海思,嵌入式,视频处理)