04、HI3518 sample_venc Makefile和源码分析

04、HI3518 sample_venc Makefile和源码分析

@(HI3518EV200学习)


在前面,已经成功运行了venc的代码,录制得到了三个文件,现在来尝试分析下源代码。

venc的makefile分析

主要分析的三个文件:

  1. mpp下的makefile.param
  2. mpp/sample下的makefile.param
  3. mpp/sample/venc下的makefile

mpp/sample/venc下的makefile

# Hisilicon Hi3516 sample Makefile

include ../Makefile.param  # 包含mpp/sample下的makefile.param 
#ifeq ($(SAMPLE_PARAM_FILE), )   
#     SAMPLE_PARAM_FILE:=../Makefile.param
#     include $(SAMPLE_PARAM_FILE)
#endif

# target source
SRC  := $(wildcard *.c)  #通配 展开
OBJ  := $(SRC:%.c=%.o)   #所有的.c替换.o

TARGET := $(OBJ:%.o=%)   #所有X.o变为X
.PHONY : clean all       #.PHONY是一个伪目标

all: $(TARGET)			所有的目标


# SENSOR_LIBS MPI_LIBS 在mpp/sample下的makefile.param 中指定
# AUDIO_LIBA CC CFLAGS 在mpp下的makefile.param 

$(TARGET):%:%.o $(COMM_OBJ)
	$(CC) $(CFLAGS) -lpthread -lm -o $@ $^ $(MPI_LIBS) $(AUDIO_LIBA) $(SENSOR_LIBS)

clean:				#清除编译生成文件
	@rm -f $(TARGET)
	@rm -f $(OBJ)
	@rm -f $(COMM_OBJ)

cleanstream:        #清理指定格式流文件
	@rm -f *.h264
	@rm -f *.jpg
	@rm -f *.mjp
	@rm -f *.mp4

**mpp/sample下的makefile.param **

# Hisilicon Hi3518e sample Makefile.param

ifeq ($(PARAM_FILE), )
     PARAM_FILE:=../../../mpp/Makefile.param  #PARAM_FILE为空,包含mpp下的makefile.param
     include $(PARAM_FILE)
endif

ifeq ($(WDR),)		#判断WDR是否定义
WDR :=n
endif

#以下CHIP_ID如果未定义,则定义
#CHIP_ID ?= CHIP_HI3516C_V200    
CHIP_ID ?= CHIP_HI3518E_V200
#CHIP_ID ?= CHIP_HI3518E_V201

################# select sensor type for your sample ####################

#SENSOR_TYPE ?= APTINA_9M034_DC_720P_30FPS

#SENSOR_TYPE ?= SONY_IMX222_DC_1080P_30FPS
#SENSOR_TYPE ?= SONY_IMX222_DC_720P_30FPS

#SENSOR_TYPE ?= APTINA_AR0130_DC_720P_30FPS

#SENSOR_TYPE ?= PANASONIC_MN34222_MIPI_1080P_30FPS

#SENSOR_TYPE ?= APTINA_AR0230_HISPI_1080P_30FPS

SENSOR_TYPE ?= OMNIVISION_OV9712_DC_720P_30FPS
#SENSOR_TYPE ?= OMNIVISION_OV9732_DC_720P_30FPS
#SENSOR_TYPE ?= OMNIVISION_OV9750_MIPI_720P_30FPS
#SENSOR_TYPE ?= OMNIVISION_OV9752_MIPI_720P_30FPS

#SENSOR_TYPE ?= OMNIVISION_OV2718_MIPI_1080P_25FPS

##########################################################################

SENSOR_LIBS := $(REL_LIB)/libisp.a   #REL_LIB在mpp下的makefile.param有定义

#以下根据不同的sensor,选择不同的sensor.a
ifeq ($(SENSOR_TYPE), APTINA_AR0130_DC_720P_30FPS)
    SENSOR_LIBS += $(REL_LIB)/libsns_ar0130.a
endif

ifeq ($(SENSOR_TYPE), APTINA_AR0130_DC_960P_30FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_ar0130.a
endif

ifeq ($(SENSOR_TYPE), APTINA_9M034_DC_720P_30FPS)
    SENSOR_LIBS += $(REL_LIB)/libsns_9m034.a
endif

ifeq ($(SENSOR_TYPE), APTINA_9M034_DC_960P_30FPS)
       SENSOR_LIBS += $(REL_LIB)/libsns_9m034.a
endif

ifeq ($(SENSOR_TYPE), SONY_IMX222_DC_1080P_30FPS)
    SENSOR_LIBS += $(REL_LIB)/libsns_imx222.a
endif

ifeq ($(SENSOR_TYPE), SONY_IMX222_DC_720P_30FPS)
    SENSOR_LIBS += $(REL_LIB)/libsns_imx222.a
endif


ifeq ($(SENSOR_TYPE), APTINA_AR0230_HISPI_1080P_30FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_ar0230.a
endif

ifeq ($(SENSOR_TYPE), PANASONIC_MN34222_MIPI_1080P_30FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_mn34222.a
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV9712_DC_720P_30FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_ov9712.a
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV9732_DC_720P_30FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_ov9732.a
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV9750_MIPI_720P_30FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_ov9750.a
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV9752_MIPI_720P_30FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_ov9752.a
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV2718_MIPI_1080P_25FPS)
      SENSOR_LIBS += $(REL_LIB)/libsns_ov2718.a
endif

#iniparser
SENSOR_LIBS += $(REL_LIB)/lib_cmoscfg.a
SENSOR_LIBS += $(REL_LIB)/lib_iniparser.a
#########################################################################

# 指定包含文件的路径
COMMON_DIR:=$(PWD)/../common

INC_FLAGS := -I$(COMMON_DIR)
INC_FLAGS += -I$(REL_INC)
INC_FLAGS += -I$(SDK_PATH)/mpp/component/acodec

ifeq ($(MPP_BUILD), y)
	INC_FLAGS += -I$(SDK_PATH)/mpp/$(EXTDRV)/tw2865
	INC_FLAGS += -I$(SDK_PATH)/mpp/$(EXTDRV)/tlv320aic31
else
	INC_FLAGS += -I$(SDK_PATH)/mpp/extdrv/tw2865
	INC_FLAGS += -I$(SDK_PATH)/mpp/$(EXTDRV)/tlv320aic31
endif

ISP_VERSION := ISP_V2
SENSOR_LIBS += $(REL_LIB)/lib_hiae.a
SENSOR_LIBS += $(REL_LIB)/lib_hiawb.a
SENSOR_LIBS += $(REL_LIB)/lib_hiaf.a

SENSOR_LIBS += $(REL_LIB)/lib_hidefog.a

MPI_LIBS := $(REL_LIB)/libmpi.a
MPI_LIBS += $(REL_LIB)/libive.a
MPI_LIBS += $(REL_LIB)/libmd.a

CFLAGS := -Wall -g $(INC_FLAGS) -D$(HIARCH) -DHICHIP=$(HICHIP) -DSENSOR_TYPE=$(SENSOR_TYPE) -D$(HIDBG) -D$(HI_FPGA) -DCHIP_ID=$(CHIP_ID) -lpthread -lm -ldl -D$(ISP_VERSION)

ifeq ($(CHIP_ID), CHIP_HI3516C_V200)
	CFLAGS += -Dhi3516cv200
endif
ifeq ($(CHIP_ID), CHIP_HI3518E_V200)
	CFLAGS += -Dhi3518ev200
endif
ifeq ($(CHIP_ID), CHIP_HI3518E_V201)
	CFLAGS += -Dhi3518ev201
endif


ifeq ($(SENSOR_TYPE), APTINA_AR0230_HISPI_1080P_30FPS)
	CFLAGS += -DHI_MIPI_ENABLE
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV4682_MIPI_1080P_30FPS)
	CFLAGS += -DHI_MIPI_ENABLE
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV4682_MIPI_720P_30FPS)
	CFLAGS += -DHI_MIPI_ENABLE
endif

ifeq ($(SENSOR_TYPE), PANASONIC_MN34222_MIPI_1080P_30FPS)
	CFLAGS += -DHI_MIPI_ENABLE
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV9750_MIPI_720P_30FPS)
	CFLAGS += -DHI_MIPI_ENABLE
endif

ifeq ($(SENSOR_TYPE), OMNIVISION_OV9752_MIPI_720P_30FPS)
	CFLAGS += -DHI_MIPI_ENABLE
endif

################ select audio codec type for your sample ################
ACODEC_TYPE ?= ACODEC_TYPE_INNER
#external acodec
#ACODEC_TYPE ?= ACODEC_TYPE_AK7756
#ACODEC_TYPE ?= ACODEC_TYPE_TLV320AIC31

ifeq ($(ACODEC_TYPE), ACODEC_TYPE_INNER)
	CFLAGS += -DHI_ACODEC_TYPE_INNER
endif

ifeq ($(ACODEC_TYPE), ACODEC_TYPE_AK7756)
	CFLAGS += -DHI_ACODEC_TYPE_AK7756
endif

ifeq ($(ACODEC_TYPE), ACODEC_TYPE_TLV320AIC31)
	CFLAGS += -DHI_ACODEC_TYPE_TLV320AIC31
endif
#########################################################################

CFLAGS += $(LIBS_CFLAGS)
CFLAGS += -DLCD_ILI9342

COMM_SRC := $(wildcard $(COMMON_DIR)/*.c)

#DEL_SRC  := $(COMMON_DIR)/sample_comm_audio.c
#COMM_SRC := $(filter-out $(DEL_SRC), $(COMM_SRC))

COMM_OBJ := $(COMM_SRC:%.c=%.o)


**mpp下的makefile.param **太多了,就不列出来了

sample_venc.c中的main如下

int main(int argc, char *argv[])
{
    HI_S32 s32Ret;
    if ( (argc < 2) || (1 != strlen(argv[1])))
    {
        SAMPLE_VENC_Usage(argv[0]);  //打印帮助 使用
        return HI_FAILURE;
    }

    signal(SIGINT, SAMPLE_VENC_HandleSig);  //异常处理
    signal(SIGTERM, SAMPLE_VENC_HandleSig);
    
    switch (*argv[1])
    {
		    //根据不同的参数,视频编码输出不同的组合 
        case '0':/* H.264@1080p@30fps+H.265@1080p@30fps+H.264@D1@30fps */
            s32Ret = SAMPLE_VENC_1080P_CLASSIC();
            break;
        case '1':/* 1*1080p mjpeg encode + 1*1080p jpeg  */
            s32Ret = SAMPLE_VENC_1080P_MJPEG_JPEG();
            break;
        case '2':/* low delay */
            s32Ret = SAMPLE_VENC_LOW_DELAY();
            break;
        case '3':/* roibg framerate */
            s32Ret = SAMPLE_VENC_ROIBG_CLASSIC();
            break;
        case '4':/* Thumbnail of 1*1080p jpeg  */
            s32Ret = SAMPLE_VENC_1080P_JPEG_Thumb();
            break;
#ifndef hi3518ev201			
		case '5':/* H.264 Svc-t */
			s32Ret = SAMPLE_VENC_SVC_H264();
			break;
#endif
        default:
            printf("the index is invaild!\n");
            SAMPLE_VENC_Usage(argv[0]);
            return HI_FAILURE;
    }
    
    if (HI_SUCCESS == s32Ret)
        printf("program exit normally!\n");
    else
        printf("program exit abnormally!\n");
    exit(s32Ret);
}

之前使用的参数为0,就先以参数为0进行分析 SAMPLE_VENC_1080P_CLASSIC
抽重点语句解析

step 1: init sys variable //系统各个值的初始化

①、根据sensor类型获取sensor的size
②、根据size决定encode流有几路及大小
③、配置每一路编码流程的video buffer (pixformat支持420和422、宽度16、32、64对齐)

SAMPLE_COMM_VI_GetSizeBySensor()   //获取sensor的类型来更新检查当前视频的size

//我们用OV9712,走这个分支,所以会有三个视频
else if (PIC_HD720 == enSize[0])
{
	enSize[1] = PIC_VGA;			
	enSize[2] = PIC_QVGA;
	s32ChnNum = 3;
}


//三个流 ,走这个分支
if(s32ChnNum >= 3)
    {
		u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
                enSize[2], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH); //根据视频参数,计算VB块大小
		stVbConf.astCommPool[2].u32BlkSize = u32BlkSize;
		stVbConf.astCommPool[2].u32BlkCnt = g_u32BlkCnt;  //这个值为4
    }



step 2: mpp system init.

系统去初始化 HI_MPI_SYS_Exit()
视频缓存区去初始化 HI_MPI_SYS_Exit()
设置视频缓存区属性 HI_MPI_VB_SetConf()
初始化MPP视频缓存池 HI_MPI_VB_Init()
配置系统控制参数 HI_MPI_SYS_SetConf()
初始化MPP系统 HI_MPI_SYS_Init()

SAMPLE_COMM_SYS_Init()  //先去初始化,后初始化

step 3: start vi dev & chn to capture 视频输入部分配置 开启VI,并捕获

①、VI配置
1、视频输入接口、视频输入制式、旋转属性、WDR工作模式、mirror,、flip属性
2、视频采集接口开启,根据sensor类型来决定注册sensor,ISP初始化(3A注册)、运行ISP HI_MPI_ISP_Run()
3、设置VI设备属性HI_MPI_VI_SetDevAttr()、启动VI设备 HI_MPI_VI_EnableDev()
4、设置通道属性 HI_MPI_VI_SetChnAttr()、 启动VI通道 HI_MPI_VI_EnableChn

step 4: start vpss and vi bind vpss 开启视频处理并绑定

①、创建一个 VPSS GROUP HI_MPI_VPSS_CreateGrp()
②、设置3DNR HI_MPI_VPSS_SetNRParam()
③、启用HI_MPI_VPSS_StartGrp()
④、绑定VI和VPSS HI_MPI_SYS_Bind()

step5:start stream venc(开启venc流视频编码)

①、Create Venc Channel HI_MPI_VENC_CreateChn()
②、Start Recv Venc Pictures HI_MPI_VENC_StartRecvPic()
③、VENC绑定VPSS通道 SAMPLE_COMM_VENC_BindVpss()

step 6: stream venc process – get stream, then save it to file. 开启venc处理,获取流,并保存到文件
①、check & prepare save-file & venc-fd
②、Start to get streams of each channel.
③、 close save-file

码率控制器

码率控制器实现对编码码率进行控制
从信息学的角度分析,图像的压缩比越低,压缩图像的质量越高;图像压缩比例越高,压缩图像的质量越低。对于场景变化的真实场景,图像质量稳定,编码码率会波动;编码码率稳定,图像质量会波动。以 H.264 编码为例,通常图像 Qp 越低,图像的质量越好,码率越高;图像 Qp 越高,图像质量越差,码率越低。
码率模式:H.264\H.265 协议编码通道 CBR、VBR、AVBR、FIXQP
MJPEG 协议编码通道 CBR、VBR、FIXQP 三种码率控制模式
CBR
CBR(Constant Bit Rate)固定比特率。即在码率统计时间内保证编码码率平稳。码率稳定主要由两个量来评估,这两个量都可以由用户在创建编码通道时指定。
码率统计时间 u32StatTime
行级码率控制调节幅度 u32RowQpDelta

VBR

VBR(Variable Bit Rate)可变比特率,即允许在码率统计时间内编码码率波动,从而保证编码图像质量平稳。以 H.264 编码为例,VENC 模块提供用户可设置 MaxQp,MinQp,MaxBitrate 和 ChangePos。MaxQp,MinQp 用于控制图像的质量范围,MaxBitrate 用于钳位码率统计时间内的最大编码码率,ChangePos 用于控制开始调整Qp 的码率基准线。当编码码率大于 MaxBitrateChangePos 时,图像 qp 会逐步向MaxQp 调整,如果图像 QP 达到 MaxQp,QP 会被钳位到最大值,MaxBitrate 的钳位效果失效,编码码率有可能会超出 MaxBitrate。当编码码率小于 MaxBitrateChangePos时,图像 QP 会逐步向 MinQp 调整,如果图像 QP 达到 MinQp,此时编码的码率已经达到最大值,而且图像质量最好。
AVBR
AVBR(Adaptive Variable Bit Rate)可变比特率,即允许在码率统计时间内编码码率波动,从而保证编码图像质量平稳。码率控制内部会检测当前场景的运动静止状态,在运动时用较高码率编码,在静止时主动降低目标码率。以 H.264 编码为例,VENC 模块提供用户可设置 MaxBitrate,ChangePos 和 MinStillPercent。MaxBitrate 表示运动场景下的最大码率,MaxBitrateChangePosMinStillPercent 表示静止情况下的最小码率。根据运动程度的不同目标码率会在最大码率和最小码率间调整。MaxQp,MinQp 用于控制图像的质量范围,码率控制以 QP 钳位为最高优先级,超出 MinQp,MaxQp 范围内码率控制将失效。

FIXQP

Fix Qp 固定 Qp 值。在码率统计时间内,编码图像所有宏块 Qp 值相同,采用用户设定的图像 Qp 值,I 帧和 P 帧的 QP 值可以分别设置。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值