rendered paste bodyIndex: contrib/Jamfile===================================================================--- contrib/Jamfile (revision 1259)+++ contrib/Jamfile (working copy)@@ -347,9 +347,12 @@ { LIBX264_PATCH += " $(PATCH) -p1 < ../patch-x264-solaris.patch && " ; }-# AQ is temporarily disabled LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-aq.patch && " ;+ # AQ is temporarily disabled LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-aq.patch && " ; LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-idr.patch && " ;+ LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-vbv-1pass.patch && " ; LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-vbv-2pass.patch && " ;+ # VAQ .48 Patch (Dark_Shikari) + LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-vaq48.patch && " ; Depends $(<) : $(>) ; Depends lib : $(<) ; }Index: contrib/patch-x264-vaq48.patch===================================================================--- contrib/patch-x264-vaq48.patch (revision 0)+++ contrib/patch-x264-vaq48.patch (revision 0)@@ -0,0 +1,300 @@+Index: encoder/ratecontrol.h+===================================================================+--- encoder/ratecontrol.h (revision 736)++++ encoder/ratecontrol.h (working copy)+@@ -34,6 +34,7 @@+ int x264_ratecontrol_qp( x264_t * );+ void x264_ratecontrol_end( x264_t *, int bits );+ void x264_ratecontrol_summary( x264_t * );++void x264_adaptive_quant ( x264_t * );+ + #endif+ +Index: encoder/encoder.c+===================================================================+--- encoder/encoder.c (revision 736)++++ encoder/encoder.c (working copy)+@@ -401,6 +401,7 @@+ 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 );++ h->param.analyse.b_aq = 0;+ }+ if( h->param.rc.i_rc_method == X264_RC_CQP )+ {+@@ -475,6 +476,10 @@+ 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.b_aq = h->param.analyse.b_aq && h->param.analyse.f_aq_strength > 0;++ /* VAQ on static sensitivity mode effectively replaces qcomp, so qcomp is raised towards 1 to compensate. */++ if(h->param.analyse.b_aq && h->param.analyse.f_aq_sensitivity != 0) ++ h->param.rc.f_qcompress = x264_clip3f(h->param.rc.f_qcompress + h->param.analyse.f_aq_strength * 0.4 / 0.28, 0, 1);+ h->param.analyse.i_noise_reduction = x264_clip3( h->param.analyse.i_noise_reduction, 0, 1<<16 );+ + {+Index: encoder/ratecontrol.c+===================================================================+--- encoder/ratecontrol.c (revision 736)++++ encoder/ratecontrol.c (working copy)+@@ -127,6 +127,10 @@+ predictor_t *pred_b_from_p; /* predict B-frame size from P-frame satd */+ int bframes; /* # consecutive B-frames before this P-frame */+ int bframe_bits; /* total cost of those frames */++ ++ /* AQ stuff */++ float aq_threshold;++ int *ac_energy;+ + int i_zones;+ x264_zone_t *zones;+@@ -169,7 +173,97 @@+ + rce->misc_bits;+ }+ ++// Find the total AC energy of the block in all planes.++static int ac_energy_mb( x264_t *h, int mb_x, int mb_y, int *satd )++{++ DECLARE_ALIGNED( static uint8_t, flat[16], 16 ) = {128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128};++// DECLARE_ALIGNED( static uint8_t, flat[16], 16 );++ unsigned int var=0, sad, ssd, i;++ for( i=0; i<3; i++ )++ {++ int w = i ? 8 : 16;++ int stride = h->fenc->i_stride[i];++ int offset = h->mb.b_interlaced++ ? w * (mb_x + (mb_y&~1) * stride) + (mb_y&1) * stride++ : w * (mb_x + mb_y * stride);++ int pix = i ? PIXEL_8x8 : PIXEL_16x16;++ stride <<= h->mb.b_interlaced;++ sad = h->pixf.sad[pix](flat, 0, h->fenc->plane[i]+offset, stride);++ ssd = h->pixf.ssd[pix](flat, 0, h->fenc->plane[i]+offset, stride);++ var += ssd - (sad * sad >> (i?6:8));++ // SATD to represent the block's overall complexity (bit cost) for intra encoding.++ // exclude the DC coef, because nothing short of an actual intra prediction will estimate DC cost.++ if( var && satd )++ *satd += h->pixf.satd[pix](flat, 0, h->fenc->plane[i]+offset, stride) - sad/2;++ }++ return var;++}++ ++void x264_autosense_aq( x264_t *h )++{++ double total = 0;++ double n = 0;++ int mb_x, mb_y;++ /* FIXME: Some of the SATDs might be already calculated elsewhere (ratecontrol?). Can we reuse them? */++ /* FIXME: Is chroma SATD necessary? */++ for( mb_y=0; mb_y<h->sps->i_mb_height; mb_y++ )++ for( mb_x=0; mb_x<h->sps->i_mb_width; mb_x++ )++ {++ int energy, satd=0;++ energy = ac_energy_mb( h, mb_x, mb_y, &satd );++ h->rc->ac_energy[mb_x + mb_y * h->sps->i_mb_width] = energy;++ /* Weight the energy value by the SATD value of the MB. This represents the fact that++ the more complex blocks in a frame should be weighted more when calculating the optimal sensitivity. ++ This also helps diminish the negative effect of large numbers of simple blocks in a frame, such as in the case++ of a letterboxed film. */++ if( energy )++ {++ x264_cpu_restore(h->param.cpu);++ total += logf(energy) * satd;++ n += satd;++ }++ }++ x264_cpu_restore(h->param.cpu);++ /* Calculate and store the threshold. */++ h->rc->aq_threshold = n ? total/n : 15;++}+ ++/*****************************************************************************++* x264_adaptive_quant:++ * adjust macroblock QP based on variance (AC energy) of the MB.++ * high variance = higher QP++ * low variance = lower QP++ * This generally increases SSIM and lowers PSNR.++*****************************************************************************/++void x264_adaptive_quant( x264_t *h )++{++ int qp = h->mb.i_qp;++ int energy;++ x264_cpu_restore(h->param.cpu);++ if(h->param.analyse.f_aq_sensitivity != 0)++ energy = ac_energy_mb( h, h->mb.i_mb_x, h->mb.i_mb_y, NULL );++ else++ energy = h->rc->ac_energy[h->mb.i_mb_xy];++ if(energy == 0)++ {++ h->mb.i_qp = h->mb.i_last_qp;++ }++ else++ {++ x264_cpu_restore(h->param.cpu);++ float result = energy;++ /* Adjust the QP based on the AC energy of the macroblock. */++ float qp_adj = 3 * (logf(result) - h->rc->aq_threshold);++ if(h->param.analyse.f_aq_sensitivity == 0) qp_adj = x264_clip3f(qp_adj, -5, 5);++ int new_qp = x264_clip3(qp + qp_adj * h->param.analyse.f_aq_strength + .5, h->param.rc.i_qp_min, h->param.rc.i_qp_max);++ /* If the QP of this MB is within 1 of the previous MB, code the same QP as the previous MB,++ * to lower the bit cost of the qp_delta. */++ if(abs(new_qp - h->mb.i_last_qp) == 1) new_qp = h->mb.i_last_qp;++ h->mb.i_qp = new_qp;++ }++ h->mb.i_chroma_qp = i_chroma_qp_table[x264_clip3( h->mb.i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )];++}+++ int x264_ratecontrol_new( x264_t *h )+ {+ x264_ratecontrol_t *rc;+@@ -244,7 +338,7 @@+ rc->rate_tolerance = 0.01;+ }+ +- h->mb.b_variable_qp = rc->b_vbv && !rc->b_2pass;++ h->mb.b_variable_qp = (rc->b_vbv && !rc->b_2pass) || h->param.analyse.b_aq;+ + if( rc->b_abr )+ {+@@ -458,10 +552,13 @@+ x264_free( p );+ }+ +- for( i=1; i<h->param.i_threads; i++ )++ for( i=0; i<h->param.i_threads; i++ )+ {+ h->thread[i]->rc = rc+i;+- rc[i] = rc[0];++ if( i )++ rc[i] = rc[0];++ if( h->param.analyse.b_aq )++ rc[i].ac_energy = x264_malloc( h->mb.i_mb_count * sizeof(int) );+ }+ + return 0;+@@ -623,6 +720,8 @@+ x264_free( rc->zones[i].param );+ x264_free( rc->zones );+ }++ for( i=0; i<h->param.i_threads; i++ )++ x264_free( rc[i].ac_energy );+ x264_free( rc );+ }+ +@@ -729,6 +828,15 @@+ + if( h->sh.i_type != SLICE_TYPE_B )+ rc->last_non_b_pict_type = h->sh.i_type;++ ++ /* Adaptive AQ sensitivity algorithm. */++ if( h->param.analyse.b_aq )++ {++ if( h->param.analyse.f_aq_sensitivity > 0 ) ++ h->rc->aq_threshold = logf(powf(h->param.analyse.f_aq_sensitivity,4)/2); //FIXME simplify++ else++ x264_autosense_aq(h);++ }+ }+ + double predict_row_size( x264_t *h, int y, int qp )+Index: encoder/analyse.c+===================================================================+--- encoder/analyse.c (revision 736)++++ encoder/analyse.c (working copy)+@@ -2047,8 +2047,13 @@+ int i_cost = COST_MAX;+ int i;+ +- /* init analysis */+- x264_mb_analyse_init( h, &analysis, x264_ratecontrol_qp( h ) );++ h->mb.i_qp = x264_ratecontrol_qp( h );++ ++ if( h->param.analyse.b_aq )++ x264_adaptive_quant( h );++ ++ /* init analysis */++ x264_mb_analyse_init( h, &analysis, h->mb.i_qp );+ + /*--------------------------- Do the analysis ---------------------------*/+ if( h->sh.i_type == SLICE_TYPE_I )+Index: x264.c+===================================================================+--- x264.c (revision 736)++++ x264.c (working copy)+@@ -244,6 +244,14 @@+ " - 2: enabled on all mode decisions\n", defaults->analyse.i_trellis );+ H0( " --no-fast-pskip Disables early SKIP detection on P-frames\n" );+ H0( " --no-dct-decimate Disables coefficient thresholding on P-frames\n" );++ H0( " --aq-strength <float> Amount to adjust QP/lambda per MB [%.1f]\n"++ " 0.0: no AQ\n"++ " 1.0: medium AQ\n", defaults->analyse.f_aq_strength );++ H0( " --aq-sensitivity <float> \"Center\" of AQ curve. [%.1f]\n"++ " 0: automatic sensitivity (avoids moving bits between frames)\n"++ " 10: most QPs are raised\n"++ " 20: good general-use sensitivity\n"++ " 30: most QPs are lowered\n", defaults->analyse.f_aq_sensitivity );+ H0( " --nr <integer> Noise reduction [%d]\n", defaults->analyse.i_noise_reduction );+ H1( "\n" );+ H1( " --deadzone-inter <int> Set the size of the inter luma quantization deadzone [%d]\n", defaults->analyse.i_luma_deadzone[0] );+@@ -407,6 +415,8 @@+ { "trellis", required_argument, NULL, 't' },+ { "no-fast-pskip", no_argument, NULL, 0 },+ { "no-dct-decimate", no_argument, NULL, 0 },++ { "aq-strength", required_argument, NULL, 0 },++ { "aq-sensitivity", required_argument, NULL, 0 },+ { "deadzone-inter", required_argument, NULL, '0' },+ { "deadzone-intra", required_argument, NULL, '0' },+ { "level", required_argument, NULL, 0 },+Index: common/common.c+===================================================================+--- common/common.c (revision 736)++++ common/common.c (working copy)+@@ -123,6 +123,9 @@+ param->analyse.i_chroma_qp_offset = 0;+ param->analyse.b_fast_pskip = 1;+ param->analyse.b_dct_decimate = 1;++ param->analyse.b_aq = 1;++ param->analyse.f_aq_strength = 0.5;++ param->analyse.f_aq_sensitivity = 13;+ param->analyse.i_luma_deadzone[0] = 21;+ param->analyse.i_luma_deadzone[1] = 11;+ param->analyse.b_psnr = 1;+@@ -455,6 +458,13 @@+ p->analyse.b_fast_pskip = atobool(value);+ OPT("dct-decimate")+ p->analyse.b_dct_decimate = atobool(value);++ OPT("aq-strength")++ {++ p->analyse.f_aq_strength = atof(value);++ p->analyse.b_aq = 1;++ }++ OPT("aq-sensitivity")++ p->analyse.f_aq_sensitivity = atof(value);+ OPT("deadzone-inter")+ p->analyse.i_luma_deadzone[0] = atoi(value);+ OPT("deadzone-intra")+@@ -883,6 +893,10 @@+ s += sprintf( s, " ip_ratio=%.2f", p->rc.f_ip_factor );+ if( p->i_bframe )+ s += sprintf( s, " pb_ratio=%.2f", p->rc.f_pb_factor );++ if( p->analyse.b_aq )++ s += sprintf( s, " aq=1:%.1f:%.1f", p->analyse.f_aq_strength, p->analyse.f_aq_sensitivity );++ else++ s += sprintf( s, " aq=0" );+ if( p->rc.psz_zones )+ s += sprintf( s, " zones=%s", p->rc.psz_zones );+ else if( p->rc.i_zones )+Index: x264.h+===================================================================+--- x264.h (revision 736)++++ x264.h (working copy)+@@ -232,6 +232,9 @@+ int i_trellis; /* trellis RD quantization */+ int b_fast_pskip; /* early SKIP detection on P-frames */+ int b_dct_decimate; /* transform coefficient thresholding on P-frames */++ int b_aq; /* psy adaptive QP */++ float f_aq_strength;++ float f_aq_sensitivity;+ int i_noise_reduction; /* adaptive pseudo-deadzone */+ + /* the deadzone size that will be used in luma quantization */+Index: contrib/patch-x264-vbv-1pass.patch===================================================================--- contrib/patch-x264-vbv-1pass.patch (revision 0)+++ contrib/patch-x264-vbv-1pass.patch (revision 0)@@ -0,0 +1,107 @@+Index: encoder/ratecontrol.c+===================================================================+--- encoder/ratecontrol.c (revision 736)++++ encoder/ratecontrol.c (working copy)+@@ -762,6 +899,15 @@+ return bits;+ }+ ++double row_bits_so_far( x264_t *h, int y )++{++ int i;++ double bits = 0;++ for( i = 0; i <= y; i++ )++ bits += h->fdec->i_row_bits[i];++ return bits;++}+++ void x264_ratecontrol_mb( x264_t *h, int bits )+ {+ x264_ratecontrol_t *rc = h->rc;+@@ -783,10 +929,10 @@+ /* B-frames shouldn't use lower QP than their reference frames */+ if( y < h->sps->i_mb_height-1 )+ {+- rc->qpm = X264_MAX( rc->qp,+- X264_MIN( h->fref0[0]->i_row_qp[y+1],+- h->fref1[0]->i_row_qp[y+1] ));++ int avg_qp = (h->fref0[0]->i_row_qp[y+1]+h->fref1[0]->i_row_qp[y+1])*0.5+rc->pb_offset * ((h->fenc->i_type == X264_TYPE_BREF) ? 0.5 : 1);++ rc->qpm = X264_MAX( rc->qp, avg_qp);+ }++ //printf("Frame: %d QP: %d PrevQP: %d NextQP: %d NewQP: %d\n",h->i_frame,rc->qp,h->fref0[0]->i_row_qp[y+1],h->fref1[0]->i_row_qp[y+1],rc->qpm);+ }+ else+ {+@@ -800,13 +946,47 @@+ int b1 = b0;+ int i_qp_max = X264_MIN( prev_row_qp + h->param.rc.i_qp_step, h->param.rc.i_qp_max );+ int i_qp_min = X264_MAX( prev_row_qp - h->param.rc.i_qp_step, h->param.rc.i_qp_min );+- float buffer_left_planned = rc->buffer_fill - rc->frame_size_planned;++ float actual_size_planned = rc->frame_size_planned;++ /* Don't modify the row QPs until a suffient amount of the bits of the frame have been processed, in case a flat */++ /* area at the top of the frame was measured inaccurately. */++ if(row_bits_so_far(h,y) < 0.15 * actual_size_planned)++ {++ return;++ }++ /* If this frame is a P-frame, make sure it isn't too large. */++ if(h->sh.i_type != SLICE_TYPE_I)++ {++ /*if(actual_size_planned > 2 * rc->buffer_rate)++ {++ float min_size = 2 * rc->buffer_rate;++ actual_size_planned *= powf(min_size/actual_size_planned,0.8);++ }*/++ }++ /* If this frame is an I-frame and isn't too large, don't run the rest of row MBRC */++ else if(b1 < rc->buffer_fill * 0.6)++ {++ /* If the current row is higher QP than the frame QP, try lowering the QP */++ if(h->fdec->i_row_qp[0] < rc->qpm)++ {++ while(b1 < rc->buffer_fill * 0.6 && rc->qpm > h->fdec->i_row_qp[0])++ {++ rc->qpm--;++ b1 = predict_row_size_sum( h, y, rc->qpm );++ }++ return;++ }++ else++ return;++ }++ /* Don't let I-frames take up more than 60% of the remaining buffer. */++ else actual_size_planned = rc->buffer_fill * 0.6;++ float buffer_left_planned = rc->buffer_fill - actual_size_planned;+ + if( !rc->b_vbv_min_rate )+ i_qp_min = X264_MAX( i_qp_min, h->sh.i_qp );+ + while( rc->qpm < i_qp_max+- && (b1 > rc->frame_size_planned * 1.15++ && (b1 > actual_size_planned * 1.15+ || (rc->buffer_fill - b1 < buffer_left_planned * 0.5)))+ {+ rc->qpm ++;+@@ -814,8 +994,8 @@+ }+ + while( rc->qpm > i_qp_min+- && buffer_left_planned > rc->buffer_size * 0.4+- && ((b1 < rc->frame_size_planned * 0.8 && rc->qpm <= prev_row_qp)++ && ((buffer_left_planned > rc->buffer_size * 0.4) || rc->qpm > h->fdec->i_row_qp[0])++ && ((b1 < actual_size_planned * 0.8 && rc->qpm <= prev_row_qp)+ || b1 < (rc->buffer_fill - rc->buffer_size + rc->buffer_rate) * 1.1) )+ {+ rc->qpm --;+@@ -1191,8 +1373,8 @@+ ( pict_type == SLICE_TYPE_P ||+ ( pict_type == SLICE_TYPE_I && rcc->last_non_b_pict_type == SLICE_TYPE_I ) ) )+ {+- if( rcc->buffer_fill/rcc->buffer_size < 0.5 )+- q /= x264_clip3f( 2.0*rcc->buffer_fill/rcc->buffer_size, 0.5, 1.0 );++ float filled = 1.0 - rcc->buffer_fill/rcc->buffer_size;++ q *= (1/0.544331054) / pow(2 - filled,1.5);+ }+ + if( rcc->b_vbv && rcc->last_satd > 0 )+