/* Begin encode * file located at: * * src/com/livecamera/encoder/h264encoder.java */ jlong Java_com_livecamera_encoder_h264encoder_CompressBegin( JNIEnv* env, jobject thiz, jint width, jint height) { Encoder *en = (Encoder*) malloc(sizeof(Encoder)); en->param = (x264_param_t*) malloc(sizeof(x264_param_t)); en->picture = (x264_picture_t*) malloc(sizeof(x264_picture_t)); x264_param_default(en->param); //set default param en->param->i_log_level = X264_LOG_NONE; en->param->i_width = width; en->param->i_height = height; en->param->rc.i_lookahead = 0; en->param->i_bframe = 0; en->param->i_fps_num = 5; en->param->i_fps_den = 1; if ((en->handle = x264_encoder_open(en->param)) == 0) { return 0; } //create a new pic x264_picture_alloc(en->picture, X264_CSP_I420, en->param->i_width, en->param->i_height); return (jlong)en; }
/**************************************************************************** * main: ****************************************************************************/ int main( int argc, char **argv ) { x264_param_t param; cli_opt_t opt; int ret; #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); #endif #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdout), _O_BINARY); #endif x264_param_default( ¶m ); /* Parse command line */ if( Parse( argc, argv, ¶m, &opt ) < 0 ) return -1; /* Control-C handler */ signal( SIGINT, SigIntHandler ); ret = Encode( ¶m, &opt ); #ifdef PTW32_STATIC_LIB pthread_win32_thread_detach_np(); pthread_win32_process_detach_np(); #endif return ret; }
void x264enc_set_param(const m_option_t* opt, char* arg) { static int initted = 0; if(!initted) { x264_param_default(¶m); x264_param_parse(¶m, "psnr", "no"); x264_param_parse(¶m, "ssim", "no"); initted = 1; } if(!arg) { parse_error = 1; return; } while(*arg) { char *name = arg; char *value; int ret; arg += strcspn(arg, ":"); if(*arg) { *arg = 0; arg++; } value = strchr( name, '=' ); if(value) { *value = 0; value++; } if(!strcmp(name, "turbo")) { turbo = value ? atoi(value) : 1; continue; } ret = x264_param_parse(¶m, name, value); if(ret == X264_PARAM_BAD_NAME) mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Unknown suboption %s\n", name); if(ret == X264_PARAM_BAD_VALUE) mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Bad argument %s=%s\n", name, value ? value : "(null)"); /* mark this option as done, so it's not reparsed if there's another -x264encopts */ *name = 0; parse_error |= ret; } if(param.rc.b_stat_write && !param.rc.b_stat_read) { /* Adjust or disable some flags to gain speed in the first pass */ if(turbo == 1) { param.i_frame_reference = ( param.i_frame_reference + 1 ) >> 1; param.analyse.i_subpel_refine = FFMAX( FFMIN( 3, param.analyse.i_subpel_refine - 1 ), 1 ); param.analyse.inter &= ( ~X264_ANALYSE_PSUB8x8 ); param.analyse.inter &= ( ~X264_ANALYSE_BSUB16x16 ); param.analyse.i_trellis = 0; } else if(turbo >= 2)
EncoderVideoSource::EncoderVideoSource(UsageEnvironment& env, unsigned int width, unsigned int height, unsigned int framerate, unsigned int bitrate, unsigned int keyinterval, VideoCodec codec, char *type): FramedSource(env), fp(NULL), fWidth(width), fHeight(height), fFramerate(framerate), fBitrate(bitrate), fKeyInterval(keyinterval), fCodec(codec), fConfigBytes(NULL), fStartTime(0), fEncoderHandle(NULL) { memset(mediaType, 0, sizeof(mediaType)); memcpy(mediaType, type, strlen(type)); #ifdef STARV_TEST if(strcmp(type, "live") == 0 || strcmp(type, "livehd") == 0) fp = fopen(VIDEO_FILE, "rb"); if(strcmp(type, "mobile") == 0) fp = fopen(VIDEO_FILE, "rb"); #endif Debug(ckite_log_message, "type = %s\n", type); if(strcmp(type, "store") == 0) { Debug(ckite_log_message, "EncoderVideoSource store \n"); } fBuffer = new unsigned char[fWidth*fHeight*3/2]; #ifdef SDKH264 #ifdef ENC_SOURCE x264_param_default(&m_param); x264_param_apply_profile(&m_param, "baseline"); m_param.i_width = fWidth; m_param.i_height = fHeight; m_param.i_fps_num = 10; // m_param.i_fps_den = 1000; m_param.i_frame_reference = 1; //m_param.i_maxframes = 0; // no find this parameter m_param.i_keyint_max = 250; m_param.i_bframe = 0; m_param.rc.i_bitrate = 1000; // the unit is kbps //m_param.rc.b_cbr = 0; m_param.rc.f_qcompress = 0; //m_param.rc.b_stat_write = 0; //m_param.analyse.inter = 0; m_param.analyse.b_psnr = 0; m_param.b_cabac = 0; m_param.rc.b_mb_tree = 0; //m_param.pf_log = NULL //if set NULL , it will segment fault x264_handle = x264_encoder_open(&m_param); //memset(p_nal, 0x0, sizeof (struct nal)); fprintf(stderr, "x264_encoder_open x264_handle:%x\n", x264_handle); #endif for(int i = 0; i < 4; i++) { more_nal[i] = NULL; more_nal_len[i] = 0; } #endif #ifdef SDKMPEG4 #ifdef ENC_SOURCE Debug(ckite_log_message, "xvid fWidth = %d, fHeight = %d\n", fWidth, fHeight); fEncoderHandle = xvid_enc_init(fWidth, fHeight, fBitrate, fFramerate, fKeyInterval, 1); #endif #endif }
H264EncWrapper::H264EncWrapper() { m_h = NULL; m_pBuffer = NULL; m_iBufferSize = 0; m_iFrameNum = 0; x264_param_default(&m_param); }
X264Encoder::X264Encoder() { m_h = NULL; x264_param_default(&m_param); sps_ = NULL; sps_size_ = 0; pps_ = NULL; pps_size_ = 0; }
static void enc_preprocess(MSFilter *f){ EncData *d=(EncData*)f->data; x264_param_t params; float bitrate; d->packer=rfc3984_new(); rfc3984_set_mode(d->packer,d->mode); rfc3984_enable_stap_a(d->packer,FALSE); x264_param_default(¶ms); params.i_threads=0; params.i_sync_lookahead=0; params.i_width=d->vsize.width; params.i_height=d->vsize.height; params.i_fps_num=(int)d->fps; params.i_fps_den=1; params.i_slice_max_size=ms_get_payload_max_size()-100; /*-100 security margin*/ params.i_level_idc=13; bitrate=(float)d->bitrate*0.92; if (bitrate>RC_MARGIN) bitrate-=RC_MARGIN; params.rc.i_rc_method = X264_RC_ABR; params.rc.i_bitrate=(int)(bitrate/1000); params.rc.f_rate_tolerance=0.1; params.rc.i_vbv_max_bitrate=(int) ((bitrate+RC_MARGIN/2)/1000); params.rc.i_vbv_buffer_size=params.rc.i_vbv_max_bitrate; params.rc.f_vbv_buffer_init=0.5; params.rc.i_lookahead=0; /*enable this by config ?*/ /* params.i_keyint_max = (int)d->fps*d->keyframe_int; params.i_keyint_min = (int)d->fps; */ params.b_repeat_headers=1; params.b_annexb=0; //these parameters must be set so that our stream is baseline params.analyse.b_transform_8x8 = 0; params.b_cabac = 0; params.i_cqm_preset = X264_CQM_FLAT; params.i_bframe = 0; params.analyse.i_weighted_pred = X264_WEIGHTP_NONE; x264_param_apply_preset(¶ms,"faster");//将编码设置成superfast模式【相比其他模式,会有一些花屏】 x264_param_apply_tune(¶ms,"zerolatency");//将延时设置成最短 d->enc=x264_encoder_open(¶ms); if (d->enc==NULL) ms_error("Fail to create x264 encoder."); d->framenum=0; video_starter_init(&d->starter); }
static void enc_preprocess(MSFilter *f){ EncData *d=(EncData*)f->data; x264_param_t *params=&d->params; d->packer=rfc3984_new(); rfc3984_set_mode(d->packer,d->mode); rfc3984_enable_stap_a(d->packer,FALSE); #if defined(__arm__) || defined(ANDROID) if (x264_param_default_preset(params,"superfast"/*"ultrafast"*/,"zerolatency")) { ms_error("Cannot apply default x264 configuration"); } #else x264_param_default(params); #endif params->i_threads=ms_get_cpu_count(); params->i_sync_lookahead=0; params->i_width=d->vconf.vsize.width; params->i_height=d->vconf.vsize.height; params->i_fps_num=(int)d->vconf.fps; params->i_fps_den=1; params->i_slice_max_size=ms_get_payload_max_size()-100; /*-100 security margin*/ params->i_level_idc=13; apply_bitrate(f); params->rc.i_lookahead=0; /*enable this by config ?*/ /* params.i_keyint_max = (int)d->fps*d->keyframe_int; params.i_keyint_min = (int)d->fps; */ params->b_repeat_headers=1; params->b_annexb=0; //these parameters must be set so that our stream is baseline params->analyse.b_transform_8x8 = 0; params->b_cabac = 0; params->i_cqm_preset = X264_CQM_FLAT; params->i_bframe = 0; params->analyse.i_weighted_pred = X264_WEIGHTP_NONE; d->enc=x264_encoder_open(params); if (d->enc==NULL) ms_error("Fail to create x264 encoder."); d->framenum=0; video_starter_init(&d->starter); }
bool init_x264_encoder(Encoder * enc,int width,int height) { enc->param = (x264_param_t*)malloc(sizeof(x264_param_t)); enc->picture = (x264_picture_t*)malloc(sizeof(x264_picture_t)); enc->picture->i_pts = 0 ; // set default param // todo improvements later x264_param_default(enc->param); // set width and height enc->param->i_width = width; enc->param->i_height = height ; enc->param->rc.i_lookahead = 0; // set fps enc->param->i_fps_num = 10 ; enc->param->i_fps_den = 1 ; // set baseline x264_param_apply_profile(enc->param, x264_profile_names[0]); // open encoder if( (enc->handle = x264_encoder_open(enc->param)) == 0 ) { SKY_LOG(1,(TAG_H264ENCODER,"Could not Open x264_encoder")); // will free when encoder close or now //free(enc->param); //free(enc->picture); return false ; } // create a new picture malloc enc->picture here X264_CSP_I422 X264_CSP_YV16 X264_CSP_NV16 //x264_picture_alloc(enc->picture,X264_CSP_YV12,enc->param->i_width,enc->param->i_height); //enc->picture->img.i_csp = X264_CSP_YV12 ; //x264_picture_alloc(enc->picture,X264_CSP_NV12,enc->param->i_width,enc->param->i_height); //enc->picture->img.i_csp = X264_CSP_NV12 ; x264_picture_alloc(enc->picture,X264_CSP_YV12,enc->param->i_width,enc->param->i_height); enc->picture->img.i_csp = X264_CSP_YV12 ; enc->picture->img.i_plane = 3 ; return true ; }
void encode_init() { // fill x264_param_t with default values and do CPU detection x264_param_default(x264_encode.para); if(x264_param_default_preset(x264_encode.para, capg.preset, capg.tune) < 0) CAP_DBG_EXIT("x264_param_default_preset error!\n"); // ricann debug CAP_DBG("-------------------after x264_param_default_preset\n"); encode_printpara(); // Configure non-default params // real frame rate is i_fps_num/i_fps_den x264_encode.para->i_fps_num = capg.frame_rate; x264_encode.para->i_width = capg.width; x264_encode.para->i_height = capg.height; x264_encode.para->i_keyint_max = capg.gop_size; x264_encode.para->i_csp = x264_encode.colorspace; x264_encode.para->b_vfr_input = 0; x264_encode.para->b_repeat_headers = 1; // ricann debug CAP_DBG("-------------------after assign value\n"); encode_printpara(); x264_encode.pic->img.i_csp = x264_encode.colorspace; x264_encode.pic->img.i_plane = 3; x264_encode.pic->i_type = X264_TYPE_AUTO; if(x264_param_apply_profile(x264_encode.para, capg.profile) < 0) CAP_DBG_EXIT("x264_param_apply_profile error!\n"); x264_encode.handle = x264_encoder_open(x264_encode.para); if(!x264_encode.handle) CAP_DBG_EXIT("x264_encoder_open error!\n"); // ricann debug CAP_DBG("-------------------after x264_encoder_open\n"); encode_printpara(); }
int main (int argc, char *argv[]) { GtkWidget *window; X264_Gtk *x264_gtk; x264_param_t *param; x264_param_t param_default; char *res; char *res_default; BIND_X264_TEXTDOMAIN(); gtk_init (&argc, &argv); window = x264_gtk_window_create (NULL); x264_gtk_shutdown (window); x264_gtk = x264_gtk_load (); param = x264_gtk_param_get (x264_gtk); /* do what you want with these data */ /* for example, displaying them and compare with default*/ res = x264_param2string (param, 0); printf ("%s\n", res); x264_param_default (¶m_default); res_default = x264_param2string (¶m_default, 0); printf ("\n%s\n", res_default); if (strcmp (res, res_default) == 0) printf (_("\nSame result !\n")); else printf (_("\nDifferent from default values\n")); x264_free (res); x264_free (res_default); x264_gtk_free (x264_gtk); g_free (param); return 1; }
void encode_init(Encoder *encoder, int img_width, int img_height) { //Set default x264 parameters encoder->param = (x264_param_t *) malloc(sizeof(x264_param_t)); encoder->picture = (x264_picture_t *) malloc(sizeof(x264_picture_t)); x264_param_default(encoder->param); encoder->param->i_width = img_width; //set frame width encoder->param->i_height = img_height; //set frame height encoder->param->rc.i_lookahead = 0; //表示i帧向前缓冲区 encoder->param->i_fps_num = 25; //帧率分子 encoder->param->i_fps_den = 1; //帧率分母 encoder->param->rc.i_lookahead = 0; encoder->param->i_sync_lookahead = 0; encoder->param->i_bframe = 0; encoder->param->b_sliced_threads = 1; encoder->param->b_vfr_input = 0; encoder->param->rc.b_mb_tree = 0; x264_param_apply_profile(encoder->param, x264_profile_names[0]); encoder->handle = x264_encoder_open(encoder->param); if (encoder->handle == 0) { return; } /* Create a new pic */ //encoder->picture->param->i_width = img_width; //encoder->picture->param->i_height = img_height; x264_picture_alloc(encoder->picture, X264_CSP_I420, encoder->param->i_width,encoder->param->i_height); encoder->picture->img.i_csp = X264_CSP_I420; encoder->picture->img.i_plane = 3; g_H264_Buf = (uint8_t *) malloc( sizeof(uint8_t) * g_ImgWidth * g_ImgHeight * 3); // 设置缓冲区 }
/**************************************************************************** * main: ****************************************************************************/ int main( int argc, char **argv ) { x264_param_t param; cli_opt_t opt; #ifdef _MSC_VER _setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdout), _O_BINARY); #endif x264_param_default( ¶m ); /* Parse command line */ if( Parse( argc, argv, ¶m, &opt ) < 0 ) return -1; /* Control-C handler */ signal( SIGINT, SigIntHandler ); return Encode( ¶m, &opt ); }
/**************************************************************************** * main: ****************************************************************************/ void main() { x264_t *h; ///// x264_ x264_param_t param; ///// x264_param_t x264_picture_t *pic; //// x264_picture FILE *fyuv; FILE *fout = stdout; int i_frame, i_frame_total; int64_t i_start, i_end; int64_t i_file; #ifdef _MSC_VER _setmode(_fileno(stdin), _O_BINARY); /* thanks to Marcos Morais <morais at dee.ufcg.edu.br> */ _setmode(_fileno(stdout), _O_BINARY); #endif x264_param_default( m ); ///// / if( ( fyuv = fopen("d:\\mother_daughter_qcif.yuv", "rb" ) ) == NULL )
//FILE* ff ; int main_bak( int argc, char **argv ) { x264_param_t param; cli_opt_t opt; int ret; //ff = fopen("ff_org.264", "wb"); initDebugLog("debug_org.log"); DEBUG_LOG(INF, "main begin"); #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); pthread_win32_thread_attach_np(); #endif #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdout), _O_BINARY); #endif /* 初始化输入参数结构体,设置为默认值 */ x264_param_default( ¶m ); /* 解析命令行,设置param(包括函数指针),并保存到opt的文件中。打开输出的文件.Parse command line */ if( Parse( argc, argv, ¶m, &opt ) < 0 ) return -1; /* 是否响应Ctrl+C终端。Control-C handler */ signal( SIGINT, SigIntHandler ); /* 编码主控函数,编码输入输出文件分别是opt中的hin和hout */ ret = Encode( ¶m, &opt ); #ifdef PTW32_STATIC_LIB pthread_win32_thread_detach_np(); pthread_win32_process_detach_np(); #endif DEBUG_LOG(INF, "main end"); return ret; }
jlong Java_h264_com_H264Encoder_CompressBegin(JNIEnv* env, jobject thiz, jint width, jint height) { Encoder * en = (Encoder *) malloc(sizeof(Encoder)); en->param = (x264_param_t *) malloc(sizeof(x264_param_t)); en->picture = (x264_param_t *) malloc(sizeof(x264_picture_t)); x264_param_default(en->param); //set default param x264_param_apply_profile(en->param,"baseline"); //en->param->rc.i_rc_method = X264_RC_CQP; en->param->i_log_level = X264_LOG_NONE; en->param->i_width = width; //set frame width en->param->i_height = height; //set frame height en->param->rc.i_lookahead =0; en->param->i_fps_num =5; en->param->i_fps_den = 1; if ((en->handle = x264_encoder_open(en->param)) == 0) { return 0; } /* Create a new pic */ x264_picture_alloc(en->picture, X264_CSP_I420, en->param->i_width, en->param->i_height); return (jlong) en; }
msx264::msx264() { pNals = NULL; iNal = 0; x264_param_default(¶ms); //x264_param_default_preset(¶ms,"fast","zerolatency"); #if 0 params.i_threads = X264_SYNC_LOOKAHEAD_AUTO; params.i_width = 640; params.i_height = 480; params.i_frame_total = 0; // Set parameters params.i_keyint_max = 25; params.i_keyint_min = 1; params.i_bframe = 0; params.b_open_gop = 0; params.i_bframe_pyramid = 0; params.i_bframe_adaptive = X264_B_ADAPT_TRELLIS; params.i_log_level = X264_LOG_DEBUG; params.i_frame_reference = 0; //params.rc.i_bitrate = (int)( ( ((float)d->bitrate)*0.8)/1000.0); params.rc.i_bitrate = 250000; params.rc.b_stat_write = 0; //params.i_slice_max_size = ms_get_payload_max_size()-100; /*arlready */ params.i_slice_max_size = 1340; /*arlready */ params.rc.i_lookahead = 0; params.b_annexb = 0; params.b_repeat_headers = 1; params.rc.i_qp_min = 2; params.rc.i_qp_max = 31; params.rc.i_qp_step = 29; params.i_fps_num = 25; params.i_fps_den = 1; #endif params.i_threads = X264_SYNC_LOOKAHEAD_AUTO; //* 取空缓冲区继续使用不死锁的保证. //* video Properties params.i_width = 640; //* 宽度. params.i_height = 480; //* 高度 params.i_frame_total = 0; //* 编码总帧数.不知道用0. params.i_keyint_max = 10; //* bitstream parameters params.i_bframe = 5; params.b_open_gop = 0; params.i_bframe_pyramid = 0; params.i_bframe_adaptive = X264_B_ADAPT_TRELLIS; //* 宽高比,有效果,但不是想要的. //pX264Param->vui.i_sar_width = 1080; //pX264Param->vui.i_sar_height = 720; //* Log params.i_log_level = X264_LOG_DEBUG; //* Rate control Parameters params.rc.i_bitrate = 1024 * 10; //* 码率(比特率,单位Kbps) //* muxing parameters params.i_fps_den = 1; //* 帧率分母 params.i_fps_num = 25; //* 帧率分子 params.i_timebase_den = params.i_fps_num; params.i_timebase_num = params.i_fps_den; // Set profile level constrains x264_param_apply_profile(¶ms,"baseline"); params.rc.i_rc_method = X264_RC_ABR; file = open("./file.h264", O_RDWR | O_NONBLOCK, 0); if (file < 0) { printf("open video error\n"); return ; } }
void CX264Encoder::ConfigParam(void* param) { if(!param) return; //fred user_param mode_normal_alg_param = { 2, /* b_rc_vbv 0x00-cqp 0x01-abr 0x02 vbv */ // 0.3, /*vbv_buffer_percent*/ // 1.5, /*vbv_drop_thr*/ 1, /*max_drop_num*/ 0, /*b_mbrc_strict*/ // 2, /*drop_start_pos*/ 1, /*b_adaptive_qp*/ //! 25 //cqp // }; user_param mode_desktop_alg_param = { 2, /* b_rc_vbv 0x00-cqp 0x01-abr 0x02 vbv */ 4, /*vbv_buffer_percent*/ 1.0, /*vbv_drop_thr*/ 5, /*max_drop_num*/ 0, /*b_mbrc_strict*/ 0, /*drop_start_pos*/ 0, /*b_adaptive_qp*/ 25 //cqp }; user_param mode_normal_abr_alg_param = { 2, /* b_rc_vbv 0x00-cqp 0x01-abr 0x02 vbv */ 0.3, /*vbv_buffer_percent*/ 1.7, /*vbv_drop_thr*/ 1, /*max_drop_num*/ 0, /*b_mbrc_strict*/ 2, /*drop_start_pos*/ 1, /*b_adaptive_qp*/ 25 //cqp }; user_param *pUsrParam; x264_param_t* pParam = (x264_param_t*)param; x264_param_default( (x264_param_t*)pParam ); pParam->i_width = m_stEncParam.iWidth; pParam->i_height = m_stEncParam.iHeight; pParam->rc.i_bitrate = m_stEncParam.iBitrate; pParam->rc.i_rc_method = X264_RC_ABR; pParam->i_fps_den = 1; pParam->i_fps_num = m_stEncParam.iFPS * pParam->i_fps_den; pParam->i_frame_reference = 3; pParam->analyse.b_psnr = 0; pParam->analyse.b_ssim = 0; pParam->b_annexb = 1; pParam->analyse.b_weighted_bipred = 0; pParam->i_threads = 1;//CLIP3(m_stEncParam.iThreads, 1, 16); pParam->rc.i_qp_min = CLIP3(m_stEncParam.iMinQP, 0, 51); pParam->rc.i_qp_max = CLIP3(m_stEncParam.iMaxQP, 20, 51); pParam->pf_log = x264_log_default; pParam->i_log_level = X264_LOG_INFO; pParam->analyse.b_psy = 0; pParam->rc.i_aq_mode = 0; //emMode pParam->intra_period = m_stEncParam.iGOP; pParam->gf_period = m_stEncParam.igfGOP; pParam->sp_period = m_stEncParam.ispGOP; if ( X264ENCPARAM::emMode_Dsktop == m_stEncParam.mode ) { pParam->em_rc_mode = em_mode_dsktop; pUsrParam = &mode_desktop_alg_param; pParam->rc.i_qp_step = 2; } else if(X264ENCPARAM::emMode_Normal_abr == m_stEncParam.mode) { pParam->em_rc_mode = em_mode_normal; pUsrParam = &mode_normal_abr_alg_param; } else { pParam->em_rc_mode = em_mode_normal;//normal as default pUsrParam = &mode_normal_alg_param; } pParam->rc.vbv_drop_thr = pUsrParam->vbv_drop_thr; pParam->rc.max_drop_num = pUsrParam->max_drop_num; pParam->rc.drop_start_pos = pUsrParam->drop_start_pos; // mdou pParam->rc.use_drop_frame = 1; if (pParam->rc.i_qp_max == pParam->rc.i_qp_min || pParam->em_rc_mode == em_mode_dsktop) // mdou cqp { pParam->rc.use_drop_frame = 0; pParam->rc.i_qp_min = 30; pParam->rc.i_qp_max = 45; } #ifdef WIN32 //complexity + -标识相对于normal的变化 switch (m_stEncParam.cp) { case X264ENCPARAM::cp_best: pParam->analyse.i_subpel_refine = 4; //+ pParam->analyse.i_mv_range = -1; pParam->analyse.b_mixed_references = 1; pParam->analyse.i_trellis = 1; pParam->b_cabac = 1; pParam->analyse.b_transform_8x8 = 1; pParam->analyse.i_me_method = X264_ME_HEX; pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16 | X264_ANALYSE_PSUB8x8; //+ pParam->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8; pParam->analyse.i_cmplx_level = 2; break; case X264ENCPARAM::cp_fast: pParam->analyse.i_subpel_refine = 1; //- pParam->analyse.i_mv_range = 64;//- pParam->analyse.b_mixed_references = 0; //- pParam->analyse.i_trellis = 0; //- pParam->b_cabac = 1; pParam->analyse.b_transform_8x8 = 0; //- pParam->analyse.i_me_method = X264_ME_DIA; //- pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; //- pParam->analyse.i_cmplx_level = 0; break; case X264ENCPARAM::cp_normal: default: pParam->analyse.i_subpel_refine = 3; pParam->analyse.i_mv_range = -1; pParam->analyse.b_mixed_references = 1; pParam->analyse.i_trellis = 1; pParam->b_cabac = 1; pParam->analyse.b_transform_8x8 = 1; pParam->analyse.i_me_method = X264_ME_HEX; pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8; pParam->analyse.i_cmplx_level = 1; break; } #else //complexity + -标识相对于normal的变化 switch (m_stEncParam.cp) { case X264ENCPARAM::cp_best: pParam->analyse.i_subpel_refine = 3; pParam->analyse.b_mixed_references = 1; pParam->b_cabac = 1; pParam->analyse.i_me_method = X264_ME_HEX; pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; pParam->analyse.i_cmplx_level = 2; break; case X264ENCPARAM::cp_fast: pParam->analyse.i_subpel_refine = 0; //- pParam->b_cabac = 1; pParam->analyse.i_me_method = X264_ME_DIA; //- pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; pParam->analyse.i_cmplx_level = 0; break; case X264ENCPARAM::cp_normal: default: pParam->analyse.i_subpel_refine = 0; //- pParam->b_cabac = 1; pParam->analyse.i_me_method = X264_ME_DIA; //- pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; pParam->analyse.i_cmplx_level = 1; break; } #endif //profile, force to conform with H.264 standard switch (m_stEncParam.eProfileLevel) { case X264ENCPARAM::emProfileLevel_High: break; case X264ENCPARAM::emProfileLevel_Main: pParam->analyse.b_transform_8x8 = 0; break; case X264ENCPARAM::emProfileLevel_Base: pParam->analyse.b_transform_8x8 = 0; pParam->b_cabac = 0; break; default: break; } #ifdef WIN32 //桌面模式I帧开I8x8,反正新码控对桌面模式又没啥用 kevin 2013.11.27 if ( X264ENCPARAM::emMode_Dsktop == m_stEncParam.mode ) { pParam->analyse.intra |= X264_ANALYSE_I8x8; } if ( X264ENCPARAM::emMode_Dsktop == m_stEncParam.mode ) { //桌面模式关键在于I帧的质量,I帧开启I8x8可以提升压缩3%,关掉trellis不影响I帧的质量,但是可以提升整体压缩性能50% pParam->analyse.i_trellis = 0; pParam->analyse.intra |= X264_ANALYSE_I8x8; } #endif #if ENCODER_DEBUG_OPT pUsrParam = m_stEncParam.usr_ptr; #endif #if ENCODER_DEBUG_OPT if ( 0 == pUsrParam->b_rc_vbv ) { pParam->rc.i_rc_method = X264_RC_CQP; pParam->rc.i_qp_constant = CLIP3(pUsrParam->cqp_qp, 0, 51);//demo cqp } else #endif { if(0 == pUsrParam->b_adaptive_qp) pParam->rc.i_aq_mode = X264_AQ_NONE; if ( 1 == pUsrParam->b_rc_vbv ) { pParam->rc.i_vbv_max_bitrate = 0; pParam->rc.i_vbv_buffer_size = 0; } else { pParam->rc.i_vbv_max_bitrate = (int)( pParam->rc.i_bitrate * pUsrParam->vbv_buffer_percent ); pParam->rc.i_vbv_buffer_size = (int)( pParam->rc.i_bitrate * pUsrParam->vbv_buffer_percent ); } if(pParam->i_threads > 1) { pParam->rc.i_bitrate = (int)(pParam->rc.i_bitrate * 0.9); } } }
static int encode(quicktime_t *file, unsigned char **row_pointers, int track) { int64_t offset = quicktime_position(file); quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_h264_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; quicktime_trak_t *trak = vtrack->track; int width = quicktime_video_width(file, track); int height = quicktime_video_height(file, track); int w_2 = quicktime_quantize2(width); // ffmpeg interprets the codec height as the presentation height int h_2 = quicktime_quantize2(height); int i; int result = 0; int bytes = 0; int is_keyframe = 0; int current_field = vtrack->current_position % codec->total_fields; quicktime_atom_t chunk_atom; unsigned char header[1024]; int header_size = 0; int got_pps = 0; int got_sps = 0; quicktime_avcc_t *avcc = &trak->mdia.minf.stbl.stsd.table[0].avcc; pthread_mutex_lock(&h264_lock); if(!codec->encode_initialized[current_field]) { codec->encode_initialized[current_field] = 1; codec->param.i_width = w_2; codec->param.i_height = h_2; codec->param.i_fps_num = quicktime_frame_rate_n(file, track); codec->param.i_fps_den = quicktime_frame_rate_d(file, track); #if X264_BUILD >= 48 codec->param.rc.i_rc_method = X264_RC_CQP; #endif // Reset quantizer if fixed bitrate x264_param_t default_params; x264_param_default(&default_params); #if X264_BUILD < 48 if(codec->param.rc.b_cbr) #else if(codec->param.rc.i_qp_constant) #endif { codec->param.rc.i_qp_constant = default_params.rc.i_qp_constant; codec->param.rc.i_qp_min = default_params.rc.i_qp_min; codec->param.rc.i_qp_max = default_params.rc.i_qp_max; } if(file->cpus > 1) { codec->param.i_threads = file->cpus; } codec->encoder[current_field] = x264_encoder_open(&codec->param); codec->pic[current_field] = calloc(1, sizeof(x264_picture_t)); //printf("encode 1 %d %d\n", codec->param.i_width, codec->param.i_height); x264_picture_alloc(codec->pic[current_field], X264_CSP_I420, codec->param.i_width, codec->param.i_height); } codec->pic[current_field]->i_type = X264_TYPE_AUTO; codec->pic[current_field]->i_qpplus1 = 0; if(codec->header_only) { bzero(codec->pic[current_field]->img.plane[0], w_2 * h_2); bzero(codec->pic[current_field]->img.plane[1], w_2 * h_2 / 4); bzero(codec->pic[current_field]->img.plane[2], w_2 * h_2 / 4); } else if(file->color_model == BC_YUV420P) { memcpy(codec->pic[current_field]->img.plane[0], row_pointers[0], w_2 * h_2); memcpy(codec->pic[current_field]->img.plane[1], row_pointers[1], w_2 * h_2 / 4); memcpy(codec->pic[current_field]->img.plane[2], row_pointers[2], w_2 * h_2 / 4); } else { //printf("encode 2 %p %p %p\n", codec->pic[current_field]->img.plane[0], codec->pic[current_field]->img.plane[1], codec->pic[current_field]->img.plane[2]); cmodel_transfer(0, /* Leave NULL if non existent */ row_pointers, codec->pic[current_field]->img.plane[0], /* Leave NULL if non existent */ codec->pic[current_field]->img.plane[1], codec->pic[current_field]->img.plane[2], row_pointers[0], /* Leave NULL if non existent */ row_pointers[1], row_pointers[2], 0, /* Dimensions to capture from input frame */ 0, width, height, 0, /* Dimensions to project on output frame */ 0, width, height, file->color_model, BC_YUV420P, 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */ width, /* For planar use the luma rowspan */ codec->pic[current_field]->img.i_stride[0]); } x264_picture_t pic_out; x264_nal_t *nals; int nnal = 0; do { x264_encoder_encode(codec->encoder[current_field], &nals, &nnal, codec->pic[current_field], &pic_out); //printf("encode %d nnal=%d\n", __LINE__, nnal); } while(codec->header_only && !nnal); int allocation = w_2 * h_2 * 3; if(!codec->work_buffer) { codec->work_buffer = calloc(1, allocation); } codec->buffer_size = 0; //printf("encode %d nnal=%d\n", __LINE__, nnal); for(i = 0; i < nnal; i++) { #if X264_BUILD >= 76 int size = nals[i].i_payload; memcpy(codec->work_buffer + codec->buffer_size, nals[i].p_payload, nals[i].i_payload); #else int size_return = 0; int size = x264_nal_encode(codec->work_buffer + codec->buffer_size, &size_return, 1, nals + i); #endif unsigned char *ptr = codec->work_buffer + codec->buffer_size; //printf("encode %d size=%d\n", __LINE__, size); if(size > 0) { if(size + codec->buffer_size > allocation) { printf("qth264.c %d: overflow size=%d allocation=%d\n", __LINE__, size, allocation); } // Size of NAL for avc uint64_t avc_size = size - 4; // Synthesize header. // Hopefully all the parameter set NAL's are present in the first frame. if(!avcc->data_size) { if(header_size < 6) { header[header_size++] = 0x01; header[header_size++] = 0x4d; header[header_size++] = 0x40; header[header_size++] = 0x1f; header[header_size++] = 0xff; header[header_size++] = 0xe1; } int nal_type = (ptr[4] & 0x1f); // Picture parameter or sequence parameter set if(nal_type == 0x7 && !got_sps) { got_sps = 1; header[header_size++] = (avc_size & 0xff00) >> 8; header[header_size++] = (avc_size & 0xff); memcpy(&header[header_size], ptr + 4, avc_size); header_size += avc_size; } else if(nal_type == 0x8 && !got_pps) { got_pps = 1; // Number of sps nal's. header[header_size++] = 0x1; header[header_size++] = (avc_size & 0xff00) >> 8; header[header_size++] = (avc_size & 0xff); memcpy(&header[header_size], ptr + 4, avc_size); header_size += avc_size; } // Write header if(got_sps && got_pps) { /* * printf("encode %d\n", __LINE__); * int j; * for(j = 0; j < header_size; j++) * { * printf("%02x ", header[j]); * } * printf("\n"); */ quicktime_set_avcc_header(avcc, header, header_size); } }
int obe_populate_avc_encoder_params( obe_t *h, int input_stream_id, x264_param_t *param ) { obe_int_input_stream_t *stream = get_input_stream( h, input_stream_id ); if( !stream ) { fprintf( stderr, "Could not find stream \n" ); return -1; } if( stream->stream_type != STREAM_TYPE_VIDEO ) { fprintf( stderr, "Stream type is not video \n" ); return -1; } if( !param ) { fprintf( stderr, "Invalid parameter pointer \n" ); return -1; } if( h->obe_system == OBE_SYSTEM_TYPE_LOWEST_LATENCY || h->obe_system == OBE_SYSTEM_TYPE_LOW_LATENCY ) x264_param_default_preset( param, "veryfast", "zerolatency" ); else x264_param_default( param ); param->b_deterministic = 0; param->b_vfr_input = 0; param->b_pic_struct = 1; param->b_open_gop = 1; param->rc.i_rc_method = X264_RC_ABR; param->i_width = stream->width; param->i_height = stream->height; param->i_fps_num = stream->timebase_den; param->i_fps_den = stream->timebase_num; param->b_interlaced = stream->interlaced; if( param->b_interlaced ) param->b_tff = stream->tff; /* A reasonable default. x264 won't go higher than this parameter irrespective of speedcontrol */ if( h->obe_system == OBE_SYSTEM_TYPE_GENERIC ) param->i_frame_reference = 4; if( stream->sar_num && stream->sar_den ) { param->vui.i_sar_width = stream->sar_num; param->vui.i_sar_height = stream->sar_den; } param->vui.i_overscan = 2; if( ( param->i_fps_num == 25 || param->i_fps_num == 50 ) && param->i_fps_den == 1 ) { param->vui.i_vidformat = 1; // PAL param->vui.i_colorprim = 5; // BT.470-2 bg param->vui.i_transfer = 5; // BT.470-2 bg param->vui.i_colmatrix = 5; // BT.470-2 bg param->i_keyint_max = param->i_fps_num == 50 ? 48 : 24; } else if( ( param->i_fps_num == 30000 || param->i_fps_num == 60000 ) && param->i_fps_den == 1001 ) { param->vui.i_vidformat = 2; // NTSC param->vui.i_colorprim = 6; // BT.601-6 param->vui.i_transfer = 6; // BT.601-6 param->vui.i_colmatrix = 6; // BT.601-6 param->i_keyint_max = param->i_fps_num / 1000; } else { param->vui.i_vidformat = 5; // undefined param->vui.i_colorprim = 2; // undefined param->vui.i_transfer = 2; // undefined param->vui.i_colmatrix = 2; // undefined } /* Change to BT.709 for HD resolutions */ if( param->i_width >= 1280 && param->i_height >= 720 ) { param->vui.i_colorprim = 1; param->vui.i_transfer = 1; param->vui.i_colmatrix = 1; } x264_param_apply_profile( param, X264_BIT_DEPTH == 10 ? "high10" : "high" ); param->i_nal_hrd = X264_NAL_HRD_FAKE_VBR; param->b_aud = 1; param->i_log_level = X264_LOG_INFO; //param->rc.f_vbv_buffer_init = 0.1; if( h->obe_system == OBE_SYSTEM_TYPE_GENERIC ) { param->sc.f_speed = 1.0; param->sc.b_alt_timer = 1; if( param->i_width >= 1280 && param->i_height >= 720 ) param->sc.max_preset = 7; /* on the conservative side for HD */ else param->sc.max_preset = 10; param->rc.i_lookahead = param->i_keyint_max; } return 0; }
static void enc_preprocess(MSFilter *f){ EncData *d=(EncData*)f->data; x264_param_t *params=&d->params; d->packer=rfc3984_new(); rfc3984_set_mode(d->packer,d->mode); rfc3984_enable_stap_a(d->packer,FALSE); #if defined(__arm__) || defined(ANDROID) if (x264_param_default_preset(params,"superfast"/*"ultrafast"*/,"zerolatency")) { #else x264_param_default(params); { #endif ms_error("Cannot apply default x264 configuration"); }; params->i_threads=ms_get_cpu_count(); params->i_sync_lookahead=0; params->i_width=d->vconf.vsize.width; params->i_height=d->vconf.vsize.height; params->i_fps_num=(int)d->vconf.fps; params->i_fps_den=1; params->i_slice_max_size=ms_get_payload_max_size()-100; /*-100 security margin*/ params->i_level_idc=13; apply_bitrate(f); params->rc.i_lookahead=0; /*enable this by config ?*/ /* params.i_keyint_max = (int)d->fps*d->keyframe_int; params.i_keyint_min = (int)d->fps; */ params->b_repeat_headers=1; params->b_annexb=0; //these parameters must be set so that our stream is baseline params->analyse.b_transform_8x8 = 0; params->b_cabac = 0; params->i_cqm_preset = X264_CQM_FLAT; params->i_bframe = 0; params->analyse.i_weighted_pred = X264_WEIGHTP_NONE; d->enc=x264_encoder_open(params); if (d->enc==NULL) ms_error("Fail to create x264 encoder."); d->framenum=0; video_starter_init(&d->starter); } static void x264_nals_to_msgb(x264_nal_t *xnals, int num_nals, MSQueue * nalus){ int i; mblk_t *m; /*int bytes;*/ for (i=0;i<num_nals;++i){ m=allocb(xnals[i].i_payload+10,0); memcpy(m->b_wptr,xnals[i].p_payload+4,xnals[i].i_payload-4); m->b_wptr+=xnals[i].i_payload-4; if (xnals[i].i_type==7) { ms_message("A SPS is being sent."); }else if (xnals[i].i_type==8) { ms_message("A PPS is being sent."); } ms_queue_put(nalus,m); } }
void x264enc_set_param(const m_option_t* opt, char* arg) { static int initialized = 0; int slow_firstpass = 0; char *preset = NULL, *tune = NULL, *profile = NULL; char *p, *copy, *name; if (!initialized) { x264_param_default(¶m); initialized = 1; } if (!arg) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: no options provided\n"); parse_error = 1; return; } else if (!*arg) /* Empty arguments, just doing initialization of default parameters. */ return; /* Step 1: look for initial preset/tune. */ copy = p = strdup(arg); while ((name = strsep(©, ":"))) { char *value = strpbrk(name, "=:"); if (!value) continue; *value++ = 0; if (!strcasecmp(name, "preset")) preset = value; else if (!strcasecmp(name, "tune")) tune = value; } if (x264_param_default_preset(¶m, preset, tune) < 0) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Invalid preset or tune.\n"); parse_error = 1; } free(p); /* Step 2: explicit user overrides */ while ((name = strsep(&arg, ":")) && *name) { int ret = 0; char *value = strpbrk(name, "=:"); if (value) *value++ = 0; if (!strcasecmp(name, "profile")) profile = value; else if (!strcasecmp(name, "turbo")) { mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option x264encopts: turbo option is deprecated; " "use slow_firstpass to disable turbo\n"); if (value && *value == '0') slow_firstpass = 1; } else if (!strcasecmp(name, "slow_firstpass")) slow_firstpass = 1; else if (strcasecmp(name, "preset") && strcasecmp(name, "tune")) { ret = x264_param_parse(¶m, name, value); if (ret == X264_PARAM_BAD_NAME) mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Unknown suboption %s\n", name); if (ret == X264_PARAM_BAD_VALUE) mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Bad argument %s=%s\n", name, value ? value : "(null)"); } /* mark this option as done, so it's not reparsed if there's another -x264encopts */ *name = 0; parse_error |= ret; } /* Step 3: Apply fast first pass (turbo) options. */ if (!slow_firstpass) x264_param_apply_fastfirstpass(¶m); /* Step 4: enforce profile */ if (profile && x264_param_apply_profile(¶m, profile) < 0) parse_error = 1; }
/***************************************************************************** * Open: probe the encoder *****************************************************************************/ static int Open ( vlc_object_t *p_this ) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; int i_val; char *psz_val; int i_qmin = 0, i_qmax = 0; x264_nal_t *nal; int i, i_nal; if( p_enc->fmt_out.i_codec != VLC_CODEC_H264 && !p_enc->b_force ) { return VLC_EGENERIC; } /* X264_POINTVER or X264_VERSION are not available */ msg_Dbg ( p_enc, "version x264 0.%d.X", X264_BUILD ); config_ChainParse( p_enc, SOUT_CFG_PREFIX, ppsz_sout_options, p_enc->p_cfg ); p_enc->fmt_out.i_cat = VIDEO_ES; p_enc->fmt_out.i_codec = VLC_CODEC_H264; p_enc->fmt_in.i_codec = VLC_CODEC_I420; p_enc->pf_encode_video = Encode; p_enc->pf_encode_audio = NULL; p_enc->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; p_sys->i_interpolated_dts = 0; p_sys->psz_stat_name = NULL; p_sys->p_buffer = NULL; x264_param_default( &p_sys->param ); p_sys->param.i_width = p_enc->fmt_in.video.i_width; p_sys->param.i_height = p_enc->fmt_in.video.i_height; p_sys->param.rc.f_qcompress = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" ); /* transcode-default bitrate is 0, * set more to ABR if user specifies bitrate */ if( p_enc->fmt_out.i_bitrate > 0 ) { p_sys->param.rc.i_bitrate = p_enc->fmt_out.i_bitrate / 1000; p_sys->param.rc.i_rc_method = X264_RC_ABR; } else /* Set default to CRF */ { i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "crf" ); if( i_val > 0 && i_val <= 51 ) { p_sys->param.rc.f_rf_constant = i_val; p_sys->param.rc.i_rc_method = X264_RC_CRF; } } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpstep" ); if( i_val >= 0 && i_val <= 51 ) p_sys->param.rc.i_qp_step = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmin" ); if( i_val >= 0 && i_val <= 51 ) { i_qmin = i_val; p_sys->param.rc.i_qp_min = i_qmin; } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpmax" ); if( i_val >= 0 && i_val <= 51 ) { i_qmax = i_val; p_sys->param.rc.i_qp_max = i_qmax; } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qp" ); if( i_val >= 0 && i_val <= 51 ) { if( i_qmin > i_val ) i_qmin = i_val; if( i_qmax < i_val ) i_qmax = i_val; /* User defined QP-value, so change ratecontrol method */ p_sys->param.rc.i_rc_method = X264_RC_CQP; p_sys->param.rc.i_qp_constant = i_val; p_sys->param.rc.i_qp_min = i_qmin; p_sys->param.rc.i_qp_max = i_qmax; } p_sys->param.rc.f_rate_tolerance = var_GetFloat( p_enc, SOUT_CFG_PREFIX "ratetol" ); p_sys->param.rc.f_vbv_buffer_init = var_GetFloat( p_enc, SOUT_CFG_PREFIX "vbv-init" ); p_sys->param.rc.i_vbv_buffer_size = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-bufsize" ); /* max bitrate = average bitrate -> CBR */ i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-maxrate" ); if( !i_val && p_sys->param.rc.i_rc_method == X264_RC_ABR ) p_sys->param.rc.i_vbv_max_bitrate = p_sys->param.rc.i_bitrate; else if ( i_val ) p_sys->param.rc.i_vbv_max_bitrate = i_val; p_sys->param.b_cabac = var_GetBool( p_enc, SOUT_CFG_PREFIX "cabac" ); /* disable deblocking when nf (no loop filter) is enabled */ p_sys->param.b_deblocking_filter = !var_GetBool( p_enc, SOUT_CFG_PREFIX "nf" ); psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "deblock" ); if( psz_val ) { char *p = strchr( psz_val, ':' ); p_sys->param.i_deblocking_filter_alphac0 = atoi( psz_val ); p_sys->param.i_deblocking_filter_beta = p ? atoi( p+1 ) : p_sys->param.i_deblocking_filter_alphac0; free( psz_val ); } psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "psy-rd" ); if( psz_val ) { char *p = strchr( psz_val, ':' ); p_sys->param.analyse.f_psy_rd = us_atof( psz_val ); p_sys->param.analyse.f_psy_trellis = p ? us_atof( p+1 ) : 0; free( psz_val ); } psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "level" ); if( psz_val ) { if( us_atof (psz_val) < 6 ) p_sys->param.i_level_idc = (int) (10 * us_atof (psz_val) + .5); else p_sys->param.i_level_idc = atoi (psz_val); free( psz_val ); } p_sys->param.b_interlaced = var_GetBool( p_enc, SOUT_CFG_PREFIX "interlaced" ); p_sys->param.rc.f_ip_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "ipratio" ); p_sys->param.rc.f_pb_factor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "pbratio" ); p_sys->param.rc.f_complexity_blur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "cplxblur" ); p_sys->param.rc.f_qblur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qblur" ); p_sys->param.rc.i_aq_mode = var_GetInteger( p_enc, SOUT_CFG_PREFIX "aq-mode" ); p_sys->param.rc.f_aq_strength = var_GetFloat( p_enc, SOUT_CFG_PREFIX "aq-strength" ); if( var_GetBool( p_enc, SOUT_CFG_PREFIX "verbose" ) ) p_sys->param.i_log_level = X264_LOG_DEBUG; if( var_GetBool( p_enc, SOUT_CFG_PREFIX "quiet" ) ) p_sys->param.i_log_level = X264_LOG_NONE; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "sps-id" ); if( i_val >= 0 ) p_sys->param.i_sps_id = i_val; if( var_GetBool( p_enc, SOUT_CFG_PREFIX "aud" ) ) p_sys->param.b_aud = true; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "keyint" ); if( i_val > 0 ) p_sys->param.i_keyint_max = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "min-keyint" ); if( i_val > 0 ) p_sys->param.i_keyint_min = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "bframes" ); if( i_val >= 0 && i_val <= 16 ) p_sys->param.i_bframe = i_val; #if X264_BUILD >= 78 psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "bpyramid" ); p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE; if( !strcmp( psz_val, "none" ) ) { p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NONE; } else if ( !strcmp( psz_val, "strict" ) ) { p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_STRICT; } else if ( !strcmp( psz_val, "normal" ) ) { p_sys->param.i_bframe_pyramid = X264_B_PYRAMID_NORMAL; } free( psz_val ); #else p_sys->param.b_bframe_pyramid = var_GetBool( p_enc, SOUT_CFG_PREFIX "bpyramid" ); #endif i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "ref" ); if( i_val > 0 && i_val <= 15 ) p_sys->param.i_frame_reference = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "scenecut" ); if( i_val >= -1 && i_val <= 100 ) p_sys->param.i_scenecut_threshold = i_val; p_sys->param.b_deterministic = var_GetBool( p_enc, SOUT_CFG_PREFIX "non-deterministic" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "subme" ); if( i_val >= 1 && i_val <= SUBME_MAX ) p_sys->param.analyse.i_subpel_refine = i_val; //TODO: psz_val == NULL ? psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "me" ); if( !strcmp( psz_val, "dia" ) ) { p_sys->param.analyse.i_me_method = X264_ME_DIA; } else if( !strcmp( psz_val, "hex" ) ) { p_sys->param.analyse.i_me_method = X264_ME_HEX; } else if( !strcmp( psz_val, "umh" ) ) { p_sys->param.analyse.i_me_method = X264_ME_UMH; } else if( !strcmp( psz_val, "esa" ) ) { p_sys->param.analyse.i_me_method = X264_ME_ESA; } else if( !strcmp( psz_val, "tesa" ) ) { p_sys->param.analyse.i_me_method = X264_ME_TESA; } free( psz_val ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "merange" ); if( i_val >= 0 && i_val <= 64 ) p_sys->param.analyse.i_me_range = i_val; p_sys->param.analyse.i_mv_range = var_GetInteger( p_enc, SOUT_CFG_PREFIX "mvrange" ); p_sys->param.analyse.i_mv_range_thread = var_GetInteger( p_enc, SOUT_CFG_PREFIX "mvrange-thread" ); psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "direct" ); if( !strcmp( psz_val, "none" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE; } else if( !strcmp( psz_val, "spatial" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL; } else if( !strcmp( psz_val, "temporal" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_TEMPORAL; } else if( !strcmp( psz_val, "auto" ) ) { p_sys->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; } free( psz_val ); p_sys->param.analyse.b_psnr = var_GetBool( p_enc, SOUT_CFG_PREFIX "psnr" ); p_sys->param.analyse.b_ssim = var_GetBool( p_enc, SOUT_CFG_PREFIX "ssim" ); p_sys->param.analyse.b_weighted_bipred = var_GetBool( p_enc, SOUT_CFG_PREFIX "weightb" ); p_sys->param.i_bframe_adaptive = var_GetInteger( p_enc, SOUT_CFG_PREFIX "b-adapt" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "b-bias" ); if( i_val >= -100 && i_val <= 100 ) p_sys->param.i_bframe_bias = i_val; p_sys->param.analyse.b_chroma_me = var_GetBool( p_enc, SOUT_CFG_PREFIX "chroma-me" ); p_sys->param.analyse.i_chroma_qp_offset = var_GetInteger( p_enc, SOUT_CFG_PREFIX "chroma-qp-offset" ); p_sys->param.analyse.b_mixed_references = var_GetBool( p_enc, SOUT_CFG_PREFIX "mixed-refs" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "trellis" ); if( i_val >= 0 && i_val <= 2 ) p_sys->param.analyse.i_trellis = i_val; p_sys->param.analyse.b_fast_pskip = var_GetBool( p_enc, SOUT_CFG_PREFIX "fast-pskip" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "nr" ); if( i_val >= 0 && i_val <= 1000 ) p_sys->param.analyse.i_noise_reduction = i_val; p_sys->param.analyse.b_dct_decimate = var_GetBool( p_enc, SOUT_CFG_PREFIX "dct-decimate" ); i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-inter" ); if( i_val >= 0 && i_val <= 32 ) p_sys->param.analyse.i_luma_deadzone[0] = i_val; i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "deadzone-intra" ); if( i_val >= 0 && i_val <= 32 ) p_sys->param.analyse.i_luma_deadzone[1] = i_val; if( !var_GetBool( p_enc, SOUT_CFG_PREFIX "asm" ) ) p_sys->param.cpu = 0; #ifndef X264_ANALYSE_BSUB16x16 # define X264_ANALYSE_BSUB16x16 0 #endif psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "partitions" ); if( !strcmp( psz_val, "none" ) ) { p_sys->param.analyse.inter = 0; } else if( !strcmp( psz_val, "fast" ) ) { p_sys->param.analyse.inter = X264_ANALYSE_I4x4; } else if( !strcmp( psz_val, "normal" ) ) { p_sys->param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; #ifdef X264_ANALYSE_I8x8 p_sys->param.analyse.inter |= X264_ANALYSE_I8x8; #endif } else if( !strcmp( psz_val, "slow" ) ) { p_sys->param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16; #ifdef X264_ANALYSE_I8x8 p_sys->param.analyse.inter |= X264_ANALYSE_I8x8; #endif } else if( !strcmp( psz_val, "all" ) ) { p_sys->param.analyse.inter = ~0; } free( psz_val ); p_sys->param.analyse.b_transform_8x8 = var_GetBool( p_enc, SOUT_CFG_PREFIX "8x8dct" ); if( p_enc->fmt_in.video.i_aspect > 0 ) { int64_t i_num, i_den; unsigned int i_dst_num, i_dst_den; i_num = p_enc->fmt_in.video.i_aspect * (int64_t)p_enc->fmt_in.video.i_height; i_den = VOUT_ASPECT_FACTOR * p_enc->fmt_in.video.i_width; vlc_ureduce( &i_dst_num, &i_dst_den, i_num, i_den, 0 ); p_sys->param.vui.i_sar_width = i_dst_num; p_sys->param.vui.i_sar_height = i_dst_den; } if( p_enc->fmt_in.video.i_frame_rate_base > 0 ) { p_sys->param.i_fps_num = p_enc->fmt_in.video.i_frame_rate; p_sys->param.i_fps_den = p_enc->fmt_in.video.i_frame_rate_base; } /* x264 vbv-bufsize = 0 (default). if not provided set period in seconds for local maximum bitrate (cache/bufsize) based on average bitrate when use has told bitrate. vbv-buffer size is set to bitrate * secods between keyframes */ if( !p_sys->param.rc.i_vbv_buffer_size && p_sys->param.rc.i_rc_method == X264_RC_ABR && p_sys->param.i_fps_num ) { p_sys->param.rc.i_vbv_buffer_size = p_sys->param.rc.i_bitrate * p_sys->param.i_fps_den; p_sys->param.rc.i_vbv_buffer_size *= p_sys->param.i_keyint_max; p_sys->param.rc.i_vbv_buffer_size /= p_sys->param.i_fps_num; } /* Check if user has given some profile (baseline,main,high) to limit * settings, and apply those*/ psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "profile" ); if( psz_val ) { if( !strcasecmp( psz_val, "baseline" ) ) { msg_Dbg( p_enc, "Limiting to baseline profile"); p_sys->param.analyse.b_transform_8x8 = 0; p_sys->param.b_cabac = 0; p_sys->param.i_bframe = 0; } else if (!strcasecmp( psz_val, "main" ) ) { msg_Dbg( p_enc, "Limiting to main-profile"); p_sys->param.analyse.b_transform_8x8 = 0; } /* high profile don't restrict stuff*/ } free( psz_val ); unsigned i_cpu = vlc_CPU(); if( !(i_cpu & CPU_CAPABILITY_MMX) ) { p_sys->param.cpu &= ~X264_CPU_MMX; } if( !(i_cpu & CPU_CAPABILITY_MMXEXT) ) { p_sys->param.cpu &= ~X264_CPU_MMXEXT; } if( !(i_cpu & CPU_CAPABILITY_SSE) ) { p_sys->param.cpu &= ~X264_CPU_SSE; } if( !(i_cpu & CPU_CAPABILITY_SSE2) ) { p_sys->param.cpu &= ~X264_CPU_SSE2; } /* BUILD 29 adds support for multi-threaded encoding while BUILD 49 (r543) also adds support for threads = 0 for automatically selecting an optimal value (cores * 1.5) based on detected CPUs. Default behavior for x264 is threads = 1, however VLC usage differs and uses threads = 0 (auto) by default unless ofcourse transcode threads is explicitly specified.. */ p_sys->param.i_threads = p_enc->i_threads; psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "stats" ); if( psz_val ) { p_sys->param.rc.psz_stat_in = p_sys->param.rc.psz_stat_out = p_sys->psz_stat_name = psz_val; } i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "pass" ); if( i_val > 0 && i_val <= 3 ) { p_sys->param.rc.b_stat_write = i_val & 1; p_sys->param.rc.b_stat_read = i_val & 2; } /* We need to initialize pthreadw32 before we open the encoder, but only once for the whole application. Since pthreadw32 doesn't keep a refcount, do it ourselves. */ #ifdef PTW32_STATIC_LIB vlc_value_t lock, count; var_Create( p_enc->p_libvlc, "pthread_win32_mutex", VLC_VAR_MUTEX ); var_Get( p_enc->p_libvlc, "pthread_win32_mutex", &lock ); vlc_mutex_lock( lock.p_address ); var_Create( p_enc->p_libvlc, "pthread_win32_count", VLC_VAR_INTEGER ); var_Get( p_enc->p_libvlc, "pthread_win32_count", &count ); if( count.i_int == 0 ) { msg_Dbg( p_enc, "initializing pthread-win32" ); if( !pthread_win32_process_attach_np() || !pthread_win32_thread_attach_np() ) { msg_Warn( p_enc, "pthread Win32 Initialization failed" ); vlc_mutex_unlock( lock.p_address ); return VLC_EGENERIC; } } count.i_int++; var_Set( p_enc->p_libvlc, "pthread_win32_count", count ); vlc_mutex_unlock( lock.p_address ); #endif /* Set lookahead value to lower than default, * as rtp-output without mux doesn't handle * difference that well yet*/ p_sys->param.rc.i_lookahead=5; /* Open the encoder */ p_sys->h = x264_encoder_open( &p_sys->param ); if( p_sys->h == NULL ) { msg_Err( p_enc, "cannot open x264 encoder" ); Close( VLC_OBJECT(p_enc) ); return VLC_EGENERIC; } /* alloc mem */ p_sys->i_buffer = 4 * p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height + 1000; p_sys->p_buffer = malloc( p_sys->i_buffer ); if( !p_sys->p_buffer ) { Close( VLC_OBJECT(p_enc) ); return VLC_ENOMEM; } /* get the globals headers */ p_enc->fmt_out.i_extra = 0; p_enc->fmt_out.p_extra = NULL; p_enc->fmt_out.i_extra = x264_encoder_headers( p_sys->h, &nal, &i_nal ); p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra ); if( !p_enc->fmt_out.p_extra ) { Close( VLC_OBJECT(p_enc) ); return VLC_ENOMEM; } void *p_tmp = p_enc->fmt_out.p_extra; for( i = 0; i < i_nal; i++ ) { memcpy( p_tmp, nal[i].p_payload, nal[i].i_payload ); p_tmp += nal[i].i_payload; } return VLC_SUCCESS; }
int main(int argc, char **argv) { int ret = 0; int y_size = 0; int i = 0; int j = 0; //Encode 50 frame //if set 0, encode all frame int frame_num = 50; int csp = X264_CSP_I420; int width = 640; int height = 360; int i_nal = 0; x264_nal_t *p_nals = NULL; x264_t *p_handle = NULL; x264_picture_t *p_pic_in = (x264_picture_t *) malloc(sizeof(x264_picture_t)); x264_picture_t *p_pic_out = (x264_picture_t *) malloc(sizeof(x264_picture_t)); x264_param_t *p_param = (x264_param_t *) malloc(sizeof(x264_param_t)); //FILE* fp_src = fopen("../cuc_ieschool_640x360_yuv444p.yuv", "rb"); FILE *fp_src = fopen("../cuc_ieschool_640x360_yuv420p.yuv", "rb"); FILE *fp_dst = fopen("cuc_ieschool.h264", "wb"); //Check if ((NULL == fp_src) || (NULL == fp_dst)) { lwlog_err("Open files error."); return -1; } x264_param_default(p_param); p_param->i_width = width; p_param->i_height = height; /* //Param p_param->i_log_level = X264_LOG_DEBUG; p_param->i_threads = X264_SYNC_LOOKAHEAD_AUTO; p_param->i_frame_total = 0; p_param->i_keyint_max = 10; p_param->i_bframe = 5; p_param->b_open_gop = 0; p_param->i_bframe_pyramid = 0; p_param->rc.i_qp_constant=0; p_param->rc.i_qp_max=0; p_param->rc.i_qp_min=0; p_param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; p_param->i_fps_den = 1; p_param->i_fps_num = 25; p_param->i_timebase_den = p_param->i_fps_num; p_param->i_timebase_num = p_param->i_fps_den; */ p_param->i_csp = csp; x264_param_apply_profile(p_param, x264_profile_names[5]); p_handle = x264_encoder_open(p_param); x264_picture_init(p_pic_out); x264_picture_alloc(p_pic_in, csp, p_param->i_width, p_param->i_height); //ret = x264_encoder_headers(p_handle, &p_nals, &i_nal); y_size = p_param->i_width * p_param->i_height; //detect frame number if (0 == frame_num) { fseek(fp_src, 0, SEEK_END); switch (csp) { case X264_CSP_I444: frame_num = ftell(fp_src) / (y_size * 3); break; case X264_CSP_I420: frame_num = ftell(fp_src) / (y_size * 3 / 2); break; default: lwlog_err("Colorspace Not Support"); return -1; } fseek(fp_src, 0, SEEK_SET); } //Loop to Encode for (i = 0; i < frame_num; ++i) { switch (csp) { case X264_CSP_I444: { fread(p_pic_in->img.plane[0], y_size, 1, fp_src); //Y fread(p_pic_in->img.plane[1], y_size, 1, fp_src); //U fread(p_pic_in->img.plane[2], y_size, 1, fp_src); //V break; } case X264_CSP_I420: { fread(p_pic_in->img.plane[0], y_size, 1, fp_src); //Y fread(p_pic_in->img.plane[1], y_size / 4, 1, fp_src); //U fread(p_pic_in->img.plane[2], y_size / 4, 1, fp_src); //V break; } default: { lwlog_err("Colorspace Not Support.\n"); return -1; } } p_pic_in->i_pts = i; ret = x264_encoder_encode(p_handle, &p_nals, &i_nal, p_pic_in, p_pic_out); if (ret < 0) { lwlog_err("x264_encoder_encode error"); return -1; } lwlog_info("Succeed encode frame: %5d\n", i); for (j = 0; j < i_nal; ++j) { fwrite(p_nals[j].p_payload, 1, p_nals[j].i_payload, fp_dst); } } i = 0; //flush encoder while (1) { ret = x264_encoder_encode(p_handle, &p_nals, &i_nal, NULL, p_pic_out); if (0 == ret) { break; } lwlog_info("Flush 1 frame."); for (j = 0; j < i_nal; ++j) { fwrite(p_nals[j].p_payload, 1, p_nals[j].i_payload, fp_dst); } ++i; } x264_picture_clean(p_pic_in); x264_encoder_close(p_handle); p_handle = NULL; free(p_pic_in); free(p_pic_out); free(p_param); fclose(fp_src); fclose(fp_dst); return 0; }
jlong Java_com_H264_H264Encoder_CompressBegin(JNIEnv* env,jobject thiz, jint width,jint height, jint FrameRate, jbyteArray filename){ en = (Encoder *) malloc(sizeof(Encoder)); en->param = (x264_param_t *) malloc(sizeof(x264_param_t)); en->picture = (x264_picture_t *) malloc(sizeof(x264_picture_t)); opt = (cli_opt_t *)malloc(sizeof(cli_opt_t)); //test nalcount=0; last_pts = 0; i_frame= 0; //test x264_nal_t *headers; int i_nal; jbyte * fname = (jbyte*)(*env)->GetByteArrayElements(env, filename, 0); mp4_output.open_file( fname, &opt->hout, &output_opt ); x264_param_default(en->param); // default param en->param->i_log_level = X264_LOG_NONE; en->param->i_width = width; // frame width en->param->i_height = height; // frame height en->param->rc.i_lookahead =0; en->param->i_bframe=0; en->param->i_fps_num =FrameRate; en->param->i_fps_den = 1; en->param->i_frame_reference=5; en->param->i_bframe_adaptive=1; en->param->b_vfr_input=1; en->param->i_timebase_num = 1; en->param->i_timebase_den = FrameRate; en->param->i_csp =X264_CSP_I420; en->param->analyse.b_psnr = 1; en->param->analyse.b_ssim = 1; int frames = 0; en->param->i_frame_total = 0; /////// // Intra refres: en->param->i_keyint_max = 30; en->param->b_intra_refresh = 1; //Rate control: en->param->rc.f_rf_constant = 25; en->param->rc.f_rf_constant_max = 35; //For streaming: en->param->b_repeat_headers = 0; en->param->b_annexb = 0; /////// uv = en->param->i_width * en->param->i_height; if ((en->handle = x264_encoder_open(en->param)) == 0) { return 0; } x264_encoder_parameters( en->handle, en->param ); /* Create a new pic */ x264_picture_alloc(en->picture, X264_CSP_I420, en->param->i_width, en->param->i_height); mp4_output.set_param(opt->hout,en->param); ticks_per_frame = (int64_t)en->param->i_timebase_den * en->param->i_fps_den / en->param->i_timebase_num / en->param->i_fps_num; ticks_per_frame = X264_MAX( ticks_per_frame, 1 ); __android_log_print(ANDROID_LOG_INFO, "H264Encoder native", "ticks_per_frame:%d",ticks_per_frame); if(x264_encoder_headers( en->handle, &headers, &i_nal)<0) ; __android_log_print(ANDROID_LOG_INFO, "H264Encoder native", "encoder header:%d",i_nal); mp4_output.write_headers(opt->hout, headers); (*env)->ReleaseByteArrayElements(env,filename,fname,0); return (jlong) en; }
bool CX264VideoEncoder::Init (void) { if (m_push != NULL) { delete m_push; m_push = NULL; } double rate; rate = TimestampTicks / Profile()->GetFloatValue(CFG_VIDEO_FRAME_RATE); m_frame_time = (Duration)rate; m_push = new CTimestampPush(6); #ifdef OUTPUT_RAW m_outfile = fopen("raw.h264", FOPEN_WRITE_BINARY); #endif if (Profile()->GetBoolValue(CFG_X264_FORCE_BASELINE)) { Profile()->SetBoolValue(CFG_VIDEO_USE_B_FRAMES, false); Profile()->SetBoolValue(CFG_X264_USE_CABAC, false); Profile()->SetBoolValue(CFG_X264_USE_PSNR, false); Profile()->SetBoolValue(CFG_X264_USE_SSIM, false); Profile()->SetBoolValue(CFG_X264_USE_8x8_DCT, false); Profile()->SetBoolValue(CFG_X264_USE_VBV, true); if (Profile()->GetIntegerValue(CFG_VIDEO_BIT_RATE) > 768) { Profile()->SetIntegerValue(CFG_VIDEO_BIT_RATE, 768); } } x264_param_default(&m_param); m_param.i_width = Profile()->m_videoWidth; m_param.i_height = Profile()->m_videoHeight; m_param.vui.i_sar_width = Profile()->GetIntegerValue(CFG_X264_SAR_WIDTH); m_param.vui.i_sar_height = Profile()->GetIntegerValue(CFG_X264_SAR_HEIGHT); m_param.i_fps_num = (int)((Profile()->GetFloatValue(CFG_VIDEO_FRAME_RATE) + .5) * 1000); m_param.i_fps_den = 1000; //m_param.i_maxframes = 0; m_key_frame_count = m_param.i_keyint_max = (int)(Profile()->GetFloatValue(CFG_VIDEO_FRAME_RATE) * Profile()->GetFloatValue(CFG_VIDEO_KEY_FRAME_INTERVAL)); if (Profile()->GetBoolValue(CFG_VIDEO_USE_B_FRAMES)) { m_param.i_bframe = Profile()->GetIntegerValue(CFG_VIDEO_NUM_OF_B_FRAMES); } else { m_param.i_bframe = 0; } //debug_message("h264 b frames %d", m_param.i_bframe); m_param.rc.i_bitrate = Profile()->GetIntegerValue(CFG_VIDEO_BIT_RATE); #ifndef HAVE_X264_PARAM_T_RC_I_RC_METHOD m_param.rc.b_cbr = Profile()->GetBoolValue(CFG_X264_USE_CBR) ? 1 : 0; #else m_param.rc.i_rc_method = X264_RC_ABR; #endif m_param.rc.f_rate_tolerance = Profile()->GetFloatValue(CFG_X264_BIT_RATE_TOLERANCE); const char *level = Profile()->GetStringValue(CFG_X264_LEVEL); if(level != NULL && *level != '\0') { if( strstr( level, "1b" ) ) { m_param.i_level_idc = 1; } else { if( atof(level) < 6 ) m_param.i_level_idc = (int)(10*atof(level)+.5); else m_param.i_level_idc = atoi(level); } } const char *partitions = Profile()->GetStringValue(CFG_X264_PARTITIONS); if(partitions != NULL) { m_param.analyse.inter = 0; if( strstr( partitions, "none" ) ) m_param.analyse.inter = 0; if( strstr( partitions, "all" ) ) m_param.analyse.inter = ~0; if( strstr( partitions, "i4x4" ) ) m_param.analyse.inter |= X264_ANALYSE_I4x4; if( strstr( partitions, "i8x8" ) ) m_param.analyse.inter |= X264_ANALYSE_I8x8; if( strstr( partitions, "p8x8" ) ) m_param.analyse.inter |= X264_ANALYSE_PSUB16x16; if( strstr( partitions, "p4x4" ) ) m_param.analyse.inter |= X264_ANALYSE_PSUB8x8; if( strstr( partitions, "b8x8" ) ) m_param.analyse.inter |= X264_ANALYSE_BSUB16x16; } const char *me = Profile()->GetStringValue(CFG_X264_ME); if(me != NULL) { x264_parse_enum( me, x264_motion_est_names, &m_param.analyse.i_me_method ); } m_param.analyse.i_me_range = Profile()->GetIntegerValue(CFG_X264_ME_RANGE); m_param.analyse.i_subpel_refine = Profile()->GetIntegerValue(CFG_X264_SUBME); if (Profile()->GetBoolValue(CFG_X264_USE_VBV)) { if (Profile()->GetBoolValue(CFG_X264_FORCE_BASELINE)) { switch(m_param.i_level_idc) { case 10: if (Profile()->GetIntegerValue(CFG_X264_VBV_MAXRATE) > 64) { Profile()->SetIntegerValue(CFG_X264_VBV_MAXRATE, 64); } if (Profile()->GetIntegerValue(CFG_X264_VBV_BUFSIZE) > 175) { Profile()->SetIntegerValue(CFG_X264_VBV_BUFSIZE, 175); } break; case 1: // Acctually level 1b if (Profile()->GetIntegerValue(CFG_X264_VBV_MAXRATE) > 128) { Profile()->SetIntegerValue(CFG_X264_VBV_MAXRATE, 128); } if (Profile()->GetIntegerValue(CFG_X264_VBV_BUFSIZE) > 350) { Profile()->SetIntegerValue(CFG_X264_VBV_BUFSIZE, 350); } m_param.i_level_idc = 11; break; case 11: if (Profile()->GetIntegerValue(CFG_X264_VBV_MAXRATE) > 192) { Profile()->SetIntegerValue(CFG_X264_VBV_MAXRATE, 192); } if (Profile()->GetIntegerValue(CFG_X264_VBV_BUFSIZE) > 500) { Profile()->SetIntegerValue(CFG_X264_VBV_BUFSIZE, 500); } break; case 12: if (Profile()->GetIntegerValue(CFG_X264_VBV_MAXRATE) > 384) { Profile()->SetIntegerValue(CFG_X264_VBV_MAXRATE, 384); } if (Profile()->GetIntegerValue(CFG_X264_VBV_BUFSIZE) > 1000) { Profile()->SetIntegerValue(CFG_X264_VBV_BUFSIZE, 1000); } break; case 13: if (Profile()->GetIntegerValue(CFG_X264_VBV_MAXRATE) > 768) { Profile()->SetIntegerValue(CFG_X264_VBV_MAXRATE, 768); } if (Profile()->GetIntegerValue(CFG_X264_VBV_BUFSIZE) > 2000) { Profile()->SetIntegerValue(CFG_X264_VBV_BUFSIZE, 2000); } break; } } m_param.rc.i_vbv_max_bitrate = Profile()->GetIntegerValue(CFG_X264_VBV_MAXRATE); m_param.rc.i_vbv_buffer_size = Profile()->GetIntegerValue(CFG_X264_VBV_BUFSIZE); } //m_param.rc.b_stat_write = 0; //m_param.analyse.inter = 0; m_param.analyse.b_psnr = Profile()->GetBoolValue(CFG_X264_USE_PSNR) ? 1 : 0; m_param.analyse.b_ssim = Profile()->GetBoolValue(CFG_X264_USE_SSIM) ? 1 : 0; m_param.analyse.b_transform_8x8 = Profile()->GetBoolValue(CFG_X264_USE_8x8_DCT) ? 1 : 0; m_param.b_cabac = Profile()->GetBoolValue(CFG_X264_USE_CABAC) ? 1 : 0; m_param.pf_log = x264_log; m_param.i_threads = Profile()->GetIntegerValue(CFG_X264_THREADS); m_pts_add = m_param.i_bframe ? (m_param.b_bframe_pyramid ? 2 : 1) : 0; m_pts_add *= m_frame_time; debug_message("pts add "D64, m_pts_add); m_h = x264_encoder_open(&m_param); if (m_h == NULL) { error_message("Couldn't init x264 encoder"); return false; } #ifdef USE_OUR_YUV m_pic_input.i_type = X264_TYPE_AUTO; m_pic_input.i_qpplus1 = 0; m_pic_input.img.i_csp = X264_CSP_I420; #else x264_picture_alloc(&m_pic_input, X264_CSP_I420, Profile()->m_videoWidth, Profile()->m_videoHeight); #endif m_count = 0; return true; }
static int check_dct( int cpu_ref, int cpu_new ) { x264_dct_function_t dct_c; x264_dct_function_t dct_ref; x264_dct_function_t dct_asm; x264_quant_function_t qf; int ret = 0, ok, used_asm, i, interlace; DECLARE_ALIGNED_16( int16_t dct1[16][4][4] ); DECLARE_ALIGNED_16( int16_t dct2[16][4][4] ); DECLARE_ALIGNED_16( int16_t dct4[16][4][4] ); DECLARE_ALIGNED_16( int16_t dct8[4][8][8] ); x264_t h_buf; x264_t *h = &h_buf; x264_dct_init( 0, &dct_c ); x264_dct_init( cpu_ref, &dct_ref); x264_dct_init( cpu_new, &dct_asm ); memset( h, 0, sizeof(*h) ); h->pps = h->pps_array; x264_param_default( &h->param ); h->param.analyse.i_luma_deadzone[0] = 0; h->param.analyse.i_luma_deadzone[1] = 0; h->param.analyse.b_transform_8x8 = 1; for( i=0; i<6; i++ ) h->pps->scaling_list[i] = x264_cqm_flat16; x264_cqm_init( h ); x264_quant_init( h, 0, &qf ); #define TEST_DCT( name, t1, t2, size ) \ if( dct_asm.name != dct_ref.name ) \ { \ set_func_name( #name );\ used_asm = 1; \ call_c( dct_c.name, t1, buf1, buf2 ); \ call_a( dct_asm.name, t2, buf1, buf2 ); \ if( memcmp( t1, t2, size ) ) \ { \ ok = 0; \ fprintf( stderr, #name " [FAILED]\n" ); \ } \ } ok = 1; used_asm = 0; TEST_DCT( sub4x4_dct, dct1[0], dct2[0], 16*2 ); TEST_DCT( sub8x8_dct, dct1, dct2, 16*2*4 ); TEST_DCT( sub16x16_dct, dct1, dct2, 16*2*16 ); report( "sub_dct4 :" ); ok = 1; used_asm = 0; TEST_DCT( sub8x8_dct8, (void*)dct1[0], (void*)dct2[0], 64*2 ); TEST_DCT( sub16x16_dct8, (void*)dct1, (void*)dct2, 64*2*4 ); report( "sub_dct8 :" ); #undef TEST_DCT // fdct and idct are denormalized by different factors, so quant/dequant // is needed to force the coefs into the right range. dct_c.sub16x16_dct( dct4, buf1, buf2 ); dct_c.sub16x16_dct8( dct8, buf1, buf2 ); for( i=0; i<16; i++ ) { qf.quant_4x4( dct4[i], h->quant4_mf[CQM_4IY][20], h->quant4_bias[CQM_4IY][20] ); qf.dequant_4x4( dct4[i], h->dequant4_mf[CQM_4IY], 20 ); } for( i=0; i<4; i++ ) { qf.quant_8x8( dct8[i], h->quant8_mf[CQM_8IY][20], h->quant8_bias[CQM_8IY][20] ); qf.dequant_8x8( dct8[i], h->dequant8_mf[CQM_8IY], 20 ); } #define TEST_IDCT( name, src ) \ if( dct_asm.name != dct_ref.name ) \ { \ set_func_name( #name );\ used_asm = 1; \ memcpy( buf3, buf1, 32*32 ); \ memcpy( buf4, buf1, 32*32 ); \ memcpy( dct1, src, 512 ); \ memcpy( dct2, src, 512 ); \ call_c1( dct_c.name, buf3, (void*)dct1 ); \ call_a1( dct_asm.name, buf4, (void*)dct2 ); \ if( memcmp( buf3, buf4, 32*32 ) ) \ { \ ok = 0; \ fprintf( stderr, #name " [FAILED]\n" ); \ } \ call_c2( dct_c.name, buf3, (void*)dct1 ); \ call_a2( dct_asm.name, buf4, (void*)dct2 ); \ } ok = 1; used_asm = 0; TEST_IDCT( add4x4_idct, dct4 ); TEST_IDCT( add8x8_idct, dct4 ); TEST_IDCT( add16x16_idct, dct4 ); report( "add_idct4 :" ); ok = 1; used_asm = 0; TEST_IDCT( add8x8_idct8, dct8 ); TEST_IDCT( add16x16_idct8, dct8 ); report( "add_idct8 :" ); #undef TEST_IDCT ok = 1; used_asm = 0; if( dct_asm.dct4x4dc != dct_ref.dct4x4dc ) { DECLARE_ALIGNED_16( int16_t dct1[4][4] ) = {{-12, 42, 23, 67},{2, 90, 89,56},{67,43,-76,91},{56,-78,-54,1}}; DECLARE_ALIGNED_16( int16_t dct2[4][4] ) = {{-12, 42, 23, 67},{2, 90, 89,56},{67,43,-76,91},{56,-78,-54,1}}; set_func_name( "dct4x4dc" ); used_asm = 1; call_c1( dct_c.dct4x4dc, dct1 ); call_a1( dct_asm.dct4x4dc, dct2 ); if( memcmp( dct1, dct2, 32 ) ) { ok = 0; fprintf( stderr, " - dct4x4dc : [FAILED]\n" ); } call_c2( dct_c.dct4x4dc, dct1 ); call_a2( dct_asm.dct4x4dc, dct2 ); } if( dct_asm.idct4x4dc != dct_ref.idct4x4dc ) { DECLARE_ALIGNED_16( int16_t dct1[4][4] ) = {{-12, 42, 23, 67},{2, 90, 89,56},{67,43,-76,91},{56,-78,-54,1}}; DECLARE_ALIGNED_16( int16_t dct2[4][4] ) = {{-12, 42, 23, 67},{2, 90, 89,56},{67,43,-76,91},{56,-78,-54,1}}; set_func_name( "idct4x4dc" ); used_asm = 1; call_c1( dct_c.idct4x4dc, dct1 ); call_a1( dct_asm.idct4x4dc, dct2 ); if( memcmp( dct1, dct2, 32 ) ) { ok = 0; fprintf( stderr, " - idct4x4dc : [FAILED]\n" ); } call_c2( dct_c.idct4x4dc, dct1 ); call_a2( dct_asm.idct4x4dc, dct2 ); } report( "(i)dct4x4dc :" ); ok = 1; used_asm = 0; if( dct_asm.dct2x2dc != dct_ref.dct2x2dc ) { DECLARE_ALIGNED_16( int16_t dct1[2][2] ) = {{-12, 42},{2, 90}}; DECLARE_ALIGNED_16( int16_t dct2[2][2] ) = {{-12, 42},{2, 90}}; set_func_name( "dct2x2dc" ); used_asm = 1; call_c( dct_c.dct2x2dc, dct1 ); call_a( dct_asm.dct2x2dc, dct2 ); if( memcmp( dct1, dct2, 4*2 ) ) { ok = 0; fprintf( stderr, " - dct2x2dc : [FAILED]\n" ); } } if( dct_asm.idct2x2dc != dct_ref.idct2x2dc ) { DECLARE_ALIGNED_16( int16_t dct1[2][2] ) = {{-12, 42},{2, 90}}; DECLARE_ALIGNED_16( int16_t dct2[2][2] ) = {{-12, 42},{2, 90}}; set_func_name( "idct2x2dc" ); used_asm = 1; call_c( dct_c.idct2x2dc, dct1 ); call_a( dct_asm.idct2x2dc, dct2 ); if( memcmp( dct1, dct2, 4*2 ) ) { ok = 0; fprintf( stderr, " - idct2x2dc : [FAILED]\n" ); } } report( "(i)dct2x2dc :" ); x264_zigzag_function_t zigzag_c; x264_zigzag_function_t zigzag_ref; x264_zigzag_function_t zigzag_asm; DECLARE_ALIGNED_16( int16_t level1[64] ); DECLARE_ALIGNED_16( int16_t level2[64] ); #define TEST_ZIGZAG_SCAN( name, t1, t2, dct, size ) \ if( zigzag_asm.name != zigzag_ref.name ) \ { \ set_func_name( "zigzag_"#name"_%s", interlace?"field":"frame" );\ used_asm = 1; \ call_c( zigzag_c.name, t1, dct ); \ call_a( zigzag_asm.name, t2, dct ); \ if( memcmp( t1, t2, size*sizeof(int16_t) ) ) \ { \ ok = 0; \ fprintf( stderr, #name " [FAILED]\n" ); \ } \ } #define TEST_ZIGZAG_SUB( name, t1, t2, size ) \ if( zigzag_asm.name != zigzag_ref.name ) \ { \ set_func_name( "zigzag_"#name"_%s", interlace?"field":"frame" );\ used_asm = 1; \ memcpy( buf3, buf1, 16*FDEC_STRIDE ); \ memcpy( buf4, buf1, 16*FDEC_STRIDE ); \ call_c1( zigzag_c.name, t1, buf2, buf3 ); \ call_a1( zigzag_asm.name, t2, buf2, buf4 ); \ if( memcmp( t1, t2, size*sizeof(int16_t) )|| memcmp( buf3, buf4, 16*FDEC_STRIDE ) ) \ { \ ok = 0; \ fprintf( stderr, #name " [FAILED]\n" ); \ } \ call_c2( zigzag_c.name, t1, buf2, buf3 ); \ call_a2( zigzag_asm.name, t2, buf2, buf4 ); \ } interlace = 0; x264_zigzag_init( 0, &zigzag_c, 0 ); x264_zigzag_init( cpu_ref, &zigzag_ref, 0 ); x264_zigzag_init( cpu_new, &zigzag_asm, 0 ); ok = 1; used_asm = 0; TEST_ZIGZAG_SCAN( scan_8x8, level1, level2, (void*)dct1, 64 ); TEST_ZIGZAG_SCAN( scan_4x4, level1, level2, dct1[0], 16 ); TEST_ZIGZAG_SUB( sub_4x4, level1, level2, 16 ); report( "zigzag_frame :" ); interlace = 1; x264_zigzag_init( 0, &zigzag_c, 1 ); x264_zigzag_init( cpu_ref, &zigzag_ref, 1 ); x264_zigzag_init( cpu_new, &zigzag_asm, 1 ); ok = 1; used_asm = 0; TEST_ZIGZAG_SCAN( scan_8x8, level1, level2, (void*)dct1, 64 ); TEST_ZIGZAG_SCAN( scan_4x4, level1, level2, dct1[0], 16 ); TEST_ZIGZAG_SUB( sub_4x4, level1, level2, 16 ); report( "zigzag_field :" ); #undef TEST_ZIGZAG_SCAN #undef TEST_ZIGZAG_SUB return ret; }
/********************** * OpenCodec * Abre el codec ***********************/ int H264RtspEncoder::OpenCodec() { x264_param_t params; Log("-OpenCodec H264 [%dbps,%dfps]\n",bitrate,fps); // Check if (opened) return Error("Codec already opened\n"); // Reset default values x264_param_default(¶ms); // Use a defulat preset x264_param_default_preset(¶ms,"fast","zerolatency"); // Set log params.pf_log = X264_log; params.i_log_level = X264_LOG_WARNING; // Set encoding context size params.i_width = width; params.i_height = height; // Set parameters params.i_keyint_max = intraPeriod; params.i_keyint_min = 1; params.b_cabac = 1; params.i_frame_reference = 0; params.rc.i_bitrate = bitrate / 1024; params.rc.b_stat_write = 0; params.i_slice_max_size = RTPPAYLOADSIZE; params.b_sliced_threads = 0; params.rc.i_lookahead = 0; params.i_bframe = 0; //params.b_annexb = 0; params.b_repeat_headers = 1; params.i_threads = 0; params.b_vfr_input = 0; params.rc.i_qp_min = qMin; params.rc.i_qp_max = qMax; params.rc.i_qp_step = qMax-qMin; params.i_fps_num = fps; params.i_fps_den = 2; // Set profile level constrains x264_param_apply_profile(¶ms,"baseline"); // Open encoder enc = x264_encoder_open(¶ms); //Check it is correct if (!enc) return Error("Could not open h264 codec\n"); // Clean pictures memset(&pic,0,sizeof(x264_picture_t)); memset(&pic_out,0,sizeof(x264_picture_t)); //Set picture type pic.i_type = X264_TYPE_AUTO; // We are opened opened=true; // Exit return 1; }
int main(int argc, char* argv[]){ x264_param_t param; x264_t *h = NULL; x264_picture_t pic_in; x264_picture_t pic_out; x264_nal_t *nal; uint8_t *data = NULL; int widthXheight = width * height; int frame_size = width * height * 1.5; int read_sum = 0, write_sum = 0; int frames = 0; int i, rnum, i_size; x264_nal_t* pNals = NULL; x264_param_default(¶m); param.i_width = width; param.i_height = height; param.i_bframe = 3; param.i_fps_num = 25; param.i_fps_den = 1; param.b_vfr_input = 0; param.i_keyint_max = 250; param.rc.i_bitrate = 1500; param.i_scenecut_threshold = 40; param.i_level_idc = 51; x264_param_apply_profile(¶m, "high"); h = x264_encoder_open( ¶m ); // printf("param.rc.i_qp_min=%d, param.rc.i_qp_max=%d, param.rc.i_qp_step=%d param.rc.i_qp_constant=%d param.rc.i_rc_method=%d\n", // param.rc.i_qp_min, param.rc.i_qp_max, param.rc.i_qp_step, param.rc.i_qp_constant, param.rc.i_rc_method); printf("param:%s\n", x264_param2string(¶m, 1)); x264_picture_init( &pic_in ); x264_picture_alloc(&pic_in, X264_CSP_YV12, width, height); pic_in.img.i_csp = X264_CSP_YV12; pic_in.img.i_plane = 3; data = (uint8_t*)malloc(0x400000); FILE* fpr = fopen(MFILE ".yuv", "rb"); FILE* fpw1 = fopen(MFILE".szhu.h264", "wb"); // FILE* fpw2 = fopen(MFILE".h264", "wb"); if(!fpr || !fpw1 ) { printf("file open failed\n"); return -1; } while(!feof(fpr)){ rnum = fread(data, 1, frame_size, fpr); if(rnum != frame_size){ printf("read file failed\n"); break; } memcpy(pic_in.img.plane[0], data, widthXheight); memcpy(pic_in.img.plane[1], data + widthXheight, widthXheight >> 2); memcpy(pic_in.img.plane[2], data + widthXheight + (widthXheight >> 2), widthXheight >> 2); read_sum += rnum; frames ++; // printf("read frames=%d %.2fMB write:%.2fMB\n", frames, read_sum * 1.0 / 0x100000, write_sum * 1.0 / 0x100000); int i_nal; int i_frame_size = 0; if(0 && frames % 12 == 0){ pic_in.i_type = X264_TYPE_I; }else{ pic_in.i_type = X264_TYPE_AUTO; } i_frame_size = x264_encoder_encode( h, &nal, &i_nal, &pic_in, &pic_out ); if(i_frame_size <= 0){ //printf("\t!!!FAILED encode frame \n"); }else{ fwrite(nal[0].p_payload, 1, i_frame_size, fpw1); // printf("\t+++i_frame_size=%d\n", i_frame_size); write_sum += i_frame_size; } #if 0 for(i = 0; i < i_nal; i ++){ i_size = nal[i].i_payload; // fwrite(nal[i].p_payload, 1, nal[i].i_payload, fpw1); fwrite(nal[i].p_payload, 1, i_frame_size, fpw1); x264_nal_encode(h, data, &nal[i]); if(i_size != nal[i].i_payload){ printf("\t\ti_size=%d nal[i].i_payload=%d\n", i_size, nal[i].i_payload); } fwrite(data, 1, nal[i].i_payload, fpw2); } #endif } free(data); x264_picture_clean(&pic_in); x264_picture_clean(&pic_out); if(h){ x264_encoder_close(h); h = NULL; } fclose(fpw1); // fclose(fpw2); fclose(fpr); printf("h=0x%X", h); return 0; }
static int check_quant( int cpu_ref, int cpu_new ) { x264_quant_function_t qf_c; x264_quant_function_t qf_ref; x264_quant_function_t qf_a; DECLARE_ALIGNED_16( int16_t dct1[64] ); DECLARE_ALIGNED_16( int16_t dct2[64] ); DECLARE_ALIGNED_16( uint8_t cqm_buf[64] ); int ret = 0, ok, used_asm; int oks[2] = {1,1}, used_asms[2] = {0,0}; int i, i_cqm, qp; x264_t h_buf; x264_t *h = &h_buf; memset( h, 0, sizeof(*h) ); h->pps = h->pps_array; x264_param_default( &h->param ); h->param.rc.i_qp_min = 26; h->param.analyse.b_transform_8x8 = 1; for( i_cqm = 0; i_cqm < 4; i_cqm++ ) { if( i_cqm == 0 ) { for( i = 0; i < 6; i++ ) h->pps->scaling_list[i] = x264_cqm_flat16; h->param.i_cqm_preset = h->pps->i_cqm_preset = X264_CQM_FLAT; } else if( i_cqm == 1 ) { for( i = 0; i < 6; i++ ) h->pps->scaling_list[i] = x264_cqm_jvt[i]; h->param.i_cqm_preset = h->pps->i_cqm_preset = X264_CQM_JVT; } else { if( i_cqm == 2 ) for( i = 0; i < 64; i++ ) cqm_buf[i] = 10 + rand() % 246; else for( i = 0; i < 64; i++ ) cqm_buf[i] = 1; for( i = 0; i < 6; i++ ) h->pps->scaling_list[i] = cqm_buf; h->param.i_cqm_preset = h->pps->i_cqm_preset = X264_CQM_CUSTOM; } x264_cqm_init( h ); x264_quant_init( h, 0, &qf_c ); x264_quant_init( h, cpu_ref, &qf_ref ); x264_quant_init( h, cpu_new, &qf_a ); #define INIT_QUANT8() \ { \ static const int scale1d[8] = {32,31,24,31,32,31,24,31}; \ int x, y; \ for( y = 0; y < 8; y++ ) \ for( x = 0; x < 8; x++ ) \ { \ unsigned int scale = (255*scale1d[y]*scale1d[x])/16; \ dct1[y*8+x] = dct2[y*8+x] = (rand()%(2*scale+1))-scale; \ } \ } #define INIT_QUANT4() \ { \ static const int scale1d[4] = {4,6,4,6}; \ int x, y; \ for( y = 0; y < 4; y++ ) \ for( x = 0; x < 4; x++ ) \ { \ unsigned int scale = 255*scale1d[y]*scale1d[x]; \ dct1[y*4+x] = dct2[y*4+x] = (rand()%(2*scale+1))-scale; \ } \ } #define TEST_QUANT_DC( name, cqm ) \ if( qf_a.name != qf_ref.name ) \ { \ set_func_name( #name ); \ used_asms[0] = 1; \ for( qp = 51; qp > 0; qp-- ) \ { \ for( i = 0; i < 16; i++ ) \ dct1[i] = dct2[i] = (rand() & 0x1fff) - 0xfff; \ call_c1( qf_c.name, (void*)dct1, h->quant4_mf[CQM_4IY][qp][0], h->quant4_bias[CQM_4IY][qp][0] ); \ call_a1( qf_a.name, (void*)dct2, h->quant4_mf[CQM_4IY][qp][0], h->quant4_bias[CQM_4IY][qp][0] ); \ if( memcmp( dct1, dct2, 16*2 ) ) \ { \ oks[0] = 0; \ fprintf( stderr, #name "(cqm=%d): [FAILED]\n", i_cqm ); \ break; \ } \ call_c2( qf_c.name, (void*)dct1, h->quant4_mf[CQM_4IY][qp][0], h->quant4_bias[CQM_4IY][qp][0] ); \ call_a2( qf_a.name, (void*)dct2, h->quant4_mf[CQM_4IY][qp][0], h->quant4_bias[CQM_4IY][qp][0] ); \ } \ } #define TEST_QUANT( qname, block, w ) \ if( qf_a.qname != qf_ref.qname ) \ { \ set_func_name( #qname ); \ used_asms[0] = 1; \ for( qp = 51; qp > 0; qp-- ) \ { \ INIT_QUANT##w() \ call_c1( qf_c.qname, (void*)dct1, h->quant##w##_mf[block][qp], h->quant##w##_bias[block][qp] ); \ call_a1( qf_a.qname, (void*)dct2, h->quant##w##_mf[block][qp], h->quant##w##_bias[block][qp] ); \ if( memcmp( dct1, dct2, w*w*2 ) ) \ { \ oks[0] = 0; \ fprintf( stderr, #qname "(qp=%d, cqm=%d, block="#block"): [FAILED]\n", qp, i_cqm ); \ break; \ } \ call_c2( qf_c.qname, (void*)dct1, h->quant##w##_mf[block][qp], h->quant##w##_bias[block][qp] ); \ call_a2( qf_a.qname, (void*)dct2, h->quant##w##_mf[block][qp], h->quant##w##_bias[block][qp] ); \ } \ } TEST_QUANT( quant_8x8, CQM_8IY, 8 ); TEST_QUANT( quant_8x8, CQM_8PY, 8 ); TEST_QUANT( quant_4x4, CQM_4IY, 4 ); TEST_QUANT( quant_4x4, CQM_4PY, 4 ); TEST_QUANT_DC( quant_4x4_dc, **h->quant4_mf[CQM_4IY] ); TEST_QUANT_DC( quant_2x2_dc, **h->quant4_mf[CQM_4IC] ); #define TEST_DEQUANT( qname, dqname, block, w ) \ if( qf_a.dqname != qf_ref.dqname ) \ { \ set_func_name( "%s_%s", #dqname, i_cqm?"cqm":"flat" ); \ used_asms[1] = 1; \ for( qp = 51; qp > 0; qp-- ) \ { \ INIT_QUANT##w() \ call_c( qf_c.qname, (void*)dct1, h->quant##w##_mf[block][qp], h->quant##w##_bias[block][qp] ); \ memcpy( dct2, dct1, w*w*2 ); \ call_c1( qf_c.dqname, (void*)dct1, h->dequant##w##_mf[block], qp ); \ call_a1( qf_a.dqname, (void*)dct2, h->dequant##w##_mf[block], qp ); \ if( memcmp( dct1, dct2, w*w*2 ) ) \ { \ oks[1] = 0; \ fprintf( stderr, #dqname "(qp=%d, cqm=%d, block="#block"): [FAILED]\n", qp, i_cqm ); \ break; \ } \ call_c2( qf_c.dqname, (void*)dct1, h->dequant##w##_mf[block], qp ); \ call_a2( qf_a.dqname, (void*)dct2, h->dequant##w##_mf[block], qp ); \ } \ } TEST_DEQUANT( quant_8x8, dequant_8x8, CQM_8IY, 8 ); TEST_DEQUANT( quant_8x8, dequant_8x8, CQM_8PY, 8 ); TEST_DEQUANT( quant_4x4, dequant_4x4, CQM_4IY, 4 ); TEST_DEQUANT( quant_4x4, dequant_4x4, CQM_4PY, 4 ); x264_cqm_delete( h ); } ok = oks[0]; used_asm = used_asms[0]; report( "quant :" ); ok = oks[1]; used_asm = used_asms[1]; report( "dequant :" ); if( qf_a.denoise_dct != qf_ref.denoise_dct ) { int size; for( size = 16; size <= 64; size += 48 ) { set_func_name( "denoise_dct" ); used_asm = 1; memcpy(dct1, buf1, size*2); memcpy(dct2, buf1, size*2); memcpy(buf3+256, buf3, 256); call_c1( qf_c.denoise_dct, dct1, (uint32_t*)buf3, (uint16_t*)buf2, size ); call_a1( qf_a.denoise_dct, dct2, (uint32_t*)(buf3+256), (uint16_t*)buf2, size ); if( memcmp( dct1, dct2, size*2 ) || memcmp( buf3+4, buf3+256+4, (size-1)*sizeof(uint32_t) ) ) ok = 0; call_c2( qf_c.denoise_dct, dct1, (uint32_t*)buf3, (uint16_t*)buf2, size ); call_a2( qf_a.denoise_dct, dct2, (uint32_t*)(buf3+256), (uint16_t*)buf2, size ); } } report( "denoise dct :" ); return ret; }