海思3531A SDK编码部分之Venc Sample讲解

Hi3531A

本文主要是看 注释

在这里插入图片描述

1.main函数

sample_venc.c文件最后部分是main函数开始的部分,本文只注释case=‘0’时的SAMPLE_VENC_720p_CLASSIC()函数。

/******************************************************************************
* function    : main()
* Description : video venc sample
******************************************************************************/
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':/* 8*720p H264/JPEG + 8*cif H264 encode */
            s32Ret = SAMPLE_VENC_720p_CLASSIC();
            break;
        case '1':/* 1*720p svc-t H264 encode */
            s32Ret = SAMPLE_VENC_SVC_T_H264();
            break;
        case '2':/* 1*720p pskip H264 encode */
            s32Ret = SAMPLE_VENC_PSKIP_H264();
            break;
        case '3':/*  roi background framerate */
            s32Ret = SAMPLE_VENC_ROIBG_CLASSIC();
            break;
        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);
}

2.SAMPLE_VENC_Usage()打印信息

/******************************************************************************
  A simple program of Hisilicon HI3531 video encode implementation.
  Copyright (C), 2010-2011, Hisilicon Tech. Co., Ltd.
 ******************************************************************************
    Modification:  2011-2 Created
******************************************************************************/
/**
//__cplusplus是C++中定义的一个宏,如果这个宏被定义,说明这个程序是C++程序;
//那么如果C++程序要调用C实现的函数或库等,则需要使用extern "C"{          ;
//这是实现C++调用C库或函数的一种手段,原因是因为C++和C语言的编译器不同导致;
**/

#ifdef __cplusplus 
#if __cplusplus    
extern "C"{
#endif
#endif /* End of #ifdef __cplusplus */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>

#include "sample_comm.h"

VIDEO_NORM_E gs_enNorm = VIDEO_ENCODING_MODE_PAL;          //PAL(德国制@25帧),中国主要也是使用这种。
#define SAMPLE_YUV_D1_FILEPATH         "SAMPLE_420_D1.yuv"
#define VPSS_BSTR_CHN     		0
#define VPSS_LSTR_CHN     		1

/******************************************************************************
* function : show usage                            介绍使用方法
******************************************************************************/
void SAMPLE_VENC_Usage(char *sPrgNm)              //接收的字符串为argv[0]
{
    printf("Usage : %s <index>\n", sPrgNm);       //string program number
    printf("index:\n");
    printf("\t 0) 8*720p H264/JPEG encode.\n");
    printf("\t 1) 8*720p H264 svc-t encode.\n");
    printf("\t 2) 8*720p pskip encode.\n");
    printf("\t 3) 8*roi background framerate.\n");

    return;
}

/******************************************************************************
* function : to process abnormal case             //处理异常情况,譬如中断处理、结束进程                               
******************************************************************************/
void SAMPLE_VENC_HandleSig(HI_S32 signo)
{
    if (SIGINT == signo || SIGTSTP == signo)
    {
        SAMPLE_COMM_SYS_Exit();
        printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
    }
    exit(-1);
}

/******************************************************************************
* function : to process abnormal case - the case of stream venc     编码异常处理
******************************************************************************/
void SAMPLE_VENC_StreamHandleSig(HI_S32 signo)
{

    if (SIGINT == signo || SIGTSTP == signo)
    {
        SAMPLE_COMM_SYS_Exit();
        printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
    }

    exit(0);
}

3.SAMPLE_VENC_720p_CLASSIC


/******************************************************************************
* function :  8*720p H264/JPEG + 8*cif H264 encode            支持编码H264码流
******************************************************************************/
HI_S32 SAMPLE_VENC_720p_CLASSIC(HI_VOID)                      /* 最重要的函数 */
{
    SAMPLE_VI_MODE_E enViMode = SAMPLE_VI_MODE_8_720P;

    HI_S32 s32VpssGrpCnt = 8;
    PAYLOAD_TYPE_E enPayLoad[3]= {PT_H264, PT_JPEG,PT_H264};  /*枚举类型、数组、3路码流的编码类型 */
    PIC_SIZE_E enSize[3] = {PIC_HD720, PIC_HD720,PIC_CIF};    /* 3路码流的分辨率 */
    HI_U32 u32Profile = 1;                                    /*0: baseline; 1:MP; 2:HP 3:svc-t */
    
	VB_CONF_S stVbConf;       /* 视频缓存池 */
    VPSS_GRP VpssGrp;         /* 这部分是和VPSS相关的 */ 
    VPSS_CHN VpssChn;         /* 媒体处理通道 */
    VENC_CHN VencChn;         /* 编码通道 */
    SAMPLE_RC_E enRcMode;
	VPSS_CHN_MODE_S stVpssChnMode;
    
    HI_S32 i;
    HI_S32 s32Ret = HI_SUCCESS;
    HI_U32 u32BlkSize;
    HI_CHAR ch = '\0';
    SIZE_S stSize;

    /******************************************
     step  1: init variable    ## 1.这里的sys指“mpp”,指的是初始化mpp的变量 ##
    ******************************************/
    memset(&stVbConf,0,sizeof(VB_CONF_S));        /* 刷新缓存池*/
     
	 
	 /*video buffer*/
	 /* “PIC_HD720”表示传进去是多少像素的,“SAMPLE_PIXEL_FORMAT”表示像素格式(RGB888或RGB565) 
    	“SAMPLE_SYS_ALIGN_WIDTH”表示对齐*/
    u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
                PIC_HD720, SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH,COMPRESS_MODE_SEG);
    stVbConf.u32MaxPoolCnt = 64;                  /* 缓存池的数量为64 */
    
    stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;
    //stVbConf.astCommPool[0].u32BlkCnt = u32ViChnCnt * 6;
    stVbConf.astCommPool[0].u32BlkCnt = s32VpssGrpCnt * 12;
    memset(stVbConf.astCommPool[0].acMmzName,0,
        sizeof(stVbConf.astCommPool[0].acMmzName));

    
    u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
                PIC_CIF, SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH,COMPRESS_MODE_SEG);
    
    memset(stVbConf.astCommPool[1].acMmzName,0,
        sizeof(stVbConf.astCommPool[1].acMmzName));
    stVbConf.astCommPool[1].u32BlkSize = u32BlkSize;
    stVbConf.astCommPool[1].u32BlkCnt = s32VpssGrpCnt * 6;
    memset(stVbConf.astCommPool[1].acMmzName,0,
        sizeof(stVbConf.astCommPool[1].acMmzName));

    /******************************************
     step 2: mpp system init.         ## 2.初始化MMP系统 ##
    ******************************************/
    s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("system init failed with %d!\n", s32Ret);
        goto END_VENC_8_720p_0;       /* MPP初始化失败直接结束编码 */
    }

    /******************************************
     step 3: start vi dev & chn to capture    ## 3.启动输入和通道捕获 ##
    ******************************************/
    s32Ret = SAMPLE_COMM_VI_Start(enViMode, gs_enNorm);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("start vi failed!\n");
        goto END_VENC_8_720p_0;
    }
    
    /******************************************
     step 4: start vpss and vi bind vpss    ##4:启动视频处理和绑定视频输入(通道)##
    ******************************************/
    s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, PIC_HD720, &stSize);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed!\n");
        goto END_VENC_8_720p_0;
    }
    
    //stGrpAttr.u32MaxW = stSize.u32Width;
    //stGrpAttr.u32MaxH = stSize.u32Height;
    //stGrpAttr.bDrEn = HI_FALSE;
    //stGrpAttr.bDbEn = HI_FALSE;
    //stGrpAttr.bIeEn = HI_TRUE;
    //stGrpAttr.bNrEn = HI_TRUE;
    //stGrpAttr.bHistEn = HI_TRUE;
    //stGrpAttr.enDieMode = VPSS_DIE_MODE_AUTO;
    //stGrpAttr.enPixFmt = SAMPLE_PIXEL_FORMAT;

    s32Ret = SAMPLE_COMM_VPSS_Start(s32VpssGrpCnt, &stSize, s32VpssGrpCnt/4,NULL);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("Start Vpss failed!\n");
        goto END_VENC_8_720p_1;
    }
	
	for (i=0; i<s32VpssGrpCnt; i++)
    {
		VpssGrp = i;
		s32Ret = HI_MPI_VPSS_GetChnMode(VpssGrp, VPSS_BSTR_CHN, &stVpssChnMode);
	    if (HI_SUCCESS != s32Ret)
	    {
	        SAMPLE_PRT("get Vpss chn mode failed!\n");
	        goto END_VENC_8_720p_2;
	    }
		memset(&stVpssChnMode,0,sizeof(VPSS_CHN_MODE_S));
		stVpssChnMode.enChnMode = VPSS_CHN_MODE_USER;
		stVpssChnMode.u32Width  = stSize.u32Width;
		stVpssChnMode.u32Height = stSize.u32Height;
		stVpssChnMode.stFrameRate.s32DstFrmRate = -1;
		stVpssChnMode.stFrameRate.s32SrcFrmRate = -1;
		stVpssChnMode.enPixelFormat  = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
		stVpssChnMode.enCompressMode = COMPRESS_MODE_NONE;
		s32Ret = HI_MPI_VPSS_SetChnMode(VpssGrp, VPSS_BSTR_CHN, &stVpssChnMode);
	    if (HI_SUCCESS != s32Ret)
	    {
	        SAMPLE_PRT("Set Vpss chn mode failed!\n");
	        goto END_VENC_8_720p_2;
	    }
		
	}


    s32Ret = SAMPLE_COMM_VI_BindVpss(enViMode);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("Vi bind Vpss failed!\n");
        goto END_VENC_8_720p_2;
    }

    /******************************************
     step 5: select rc mode
    ******************************************/
    while(1)
    {
        printf("please choose rc mode:\n"); 
        printf("\t0) CBR\n"); 
        printf("\t1) VBR\n"); 
        printf("\t2) FIXQP\n"); 
        ch = getchar();
        if(10 == ch)
        {
            continue;
        }
        getchar();
        if ('0' == ch)
        {
            enRcMode = SAMPLE_RC_CBR;
            break;
        }
        else if ('1' == ch)
        {
            enRcMode = SAMPLE_RC_VBR;
            break;
        }
        else if ('2' == ch)
        {
            enRcMode = SAMPLE_RC_FIXQP;
            break;
        }
        else
        {
            printf("rc mode invaild! please try again.\n");
            continue;
        }
    }
    /******************************************
     step 5: start stream venc (big + little)  # 可以在这里叠加OSD信息,并研究哪些码流 #
    ******************************************/
    for (i=0; i<s32VpssGrpCnt; i++)
    {
        /*** main stream,H264**/
        VencChn = i*2;
        VpssGrp = i;
		
		/* 通道VencChn、负载类型enPayLoad:PT_H264、VIDEO_ENCODING_MODE_PAL制式、PIC_HD720、恒定比特率编码、MP */
        s32Ret = SAMPLE_COMM_VENC_Start(VencChn, enPayLoad[0],\
                                       gs_enNorm, enSize[0], enRcMode,u32Profile);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
            goto END_VENC_8_720p_2;
        }

        s32Ret = SAMPLE_COMM_VENC_BindVpss(VencChn,VpssGrp, VPSS_BSTR_CHN);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
            goto END_VENC_8_720p_3;
        }

       
	   /*** Sub stream **/
        VencChn ++;
        s32Ret = SAMPLE_COMM_VENC_Start(VencChn, enPayLoad[2], \
                                        gs_enNorm, enSize[2], enRcMode,u32Profile);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
            goto END_VENC_8_720p_3;
        }

        s32Ret = SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VPSS_LSTR_CHN);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
            goto END_VENC_8_720p_3;
        }

		/*** Main stream jpeg**/
        VencChn = 2*(s32VpssGrpCnt + i);
		s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, enSize[1], &stSize);
	    if (HI_SUCCESS != s32Ret)
	    {
	        SAMPLE_PRT("Get picture size failed!\n");
	        goto END_VENC_8_720p_3;
	    }
		
        s32Ret = SAMPLE_COMM_VENC_SnapStart(VencChn,&stSize);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
            goto END_VENC_8_720p_3;
        }

        //s32Ret = SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VPSS_BSTR_CHN);
        //if (HI_SUCCESS != s32Ret)
        //{
        //    SAMPLE_PRT("Start Venc failed!\n");
        //    goto END_VENC_8_720p_3;
        //}
    }

    /******************************************
     step 6: stream venc process -- get stream, then save it to file. 
    ******************************************/
    s32Ret = SAMPLE_COMM_VENC_StartGetStream(s32VpssGrpCnt*2);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("Start Venc failed!\n");
        goto END_VENC_8_720p_3;
    }
	
    printf("peress ENTER to capture one picture to file\n");
	while (ch != 'q')
	{
		for (i=0; i<s32VpssGrpCnt; i++)
		{
			/*** main frame **/
			VpssGrp = i;
			VencChn = 2*(s32VpssGrpCnt + i);
			s32Ret = SAMPLE_COMM_VENC_SnapProcess(VencChn, VpssGrp, VPSS_BSTR_CHN);
			if (HI_SUCCESS != s32Ret)
			{
				SAMPLE_PRT("snap process failed!\n");
			}
			printf("snap chn %d ok!\n", i);
		
			//sleep(1);
			
			printf("press 'q' to exit snap process!peress ENTER to capture one picture to file\n");
			if((ch = getchar()) == 'q')
			{
				break;
			}
		}

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

    /******************************************
     step 7: exit process
    ******************************************/
    SAMPLE_COMM_VENC_StopGetStream();
    //for (i=0; i<s32VpssGrpCnt; i++)
    //   {
    //	VencChn = 2*(s32VpssGrpCnt + i);
    //	s32Ret = SAMPLE_COMM_VENC_SnapStop(VencChn);
    //    if (HI_SUCCESS != s32Ret)
    //    {
    //        SAMPLE_PRT("Stop snap failed!\n");
    //        goto END_VENC_8_720p_3;
    //    }
    //}
    
END_VENC_8_720p_3:
	for (i=0; i<s32VpssGrpCnt; i++)
	{
		VencChn = (i+s32VpssGrpCnt)*2;
		VpssGrp = i;
		VpssChn = VPSS_BSTR_CHN;
		SAMPLE_COMM_VENC_UnBindVpss(VencChn, VpssGrp, VpssChn);
		SAMPLE_COMM_VENC_SnapStop(VencChn);
	}

    for (i=0; i<s32VpssGrpCnt*2; i++)
    {
        VencChn = i;
        VpssGrp = i/2;
        VpssChn = (VpssGrp%2)?VPSS_LSTR_CHN:(VPSS_BSTR_CHN);
        SAMPLE_COMM_VENC_UnBindVpss(VencChn, VpssGrp, VpssChn);
        SAMPLE_COMM_VENC_Stop(VencChn);
    }
	
	SAMPLE_COMM_VI_UnBindVpss(enViMode);
END_VENC_8_720p_2:	
    SAMPLE_COMM_VPSS_Stop(s32VpssGrpCnt, VPSS_MAX_CHN_NUM);
END_VENC_8_720p_1:	
    SAMPLE_COMM_VI_Stop(enViMode);
END_VENC_8_720p_0:	
    SAMPLE_COMM_SYS_Exit();
    
    return s32Ret;
}

4.hi_comm_video.h

typedef enum hiVIDEO_NORM_E
{
    VIDEO_ENCODING_MODE_PAL=0,
    VIDEO_ENCODING_MODE_NTSC,
    VIDEO_ENCODING_MODE_AUTO, /*图像格式标准*/
    VIDEO_ENCODING_MODE_BUTT
} VIDEO_NORM_E;

5.hi_common.h

typedef enum hiROTATE_E
{
    ROTATE_NONE = 0,               /* no rotate ,图像不旋转*/
    ROTATE_90   = 1,               /* 90 degrees clockwise */
    ROTATE_180  = 2,               /* 180 degrees clockwise */
    ROTATE_270  = 3,               /* 270 degrees clockwise */
    ROTATE_BUTT
} ROTATE_E;
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ltqshs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值