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;