📄 encoder.c
字号:
{
x264_log( h, X264_LOG_ERROR, "invalid width x height (%dx%d)\n",
h->param.i_width, h->param.i_height );
return -1;
}
if( h->param.i_width % 2 || h->param.i_height % 2 )
{
x264_log( h, X264_LOG_ERROR, "width or height not divisible by 2 (%dx%d)\n",
h->param.i_width, h->param.i_height );
return -1;
}
if( h->param.i_csp != X264_CSP_I420 )
{
x264_log( h, X264_LOG_ERROR, "invalid CSP (only I420 supported)\n" );
return -1;
}
if( h->param.i_threads == 0 )
h->param.i_threads = 1;//x264_cpu_num_processors();
// h->param.i_threads = x264_clip3( h->param.i_threads, 1, X264_SLICE_MAX );//del
// h->param.i_threads = X264_MIN( h->param.i_threads, (h->param.i_height + 15) / 16 );//del
/*#ifndef HAVE_PTHREAD
if( h->param.i_threads > 1 )
{
x264_log( h, X264_LOG_WARNING, "not compiled with pthread support!\n");
x264_log( h, X264_LOG_WARNING, "multislicing anyway, but you won't see any speed gain.\n" );
}
#endif*///del
if( h->param.rc.i_rc_method < 0 || h->param.rc.i_rc_method > 2 )
{
x264_log( h, X264_LOG_ERROR, "invalid RC method\n" );
return -1;
}
h->param.rc.i_rf_constant = x264_clip3( h->param.rc.i_rf_constant, 0, 51 );
h->param.rc.i_qp_constant = x264_clip3( h->param.rc.i_qp_constant, 0, 51 );
if( h->param.rc.i_rc_method == X264_RC_CRF )
h->param.rc.i_qp_constant = h->param.rc.i_rf_constant;
if( (h->param.rc.i_rc_method == X264_RC_CQP || h->param.rc.i_rc_method == X264_RC_CRF)
&& h->param.rc.i_qp_constant == 0 )
{
h->mb.b_lossless = 1;
h->param.i_cqm_preset = X264_CQM_FLAT;
h->param.psz_cqm_file = NULL;
h->param.rc.i_rc_method = X264_RC_CQP;
h->param.rc.f_ip_factor = 1;
h->param.rc.f_pb_factor = 1;
h->param.analyse.b_transform_8x8 = 0;
h->param.analyse.b_psnr = 0;
h->param.analyse.i_chroma_qp_offset = 0;
h->param.analyse.i_trellis = 0;
h->param.analyse.b_fast_pskip = 0;
h->param.analyse.i_noise_reduction = 0;
h->param.analyse.i_subpel_refine = x264_clip3( h->param.analyse.i_subpel_refine, 1, 6 );
}
if( ( h->param.i_width % 16 || h->param.i_height % 16 ) && !h->mb.b_lossless )
{
x264_log( h, X264_LOG_WARNING,
"width or height not divisible by 16 (%dx%d), compression will suffer.\n",
h->param.i_width, h->param.i_height );
}
h->param.i_frame_reference = x264_clip3( h->param.i_frame_reference, 1, 16 );
if( h->param.i_keyint_max <= 0 )
h->param.i_keyint_max = 1;
h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );
h->param.i_bframe = x264_clip3( h->param.i_bframe, 0, X264_BFRAME_MAX );
h->param.i_bframe_bias = x264_clip3( h->param.i_bframe_bias, -90, 100 );
h->param.b_bframe_pyramid = h->param.b_bframe_pyramid && h->param.i_bframe > 1;
h->param.b_bframe_adaptive = h->param.b_bframe_adaptive && h->param.i_bframe > 0;
h->param.analyse.b_weighted_bipred = h->param.analyse.b_weighted_bipred && h->param.i_bframe > 0;
h->mb.b_direct_auto_write = h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_AUTO
&& h->param.i_bframe
&& ( h->param.rc.b_stat_write || !h->param.rc.b_stat_read );
h->param.i_deblocking_filter_alphac0 = x264_clip3( h->param.i_deblocking_filter_alphac0, -6, 6 );
h->param.i_deblocking_filter_beta = x264_clip3( h->param.i_deblocking_filter_beta, -6, 6 );
h->param.i_cabac_init_idc = x264_clip3( h->param.i_cabac_init_idc, 0, 2 );
if( h->param.i_cqm_preset < X264_CQM_FLAT || h->param.i_cqm_preset > X264_CQM_CUSTOM )
h->param.i_cqm_preset = X264_CQM_FLAT;
if( h->param.analyse.i_me_method < X264_ME_DIA ||
h->param.analyse.i_me_method > X264_ME_ESA )
h->param.analyse.i_me_method = X264_ME_HEX;
if( h->param.analyse.i_me_range < 4 )
h->param.analyse.i_me_range = 4;
if( h->param.analyse.i_me_range > 16 && h->param.analyse.i_me_method <= X264_ME_HEX )
h->param.analyse.i_me_range = 16;
h->param.analyse.i_subpel_refine = x264_clip3( h->param.analyse.i_subpel_refine, 1, 7 );
h->param.analyse.b_bframe_rdo = h->param.analyse.b_bframe_rdo && h->param.analyse.i_subpel_refine >= 6;
h->param.analyse.b_mixed_references = h->param.analyse.b_mixed_references && h->param.i_frame_reference > 1;
h->param.analyse.inter &= X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16|
X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
h->param.analyse.intra &= X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
if( !(h->param.analyse.inter & X264_ANALYSE_PSUB16x16) )
h->param.analyse.inter &= ~X264_ANALYSE_PSUB8x8;
if( !h->param.analyse.b_transform_8x8 )
{
h->param.analyse.inter &= ~X264_ANALYSE_I8x8;
h->param.analyse.intra &= ~X264_ANALYSE_I8x8;
}
h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);
/* if( !h->param.b_cabac )
h->param.analyse.i_trellis = 0;*/
h->param.analyse.i_trellis = x264_clip3( h->param.analyse.i_trellis, 0, 2 );
h->param.analyse.i_noise_reduction = x264_clip3( h->param.analyse.i_noise_reduction, 0, 1<<16 );
{
const x264_level_t *l = x264_levels;
while( l->level_idc != 0 && l->level_idc != h->param.i_level_idc )
l++;
if( l->level_idc == 0 )
{
x264_log( h, X264_LOG_ERROR, "invalid level_idc: %d\n", h->param.i_level_idc );
return -1;
}
if( h->param.analyse.i_mv_range <= 0 )
h->param.analyse.i_mv_range = l->mv_range;
else
h->param.analyse.i_mv_range = x264_clip3(h->param.analyse.i_mv_range, 32, 2048);
}
if( h->param.rc.f_qblur < 0 )
h->param.rc.f_qblur = 0;
if( h->param.rc.f_complexity_blur < 0 )
h->param.rc.f_complexity_blur = 0;
h->param.i_sps_id &= 31;
/* ensure the booleans are 0 or 1 so they can be used in math */
#define BOOLIFY(x) h->param.x = !!h->param.x
/// BOOLIFY( b_cabac );
BOOLIFY( b_deblocking_filter );
BOOLIFY( analyse.b_transform_8x8 );
BOOLIFY( analyse.b_bidir_me );
BOOLIFY( analyse.b_chroma_me );
BOOLIFY( analyse.b_fast_pskip );
BOOLIFY( rc.b_stat_write );
BOOLIFY( rc.b_stat_read );
#undef BOOLIFY
return 0;
}
/****************************************************************************
* x264_encoder_open:
****************************************************************************/
x264_t *x264_encoder_open ( x264_param_t *param )
{
x264_t *h = x264_malloc( sizeof( x264_t ) );
int i;
memset( h, 0, sizeof( x264_t ) );
/* Create a copy of param */
memcpy( &h->param, param, sizeof( x264_param_t ) );
if( x264_validate_parameters( h ) < 0 )
{
x264_free( h );
return NULL;
}
if( h->param.psz_cqm_file )
if( x264_cqm_parse_file( h, h->param.psz_cqm_file ) < 0 )
{
x264_free( h );
return NULL;
}
/*@Pan:
if( h->param.rc.psz_stat_out )
h->param.rc.psz_stat_out = strdup( h->param.rc.psz_stat_out );
if( h->param.rc.psz_stat_in )
h->param.rc.psz_stat_in = strdup( h->param.rc.psz_stat_in );
if( h->param.rc.psz_rc_eq )
h->param.rc.psz_rc_eq = strdup( h->param.rc.psz_rc_eq );
*/
if( h->param.rc.psz_stat_out ){
int strSz = strlen(h->param.rc.psz_stat_out)+1;
h->param.rc.psz_stat_out = (char *)malloc(strSz);
}
if( h->param.rc.psz_stat_in ){
int strSz = strlen( h->param.rc.psz_stat_in )+1;
h->param.rc.psz_stat_in = (char *)malloc(strSz);
}
if( h->param.rc.psz_rc_eq ){
int strSz = strlen(h->param.rc.psz_rc_eq )+1;
h->param.rc.psz_rc_eq = (char *)malloc(strSz);
}
/* VUI */
if( h->param.vui.i_sar_width > 0 && h->param.vui.i_sar_height > 0 )
{
int i_w = param->vui.i_sar_width;
int i_h = param->vui.i_sar_height;
x264_reduce_fraction( &i_w, &i_h );
while( i_w > 65535 || i_h > 65535 )
{
i_w /= 2;
i_h /= 2;
}
h->param.vui.i_sar_width = 0;
h->param.vui.i_sar_height = 0;
if( i_w == 0 || i_h == 0 )
{
x264_log( h, X264_LOG_WARNING, "cannot create valid sample aspect ratio\n" );
}
else
{
x264_log( h, X264_LOG_INFO, "using SAR=%d/%d\n", i_w, i_h );
h->param.vui.i_sar_width = i_w;
h->param.vui.i_sar_height = i_h;
}
}
x264_reduce_fraction( &h->param.i_fps_num, &h->param.i_fps_den );
/* Init x264_t */
h->out.i_nal = 0;
h->out.i_bitstream = X264_MAX( 1000000, h->param.i_width * h->param.i_height * 1.7
* ( h->param.rc.i_rc_method == X264_RC_ABR ? pow( 0.5, h->param.rc.i_qp_min )
: pow( 0.5, h->param.rc.i_qp_constant ) * X264_MAX( 1, h->param.rc.f_ip_factor )));
h->out.p_bitstream = x264_malloc( h->out.i_bitstream );
h->i_frame = 0;
h->i_frame_num = 0;
h->i_idr_pic_id = 0;
h->sps = &h->sps_array[0];
x264_sps_init( h->sps, h->param.i_sps_id, &h->param );
h->pps = &h->pps_array[0];
x264_pps_init( h->pps, h->param.i_sps_id, &h->param, h->sps);
x264_validate_levels( h );
x264_cqm_init( h );
h->mb.i_mb_count = h->sps->i_mb_width * h->sps->i_mb_height;
/* Init frames. */
h->frames.i_delay = h->param.i_bframe;
h->frames.i_max_ref0 = h->param.i_frame_reference;
h->frames.i_max_ref1 = h->sps->vui.i_num_reorder_frames;
h->frames.i_max_dpb = h->sps->vui.i_max_dec_frame_buffering + 1;
h->frames.b_have_lowres = !h->param.rc.b_stat_read
&& ( h->param.rc.i_rc_method == X264_RC_ABR
|| h->param.rc.i_rc_method == X264_RC_CRF
|| h->param.b_bframe_adaptive );
for( i = 0; i < X264_BFRAME_MAX + 3; i++ )
{
h->frames.current[i] = NULL;
h->frames.next[i] = NULL;
h->frames.unused[i] = NULL;
}
for( i = 0; i < 1 + h->frames.i_delay; i++ )
{
h->frames.unused[i] = x264_frame_new( h );
if( !h->frames.unused[i] )
return NULL;
}
for( i = 0; i < h->frames.i_max_dpb; i++ )
{
h->frames.reference[i] = x264_frame_new( h );
if( !h->frames.reference[i] )
return NULL;
}
h->frames.reference[h->frames.i_max_dpb] = NULL;
h->frames.i_last_idr = - h->param.i_keyint_max;
h->frames.i_input = 0;
h->frames.last_nonb = NULL;
h->i_ref0 = 0;
h->i_ref1 = 0;
h->fdec = h->frames.reference[0];
if( x264_macroblock_cache_init( h ) < 0 )
return NULL;
/// x264_rdo_init( );
/* init CPU functions */
x264_predict_16x16_init( h->param.cpu, h->predict_16x16 );
x264_predict_8x8c_init( h->param.cpu, h->predict_8x8c );
x264_predict_8x8_init( h->param.cpu, h->predict_8x8 );
x264_predict_4x4_init( h->param.cpu, h->predict_4x4 );
x264_pixel_init( h->param.cpu, &h->pixf );
x264_dct_init( h->param.cpu, &h->dctf );
x264_mc_init( h->param.cpu, &h->mc );
x264_csp_init( h->param.cpu, h->param.i_csp, &h->csp );
x264_quant_init( h, h->param.cpu, &h->quantf );
x264_deblock_init( h->param.cpu, &h->loopf );
memcpy( h->pixf.mbcmp,
( h->mb.b_lossless || h->param.analyse.i_subpel_refine <= 1 ) ? h->pixf.sad : h->pixf.satd,
sizeof(h->pixf.mbcmp) );
/* rate control */
if( x264_ratecontrol_new( h ) < 0 )
return NULL;
x264_log( h, X264_LOG_INFO, "using cpu capabilities %s%s%s%s%s%s\n",
param->cpu&X264_CPU_MMX ? "MMX " : "",
param->cpu&X264_CPU_MMXEXT ? "MMXEXT " : "",
param->cpu&X264_CPU_SSE ? "SSE " : "",
param->cpu&X264_CPU_SSE2 ? "SSE2 " : "",
param->cpu&X264_CPU_3DNOW ? "3DNow! " : "",
param->cpu&X264_CPU_ALTIVEC ? "Altivec " : "" );
h->thread[0] = h;
h->i_thread_num = 0;
for( i = 1; i < h->param.i_threads; i++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -