SmartAudio/package/allwinner/tina_multimedia/libcedarc/demo/vencoderDemo/EncoderTest.c

1869 lines
60 KiB
C
Executable File

/*
* Copyright (c) 2008-2016 Allwinner Technology Co. Ltd.
* All rights reserved.
*
* File : EncoderTest.c
* Description : EncoderTest
* History :
*
*/
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vencoder.h"
#include <sys/time.h>
#include <time.h>
#include <memoryAdapter.h>
#include <math.h>
#define DEMO_FILE_NAME_LEN 256
#define USE_H265_ENC
#define ROI_NUM 4
#define NO_READ_WRITE 0
//#define YU12_NV12
//#define USE_AFBC_INPUT
//#define YU12_NV21
//#define VBR
//#define USE_SVC
//#define USE_VIDEO_SIGNAL
//#define USE_ASPECT_RATIO
//#define USE_SUPER_FRAME
//#define GET_MB_INFO
//#define SET_MB_INFO
//#define SET_SMART
#define ALIGN_XXB(y, x) (((x) + ((y)-1)) & ~((y)-1))
#define my_printf() logd("func:%s, line:%d\n", __func__, __LINE__)
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
static long long GetNowUs()
{
struct timeval now;
gettimeofday(&now, NULL);
return now.tv_sec * 1000000 + now.tv_usec;
}
long long time1=0;
long long time2=0;
long long time3=0;
typedef struct {
char intput_file[256];
char output_file[256];
char reference_file[256];
int compare_flag;
int compare_result;
unsigned int encode_frame_num;
unsigned int encode_format;
unsigned int src_size;
unsigned int dst_size;
unsigned int src_width;
unsigned int src_height;
unsigned int dst_width;
unsigned int dst_height;
int bit_rate;
int frame_rate;
int maxKeyFrame;
}encode_param_t;
typedef enum {
INPUT,
HELP,
ENCODE_FRAME_NUM,
ENCODE_FORMAT,
OUTPUT,
SRC_SIZE,
DST_SIZE,
COMPARE_FILE,
BIT_RATE,
INVALID
}ARGUMENT_T;
typedef struct {
char Short[8];
char Name[128];
ARGUMENT_T argument;
char Description[512];
}argument_t;
static const argument_t ArgumentMapping[] =
{
{ "-h", "--help", HELP,
"Print this help" },
{ "-i", "--input", INPUT,
"Input file path" },
{ "-n", "--encode_frame_num", ENCODE_FRAME_NUM,
"After encoder n frames, encoder stop" },
{ "-f", "--encode_format", ENCODE_FORMAT,
"0:h264 encoder, 1:jpeg_encoder, 3:h265 encoder" },
{ "-o", "--output", OUTPUT,
"output file path" },
{ "-s", "--srcsize", SRC_SIZE,
"src_size,can be 2160,1080,720,480,288" },
{ "-d", "--dstsize", DST_SIZE,
"dst_size,can be 2160,1080,720,480,288" },
{ "-c", "--compare", COMPARE_FILE,
"compare file:reference file path" },
{ "-b", "--bitrate", BIT_RATE,
"bitRate:kbps" },
};
typedef struct {
unsigned int width;
unsigned int height;
unsigned int width_aligh16;
unsigned int height_aligh16;
unsigned char* argb_addr;
unsigned int size;
}BitMapInfoS;
typedef struct {
EXIFInfo exifinfo;
int quality;
int jpeg_mode;
VencJpegVideoSignal vs;
int jpeg_biteRate;
int jpeg_frameRate;
VencBitRateRange bitRateRange;
VencOverlayInfoS sOverlayInfo;
}jpeg_func_t;
typedef struct {
VencHeaderData sps_pps_data;
VencH264Param h264Param;
VencMBModeCtrl h264MBMode;
VencMBInfo MBInfo;
VencH264FixQP fixQP;
VencSuperFrameConfig sSuperFrameCfg;
VencH264SVCSkip SVCSkip; // set SVC and skip_frame
VencH264AspectRatio sAspectRatio;
VencH264VideoSignal sVideoSignal;
VencCyclicIntraRefresh sIntraRefresh;
VencROIConfig sRoiConfig[ROI_NUM];
VeProcSet sVeProcInfo;
VencOverlayInfoS sOverlayInfo;
VencSmartFun sH264Smart;
}h264_func_t;
typedef struct {
VencH265Param h265Param;
VencH265GopStruct h265Gop;
VencHVS h265Hvs;
VencH265TendRatioCoef h265Trc;
VencSmartFun h265Smart;
VencMBModeCtrl h265MBMode;
VencMBInfo MBInfo;
VencH264FixQP fixQP;
VencSuperFrameConfig sSuperFrameCfg;
VencH264SVCSkip SVCSkip; // set SVC and skip_frame
VencH264AspectRatio sAspectRatio;
VencH264VideoSignal sVideoSignal;
VencCyclicIntraRefresh sIntraRefresh;
VencROIConfig sRoiConfig[ROI_NUM];
VencAlterFrameRateInfo sAlterFrameRateInfo;
int h265_rc_frame_total;
VeProcSet sVeProcInfo;
VencOverlayInfoS sOverlayInfo;
}h265_func_t;
jpeg_func_t jpeg_func;
h264_func_t h264_func;
h265_func_t h265_func;
BitMapInfoS bit_map_info[13] = {0};
int yu12_nv12(unsigned int width, unsigned int height, unsigned char *addr_uv,
unsigned char *addr_tmp_uv)
{
unsigned int i, chroma_bytes;
unsigned char *u_addr = NULL;
unsigned char *v_addr = NULL;
unsigned char *tmp_addr = NULL;
chroma_bytes = width*height/4;
u_addr = addr_uv;
v_addr = addr_uv + chroma_bytes;
tmp_addr = addr_tmp_uv;
for(i=0; i<chroma_bytes; i++)
{
*(tmp_addr++) = *(u_addr++);
*(tmp_addr++) = *(v_addr++);
}
memcpy(addr_uv, addr_tmp_uv, chroma_bytes*2);
return 0;
}
int yu12_nv21(unsigned int width, unsigned int height, unsigned char *addr_uv,
unsigned char *addr_tmp_uv)
{
unsigned int i, chroma_bytes;
unsigned char *u_addr = NULL;
unsigned char *v_addr = NULL;
unsigned char *tmp_addr = NULL;
chroma_bytes = width*height/4;
u_addr = addr_uv;
v_addr = addr_uv + chroma_bytes;
tmp_addr = addr_tmp_uv;
for(i=0; i<chroma_bytes; i++)
{
*(tmp_addr++) = *(v_addr++);
*(tmp_addr++) = *(u_addr++);
}
memcpy(addr_uv, addr_tmp_uv, chroma_bytes*2);
return 0;
}
ARGUMENT_T GetArgument(char *name)
{
int i = 0;
int num = sizeof(ArgumentMapping) / sizeof(argument_t);
while(i < num)
{
if((0 == strcmp(ArgumentMapping[i].Name, name)) ||
((0 == strcmp(ArgumentMapping[i].Short, name)) &&
(0 != strcmp(ArgumentMapping[i].Short, "--"))))
{
return ArgumentMapping[i].argument;
}
i++;
}
return INVALID;
}
static void PrintDemoUsage(void)
{
int i = 0;
int num = sizeof(ArgumentMapping) / sizeof(argument_t);
printf("Usage:");
while(i < num)
{
printf("%s %-32s %s", ArgumentMapping[i].Short, ArgumentMapping[i].Name,
ArgumentMapping[i].Description);
printf("\n");
i++;
}
}
void ParseArgument(encode_param_t *encode_param, char *argument, char *value)
{
ARGUMENT_T arg;
arg = GetArgument(argument);
switch(arg)
{
case HELP:
PrintDemoUsage();
exit(-1);
case INPUT:
memset(encode_param->intput_file, 0, sizeof(encode_param->intput_file));
sscanf(value, "%255s", encode_param->intput_file);
logd(" get input file: %s ", encode_param->intput_file);
break;
case ENCODE_FRAME_NUM:
sscanf(value, "%32u", &encode_param->encode_frame_num);
break;
case ENCODE_FORMAT:
sscanf(value, "%32u", &encode_param->encode_format);
break;
case OUTPUT:
memset(encode_param->output_file, 0, sizeof(encode_param->output_file));
sscanf(value, "%255s", encode_param->output_file);
logd(" get output file: %s ", encode_param->output_file);
break;
case SRC_SIZE:
sscanf(value, "%32u", &encode_param->src_size);
logd(" get src_size: %dp ", encode_param->src_size);
if(encode_param->src_size == 1080)
{
encode_param->src_width = 1920;
encode_param->src_height = 1080;
}
else if(encode_param->src_size == 720)
{
encode_param->src_width = 1280;
encode_param->src_height = 720;
}
else if(encode_param->src_size == 480)
{
encode_param->src_width = 640;
encode_param->src_height = 480;
}
else if(encode_param->src_size == 2160)
{
encode_param->src_width = 3840;
encode_param->src_height = 2160;
}
else if(encode_param->src_size == 288)
{
encode_param->src_width = 352;
encode_param->src_height = 288;
}
else
{
encode_param->src_width = 1280;
encode_param->src_height = 720;
logw("encoder demo only support the size 1080p,720p,480p, \
now use the default size 720p\n");
}
break;
case DST_SIZE:
sscanf(value, "%32u", &encode_param->dst_size);
logd(" get dst_size: %dp ", encode_param->dst_size);
if(encode_param->dst_size == 1080)
{
encode_param->dst_width = 1920;
encode_param->dst_height = 1080;
}
else if(encode_param->dst_size == 720)
{
encode_param->dst_width = 1280;
encode_param->dst_height = 720;
}
else if(encode_param->dst_size == 480)
{
encode_param->dst_width = 640;
encode_param->dst_height = 480;
}
else if(encode_param->dst_size == 2160)
{
encode_param->dst_width = 3840;
encode_param->dst_height = 2160;
}
else if(encode_param->dst_size == 288)
{
encode_param->dst_width = 352;
encode_param->dst_height = 288;
}
else
{
encode_param->dst_width = 1280;
encode_param->dst_height = 720;
logw("encoder demo only support the size 1080p,720p,480p,\
now use the default size 720p\n");
}
break;
case COMPARE_FILE:
memset(encode_param->reference_file, 0, sizeof(encode_param->reference_file));
sscanf(value, "%255s", encode_param->reference_file);
encode_param->compare_flag = 1;
logd(" get reference file: %s ", encode_param->reference_file);
break;
case BIT_RATE:
sscanf(value, "%32d", &encode_param->bit_rate);
logd(" bit rate: %d ", encode_param->bit_rate);
break;
case INVALID:
default:
logd("unknowed argument : %s", argument);
break;
}
}
int SeekPrefixNAL(char* begin)
{
unsigned int i;
char* pchar = begin;
char isPrefixNAL = 1;
char NAL[4] = {0x00, 0x00, 0x00, 0x01};
if(!pchar)
{
return -1;
}
for(i=0; i<4; i++)
{
if(pchar[i] != NAL[i])
{
isPrefixNAL = 0;
break;
}
}
if(isPrefixNAL == 1)
{
isPrefixNAL = 0;
char PrefixNAL[3] = {0x6e, 0x4e, 0x0e};
for(i=0; i<3; i++)
{
if(pchar[4] == PrefixNAL[i])
{
isPrefixNAL = 1;
break;
}
}
}
// read temporal_id
if(isPrefixNAL == 1)
{
char TemporalID = pchar[7];
TemporalID >>= 5;
return TemporalID;
}
return -1;
}
void init_jpeg_exif(EXIFInfo *exifinfo)
{
exifinfo->ThumbWidth = 640;
exifinfo->ThumbHeight = 480;
strcpy((char*)exifinfo->CameraMake, "allwinner make test");
strcpy((char*)exifinfo->CameraModel, "allwinner model test");
strcpy((char*)exifinfo->DateTime, "2014:02:21 10:54:05");
strcpy((char*)exifinfo->gpsProcessingMethod, "allwinner gps");
exifinfo->Orientation = 0;
exifinfo->ExposureTime.num = 2;
exifinfo->ExposureTime.den = 1000;
exifinfo->FNumber.num = 20;
exifinfo->FNumber.den = 10;
exifinfo->ISOSpeed = 50;
exifinfo->ExposureBiasValue.num= -4;
exifinfo->ExposureBiasValue.den= 1;
exifinfo->MeteringMode = 1;
exifinfo->FlashUsed = 0;
exifinfo->FocalLength.num = 1400;
exifinfo->FocalLength.den = 100;
exifinfo->DigitalZoomRatio.num = 4;
exifinfo->DigitalZoomRatio.den = 1;
exifinfo->WhiteBalance = 1;
exifinfo->ExposureMode = 1;
exifinfo->enableGpsInfo = 1;
exifinfo->gps_latitude = 23.2368;
exifinfo->gps_longitude = 24.3244;
exifinfo->gps_altitude = 1234.5;
exifinfo->gps_timestamp = (long)time(NULL);
strcpy((char*)exifinfo->CameraSerialNum, "123456789");
strcpy((char*)exifinfo->ImageName, "exif-name-test");
strcpy((char*)exifinfo->ImageDescription, "exif-descriptor-test");
}
void init_h265_gop(VencH265GopStruct *h265Gop)
{
h265Gop->gop_size = 8;
h265Gop->intra_period = 16;
h265Gop->use_lt_ref_flag = 1;
if(h265Gop->use_lt_ref_flag)
{
h265Gop->max_num_ref_pics = 2;
h265Gop->num_ref_idx_l0_default_active = 2;
h265Gop->num_ref_idx_l1_default_active = 2;
h265Gop->use_sps_rps_flag = 0;
}
else
{
h265Gop->max_num_ref_pics = 1;
h265Gop->num_ref_idx_l0_default_active = 1;
h265Gop->num_ref_idx_l1_default_active = 1;
h265Gop->use_sps_rps_flag = 1;
}
//1:user config the reference info; 0:encoder config the reference info
h265Gop->custom_rps_flag = 0;
if(1 == h265Gop->custom_rps_flag)
{
int pos = 0;
for (pos = 0; pos < h265Gop->gop_size; pos++)
{
h265Gop->ref_str[pos].slice_type = H265_P_SLICE;
h265Gop->ref_str[pos].poc = pos + 1;
h265Gop->ref_str[pos].qp_offset = 0;
h265Gop->ref_str[pos].tc_offset_div2 = 0;
h265Gop->ref_str[pos].beta_offset_div2 = 0;
h265Gop->ref_str[pos].num_ref_pics = 2;
h265Gop->ref_str[pos].reference_pics[0] = -1;
h265Gop->ref_str[pos].reference_pics[1] = -(pos + 1);
h265Gop->ref_str[pos].discard_pics[0] = -2;
h265Gop->ref_str[pos].lt_ref_flag = 1;
h265Gop->ref_str[pos].lt_ref_poc = 0;
h265Gop->ref_str[pos].predict = 1;
h265Gop->ref_str[pos].delta_rps_idx = 1;
h265Gop->ref_str[pos].delta_rps = -1;
h265Gop->ref_str[pos].num_ref_idcs = 3;
h265Gop->ref_str[pos].reference_idcs[0][0] = REF_IDC_DISCARD;
h265Gop->ref_str[pos].reference_idcs[0][1] = REF_IDC_CURRENT_USE;
h265Gop->ref_str[pos].reference_idcs[0][2] = REF_IDC_LONG_TERM;
}
h265Gop->ref_str[0].num_ref_pics = 1;
h265Gop->ref_str[0].reference_pics[1] = -1;
h265Gop->ref_str[0].discard_pics[1] = -(h265Gop->gop_size + 1);
h265Gop->ref_str[0].lt_ref_flag = 0;
h265Gop->ref_str[0].predict = 0;
h265Gop->ref_str[0].num_ref_idcs = 3;
h265Gop->ref_str[0].reference_idcs[0][1] = REF_IDC_CURRENT_USE;
h265Gop->ref_str[0].reference_idcs[0][2] = REF_IDC_DISCARD;
h265Gop->ref_str[1].num_ref_idcs = 2;
h265Gop->ref_str[1].reference_idcs[0][0] = REF_IDC_CURRENT_USE;
h265Gop->ref_str[1].reference_idcs[0][1] = REF_IDC_LONG_TERM;
h265Gop->ref_str[h265Gop->gop_size].slice_type = H265_IDR_SLICE;
h265Gop->ref_str[h265Gop->gop_size].poc = 0;
h265Gop->ref_str[h265Gop->gop_size].predict = 0;
if (h265Gop->use_lt_ref_flag)
{
h265Gop->ref_str[h265Gop->gop_size + 1].num_ref_pics = 1;
h265Gop->ref_str[h265Gop->gop_size + 1].reference_pics[0] = -1;
h265Gop->ref_str[h265Gop->gop_size + 1].delta_rps_idx = 1;
h265Gop->ref_str[h265Gop->gop_size + 1].delta_rps = -1;
h265Gop->ref_str[h265Gop->gop_size + 1].num_ref_idcs = 1;
h265Gop->ref_str[h265Gop->gop_size + 1].reference_idcs[0][0] = REF_IDC_CURRENT_USE;
}
}
}
void init_mb_mode(VencMBModeCtrl *pMBMode, encode_param_t *encode_param)
{
unsigned int mb_num;
unsigned int j;
mb_num = (ALIGN_XXB(16, encode_param->dst_width) >> 4)
* (ALIGN_XXB(16, encode_param->dst_height) >> 4);
pMBMode->p_info = malloc(sizeof(VencMBModeCtrlInfo) * mb_num);
pMBMode->mode_ctrl_en = 1;
for (j = 0; j < mb_num / 2; j++)
{
pMBMode->p_info[j].mb_en = 1;
pMBMode->p_info[j].mb_skip_flag = 0;
pMBMode->p_info[j].mb_qp = 22;
}
for (; j < mb_num; j++)
{
pMBMode->p_info[j].mb_en = 1;
pMBMode->p_info[j].mb_skip_flag = 0;
pMBMode->p_info[j].mb_qp = 32;
}
}
void init_mb_info(VencMBInfo *MBInfo, encode_param_t *encode_param)
{
if(encode_param->encode_format == VENC_CODEC_H265)
{
MBInfo->num_mb = (ALIGN_XXB(32, encode_param->dst_width) *
ALIGN_XXB(32, encode_param->dst_height)) >> 10;
}
else
{
MBInfo->num_mb = (ALIGN_XXB(16, encode_param->dst_width) *
ALIGN_XXB(16, encode_param->dst_height)) >> 8;
}
MBInfo->p_para = (VencMBInfoPara *)malloc(sizeof(VencMBInfoPara) * MBInfo->num_mb);
if(MBInfo->p_para == NULL)
{
loge("malloc MBInfo->p_para error\n");
return;
}
logv("mb_num:%d, mb_info_queue_addr:%p\n", MBInfo->num_mb, MBInfo->p_para);
}
void init_fix_qp(VencH264FixQP *fixQP)
{
fixQP->bEnable = 1;
fixQP->nIQp = 35;
fixQP->nPQp = 35;
}
void init_super_frame_cfg(VencSuperFrameConfig *sSuperFrameCfg)
{
sSuperFrameCfg->eSuperFrameMode = VENC_SUPERFRAME_NONE;
sSuperFrameCfg->nMaxIFrameBits = 30000*8;
sSuperFrameCfg->nMaxPFrameBits = 15000*8;
}
void init_svc_skip(VencH264SVCSkip *SVCSkip)
{
SVCSkip->nTemporalSVC = T_LAYER_4;
switch(SVCSkip->nTemporalSVC)
{
case T_LAYER_4:
SVCSkip->nSkipFrame = SKIP_8;
break;
case T_LAYER_3:
SVCSkip->nSkipFrame = SKIP_4;
break;
case T_LAYER_2:
SVCSkip->nSkipFrame = SKIP_2;
break;
default:
SVCSkip->nSkipFrame = NO_SKIP;
break;
}
}
void init_aspect_ratio(VencH264AspectRatio *sAspectRatio)
{
sAspectRatio->aspect_ratio_idc = 255;
sAspectRatio->sar_width = 4;
sAspectRatio->sar_height = 3;
}
void init_video_signal(VencH264VideoSignal *sVideoSignal)
{
sVideoSignal->video_format = 5;
sVideoSignal->src_colour_primaries = 0;
sVideoSignal->dst_colour_primaries = 1;
}
void init_intra_refresh(VencCyclicIntraRefresh *sIntraRefresh)
{
sIntraRefresh->bEnable = 1;
sIntraRefresh->nBlockNumber = 10;
}
void init_roi(VencROIConfig *sRoiConfig)
{
sRoiConfig[0].bEnable = 1;
sRoiConfig[0].index = 0;
sRoiConfig[0].nQPoffset = 10;
sRoiConfig[0].sRect.nLeft = 0;
sRoiConfig[0].sRect.nTop = 0;
sRoiConfig[0].sRect.nWidth = 1280;
sRoiConfig[0].sRect.nHeight = 320;
sRoiConfig[1].bEnable = 1;
sRoiConfig[1].index = 1;
sRoiConfig[1].nQPoffset = 10;
sRoiConfig[1].sRect.nLeft = 320;
sRoiConfig[1].sRect.nTop = 180;
sRoiConfig[1].sRect.nWidth = 320;
sRoiConfig[1].sRect.nHeight = 180;
sRoiConfig[2].bEnable = 1;
sRoiConfig[2].index = 2;
sRoiConfig[2].nQPoffset = 10;
sRoiConfig[2].sRect.nLeft = 320;
sRoiConfig[2].sRect.nTop = 180;
sRoiConfig[2].sRect.nWidth = 320;
sRoiConfig[2].sRect.nHeight = 180;
sRoiConfig[3].bEnable = 1;
sRoiConfig[3].index = 3;
sRoiConfig[3].nQPoffset = 10;
sRoiConfig[3].sRect.nLeft = 320;
sRoiConfig[3].sRect.nTop = 180;
sRoiConfig[3].sRect.nWidth = 320;
sRoiConfig[3].sRect.nHeight = 180;
}
void init_alter_frame_rate_info(VencAlterFrameRateInfo *pAlterFrameRateInfo)
{
memset(pAlterFrameRateInfo, 0 , sizeof(VencAlterFrameRateInfo));
pAlterFrameRateInfo->bEnable = 1;
pAlterFrameRateInfo->bUseUserSetRoiInfo = 1;
pAlterFrameRateInfo->sRoiBgFrameRate.nSrcFrameRate = 25;
pAlterFrameRateInfo->sRoiBgFrameRate.nDstFrameRate = 5;
pAlterFrameRateInfo->roi_param[0].bEnable = 1;
pAlterFrameRateInfo->roi_param[0].index = 0;
pAlterFrameRateInfo->roi_param[0].nQPoffset = 10;
pAlterFrameRateInfo->roi_param[0].roi_abs_flag = 1;
pAlterFrameRateInfo->roi_param[0].sRect.nLeft = 0;
pAlterFrameRateInfo->roi_param[0].sRect.nTop = 0;
pAlterFrameRateInfo->roi_param[0].sRect.nWidth = 320;
pAlterFrameRateInfo->roi_param[0].sRect.nHeight = 320;
pAlterFrameRateInfo->roi_param[1].bEnable = 1;
pAlterFrameRateInfo->roi_param[1].index = 0;
pAlterFrameRateInfo->roi_param[1].nQPoffset = 10;
pAlterFrameRateInfo->roi_param[1].roi_abs_flag = 1;
pAlterFrameRateInfo->roi_param[1].sRect.nLeft = 320;
pAlterFrameRateInfo->roi_param[1].sRect.nTop = 320;
pAlterFrameRateInfo->roi_param[1].sRect.nWidth = 320;
pAlterFrameRateInfo->roi_param[1].sRect.nHeight = 320;
}
void init_enc_proc_info(VeProcSet *ve_proc_set)
{
ve_proc_set->bProcEnable = 1;
ve_proc_set->nProcFreq = 3;
}
void init_overlay_info(VencOverlayInfoS *pOverlayInfo)
{
int i;
unsigned char num_bitMap = 13;
BitMapInfoS* pBitMapInfo;
unsigned int time_id_list[19];
unsigned int start_mb_x;
unsigned int start_mb_y;
memset(pOverlayInfo, 0, sizeof(VencOverlayInfoS));
#if 0
char filename[64];
int ret;
for(i = 0; i < num_bitMap; i++)
{
FILE* icon_hdle = NULL;
int width = 0;
int height = 0;
sprintf(filename, "%s%d.bmp", "/mnt/libcedarc/bitmap/icon_720p_",i);
icon_hdle = fopen(filename, "r");
if (icon_hdle == NULL) {
printf("get wartermark %s error\n", filename);
return;
}
//get watermark picture size
fseek(icon_hdle, 18, SEEK_SET);
fread(&width, 1, 4, icon_hdle);
fread(&height, 1, 4, icon_hdle);
fseek(icon_hdle, 54, SEEK_SET);
bit_map_info[i].argb_addr = NULL;
bit_map_info[i].width = 0;
bit_map_info[i].height = 0;
bit_map_info[i].width = width;
bit_map_info[i].height = height*(-1);
bit_map_info[i].width_aligh16 = ALIGN_XXB(16, bit_map_info[i].width);
bit_map_info[i].height_aligh16 = ALIGN_XXB(16, bit_map_info[i].height);
if(bit_map_info[i].argb_addr == NULL) {
bit_map_info[i].argb_addr =
(unsigned char*)malloc(bit_map_info[i].width_aligh16*bit_map_info[i].height_aligh16*4);
if(bit_map_info[i].argb_addr == NULL)
{
loge("malloc bit_map_info[%d].argb_addr fail\n", i);
return;
}
}
logd("bitMap[%d] size[%d,%d], size_align16[%d, %d], argb_addr:%p\n", i,
bit_map_info[i].width,
bit_map_info[i].height,
bit_map_info[i].width_aligh16,
bit_map_info[i].height_aligh16,
bit_map_info[i].argb_addr);
ret = fread(bit_map_info[i].argb_addr, 1,
bit_map_info[i].width*bit_map_info[i].height*4, icon_hdle);
if(ret != bit_map_info[i].width*bit_map_info[i].height*4)
loge("read bitMap[%d] error, ret value:%d\n", i, ret);
bit_map_info[i].size = bit_map_info[i].width_aligh16 * bit_map_info[i].height_aligh16 * 4;
if (icon_hdle) {
fclose(icon_hdle);
icon_hdle = NULL;
}
}
//time 2017-04-27 18:28:26
time_id_list[0] = 2;
time_id_list[1] = 0;
time_id_list[2] = 1;
time_id_list[3] = 7;
time_id_list[4] = 11;
time_id_list[5] = 0;
time_id_list[6] = 4;
time_id_list[7] = 11;
time_id_list[8] = 2;
time_id_list[9] = 7;
time_id_list[10] = 10;
time_id_list[11] = 1;
time_id_list[12] = 8;
time_id_list[13] = 12;
time_id_list[14] = 2;
time_id_list[15] = 8;
time_id_list[16] = 12;
time_id_list[17] = 2;
time_id_list[18] = 6;
logd("pOverlayInfo:%p\n", pOverlayInfo);
pOverlayInfo->blk_num = 19;
#else
FILE* icon_hdle = NULL;
int width = 96;
int height = 48;
memset(time_id_list, 0 ,sizeof(time_id_list));
icon_hdle = fopen("/mnt/libcedarc/data_argb.dat", "r");
if (icon_hdle == NULL) {
printf("get icon_hdle error\n");
return;
}
for(i = 0; i < num_bitMap; i++)
{
bit_map_info[i].argb_addr = NULL;
bit_map_info[i].width = width;
bit_map_info[i].height = height;
bit_map_info[i].width_aligh16 = ALIGN_XXB(16, bit_map_info[i].width);
bit_map_info[i].height_aligh16 = ALIGN_XXB(16, bit_map_info[i].height);
if(bit_map_info[i].argb_addr == NULL) {
bit_map_info[i].argb_addr =
(unsigned char*)malloc(bit_map_info[i].width_aligh16*bit_map_info[i].height_aligh16*4);
if(bit_map_info[i].argb_addr == NULL)
{
loge("malloc bit_map_info[%d].argb_addr fail\n", i);
if (icon_hdle) {
fclose(icon_hdle);
icon_hdle = NULL;
}
return;
}
}
logv("bitMap[%d] size[%d,%d], size_align16[%d, %d], argb_addr:%p\n", i,
bit_map_info[i].width,
bit_map_info[i].height,
bit_map_info[i].width_aligh16,
bit_map_info[i].height_aligh16,
bit_map_info[i].argb_addr);
int ret;
ret = fread(bit_map_info[i].argb_addr, 1,
bit_map_info[i].width*bit_map_info[i].height*4, icon_hdle);
if(ret != bit_map_info[i].width*bit_map_info[i].height*4)
loge("read bitMap[%d] error, ret value:%d\n", i, ret);
bit_map_info[i].size
= bit_map_info[i].width_aligh16 * bit_map_info[i].height_aligh16 * 4;
}
if (icon_hdle) {
fclose(icon_hdle);
icon_hdle = NULL;
}
#endif
pOverlayInfo->argb_type = VENC_OVERLAY_ARGB8888;
pOverlayInfo->blk_num = 12;
logd("blk_num:%d, argb_type:%d\n", pOverlayInfo->blk_num, pOverlayInfo->argb_type);
start_mb_x = 0;
start_mb_y = 0;
for(i=0; i<pOverlayInfo->blk_num; i++)
{
//id = time_id_list[i];
//pBitMapInfo = &bit_map_info[id];
pBitMapInfo = &bit_map_info[i];
pOverlayInfo->overlayHeaderList[i].start_mb_x = start_mb_x;
pOverlayInfo->overlayHeaderList[i].start_mb_y = start_mb_y;
pOverlayInfo->overlayHeaderList[i].end_mb_x = start_mb_x
+ (pBitMapInfo->width_aligh16 / 16 - 1);
pOverlayInfo->overlayHeaderList[i].end_mb_y = start_mb_y
+ (pBitMapInfo->height_aligh16 / 16 -1);
pOverlayInfo->overlayHeaderList[i].extra_alpha_flag = 0;
pOverlayInfo->overlayHeaderList[i].extra_alpha = 8;
if(i%3 == 0)
pOverlayInfo->overlayHeaderList[i].overlay_type = LUMA_REVERSE_OVERLAY;
else if(i%2 == 0 && i!=0)
pOverlayInfo->overlayHeaderList[i].overlay_type = COVER_OVERLAY;
else
pOverlayInfo->overlayHeaderList[i].overlay_type = NORMAL_OVERLAY;
if(pOverlayInfo->overlayHeaderList[i].overlay_type == COVER_OVERLAY)
{
pOverlayInfo->overlayHeaderList[i].cover_yuv.cover_y = 0xa0;
pOverlayInfo->overlayHeaderList[i].cover_yuv.cover_u = 0xa0;
pOverlayInfo->overlayHeaderList[i].cover_yuv.cover_v = 0xa0;
}
pOverlayInfo->overlayHeaderList[i].overlay_blk_addr = pBitMapInfo->argb_addr;
pOverlayInfo->overlayHeaderList[i].bitmap_size = pBitMapInfo->size;
logv("blk_%d[%d], start_mb[%d,%d], end_mb[%d,%d],extra_alpha_flag:%d, extra_alpha:%d\n",
i,
time_id_list[i],
pOverlayInfo->overlayHeaderList[i].start_mb_x,
pOverlayInfo->overlayHeaderList[i].start_mb_y,
pOverlayInfo->overlayHeaderList[i].end_mb_x,
pOverlayInfo->overlayHeaderList[i].end_mb_y,
pOverlayInfo->overlayHeaderList[i].extra_alpha_flag,
pOverlayInfo->overlayHeaderList[i].extra_alpha);
logv("overlay_type:%d, cover_yuv[%d,%d,%d], overlay_blk_addr:%p, bitmap_size:%d\n",
pOverlayInfo->overlayHeaderList[i].overlay_type,
pOverlayInfo->overlayHeaderList[i].cover_yuv.cover_y,
pOverlayInfo->overlayHeaderList[i].cover_yuv.cover_u,
pOverlayInfo->overlayHeaderList[i].cover_yuv.cover_v,
pOverlayInfo->overlayHeaderList[i].overlay_blk_addr,
pOverlayInfo->overlayHeaderList[i].bitmap_size);
//if(i != 5)
{
start_mb_x += pBitMapInfo->width_aligh16 / 16;
start_mb_y += pBitMapInfo->height_aligh16 / 16;
}
}
return;
}
void init_jpeg_rate_ctrl(jpeg_func_t *jpeg_func)
{
jpeg_func->jpeg_biteRate = 12*1024*1024;
jpeg_func->jpeg_frameRate = 30;
jpeg_func->bitRateRange.bitRateMax = 14*1024*1024;
jpeg_func->bitRateRange.bitRateMin = 10*1024*1024;
}
int initH264Func(h264_func_t *h264_func, encode_param_t *encode_param)
{
memset(h264_func, 0, sizeof(h264_func_t));
//init h264Param
h264_func->h264Param.bEntropyCodingCABAC = 1;
h264_func->h264Param.nBitrate = encode_param->bit_rate;
h264_func->h264Param.nFramerate = encode_param->frame_rate;
h264_func->h264Param.nCodingMode = VENC_FRAME_CODING;
h264_func->h264Param.nMaxKeyInterval = encode_param->maxKeyFrame;
h264_func->h264Param.sProfileLevel.nProfile = VENC_H264ProfileHigh;
h264_func->h264Param.sProfileLevel.nLevel = VENC_H264Level51;
h264_func->h264Param.sQPRange.nMinqp = 10;
h264_func->h264Param.sQPRange.nMaxqp = 50;
h264_func->h264Param.bLongRefEnable = 1;
h264_func->h264Param.nLongRefPoc = 0;
#if 1
h264_func->sH264Smart.img_bin_en = 1;
h264_func->sH264Smart.img_bin_th = 27;
h264_func->sH264Smart.shift_bits = 2;
h264_func->sH264Smart.smart_fun_en = 1;
#endif
//init VencMBModeCtrl
init_mb_mode(&h264_func->h264MBMode, encode_param);
//init VencMBInfo
init_mb_info(&h264_func->MBInfo, encode_param);
//init VencH264FixQP
init_fix_qp(&h264_func->fixQP);
//init VencSuperFrameConfig
init_super_frame_cfg(&h264_func->sSuperFrameCfg);
//init VencH264SVCSkip
init_svc_skip(&h264_func->SVCSkip);
//init VencH264AspectRatio
init_aspect_ratio(&h264_func->sAspectRatio);
//init VencH264AspectRatio
init_video_signal(&h264_func->sVideoSignal);
//init CyclicIntraRefresh
init_intra_refresh(&h264_func->sIntraRefresh);
//init VencROIConfig
init_roi(h264_func->sRoiConfig);
//init proc info
init_enc_proc_info(&h264_func->sVeProcInfo);
//init VencOverlayConfig
init_overlay_info(&h264_func->sOverlayInfo);
return 0;
}
int initH265Func(h265_func_t *h265_func, encode_param_t *encode_param)
{
memset(h265_func, 0, sizeof(h264_func_t));
//init h265Param
h265_func->h265Param.nBitrate = encode_param->bit_rate;
h265_func->h265Param.nFramerate = encode_param->frame_rate;
h265_func->h265Param.sProfileLevel.nProfile = VENC_H265ProfileMain;
h265_func->h265Param.sProfileLevel.nLevel = VENC_H265Level41;
h265_func->h265Param.sQPRange.nMaxqp = 52;
h265_func->h265Param.sQPRange.nMinqp = 10;
h265_func->h265Param.nQPInit = 30;
h265_func->h265Param.idr_period = 30;
h265_func->h265Param.nGopSize = h265_func->h265Param.idr_period;
h265_func->h265Param.nIntraPeriod = h265_func->h265Param.idr_period;
h265_func->h265Param.bLongTermRef = 1;
#if 1
h265_func->h265Hvs.hvs_en = 1;
h265_func->h265Hvs.th_dir = 24;
h265_func->h265Hvs.th_coef_shift = 4;
h265_func->h265Trc.inter_tend = 63;
h265_func->h265Trc.skip_tend = 3;
h265_func->h265Trc.merge_tend = 0;
h265_func->h265Smart.img_bin_en = 1;
h265_func->h265Smart.img_bin_th = 27;
h265_func->h265Smart.shift_bits = 2;
h265_func->h265Smart.smart_fun_en = 1;
#endif
h265_func->h265_rc_frame_total = 20*h265_func->h265Param.nGopSize;
//init H265Gop
init_h265_gop(&h265_func->h265Gop);
//init VencMBModeCtrl
init_mb_mode(&h265_func->h265MBMode, encode_param);
//init VencMBInfo
init_mb_info(&h265_func->MBInfo, encode_param);
//init VencH264FixQP
init_fix_qp(&h265_func->fixQP);
//init VencSuperFrameConfig
init_super_frame_cfg(&h265_func->sSuperFrameCfg);
//init VencH264SVCSkip
init_svc_skip(&h265_func->SVCSkip);
//init VencH264AspectRatio
init_aspect_ratio(&h265_func->sAspectRatio);
//init VencH264AspectRatio
init_video_signal(&h265_func->sVideoSignal);
//init CyclicIntraRefresh
init_intra_refresh(&h265_func->sIntraRefresh);
//init VencROIConfig
init_roi(h265_func->sRoiConfig);
//init alter frameRate info
init_alter_frame_rate_info(&h265_func->sAlterFrameRateInfo);
//init proc info
init_enc_proc_info(&h265_func->sVeProcInfo);
//init VencOverlayConfig
init_overlay_info(&h265_func->sOverlayInfo);
return 0;
}
int initJpegFunc(jpeg_func_t *jpeg_func, encode_param_t *encode_param)
{
memset(jpeg_func, 0, sizeof(jpeg_func_t));
jpeg_func->quality = 95;
if(encode_param->encode_frame_num > 1)
jpeg_func->jpeg_mode = 1;
else
jpeg_func->jpeg_mode = 0;
if(0 == jpeg_func->jpeg_mode)
init_jpeg_exif(&jpeg_func->exifinfo);
else if(1 == jpeg_func->jpeg_mode)
init_jpeg_rate_ctrl(jpeg_func);
else
{
loge("encoder do not support the jpeg_mode:%d\n", jpeg_func->jpeg_mode);
return -1;
}
//init VencOverlayConfig
init_overlay_info(&jpeg_func->sOverlayInfo);
return 0;
}
int setEncParam(VideoEncoder *pVideoEnc ,encode_param_t *encode_param)
{
int result = 0;
if(encode_param->encode_format == VENC_CODEC_JPEG)
{
result = initJpegFunc(&jpeg_func, encode_param);
if(result)
{
loge("initJpegFunc error, return \n");
return -1;
}
if(1 == jpeg_func.jpeg_mode)
{
VideoEncSetParameter(pVideoEnc, VENC_IndexParamJpegEncMode, &jpeg_func.jpeg_mode);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamBitrate, &jpeg_func.jpeg_biteRate);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamFramerate, &jpeg_func.jpeg_frameRate);
VideoEncSetParameter(pVideoEnc,
VENC_IndexParamSetBitRateRange, &jpeg_func.bitRateRange);
}
else
{
unsigned int vbv_size = 4*1024*1024;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSetVbvSize, &vbv_size);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamJpegQuality, &jpeg_func.quality);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamJpegExifInfo, &jpeg_func.exifinfo);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSetOverlay, &jpeg_func.sOverlayInfo);
}
}
else if(encode_param->encode_format == VENC_CODEC_H264)
{
result = initH264Func(&h264_func, encode_param);
if(result)
{
loge("initH264Func error, return \n");
return -1;
}
unsigned int vbv_size = 12*1024*1024;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamH264Param, &h264_func.h264Param);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSetVbvSize, &vbv_size);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamH264FixQP, &h264_func.fixQP);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamSetOverlay, &h264_func.sOverlayInfo);
#ifdef GET_MB_INFO
VideoEncSetParameter(pVideoEnc, VENC_IndexParamMBInfoOutput, &h264_func.MBInfo);
#endif
#if 0
unsigned char value = 1;
//set the specify func
VideoEncSetParameter(pVideoEnc, VENC_IndexParamH264SVCSkip, &h264_func.SVCSkip);
value = 0;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamIfilter, &value);
value = 0; //degree
VideoEncSetParameter(pVideoEnc, VENC_IndexParamRotation, &value);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamH264FixQP, &h264_func.fixQP);
VideoEncSetParameter(pVideoEnc,
VENC_IndexParamH264CyclicIntraRefresh, &h264_func.sIntraRefresh);
value = 720/4;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSliceHeight, &value);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamROIConfig, &h264_func.sRoiConfig[0]);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamROIConfig, &h264_func.sRoiConfig[1]);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamROIConfig, &h264_func.sRoiConfig[2]);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamROIConfig, &h264_func.sRoiConfig[3]);
value = 0;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSetPSkip, &value);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamH264AspectRatio, &h264_func.sAspectRatio);
value = 0;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamFastEnc, &value);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamH264VideoSignal, &h264_func.sVideoSignal);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSuperFrameConfig, &h264_func.sSuperFrameCfg);
#endif
}
else if(encode_param->encode_format == VENC_CODEC_H265)
{
result = initH265Func(&h265_func, encode_param);
if(result)
{
loge("initH265Func error, return \n");
return -1;
}
unsigned int vbv_size = 12*1024*1024;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSetVbvSize, &vbv_size);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamH265Param, &h265_func.h265Param);
unsigned int value = 1;
//VideoEncSetParameter(pVideoEnc,
//VENC_IndexParamAlterFrame, &h265_func.sAlterFrameRateInfo);
VideoEncSetParameter(pVideoEnc, VENC_IndexParamChannelNum, &value);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamProcSet, &h265_func.sVeProcInfo);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamSetOverlay, &h265_func.sOverlayInfo);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamVirtualIFrame, &encode_param->frame_rate);
//value = 0;
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamPFrameIntraEn, &value);
//value = 1;
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamEncodeTimeEn, &value);
//VideoEncSetParameter(pVideoEnc,
//VENC_IndexParamH265ToalFramesNum, &h265_func.h265_rc_frame_total);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamH265Gop, &h265_func.h265Gop);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamROIConfig, &h265_func.sRoiConfig[0]);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamH264FixQP, &h265_func.fixQP);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamH265HVS, &h265_func.h265Hvs);
//VideoEncSetParameter(pVideoEnc, VENC_IndexParamH265TendRatioCoef, &h265_func.h265Trc);
#ifdef GET_MB_INFO
VideoEncSetParameter(pVideoEnc, VENC_IndexParamMBInfoOutput, &h265_func.MBInfo);
#endif
}
return 0;
}
void setMbMode(VideoEncoder *pVideoEnc, encode_param_t *encode_param)
{
if(encode_param->encode_format == VENC_CODEC_H264 && h264_func.h264MBMode.mode_ctrl_en)
{
VideoEncSetParameter(pVideoEnc, VENC_IndexParamMBModeCtrl, &h264_func.h264MBMode);
}
else if(encode_param->encode_format == VENC_CODEC_H265 && h265_func.h265MBMode.mode_ctrl_en)
{
VideoEncSetParameter(pVideoEnc, VENC_IndexParamMBModeCtrl, &h265_func.h265MBMode);
}
else
return;
}
void getMbMinfo(VideoEncoder *pVideoEnc, encode_param_t *encode_param)
{
#if 0
VencMBInfo *pMBInfo;
if(encode_param->encode_format == VENC_CODEC_H264 && h264_func.h264MBMode.mode_ctrl_en)
{
pMBInfo = &h264_func.MBInfo;
}
else if(encode_param->encode_format == VENC_CODEC_H265 && h265_func.h265MBMode.mode_ctrl_en)
{
pMBInfo = &h265_func.MBInfo;
}
else
return;
int i;
for(i = 0; i < pMBInfo->num_mb; i++)
{
logd("No.%d MB: mad=%d, qp=%d, sse=%d, psnr=%f\n",i,pMBInfo->p_para[i].mb_mad,
pMBInfo->p_para[i].mb_qp, pMBInfo->p_para[i].mb_sse, pMBInfo->p_para[i].mb_psnr);
}
#endif
}
void releaseMb(encode_param_t *encode_param)
{
VencMBInfo *pMBInfo;
VencMBModeCtrl *pMBMode;
if(encode_param->encode_format == VENC_CODEC_H264 && h264_func.h264MBMode.mode_ctrl_en)
{
pMBInfo = &h264_func.MBInfo;
pMBMode = &h264_func.h264MBMode;
}
else if(encode_param->encode_format == VENC_CODEC_H265 && h265_func.h265MBMode.mode_ctrl_en)
{
pMBInfo = &h264_func.MBInfo;
pMBMode = &h265_func.h265MBMode;
}
else
return;
if(pMBInfo->p_para)
free(pMBInfo->p_para);
if(pMBMode->p_info)
free(pMBMode->p_info);
}
int main(int argc, char** argv)
{
VencBaseConfig baseConfig;
VencAllocateBufferParam bufferParam;
VideoEncoder* pVideoEnc = NULL;
VencInputBuffer inputBuffer;
VencOutputBuffer outputBuffer;
VencHeaderData sps_pps_data;
unsigned char *uv_tmp_buffer = NULL;
unsigned int afbc_header_size;
int result = 0;
int i = 0;
long long pts = 0;
unsigned char yu12_nv12_flag = 0;
unsigned char yu12_nv21_flag = 0;
FILE *in_file = NULL;
FILE *out_file = NULL;
FILE *reference_file = NULL;
char *input_path = NULL;
char *output_path = NULL;
char *reference_path = NULL;
unsigned char *reference_buffer = NULL;
VencMBSumInfo sMbSumInfo;
memset(&sMbSumInfo, 0, sizeof(VencMBSumInfo));
unsigned long long sum_sse = 0;
unsigned long long min_sse = 0;
unsigned long long max_sse = 0;
unsigned long long avr_sse = 0;
unsigned int min_sse_frame = 0;
unsigned int max_sse_frame = 0;
/******** begin set the default encode param ********/
encode_param_t encode_param;
memset(&encode_param, 0, sizeof(encode_param));
encode_param.src_width = 1024;
encode_param.src_height = 1024;
encode_param.dst_width = 1024;
encode_param.dst_height = 1024;
encode_param.bit_rate = 20*1024*1024;
encode_param.frame_rate = 30;
encode_param.maxKeyFrame = 30;
encode_param.encode_format = VENC_CODEC_H265;
encode_param.encode_frame_num = 200;
strcpy((char*)encode_param.intput_file, "/data/camera/720p-30zhen.yuv");
strcpy((char*)encode_param.output_file, "/data/camera/720p.264");
strcpy((char*)encode_param.reference_file, "/mnt/bsp_ve_test/reference_data/reference.jpg");
if(encode_param.dst_width == 3840)
encode_param.bit_rate = 20*1024*1024;
else if(encode_param.dst_width == 1920)
encode_param.bit_rate = 10*1024*1024;
else if(encode_param.dst_width ==1280)
encode_param.bit_rate = 6*1024*1024;//6*1024*1024;
else if(encode_param.dst_width == 640)
encode_param.bit_rate = 2*1024*1024;
else if(encode_param.dst_width == 288)
encode_param.bit_rate = 1*1024*1024;
else
encode_param.bit_rate = 4*1024*1024;
/******** end set the default encode param ********/
/******** begin parse the config paramter ********/
if(argc >= 2)
{
for(i = 1; i < (int)argc; i += 2)
{
ParseArgument(&encode_param, argv[i], argv[i + 1]);
}
}
else
{
printf(" we need more arguments ");
PrintDemoUsage();
return 0;
}
/******** end parse the config paramter ********/
/******** begin open input , output and reference file ********/
input_path = encode_param.intput_file;
output_path = encode_param.output_file;
in_file = fopen(input_path, "r");
if(in_file == NULL)
{
loge("open in_file fail\n");
return -1;
}
out_file = fopen(output_path, "wb");
if(out_file == NULL)
{
loge("open out_file fail\n");
fclose(in_file);
return -1;
}
if(encode_param.compare_flag)
{
reference_path = encode_param.reference_file;
reference_file = fopen(reference_path, "r");
if(reference_file == NULL)
{
loge("open reference_file fail\n");
goto out;
}
reference_buffer = (unsigned char*)malloc(1*1024*1024);
if(reference_buffer == NULL)
{
loge("malloc reference_buffer error\n");
goto out;
}
}
/******** end open input , output and reference file ********/
/******** begin set baseConfig param********/
memset(&baseConfig, 0 ,sizeof(VencBaseConfig));
memset(&bufferParam, 0 ,sizeof(VencAllocateBufferParam));
baseConfig.memops = MemAdapterGetOpsS();
if (baseConfig.memops == NULL)
{
printf("MemAdapterGetOpsS failed\n");
goto out;
}
CdcMemOpen(baseConfig.memops);
baseConfig.nInputWidth= encode_param.src_width;
baseConfig.nInputHeight = encode_param.src_height;
baseConfig.nStride = encode_param.src_width;
baseConfig.nDstWidth = encode_param.dst_width;
baseConfig.nDstHeight = encode_param.dst_height;
/*
* the format of yuv file is yuv420p, but the old ic only support the yuv420sp,
* so use the func yu12_nv12() to config all the format.
*/
baseConfig.eInputFormat = VENC_PIXEL_YUV420P;
if(baseConfig.eInputFormat == VENC_PIXEL_YUV420P)
{
#ifdef YU12_NV12
baseConfig.eInputFormat = VENC_PIXEL_YUV420SP;
yu12_nv12_flag = 1;
#endif
#ifdef YU12_NV21
baseConfig.eInputFormat = VENC_PIXEL_YVU420SP;
yu12_nv21_flag = 1;
#endif
}
bufferParam.nSizeY = baseConfig.nInputWidth*baseConfig.nInputHeight;
bufferParam.nSizeC = baseConfig.nInputWidth*baseConfig.nInputHeight/2;
bufferParam.nBufferNum = 1;
#ifdef USE_AFBC_INPUT
afbc_header_size = ((baseConfig.nInputWidth +127)>>7)*((baseConfig.nInputHeight+31)>>5)*96;
logd("size_y:%x, size_c:%x, afbc_header:%x\n",
bufferParam.nSizeY,
bufferParam.nSizeC,
afbc_header_size);
bufferParam.nSizeY += afbc_header_size + bufferParam.nSizeC;
bufferParam.nSizeC = 0;
logd("afbc buffer size:%x\n", bufferParam.nSizeY);
baseConfig.eInputFormat = VENC_PIXEL_AFBC_AW;
#endif
/******** end set baseConfig param********/
//create encoder
logd("encode_param.encode_format:%d\n", encode_param.encode_format);
pVideoEnc = VideoEncCreate(encode_param.encode_format);
//set enc parameter
result = setEncParam(pVideoEnc ,&encode_param);
if(result)
{
loge("setEncParam error, return");
goto out;
}
VideoEncInit(pVideoEnc, &baseConfig);
if(encode_param.encode_format == VENC_CODEC_H264 || \
encode_param.encode_format == VENC_CODEC_H265)
{
unsigned int head_num = 0;
if(encode_param.encode_format == VENC_CODEC_H264)
{
VideoEncGetParameter(pVideoEnc, VENC_IndexParamH264SPSPPS, &sps_pps_data);
unsigned char value = 1;
//VideoEncGetParameter(pVideoEnc, VENC_IndexParamAllParams, &value);
}
else if(encode_param.encode_format == VENC_CODEC_H265)
{
VideoEncGetParameter(pVideoEnc, VENC_IndexParamH265Header, &sps_pps_data);
unsigned char value = 1;
//VideoEncGetParameter(pVideoEnc, VENC_IndexParamAllParams, &value);
}
fwrite(sps_pps_data.pBuffer, 1, sps_pps_data.nLength, out_file);
logd("sps_pps_data.nLength: %d", sps_pps_data.nLength);
//for(head_num=0; head_num<sps_pps_data.nLength; head_num++)
//logd("the sps_pps :%02x\n", *(sps_pps_data.pBuffer+head_num));
if(encode_param.compare_flag)
{
result = fread(reference_buffer, 1, sps_pps_data.nLength, reference_file);
if(result != sps_pps_data.nLength)
{
loge("read reference_file sps info error\n");
goto out;
}
for(i=0; i<sps_pps_data.nLength; i++)
{
if(sps_pps_data.pBuffer[i] != reference_buffer[i])
{
loge("the sps %d byte is not same, ref[%02x], cur[%02x]\n",
i,
reference_buffer[i],
sps_pps_data.pBuffer[i]);
goto out;
}
}
}
}
AllocInputBuffer(pVideoEnc, &bufferParam);
if(yu12_nv12_flag || yu12_nv21_flag)
{
uv_tmp_buffer = (unsigned char*)malloc(baseConfig.nInputWidth*baseConfig.nInputHeight/2);
if(uv_tmp_buffer == NULL)
{
loge("malloc uv_tmp_buffer fail\n");
goto out;
}
}
#ifdef USE_SVC
// used for throw frame test with SVC
int TemporalLayer = -1;
char p9bytes[9] = {0};
#endif
unsigned int testNumber = 0;
while(testNumber < encode_param.encode_frame_num)
{
GetOneAllocInputBuffer(pVideoEnc, &inputBuffer);
{
#if NO_READ_WRITE
if(testNumber == 0)
#endif
{
#ifdef USE_AFBC_INPUT
unsigned int size1, size2;
size1 = fread(inputBuffer.pAddrVirY, 1, bufferParam.nSizeY, in_file);
if(size1!= bufferParam.nSizeY)
{
fseek(in_file, 0L, SEEK_SET);
size1 = fread(inputBuffer.pAddrVirY, 1, bufferParam.nSizeY, in_file);
}
#else
unsigned int size1, size2;
size1 = fread(inputBuffer.pAddrVirY, 1,
baseConfig.nInputWidth*baseConfig.nInputHeight, in_file);
size2 = fread(inputBuffer.pAddrVirC, 1,
baseConfig.nInputWidth*baseConfig.nInputHeight/2, in_file);
if((size1!= baseConfig.nInputWidth*baseConfig.nInputHeight)
|| (size2!= baseConfig.nInputWidth*baseConfig.nInputHeight/2))
{
fseek(in_file, 0L, SEEK_SET);
size1 = fread(inputBuffer.pAddrVirY, 1,
baseConfig.nInputWidth*baseConfig.nInputHeight, in_file);
size2 = fread(inputBuffer.pAddrVirC, 1,
baseConfig.nInputWidth*baseConfig.nInputHeight/2, in_file);
}
if(yu12_nv12_flag)
{
yu12_nv12(baseConfig.nInputWidth, baseConfig.nInputHeight,
inputBuffer.pAddrVirC, uv_tmp_buffer);
}
else if(yu12_nv21_flag)
{
yu12_nv21(baseConfig.nInputWidth, baseConfig.nInputHeight,
inputBuffer.pAddrVirC, uv_tmp_buffer);
}
#endif
}
}
inputBuffer.bEnableCorp = 0;
inputBuffer.sCropInfo.nLeft = 240;
inputBuffer.sCropInfo.nTop = 240;
inputBuffer.sCropInfo.nWidth = 240;
inputBuffer.sCropInfo.nHeight = 240;
FlushCacheAllocInputBuffer(pVideoEnc, &inputBuffer);
pts += 1*1000/encode_param.frame_rate;
inputBuffer.nPts = pts;
AddOneInputBuffer(pVideoEnc, &inputBuffer);
#ifdef SET_MB_INFO
setMbMode(pVideoEnc, &encode_param);
#endif
#ifdef SET_SMART
if(testNumber == 0)
{
if(encode_param.encode_format == VENC_CODEC_H264)
{
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSmartFuntion, &h264_func.sH264Smart);
}
else if(encode_param.encode_format == VENC_CODEC_H265)
{
VideoEncSetParameter(pVideoEnc, VENC_IndexParamSmartFuntion, &h265_func.h265Smart);
}
}
#endif
#ifdef VBR
unsigned int bitRate = 50*1024*1024;
if(testNumber == 0)
{
VideoEncSetParameter(pVideoEnc, VENC_IndexParamBitrate, &bitRate);
}
if(testNumber == 90)
{
bitRate = 80*1024*1024;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamBitrate, &bitRate);
}
else if(testNumber == 180)
{
bitRate = 50*1024*1024;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamBitrate, &bitRate);
}
else if(testNumber == 250)
{
bitRate = 80*1024*1024;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamBitrate, &bitRate);
}
else if(testNumber == 1500)
{
bitRate = 50*1024*1024;
VideoEncSetParameter(pVideoEnc, VENC_IndexParamBitrate, &bitRate);
}
#endif
time1 = GetNowUs();
VideoEncodeOneFrame(pVideoEnc);
time2 = GetNowUs();
logv("encode frame %d use time is %lldus..\n",testNumber,(time2-time1));
logv("\n");
logv("\n");
time3 += time2-time1;
#ifdef GET_MB_INFO
getMbMinfo(pVideoEnc, &encode_param);
if(encode_param.encode_format == VENC_CODEC_H264)
{
VideoEncGetParameter(pVideoEnc, VENC_IndexParamMBSumInfoOutput, &sMbSumInfo);
}
else if(encode_param.encode_format == VENC_CODEC_H265)
{
VideoEncGetParameter(pVideoEnc, VENC_IndexParamMBSumInfoOutput, &sMbSumInfo);
}
avr_sse += sMbSumInfo.sum_sse;
sum_sse = avr_sse;
if(testNumber == 0)
{
min_sse = sMbSumInfo.sum_sse;
max_sse = sMbSumInfo.sum_sse;
}
else
{
if(sMbSumInfo.sum_sse < min_sse)
{
min_sse = sMbSumInfo.sum_sse;
min_sse_frame = testNumber;
}
else if(sMbSumInfo.sum_sse > max_sse)
{
max_sse = sMbSumInfo.sum_sse;
max_sse_frame = testNumber;
}
}
if(testNumber == (encode_param.encode_frame_num - 1))
{
double min_psnr, max_psnr, avr_psnr;
unsigned pic_size = encode_param.dst_width * encode_param.dst_height;
avr_sse /= encode_param.encode_frame_num;
max_psnr = 10.0 * log10(255.0 * 255.0 * 1024 / (1.0 * min_sse / pic_size));
min_psnr = 10.0 * log10(255.0 * 255.0 * 1024 / (1.0 * max_sse / pic_size));
avr_psnr = 10.0 * log10(255.0 * 255.0 * 1024 / (1.0 * avr_sse / pic_size));
logd("frame[%d] get min_psnr:%f, frame[%d] get max_psnr:%f, average_psnr:%f\n",
max_sse_frame,
min_psnr,
min_sse_frame,
max_psnr,
avr_psnr);
}
#endif
#if 0
VencEncodeTimeS sEncTime;
VideoEncGetParameter(pVideoEnc, VENC_IndexParamGetEncodeTime, &sEncTime);
logd("frame:%d, enc_time:%d, max_enc_time:%d, max_enc_time_frame:%d, avr_enc_time:%d",
sEncTime.frame_num, sEncTime.curr_enc_time, sEncTime.max_enc_time,
sEncTime.max_enc_time_frame_num,sEncTime.avr_enc_time);
logd("empty_time:%d, max_empty_time:%d, max_empty_time_frame:%d, avr_empty_time:%d\n",
sEncTime.curr_empty_time, sEncTime.max_empty_time,
sEncTime.max_empty_time_frame_num,sEncTime.avr_empty_time);
#endif
AlreadyUsedInputBuffer(pVideoEnc,&inputBuffer);
ReturnOneAllocInputBuffer(pVideoEnc, &inputBuffer);
result = GetOneBitstreamFrame(pVideoEnc, &outputBuffer);
#ifdef USE_SUPER_FRAME
if((sSuperFrameCfg.eSuperFrameMode==VENC_SUPERFRAME_DISCARD) && (result==-1))
{
logd("VENC_SUPERFRAME_DISCARD: discard frame %d\n",testNumber);
continue;
}
#endif
if(result == -1)
{
goto out;
}
#ifdef USE_SVC
// used for throw frame test with SVC
memcpy(p9bytes, outputBuffer.pData0, 9);
TemporalLayer = SeekPrefixNAL(p9bytes);
switch(TemporalLayer)
{
case 3:
case 2:
case 1:
logv("just write the PrefixNAL\n");
fwrite(outputBuffer.pData0, 1, 9, out_file);
break;
default:
logv("\nTemporalLayer=%d, testNumber=%d\n", TemporalLayer, testNumber);
fwrite(outputBuffer.pData0, 1, outputBuffer.nSize0, out_file);
//fwrite(outputBuffer.pData0+9, 1, outputBuffer.nSize0-9, out_file);
if(outputBuffer.nSize1)
{
fwrite(outputBuffer.pData1, 1, outputBuffer.nSize1, out_file);
}
break;
}
#else
#if NO_READ_WRITE
#else
fwrite(outputBuffer.pData0, 1, outputBuffer.nSize0, out_file);
if(outputBuffer.nSize1)
{
fwrite(outputBuffer.pData1, 1, outputBuffer.nSize1, out_file);
}
#endif
#endif
if(encode_param.compare_flag)
{
result = fread(reference_buffer, 1, outputBuffer.nSize0, reference_file);
if(result != outputBuffer.nSize0)
{
loge("read reference_file error\n");
goto out;
}
for(i=0; i<outputBuffer.nSize0; i++)
{
if(outputBuffer.pData0[i] != reference_buffer[i])
{
loge("the %d frame's ref_data_%d[%02x] and cur_data_%d[%02x] is not same\n",
testNumber,
i,
reference_buffer[i],
i,
outputBuffer.pData0[i]);
goto out;
}
}
result = fread(reference_buffer, 1, outputBuffer.nSize1, reference_file);
if(result != outputBuffer.nSize1)
{
loge("read reference_file error\n");
goto out;
}
for(i=0; i<outputBuffer.nSize1; i++)
{
if((outputBuffer.pData1)[i] != reference_buffer[i])
{
loge("the %d frame's data1 %d byte is not same\n", testNumber, i);
goto out;
}
}
}
FreeOneBitStreamFrame(pVideoEnc, &outputBuffer);
testNumber++;
}
if(encode_param.compare_flag)
{
encode_param.compare_result = 1;
logd("the compare result is ok\n");
}
logd("the average encode time is %lldus...\n",time3/testNumber);
if(pVideoEnc)
{
VideoEncDestroy(pVideoEnc);
}
pVideoEnc = NULL;
printf("output file is saved:%s\n",encode_param.output_file);
out:
if(out_file)
fclose(out_file);
if(in_file)
fclose(in_file);
if(uv_tmp_buffer)
free(uv_tmp_buffer);
if(baseConfig.memops)
{
CdcMemClose(baseConfig.memops);
}
releaseMb(&encode_param);
if(encode_param.compare_flag)
{
if(reference_buffer)
free(reference_buffer);
if(reference_file)
fclose(reference_file);
if(encode_param.compare_result)
{
logd("****************************************\n");
logd("the compare result is ok\n");
logd("the compare result is ok\n");
logd("the compare result is ok\n");
logd("****************************************\n");
}
else
{
logd("****************************************\n");
logd("the compare result is fail\n");
logd("the compare result is fail\n");
logd("the compare result is fail\n");
logd("****************************************\n");
return -1;
}
}
unsigned int bit_map_num;
for(bit_map_num=0; bit_map_num++; i<13)
{
if(bit_map_info[bit_map_num].argb_addr)
free(bit_map_info[bit_map_num].argb_addr);
}
return 0;
}