X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=encoder%2Fencoder.c;h=4692d3ca5aca6dc76c310ce50f119c15bc34f004;hb=35a05f459dbdf46a7918aefcdd5166d32b104261;hp=79997b96ef82fda8838e1eaeeeb7551a3d1aa651;hpb=f04062e6380cbe10453dab33a3575c373e63ff9b;p=x264 diff --git a/encoder/encoder.c b/encoder/encoder.c index 79997b96..4692d3ca 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -1,7 +1,7 @@ /***************************************************************************** * encoder.c: top-level encoder functions ***************************************************************************** - * Copyright (C) 2003-2015 x264 project + * Copyright (C) 2003-2016 x264 project * * Authors: Laurent Aimar * Loren Merritt @@ -1249,6 +1249,8 @@ static int x264_validate_parameters( x264_t *h, int b_open ) h->param.rc.f_qblur = 0; if( h->param.rc.f_complexity_blur < 0 ) h->param.rc.f_complexity_blur = 0; + if( h->param.sc.i_buffer_size < 0 || h->param.sc.f_speed <= 0 ) + h->param.sc.i_buffer_size = 0; h->param.i_sps_id &= 31; @@ -1270,6 +1272,8 @@ static int x264_validate_parameters( x264_t *h, int b_open ) if( h->param.i_nal_hrd == X264_NAL_HRD_CBR ) h->param.rc.b_filler = 1; + h->param.sc.max_preset = x264_clip3( h->param.sc.max_preset, 1, SC_PRESETS ); + /* 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 ); @@ -1409,7 +1413,7 @@ x264_t *x264_encoder_open( x264_param_t *param ) { x264_t *h; char buf[1000], *p; - int qp, i_slicetype_length; + int i_slicetype_length; CHECKED_MALLOCZERO( h, sizeof(x264_t) ); @@ -1550,6 +1554,10 @@ x264_t *x264_encoder_open( x264_param_t *param ) mbcmp_init( h ); chroma_dsp_init( h ); + if( h->param.sc.i_buffer_size ) + x264_speedcontrol_new( h ); + + p = buf + sprintf( buf, "using cpu capabilities:" ); for( int i = 0; x264_cpu_names[i].flags; i++ ) { @@ -1576,15 +1584,8 @@ x264_t *x264_encoder_open( x264_param_t *param ) p += sprintf( p, " none!" ); x264_log( h, X264_LOG_INFO, "%s\n", buf ); - float *logs = x264_analyse_prepare_costs( h ); - if( !logs ) - goto fail; - for( qp = X264_MIN( h->param.rc.i_qp_min, QP_MAX_SPEC ); qp <= h->param.rc.i_qp_max; qp++ ) - if( x264_analyse_init_costs( h, logs, qp ) ) - goto fail; - if( x264_analyse_init_costs( h, logs, X264_LOOKAHEAD_QP ) ) + if( x264_analyse_init_costs( h ) ) goto fail; - x264_free( logs ); static const uint16_t cost_mv_correct[7] = { 24, 47, 95, 189, 379, 757, 1515 }; /* Checks for known miscompilation issues. */ @@ -1958,22 +1959,10 @@ static int x264_encoder_encapsulate_nals( x264_t *h, int start ) for( int i = start; i < h->out.i_nal; i++ ) { - int old_payload_len = h->out.nal[i].i_payload; h->out.nal[i].b_long_startcode = !i || h->out.nal[i].i_type == NAL_SPS || h->out.nal[i].i_type == NAL_PPS || h->param.i_avcintra_class; x264_nal_encode( h, nal_buffer, &h->out.nal[i] ); nal_buffer += h->out.nal[i].i_payload; - if( h->param.i_avcintra_class ) - { - h->out.nal[i].i_padding -= h->out.nal[i].i_payload - (old_payload_len + NALU_OVERHEAD); - if( h->out.nal[i].i_padding > 0 ) - { - memset( nal_buffer, 0, h->out.nal[i].i_padding ); - nal_buffer += h->out.nal[i].i_padding; - h->out.nal[i].i_payload += h->out.nal[i].i_padding; - } - h->out.nal[i].i_padding = X264_MAX( h->out.nal[i].i_padding, 0 ); - } } x264_emms(); @@ -3346,7 +3335,7 @@ int x264_encoder_encode( x264_t *h, if( x264_threadpool_wait_all( h ) < 0 ) return -1; - if( h->i_frame == h->i_thread_frames - 1 ) + if( h->i_frame == 0 ) h->i_reordered_pts_delay = h->fenc->i_reordered_pts; if( h->reconfig ) { @@ -3704,6 +3693,10 @@ int x264_encoder_encode( x264_t *h, overhead += h->out.nal[h->out.i_nal-1].i_payload + h->out.nal[h->out.i_nal-1].i_padding + SEI_OVERHEAD; } + /* Init the speed control */ + if( h->param.sc.i_buffer_size ) + x264_speedcontrol_frame( h ); + /* Init the rate control */ /* FIXME: Include slice header bit cost. */ x264_ratecontrol_start( h, h->fenc->i_qpplus1, overhead*8 ); @@ -3837,21 +3830,32 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current, * We don't know the size of the last slice until encapsulation so we add filler to the encapsulated NAL */ if( h->param.i_avcintra_class ) { - x264_t *h0 = h->thread[0]; - int ret = x264_check_encapsulated_buffer( h, h0, h->out.i_nal, frame_size, frame_size + filler ); - if( ret < 0 ) + if( x264_check_encapsulated_buffer( h, h->thread[0], h->out.i_nal, frame_size, frame_size + filler ) < 0 ) return -1; - memset( h->out.nal[0].p_payload + frame_size, 0, filler ); - h->out.nal[h->out.i_nal-1].i_payload += filler; - h->out.nal[h->out.i_nal-1].i_padding = filler; + + x264_nal_t *nal = &h->out.nal[h->out.i_nal-1]; + memset( nal->p_payload + nal->i_payload, 0, filler ); + nal->i_payload += filler; + nal->i_padding = filler; frame_size += filler; + + /* Fix up the size header for mp4/etc */ + if( !h->param.b_annexb ) + { + /* Size doesn't include the size of the header we're writing now. */ + uint8_t *nal_data = nal->p_payload; + int chunk_size = nal->i_payload - 4; + nal_data[0] = chunk_size >> 24; + nal_data[1] = chunk_size >> 16; + nal_data[2] = chunk_size >> 8; + nal_data[3] = chunk_size >> 0; + } } else { while( filler > 0 ) { - int f, overhead; - overhead = (FILLER_OVERHEAD - h->param.b_annexb); + int f, overhead = FILLER_OVERHEAD - h->param.b_annexb; if( h->param.i_slice_max_size && filler > h->param.i_slice_max_size ) { int next_size = filler - h->param.i_slice_max_size; @@ -3883,6 +3887,9 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current, x264_noise_reduction_update( h ); + if( h->param.sc.i_buffer_size ) + x264_speedcontrol_frame_end( h ); + /* ---------------------- Compute/Print statistics --------------------- */ x264_thread_sync_stat( h, h->thread[0] ); @@ -3962,13 +3969,13 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current, { pic_out->prop.f_ssim = h->stat.frame.f_ssim / h->stat.frame.i_ssim_cnt; h->stat.f_ssim_mean_y[h->sh.i_type] += pic_out->prop.f_ssim * dur; - snprintf( psz_message + strlen(psz_message), 80 - strlen(psz_message), - " SSIM Y:%.5f", pic_out->prop.f_ssim ); + int msg_len = strlen(psz_message); + snprintf( psz_message + msg_len, 80 - msg_len, " SSIM Y:%.5f", pic_out->prop.f_ssim ); } psz_message[79] = '\0'; x264_log( h, X264_LOG_DEBUG, - "frame=%4d QP=%.2f NAL=%d Slice:%c Poc:%-3d I:%-4d P:%-4d SKIP:%-4d size=%d bytes%s\n", + "frame=%4d QP=%.2f NAL=%d Slice:%c Poc:%-3d I:%-4d P:%-4d SKIP:%-4d size=%d bytes%s\n", h->i_frame, h->fdec->f_qp_avg_aq, h->i_nal_ref_idc, @@ -4335,6 +4342,7 @@ void x264_encoder_close ( x264_t *h ) /* rc */ x264_ratecontrol_delete( h ); + x264_speedcontrol_delete( h ); /* param */ if( h->param.rc.psz_stat_out )