All pastes #1544530 Raw Edit

x264_OreAQ12.mod.1235.diff NOT W

public diff v1 · immutable
#1544530 ·published 2009-08-27 10:33 UTC
rendered paste body
diff -NdurwBE x264-oreaqtest3/common/common.c x264-oreaqtest4/common/common.c--- x264-oreaqtest3/common/common.c	2009-08-27 11:07:37 +0300+++ x264-oreaqtest4/common/common.c	2009-08-27 12:07:48 +0300@@ -95,8 +95,27 @@     param->rc.f_pb_factor = 1.3;     param->rc.i_aq_mode = X264_AQ_VARIANCE;     param->rc.i_aq_metric = 0;-    param->rc.f_aq_strength = 1.0;+    param->rc.f_aq_strength = 0.5;+    param->rc.f_aq_strength_up[0] = 0;+    param->rc.f_aq_strength_up[1] = 0;+    param->rc.f_aq_strength_up[2] = 0;+    param->rc.f_aq_strength_up[3] = 0;+    param->rc.f_aq_strength_down[0] = 0;+    param->rc.f_aq_strength_down[1] = 0;+    param->rc.f_aq_strength_down[2] = 0;+    param->rc.f_aq_strength_down[3] = 0;     param->rc.f_aq_sensitivity = 10;+    param->rc.f_aq_ifactor[0] = 1.0;+    param->rc.f_aq_ifactor[1] = 1.0;+    param->rc.f_aq_pfactor[0] = 1.0;+    param->rc.f_aq_pfactor[1] = 1.0;+    param->rc.f_aq_bfactor[0] = 1.0;+    param->rc.f_aq_bfactor[1] = 1.0;+    param->rc.b_aq_boundary = 0;+    param->rc.i_aq_boundary[0] = 192;+    param->rc.i_aq_boundary[1] = 64;+    param->rc.i_aq_boundary[2] = 24;+    param->rc.b_aq_debug = 0;     param->rc.i_lookahead = 40;      param->rc.b_stat_write = 0;@@ -581,9 +600,90 @@     OPT("aq-metric")         p->rc.i_aq_metric = atoi(value);     OPT("aq-strength")-        p->rc.f_aq_strength = atof(value);+    {+        if( 7 == sscanf( value, "%f:%f:%f:%f:%f:%f:%f",+                         &p->rc.f_aq_strength_up[0], &p->rc.f_aq_strength_down[0], &p->rc.f_aq_strength_up[1], &p->rc.f_aq_strength_down[1],+                         &p->rc.f_aq_strength_up[2], &p->rc.f_aq_strength_down[2], &p->rc.f_aq_strength_up[3] ) ||+            7 == sscanf( value, "%f,%f,%f,%f,%f,%f,%f",+                         &p->rc.f_aq_strength_up[0], &p->rc.f_aq_strength_down[0], &p->rc.f_aq_strength_up[1], &p->rc.f_aq_strength_down[1],+                         &p->rc.f_aq_strength_up[2], &p->rc.f_aq_strength_down[2], &p->rc.f_aq_strength_up[3] ) )+        {+            p->rc.f_aq_strength = 0.0;+        }+        else if( 2 == sscanf( value, "%f:%f", &p->rc.f_aq_strength_up[0], &p->rc.f_aq_strength_down[0] ) ||+                 2 == sscanf( value, "%f,%f", &p->rc.f_aq_strength_up[0], &p->rc.f_aq_strength_down[0] ) )+        {+            p->rc.f_aq_strength = 0.0;+            for( i=1; i<4; i++ )+            {+                p->rc.f_aq_strength_up[i] = p->rc.f_aq_strength_up[0];+                p->rc.f_aq_strength_down[i] = p->rc.f_aq_strength_down[0];+            }+        }+        else if( sscanf( value, "%f", &p->rc.f_aq_strength ) )+        {+            for( i=0; i<4; i++ )+            {+                p->rc.f_aq_strength_up[i] = p->rc.f_aq_strength;+                p->rc.f_aq_strength_down[i] = p->rc.f_aq_strength;+            }+        }+    }     OPT("aq-sensitivity")         p->rc.f_aq_sensitivity = atof(value);+    OPT("aq-ifactor")+        if( 2 == sscanf( value, "%f:%f", &p->rc.f_aq_ifactor[0], &p->rc.f_aq_ifactor[1] ) ||+            2 == sscanf( value, "%f,%f", &p->rc.f_aq_ifactor[0], &p->rc.f_aq_ifactor[1] ) )+        { }+        else if( sscanf( value, "%f", &p->rc.f_aq_ifactor[0] ) )+        {+            p->rc.f_aq_ifactor[1] = p->rc.f_aq_ifactor[0];+        }+        else+        {+            p->rc.f_aq_ifactor[1] = p->rc.f_aq_ifactor[0] = 1.0;+        }+    OPT("aq-pfactor")+        if( 2 == sscanf( value, "%f:%f", &p->rc.f_aq_pfactor[0], &p->rc.f_aq_pfactor[1] ) ||+            2 == sscanf( value, "%f,%f", &p->rc.f_aq_pfactor[0], &p->rc.f_aq_pfactor[1] ) )+        { }+        else if( sscanf( value, "%f", &p->rc.f_aq_pfactor[0] ) )+        {+            p->rc.f_aq_pfactor[1] = p->rc.f_aq_pfactor[0];+        }+        else+        {+            p->rc.f_aq_pfactor[1] = p->rc.f_aq_pfactor[0] = 1.0;+        }+    OPT("aq-bfactor")+        if( 2 == sscanf( value, "%f:%f", &p->rc.f_aq_bfactor[0], &p->rc.f_aq_bfactor[1] ) ||+            2 == sscanf( value, "%f,%f", &p->rc.f_aq_bfactor[0], &p->rc.f_aq_bfactor[1] ) )+        { }+        else if( sscanf( value, "%f", &p->rc.f_aq_bfactor[0] ) )+        {+            p->rc.f_aq_bfactor[1] = p->rc.f_aq_bfactor[0];+        }+        else+        {+            p->rc.f_aq_bfactor[1] = p->rc.f_aq_bfactor[0] = 1.0;+        }+    OPT("aq-boundary")+    {+        if( 3 == sscanf( value, "%d:%d:%d", &p->rc.i_aq_boundary[0], &p->rc.i_aq_boundary[1], &p->rc.i_aq_boundary[2] ) ||+            3 == sscanf( value, "%d,%d,%d", &p->rc.i_aq_boundary[0], &p->rc.i_aq_boundary[1], &p->rc.i_aq_boundary[2] ) )+        {+            p->rc.b_aq_boundary = 1;+        }+        else+        {+            p->rc.i_aq_boundary[0] = p->rc.i_aq_boundary[1] = p->rc.i_aq_boundary[2] = 0;+        }+    }+    OPT("aq-debug")+    {+        p->rc.b_aq_debug = 1;+        p->rc.psz_aq_debug_name = strdup(value);+    }     OPT("pass")     {         int i = x264_clip3( atoi(value), 0, 3 );@@ -933,7 +1033,17 @@             s += sprintf( s, " pb_ratio=%.2f", p->rc.f_pb_factor );         s += sprintf( s, " aq=%d", p->rc.i_aq_mode );         if( p->rc.i_aq_mode )-            s += sprintf( s, ":%d:%.2f:%.2f", p->rc.i_aq_metric, p->rc.f_aq_strength, p->rc.f_aq_sensitivity );+        {+            s += sprintf( s, " aq-strength=%.2f:%.2f:%.2f:%.2f:%.2f:%.2f:%.2f",+                          p->rc.f_aq_strength_up[0], p->rc.f_aq_strength_down[0], p->rc.f_aq_strength_up[1], p->rc.f_aq_strength_down[1],+                          p->rc.f_aq_strength_up[2], p->rc.f_aq_strength_down[2], p->rc.f_aq_strength_up[3] );+            s += sprintf( s, " aq-sensitivity=%.2f", p->rc.f_aq_sensitivity );+            s += sprintf( s, " aq-ifactor=%.2f:%.2f", p->rc.f_aq_ifactor[0], p->rc.f_aq_ifactor[1] );+            s += sprintf( s, " aq-pfactor=%.2f:%.2f", p->rc.f_aq_pfactor[0], p->rc.f_aq_pfactor[1] );+            s += sprintf( s, " aq-bfactor=%.2f:%.2f", p->rc.f_aq_bfactor[0], p->rc.f_aq_bfactor[1] );+            s += sprintf( s, " aq-metric=%d", p->rc.i_aq_metric );+            s += sprintf( s, " aq-boundary=%d:%d:%d", p->rc.i_aq_boundary[0], p->rc.i_aq_boundary[1], p->rc.i_aq_boundary[2] );+        }         if( p->rc.psz_zones )             s += sprintf( s, " zones=%s", p->rc.psz_zones );         else if( p->rc.i_zones )diff -NdurwBE x264-oreaqtest3/common/common.h x264-oreaqtest4/common/common.h--- x264-oreaqtest3/common/common.h	2009-08-27 11:38:19 +0300+++ x264-oreaqtest4/common/common.h	2009-08-27 11:52:20 +0300@@ -653,6 +653,13 @@             /* Metrics */             int64_t i_ssd[3];             double f_ssim;++            /* AQ stats per frame */+            uint64_t i_aq_count[4];+            uint64_t i_aq_result[4][3];+            uint64_t i_aq_change[101];+            int i_aq_change_min;+            int i_aq_change_max;         } frame;          /* Cumulated stats */@@ -678,7 +685,13 @@         /* */         int     i_direct_score[2];         int     i_direct_frames[2];-+        /* */+        uint64_t i_aq_count_total;+        uint64_t i_aq_count[4];+        uint64_t i_aq_result[4][3];+        uint64_t i_aq_change[101];+        int i_aq_change_min;+        int i_aq_change_max;     } stat;      void *scratch_buffer; /* for any temporary storage that doesn't want repeated malloc */diff -NdurwBE x264-oreaqtest3/common/frame.c x264-oreaqtest4/common/frame.c--- x264-oreaqtest3/common/frame.c	2009-08-27 11:38:19 +0300+++ x264-oreaqtest4/common/frame.c	2009-08-27 12:12:29 +0300@@ -144,6 +144,7 @@     {         CHECKED_MALLOC( frame->f_qp_offset, h->mb.i_mb_count * sizeof(float) );         CHECKED_MALLOC( frame->f_qp_offset_aq, h->mb.i_mb_count * sizeof(float) );+        CHECKED_MALLOC( frame->i_aq_type, h->mb.i_mb_count * sizeof(int) );         if( h->frames.b_have_lowres )             /* shouldn't really be initialized, just silences a valgrind false-positive in x264_mbtree_propagate_cost_sse2 */             CHECKED_MALLOCZERO( frame->i_inv_qscale_factor, (h->mb.i_mb_count+3) * sizeof(uint16_t) );@@ -185,6 +186,7 @@             x264_free( frame->lowres_inter_types[j][i] );         }     x264_free( frame->f_qp_offset );+    x264_free( frame->i_aq_type );     x264_free( frame->f_qp_offset_aq );     x264_free( frame->i_inv_qscale_factor );     x264_free( frame->i_row_bits );diff -NdurwBE x264-oreaqtest3/common/frame.h x264-oreaqtest4/common/frame.h--- x264-oreaqtest3/common/frame.h	2009-08-27 11:38:19 +0300+++ x264-oreaqtest4/common/frame.h	2009-08-27 12:13:30 +0300@@ -86,6 +86,7 @@     int     *i_row_bits;     int     *i_row_qp;     float   *f_qp_offset;+    int     *i_aq_type;        // OreAQ mode type     float   *f_qp_offset_aq;     int     b_intra_calculated;     uint16_t *i_intra_cost;diff -NdurwBE x264-oreaqtest3/common/pixel.c x264-oreaqtest4/common/pixel.c--- x264-oreaqtest3/common/pixel.c	2009-08-27 11:38:19 +0300+++ x264-oreaqtest4/common/pixel.c	2009-08-27 12:14:35 +0300@@ -67,6 +67,14 @@ PIXEL_SAD_C( x264_pixel_sad_4x8,    4,  8 ) PIXEL_SAD_C( x264_pixel_sad_4x4,    4,  4 ) +static int x264_pixel_count_8x8( uint8_t *pix, int i_pix, uint32_t threshold )+{+    int x, y, sum = 0;+    for( y=0; y<8; y++, pix += i_pix )+        for( x=0; x<8; x++ )+            sum += pix[x] > (uint8_t)threshold;+    return sum;+}  /****************************************************************************  * pixel_ssd_WxH@@ -643,6 +651,7 @@     pixf->ssim_4x4x2_core = ssim_4x4x2_core;     pixf->ssim_end4 = ssim_end4;     pixf->var2_8x8 = pixel_var2_8x8;+    pixf->count_8x8 = x264_pixel_count_8x8;  #ifdef HAVE_MMX     if( cpu&X264_CPU_MMX )diff -NdurwBE x264-oreaqtest3/common/pixel.h x264-oreaqtest4/common/pixel.h--- x264-oreaqtest3/common/pixel.h	2009-08-27 11:38:19 +0300+++ x264-oreaqtest4/common/pixel.h	2009-08-27 11:52:20 +0300@@ -93,6 +93,8 @@     int (*ads[7])( int enc_dc[4], uint16_t *sums, int delta,                    uint16_t *cost_mvx, int16_t *mvs, int width, int thresh ); +    int (*count_8x8)( uint8_t *pix, int i_pix, uint32_t threshold );+     /* calculate satd or sad of V, H, and DC modes.      * may be NULL, in which case just use pred+satd instead. */     void (*intra_mbcmp_x3_16x16)( uint8_t *fenc, uint8_t *fdec  , int res[3] );diff -NdurwBE x264-oreaqtest3/encoder/encoder.c x264-oreaqtest4/encoder/encoder.c--- x264-oreaqtest3/encoder/encoder.c	2009-08-27 11:12:43 +0300+++ x264-oreaqtest4/encoder/encoder.c	2009-08-27 12:20:19 +0300@@ -365,6 +365,8 @@  static int x264_validate_parameters( x264_t *h ) {+    int i;+ #ifdef HAVE_MMX     if( !(x264_cpu_detect() & X264_CPU_SSE) )     {@@ -632,11 +634,46 @@     h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);     h->param.rc.i_aq_mode = x264_clip3( h->param.rc.i_aq_mode, 0, 2 );     h->param.rc.f_aq_strength = x264_clip3f( h->param.rc.f_aq_strength, 0, 3 );+    for( i=0; i<4; i++ )+    {+        h->param.rc.f_aq_strength_up[i] = x264_clip3f( h->param.rc.f_aq_strength_up[i], 0, 3 );+        h->param.rc.f_aq_strength_down[i] = x264_clip3f( h->param.rc.f_aq_strength_down[i], 0, 3 );+    }+    if( h->param.rc.f_aq_strength_up[0] == 0 && h->param.rc.f_aq_strength_down[0] == 0 &&+        h->param.rc.f_aq_strength_up[1] == 0 && h->param.rc.f_aq_strength_down[1] == 0 &&+        h->param.rc.f_aq_strength_up[2] == 0 && h->param.rc.f_aq_strength_down[2] == 0 &&+        h->param.rc.f_aq_strength_up[3] == 0 )+    {     if( h->param.rc.f_aq_strength == 0 )         h->param.rc.i_aq_mode = 0;+        else+        {+            for( i=0; i<4; i++ )+            {+                h->param.rc.f_aq_strength_up[i] = h->param.rc.f_aq_strength;+                h->param.rc.f_aq_strength_down[i] = h->param.rc.f_aq_strength;+            }+        }+    }     if( h->param.rc.f_aq_sensitivity < 0 )         h->param.rc.f_aq_sensitivity = 0;+    h->param.rc.f_aq_ifactor[0] = x264_clip3f( h->param.rc.f_aq_ifactor[0], -10, 10 );+    h->param.rc.f_aq_ifactor[1] = x264_clip3f( h->param.rc.f_aq_ifactor[1], -10, 10 );+    h->param.rc.f_aq_pfactor[0] = x264_clip3f( h->param.rc.f_aq_pfactor[0], -10, 10 );+    h->param.rc.f_aq_pfactor[1] = x264_clip3f( h->param.rc.f_aq_pfactor[1], -10, 10 );+    h->param.rc.f_aq_bfactor[0] = x264_clip3f( h->param.rc.f_aq_bfactor[0], -10, 10 );+    h->param.rc.f_aq_bfactor[1] = x264_clip3f( h->param.rc.f_aq_bfactor[1], -10, 10 );     h->param.rc.i_aq_metric = x264_clip3( h->param.rc.i_aq_metric, 0, 1 );+    h->param.rc.i_aq_boundary[0] = x264_clip3( h->param.rc.i_aq_boundary[0], 0, 255 );+    h->param.rc.i_aq_boundary[1] = x264_clip3( h->param.rc.i_aq_boundary[1], 0, 255 );+    h->param.rc.i_aq_boundary[2] = x264_clip3( h->param.rc.i_aq_boundary[2], 0, 255 );+    if( !h->param.rc.b_aq_boundary ||+        h->param.rc.i_aq_boundary[0] <= h->param.rc.i_aq_boundary[1] || h->param.rc.i_aq_boundary[1] <= h->param.rc.i_aq_boundary[2] )+    {+        h->param.rc.i_aq_boundary[0] = h->param.vui.b_fullrange ? 205 : 192;+        h->param.rc.i_aq_boundary[1] = h->param.vui.b_fullrange ? 56 : 64;+        h->param.rc.i_aq_boundary[2] = h->param.vui.b_fullrange ? 9 : 24;+    }     /* MB-tree requires AQ to be on, even if the strength is zero. */     if( !h->param.rc.i_aq_mode && h->param.rc.b_mb_tree )     {@@ -1011,6 +1048,27 @@     COPY( analyse.b_mixed_references );     COPY( analyse.f_psy_rd );     COPY( analyse.f_psy_trellis );+    COPY( rc.i_aq_mode );+    COPY( rc.i_aq_metric );+    COPY( rc.f_aq_strength );+    COPY( rc.f_aq_strength_up[0] );+    COPY( rc.f_aq_strength_up[1] );+    COPY( rc.f_aq_strength_up[2] );+    COPY( rc.f_aq_strength_up[3] );+    COPY( rc.f_aq_strength_down[0] );+    COPY( rc.f_aq_strength_down[1] );+    COPY( rc.f_aq_strength_down[2] );+    COPY( rc.f_aq_sensitivity );+    COPY( rc.f_aq_ifactor[0] );+    COPY( rc.f_aq_ifactor[1] );+    COPY( rc.f_aq_pfactor[0] );+    COPY( rc.f_aq_pfactor[1] );+    COPY( rc.f_aq_bfactor[0] );+    COPY( rc.f_aq_bfactor[1] );+    COPY( rc.b_aq_boundary );+    COPY( rc.i_aq_boundary[0] );+    COPY( rc.i_aq_boundary[1] );+    COPY( rc.i_aq_boundary[2] );     // can only twiddle these if they were enabled to begin with:     if( h->param.analyse.i_me_method >= X264_ME_ESA || param->analyse.i_me_method < X264_ME_ESA )         COPY( analyse.i_me_method );@@ -2055,6 +2113,23 @@         snprintf( psz_message + strlen(psz_message), 80 - strlen(psz_message),                   " SSIM Y:%.5f", ssim_y );     }++    if( h->param.rc.i_aq_mode )+    {+        h->stat.i_aq_count_total += h->mb.i_mb_count;+        for( i=0; i<4; i++ )+        {+            h->stat.i_aq_count[i] += h->stat.frame.i_aq_count[i];+            h->stat.i_aq_result[i][0] += h->stat.frame.i_aq_result[i][0];+            h->stat.i_aq_result[i][1] += h->stat.frame.i_aq_result[i][1];+            h->stat.i_aq_result[i][2] += h->stat.frame.i_aq_result[i][2];+        }+        for( i=h->stat.frame.i_aq_change_min+50; i<=h->stat.frame.i_aq_change_max+50; i++ )+            h->stat.i_aq_change[i] += h->stat.frame.i_aq_change[i];+        h->stat.i_aq_change_min = X264_MIN(h->stat.i_aq_change_min, h->stat.frame.i_aq_change_min);+        h->stat.i_aq_change_max = X264_MAX(h->stat.i_aq_change_max, h->stat.frame.i_aq_change_max);+    }+     psz_message[79] = '\0';      x264_log( h, X264_LOG_DEBUG,@@ -2325,6 +2400,38 @@             }         } +        if( h->param.rc.i_aq_mode )+        {+#define GET_AQ_RESULT(x) \+            h->stat.i_aq_count_total ? (100.0 / h->stat.i_aq_count_total * h->stat.i_aq_count[x]) : 0, \+            h->stat.i_aq_count[x] ? (100.0 / h->stat.i_aq_count[x] * h->stat.i_aq_result[x][0]) : 0, \+            h->stat.i_aq_count[x] ? (100.0 / h->stat.i_aq_count[x] * h->stat.i_aq_result[x][1]) : 0, \+            h->stat.i_aq_count[x] ? (100.0 / h->stat.i_aq_count[x] * h->stat.i_aq_result[x][2]) : 0+            char buf[1500];+            char *p = buf;++            x264_log( h, X264_LOG_INFO,+                "AQ Result  Bright MB:%5.2f%%  QP Up:%5.2f%% Down:%5.2f%% Even:%5.2f%%\n",+                GET_AQ_RESULT(0));++            x264_log( h, X264_LOG_INFO,+                "AQ Result  Middle MB:%5.2f%%  QP Up:%5.2f%% Down:%5.2f%% Even:%5.2f%%\n",+                GET_AQ_RESULT(1));++            x264_log( h, X264_LOG_INFO,+                "AQ Result    Dark MB:%5.2f%%  QP Up:%5.2f%% Down:%5.2f%% Even:%5.2f%%\n",+                GET_AQ_RESULT(2));++            x264_log( h, X264_LOG_INFO,+                "AQ Result  M.Dark MB:%5.2f%%  QP Up:%5.2f%% Down:%5.2f%% Even:%5.2f%%\n",+                GET_AQ_RESULT(3));++            for(i = h->stat.i_aq_change_min; i<=h->stat.i_aq_change_max; i++)+                p += sprintf(p, " %d:%.2f%%", -i, 100.0 / h->stat.i_aq_count_total * h->stat.i_aq_change[i+50]);+            x264_log( h, X264_LOG_INFO, "AQ change value %s\n", buf);++        }+         if( h->param.analyse.b_ssim )         {             x264_log( h, X264_LOG_INFO,diff -NdurwBE x264-oreaqtest3/encoder/ratecontrol.c x264-oreaqtest4/encoder/ratecontrol.c--- x264-oreaqtest3/encoder/ratecontrol.c	2009-08-27 11:28:31 +0300+++ x264-oreaqtest4/encoder/ratecontrol.c	2009-08-27 12:45:58 +0300@@ -61,7 +61,7 @@     double offset; } predictor_t; -typedef int (*x264_aq_metric_t)( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame );+typedef int (*x264_aq_metric_t)( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame, int *energy );  struct x264_ratecontrol_t {@@ -142,13 +142,16 @@     int bframe_bits;            /* total cost of those frames */      /* AQ stuff */-    x264_aq_metric_t aq_metric_func;+    float aq_threshold;+    FILE *p_aq_debug;+    void *aqlog;      int i_zones;     x264_zone_t *zones;     x264_zone_t *prev_zone; }; +#include "AQDebugLog.h"  static int parse_zones( x264_t *h ); static int init_pass2(x264_t *);@@ -185,7 +188,7 @@ }  // Find the total AC energy of the block in all planes.-static NOINLINE uint32_t ac_energy_mb( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame )+static NOINLINE int ac_energy_mb( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame, int *energy ) {     /* This function contains annoying hacks because GCC has a habit of reordering emms      * and putting it after floating point ops.  As a result, we put the emms at the end of the@@ -201,13 +204,14 @@             : w * (mb_x + mb_y * stride);         int pix = i ? PIXEL_8x8 : PIXEL_16x16;         stride <<= h->mb.b_interlaced;-        var += h->pixf.var[pix]( frame->plane[i]+offset, stride );+        energy[i] = h->pixf.var[pix]( frame->plane[i]+offset, stride );+        var += energy[i];     }     x264_emms();     return var; } -static NOINLINE int aqm_4ver0c( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame )+static NOINLINE int aqm_4ver0c( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame, int *energy ) {     DECLARE_ALIGNED_16( static uint8_t zero[17] ) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};     DECLARE_ALIGNED_16( static uint8_t avg_flat[16] );@@ -223,13 +227,148 @@         stride <<= h->mb.b_interlaced;         sad = h->pixf.sad[pix]( zero, 0, frame->plane[i]+offset, stride );         memset( avg_flat, sad >> (i?6:8), sizeof(avg_flat) );-        var += h->pixf.ssd[pix]( avg_flat, 0, frame->plane[i]+offset, stride );+        energy[i] = h->pixf.ssd[pix]( avg_flat, 0, frame->plane[i]+offset, stride );+        var += energy[i];     }     var = X264_MAX(var,1);     x264_emms();     return var; } +static NOINLINE void get_image_mb( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame, int *luma, int *bluePoint)+{+    DECLARE_ALIGNED_16( static uint8_t zero[17] ) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};+    int stride[3];+    int offset[3];+    int i;++    for( i=0; i<3; i++ )+    {+        int w = i ? 8 : 16;+        stride[i] = frame->i_stride[i];+        offset[i] = h->mb.b_interlaced+            ? w * (mb_x + (mb_y&~1) * stride[i]) + (mb_y&1) * stride[i]+            : w * (mb_x + mb_y * stride[i]);+        stride[i] <<= h->mb.b_interlaced;+    }++    *luma = h->pixf.sad[PIXEL_16x16](frame->plane[0]+offset[0], stride[0], zero, 0)>>8;+    *bluePoint =+        (h->pixf.count_8x8(frame->plane[1]+offset[1], stride[1], 0x81818181) >= 40) &&+        (h->pixf.count_8x8(frame->plane[2]+offset[2], stride[2], 0x87878787) <= 24);+}++static NOINLINE int x264_adjust_OreAQ( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame, int *energy )+{+    int mode;+    int bluePoint = 0;+    int luma = 0;+    float energy_y, energy_uv, f_qp_adj;+    uint32_t _energy_y, _energy_uv;+    int lz_y, lz_uv;++    get_image_mb( h, mb_x, mb_y, frame, &luma, &bluePoint );+    x264_emms();++    _energy_y = X264_MAX( energy[0], 1 );+    _energy_uv = X264_MAX( energy[1] + energy[2], 1 );+    lz_y = x264_clz( _energy_y );+    lz_uv = x264_clz( _energy_uv );++    if(h->param.rc.b_aq_debug)+        x264_write_aqlog_body( h, mb_x + mb_y*h->mb.i_mb_stride, frame, luma, bluePoint, (float)_energy_y, (float)_energy_uv );++    // logf(energy) = (1.0397 * (log2_lut[(energy<<lz>>24)&0x7f] - lz + 31.00024f) / 1.5+    // energy_y  = 1.2 * (logf(_energy_y ) - (h->rc->aq_threshold * .91) + .5);+    // energy_uv = 0.8 * (logf(_energy_uv) - (h->rc->aq_threshold * .91) + .5);+    energy_y  = 0.83176f * (log2_lut[(_energy_y<<lz_y>>24)&0x7f] - lz_y + 31.00024f) - (h->rc->aq_threshold * 1.092f) + .5f;+    energy_uv = 0.55451f * (log2_lut[(_energy_uv<<lz_uv>>24)&0x7f] - lz_uv + 31.00024f) - (h->rc->aq_threshold * 0.728f) + .5f;+    f_qp_adj = 0.0;++    // lumal+    if(luma > h->param.rc.i_aq_boundary[0]){+        // ***  ***+        // Y & UV Flat      -> qp up+        // Y Flat / UV Bump -> qp y up+        // Y Bump / UV Flat -> even+        // Y & UV Bump      -> qp down+        mode = 0;++        // qp up+        if(!bluePoint && energy_y < 0 && energy_uv < 0)+            f_qp_adj = X264_MIN(energy_y, energy_uv);+        // qp y up+        else if(!bluePoint && energy_y < 0 && energy_uv >= 0)+            f_qp_adj = energy_y;+        // qp down+        else if (energy_y >= 0 && energy_uv >= 0)+            f_qp_adj = X264_MAX(energy_y, energy_uv) * .5;+    } else if(luma > h->param.rc.i_aq_boundary[1]){+        // ***  ***+        // Y & UV Flat      -> qp up+        // Y Flat / UV Bump -> even+        // Y Bump / UV Flat -> qp mix down+        // Y & UV Bump      -> qp down+        mode = 1;++        // qp up+        if(!bluePoint && energy_y < 0 && energy_uv < 0)+            f_qp_adj = X264_MAX(energy_y, energy_uv);+        // qp mix down+        else if (energy_y >= 0 && energy_uv < 0)+            f_qp_adj = X264_MAX(energy_y + (!bluePoint * energy_uv), 0) * .5;+        // qp down+        else if (energy_y >= 0 && energy_uv >= 0)+            f_qp_adj = X264_MAX(energy_y, bluePoint * energy_uv);+    } else if(luma > h->param.rc.i_aq_boundary[2]){+        // ***  ***+        // Y & UV Flat      -> qp up+        // Y Flat / UV Bump -> qp uv down+        // Y Bump / UV Flat -> qp y down+        // Y & UV Bump      -> qp down+        mode = 2;++        // qp up+        if(energy_y < 0 && energy_uv < 0)+            f_qp_adj = X264_MAX(energy_y, energy_uv) * .5;+        // qp uv down+        else if (energy_y < 0 && energy_uv >= 0)+            f_qp_adj = energy_uv * 1.25;+        // qp y down+        else if (energy_y >= 0 && energy_uv < 0)+            f_qp_adj = energy_y * 1.25;+        // qp down+        else if (energy_y >= 0 && energy_uv >= 0)+            f_qp_adj = X264_MAX(energy_y, energy_uv) * 1.25;+    } else {+        // ***  ***+        // Y & UV Flat      -> qp double up+        // Y Flat / UV Bump -> qp y up+        // Y Bump / UV Flat -> qp uv up+        // Y & UV Bump      -> even+        mode = 3;++        // qp double up+        if(energy_y < 0 && energy_uv < 0)+            f_qp_adj = energy_y + energy_uv;+        // qp mix up+        else if (energy_y < 0 && energy_uv >= 0)+            f_qp_adj = energy_y;+        // qp uv down+        else if (energy_y >= 0 && energy_uv < 0)+            f_qp_adj = energy_uv * .5;+    }++    // qp down+    if(f_qp_adj > 0)+        f_qp_adj *= h->param.rc.f_aq_strength_down[mode];+    else+        f_qp_adj *= h->param.rc.f_aq_strength_up[mode];++    frame->i_aq_type[mb_x + mb_y*h->mb.i_mb_stride] = mode;++    return -f_qp_adj;+}  void x264_adaptive_quant_frame( x264_t *h, x264_frame_t *frame ) {@@ -237,6 +376,16 @@      * FIXME: while they're written in 5 significant digits, they're only tuned to 2. */     int mb_x, mb_y;     float strength;+    int energy[3] = {0, 0, 0};+    x264_aq_metric_t aq_metric_func;++    h->rc->aq_threshold = logf(powf(h->param.rc.f_aq_sensitivity,4)/2.0);++    if( h->param.rc.i_aq_metric == 1 )+        aq_metric_func = aqm_4ver0c;+    else+        aq_metric_func = ac_energy_mb;+     float avg_adj = 0.f;     /* Need to init it anyways for MB tree. */     if( h->param.rc.f_aq_strength == 0 )@@ -246,7 +395,7 @@         memset( frame->f_qp_offset_aq, 0, h->mb.i_mb_count * sizeof(float) );         if( h->frames.b_have_lowres )             for( mb_xy = 0; mb_xy < h->mb.i_mb_count; mb_xy++ )-                frame->i_inv_qscale_factor[mb_xy] = 256;+                frame->i_inv_qscale_factor[mb_x+mb_y*h->mb.i_mb_stride] = FIX8(pow(2.0,-f_qp_adj/6.0));         return;     } @@ -256,9 +405,13 @@             for( mb_x = 0; mb_x < h->sps->i_mb_width; mb_x++ )             {                 uint32_t energy = ac_energy_mb( h, mb_x, mb_y, frame );-                float qp_adj = x264_log2( energy + 2 );-                qp_adj *= qp_adj;-                frame->f_qp_offset[mb_x + mb_y*h->mb.i_mb_stride] = qp_adj;+                /*float qp_adj = x264_log2( energy + 2 );*/+                float f_qp_adj;+                aq_metric_func( h, mb_x, mb_y, frame, energy );+                f_qp_adj = x264_adjust_OreAQ( h, mb_x, mb_y, frame, energy );+                frame->f_qp_offset[mb_x + mb_y*h->mb.i_mb_stride] = f_qp_adj;+                /*qp_adj *= qp_adj;*/+                /*frame->f_qp_offset[mb_x + mb_y*h->mb.i_mb_stride] = qp_adj;*/                 avg_adj += qp_adj;             }         avg_adj /= h->mb.i_mb_count;@@ -300,8 +453,29 @@ *****************************************************************************/ void x264_adaptive_quant( x264_t *h ) {+    int i_qp_adj;+    float factor, f_qp_adj;+         x264_emms();-    h->mb.i_qp = x264_clip3( h->rc->f_qpm + h->fenc->f_qp_offset[h->mb.i_mb_xy] + .5, h->param.rc.i_qp_min, h->param.rc.i_qp_max );+    f_qp_adj = h->fenc->f_qp_offset[h->mb.i_mb_xy];+    if( h->sh.i_type == SLICE_TYPE_I )+        factor = h->param.rc.f_aq_ifactor[f_qp_adj<0];+    else if( h->sh.i_type == SLICE_TYPE_P )+        factor = h->param.rc.f_aq_pfactor[f_qp_adj<0];+    else if( h->sh.i_type == SLICE_TYPE_B )+        factor = h->param.rc.f_aq_bfactor[f_qp_adj<0];+    else+        factor = 1.0;+    h->mb.i_qp = (int)(h->rc->f_qpm + factor * f_qp_adj + .5);+    i_qp_adj = x264_clip3( h->rc->f_qpm - h->mb.i_qp + .5, -50, 50 );++    h->stat.frame.i_aq_change[i_qp_adj + 50] += 1;+    h->stat.frame.i_aq_count[ h->fenc->i_aq_type[h->mb.i_mb_xy] ] += 1;+    h->stat.frame.i_aq_result[ h->fenc->i_aq_type[h->mb.i_mb_xy] ][ (i_qp_adj<0?0:(i_qp_adj>0?1:2)) ] += 1;+    h->stat.frame.i_aq_change_min = X264_MIN(h->stat.frame.i_aq_change_min, i_qp_adj);+    h->stat.frame.i_aq_change_max = X264_MAX(h->stat.frame.i_aq_change_max, i_qp_adj);++    h->mb.i_qp = x264_clip3( h->mb.i_qp, h->param.rc.i_qp_min, h->param.rc.i_qp_max ); }  int x264_macroblock_tree_read( x264_t *h, x264_frame_t *frame )@@ -403,11 +577,6 @@     rc->last_non_b_pict_type = -1;     rc->cbr_decay = 1.0; -    if(h->param.rc.i_aq_metric == 1)-        rc->aq_metric_func = aqm_4ver0c;-    else-        rc->aq_metric_func = ac_energy_mb;-     if( h->param.rc.i_rc_method == X264_RC_CRF && h->param.rc.b_stat_read )     {         x264_log(h, X264_LOG_ERROR, "constant rate-factor is incompatible with 2pass.\n");@@ -728,6 +897,21 @@     if( h->param.rc.b_mb_tree && (h->param.rc.b_stat_read || h->param.rc.b_stat_write) )         CHECKED_MALLOC( rc->qp_buffer, h->mb.i_mb_count * sizeof(uint16_t) ); +    /* Open AQ Log file */+    if( h->param.rc.b_aq_debug )+    {+        rc->p_aq_debug = fopen( h->param.rc.psz_aq_debug_name, "wb" );+        if( rc->p_aq_debug == NULL )+        {+            x264_log(h, X264_LOG_ERROR, "ratecontrol_init: can't open AQ debug file\n");+            return -1;+        }+        setvbuf( rc->p_aq_debug, NULL, _IOFBF, 1024*1024*8 ); // 8M Buffer+        x264_write_aqlog_header( h, "OreAQ04", h->param.rc.i_aq_metric,+                                    h->param.rc.f_aq_strength_up, h->param.rc.f_aq_strength_down, h->param.rc.f_aq_sensitivity, 0,+                                    h->param.rc.i_aq_boundary );+    }+     for( i=0; i<h->param.i_thread_queue; i++ )     {         h->thread[i]->rc = rc+i;@@ -918,6 +1102,8 @@                 rc->zones[i].param->param_free( rc->zones[i].param );         x264_free( rc->zones );     }+    if( rc->p_aq_debug )+        fclose( rc->p_aq_debug );     x264_free( rc ); } diff -NdurwBE x264-oreaqtest3/x264.c x264-oreaqtest4/x264.c--- x264-oreaqtest3/x264.c	2009-08-27 11:33:34 +0300+++ x264-oreaqtest4/x264.c	2009-08-27 12:51:48 +0300@@ -218,7 +218,7 @@     H1( "      --chroma-qp-offset <integer>  QP difference between chroma and luma [%d]\n", defaults->analyse.i_chroma_qp_offset );     H1( "      --aq-mode <integer>     AQ method [%d]\n"         "                                  - 0: Disabled\n"-        "                                  - 1: Variance AQ (complexity mask)\n"+        "                                  - 1: OreAQ\n", defaults->rc.i_aq_mode );         "                                  - 2: Auto-variance AQ (experimental)\n", defaults->rc.i_aq_mode );     H0( "      --aq-metric <integer>   The metric used for AQ [%d]\n"          "                                  - 0: Original GIT metric (ac_energy_mb)\n"@@ -226,11 +226,23 @@     H0( "      --aq-strength <float>   Reduces blocking and blurring in flat and\n"         "                              textured areas. [%.1f]\n"         "                                  - 0.5: weak AQ\n"-        "                                  - 1.5: strong AQ\n", defaults->rc.f_aq_strength );+        "                                  - 1.5: strong AQ\n"+        "                    <Up:Down> or <Up1:Down1:Up2:Down2:Up3:Down3:Up4>\n"+        "                              Set QP up/down strength.\n", defaults->rc.f_aq_strength );     H0( "      --aq-sensitivity <float> \"Center\" of AQ curve. [%.1f]\n"         "                                  -  5: most QPs are raised\n"         "                                  - 10: good general-use sensitivity\n"         "                                  - 15: most QPs are lowered\n", defaults->rc.f_aq_sensitivity );+    H1( "      --aq-ifactor <Up:Down>  AQ strength factor of I-frames [%.1f:%.1f]\n", defaults->rc.f_aq_ifactor[0], defaults->rc.f_aq_ifactor[1] );+    H1( "      --aq-pfactor <Up:Down>  AQ strength factor of P-frames [%.1f:%.1f]\n", defaults->rc.f_aq_pfactor[0], defaults->rc.f_aq_pfactor[1] );+    H1( "      --aq-bfactor <Up:Down>  AQ strength factor of B-frames [%.1f:%.1f]\n", defaults->rc.f_aq_bfactor[0], defaults->rc.f_aq_bfactor[1] );+    H1( "      --aq-boundary <int:int:int>  AQ boundary. \n"+        "                                  fullrange=off: [192:64:24]\n"+        "                                  fullrange=on : [205:56:9]\n"+        "                                  #1: Bright-Middle\n"+        "                                  #2: Middle-Dark\n"+        "                                  #3: Dark-M.Dark\n" );+    H0( "      --aq-debug <string>     Filename for AQ debug log [\"%s\"]\n", defaults->rc.psz_aq_debug_name );     H0( "\n" );     H0( "  -p, --pass <1|2|3>          Enable multipass ratecontrol\n"         "                                  - 1: First pass, creates stats file\n"@@ -455,8 +467,13 @@     { "no-dct-decimate",   no_argument, NULL, 0 },     { "aq-strength", required_argument, NULL, 0 },     { "aq-sensitivity", required_argument, NULL, 0 },+    { "aq-ifactor", required_argument, NULL, 0 },+    { "aq-pfactor", required_argument, NULL, 0 },+    { "aq-bfactor", required_argument, NULL, 0 },     { "aq-mode",     required_argument, NULL, 0 },     { "aq-metric", required_argument, NULL, 0 },+    { "aq-boundary", required_argument, NULL, 0 },+    { "aq-debug", required_argument, NULL, 0 },     { "deadzone-inter", required_argument, NULL, '0' },     { "deadzone-intra", required_argument, NULL, '0' },     { "level",       required_argument, NULL, 0 },diff -NdurwBE x264-oreaqtest3/x264.h x264-oreaqtest4/x264.h--- x264-oreaqtest3/x264.h	2009-08-27 11:34:52 +0300+++ x264-oreaqtest4/x264.h	2009-08-27 12:55:18 +0300@@ -36,6 +36,7 @@ #include <stdarg.h>  #define X264_BUILD 72+#define X264_SUB_BUILD 2 // OreAQ  /* x264_t:  *      opaque handler for encoder */@@ -279,7 +280,17 @@         int         i_aq_mode;      /* psy adaptive QP. (X264_AQ_*) */         int         i_aq_metric;         float       f_aq_strength;+        float       f_aq_strength_up[4];   /* { Bright, Middle, Dark, M.Dark } */+        float       f_aq_strength_down[4]; /* { Bright, Middle, Dark, NULL } */         float       f_aq_sensitivity;+        float       f_aq_ifactor[2]; /* { Up, Down } */+        float       f_aq_pfactor[2]; /* { Up, Down } */+        float       f_aq_bfactor[2]; /* { Up, Down } */+        int         b_aq_boundary;+        int         i_aq_boundary[3];+        int         b_aq_debug;+        char        *psz_aq_debug_name;+                 int         b_mb_tree;      /* Macroblock-tree ratecontrol. */         int         i_lookahead;