]> git.sesse.net Git - x264/blobdiff - encoder/analyse.c
msvs: WinRT support
[x264] / encoder / analyse.c
index 3780ddee6b1dfacda8e95a81c740ffc232daa8e7..2bb67ad674859de2fdba4457d0c3ffe9cc0e8214 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * analyse.c: macroblock analysis
  *****************************************************************************
- * Copyright (C) 2003-2013 x264 project
+ * Copyright (C) 2003-2016 x264 project
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Loren Merritt <lorenm@u.washington.edu>
@@ -278,18 +278,7 @@ static uint16_t x264_cost_ref[QP_MAX+1][3][33];
 static UNUSED x264_pthread_mutex_t cost_ref_mutex = X264_PTHREAD_MUTEX_INITIALIZER;
 static uint16_t x264_cost_i4x4_mode[(QP_MAX+2)*32];
 
-float *x264_analyse_prepare_costs( x264_t *h )
-{
-    float *logs = x264_malloc( (2*4*2048+1)*sizeof(float) );
-    if( !logs )
-        return NULL;
-    logs[0] = 0.718f;
-    for( int i = 1; i <= 2*4*2048; i++ )
-        logs[i] = log2f(i+1)*2 + 1.718f;
-    return logs;
-}
-
-int x264_analyse_init_costs( x264_t *h, float *logs, int qp )
+static int init_costs( x264_t *h, float *logs, int qp )
 {
     int lambda = x264_lambda_tab[qp];
     if( h->cost_mv[qp] )
@@ -325,6 +314,30 @@ fail:
     return -1;
 }
 
+int x264_analyse_init_costs( x264_t *h )
+{
+    float *logs = x264_malloc( (2*4*2048+1) * sizeof(float) );
+    if( !logs )
+        return -1;
+
+    logs[0] = 0.718f;
+    for( int i = 1; i <= 2*4*2048; i++ )
+        logs[i] = log2f( i+1 ) * 2.0f + 1.718f;
+
+    for( int qp = X264_MIN( h->param.rc.i_qp_min, QP_MAX_SPEC ); qp <= h->param.rc.i_qp_max; qp++ )
+        if( init_costs( h, logs, qp ) )
+            goto fail;
+
+    if( init_costs( h, logs, X264_LOOKAHEAD_QP ) )
+        goto fail;
+
+    x264_free( logs );
+    return 0;
+fail:
+    x264_free( logs );
+    return -1;
+}
+
 void x264_analyse_free_costs( x264_t *h )
 {
     for( int i = 0; i < QP_MAX+1; i++ )
@@ -436,7 +449,7 @@ static void x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int qp )
     /* non-RD PCM decision is inaccurate (as is psy-rd), so don't do it.
      * PCM cost can overflow with high lambda2, so cap it at COST_MAX. */
     uint64_t pcm_cost = ((uint64_t)X264_PCM_COST*a->i_lambda2 + 128) >> 8;
-    a->i_satd_pcm = !h->mb.i_psy_rd && a->i_mbrd && pcm_cost < COST_MAX ? pcm_cost : COST_MAX;
+    a->i_satd_pcm = !h->param.i_avcintra_class && !h->mb.i_psy_rd && a->i_mbrd && pcm_cost < COST_MAX ? pcm_cost : COST_MAX;
 
     a->b_fast_intra = 0;
     a->b_avoid_topright = 0;
@@ -811,58 +824,60 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_satd_
     int lambda = a->i_lambda;
 
     /*---------------- Try all mode and calculate their score ---------------*/
-
-    /* 16x16 prediction selection */
-    const int8_t *predict_mode = predict_16x16_mode_available( h->mb.i_neighbour_intra );
-
-    /* Not heavily tuned */
-    static const uint8_t i16x16_thresh_lut[11] = { 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4 };
-    int i16x16_thresh = a->b_fast_intra ? (i16x16_thresh_lut[h->mb.i_subpel_refine]*i_satd_inter)>>1 : COST_MAX;
-
-    if( !h->mb.b_lossless && predict_mode[3] >= 0 )
+    /* Disabled i16x16 for AVC-Intra compat */
+    if( !h->param.i_avcintra_class )
     {
-        h->pixf.intra_mbcmp_x3_16x16( p_src, p_dst, a->i_satd_i16x16_dir );
-        a->i_satd_i16x16_dir[0] += lambda * bs_size_ue(0);
-        a->i_satd_i16x16_dir[1] += lambda * bs_size_ue(1);
-        a->i_satd_i16x16_dir[2] += lambda * bs_size_ue(2);
-        COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[0], a->i_predict16x16, 0 );
-        COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[1], a->i_predict16x16, 1 );
-        COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[2], a->i_predict16x16, 2 );
+        const int8_t *predict_mode = predict_16x16_mode_available( h->mb.i_neighbour_intra );
 
-        /* Plane is expensive, so don't check it unless one of the previous modes was useful. */
-        if( a->i_satd_i16x16 <= i16x16_thresh )
+        /* Not heavily tuned */
+        static const uint8_t i16x16_thresh_lut[11] = { 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4 };
+        int i16x16_thresh = a->b_fast_intra ? (i16x16_thresh_lut[h->mb.i_subpel_refine]*i_satd_inter)>>1 : COST_MAX;
+
+        if( !h->mb.b_lossless && predict_mode[3] >= 0 )
         {
-            h->predict_16x16[I_PRED_16x16_P]( p_dst );
-            a->i_satd_i16x16_dir[I_PRED_16x16_P] = h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE );
-            a->i_satd_i16x16_dir[I_PRED_16x16_P] += lambda * bs_size_ue(3);
-            COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[I_PRED_16x16_P], a->i_predict16x16, 3 );
+            h->pixf.intra_mbcmp_x3_16x16( p_src, p_dst, a->i_satd_i16x16_dir );
+            a->i_satd_i16x16_dir[0] += lambda * bs_size_ue(0);
+            a->i_satd_i16x16_dir[1] += lambda * bs_size_ue(1);
+            a->i_satd_i16x16_dir[2] += lambda * bs_size_ue(2);
+            COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[0], a->i_predict16x16, 0 );
+            COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[1], a->i_predict16x16, 1 );
+            COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[2], a->i_predict16x16, 2 );
+
+            /* Plane is expensive, so don't check it unless one of the previous modes was useful. */
+            if( a->i_satd_i16x16 <= i16x16_thresh )
+            {
+                h->predict_16x16[I_PRED_16x16_P]( p_dst );
+                a->i_satd_i16x16_dir[I_PRED_16x16_P] = h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE );
+                a->i_satd_i16x16_dir[I_PRED_16x16_P] += lambda * bs_size_ue(3);
+                COPY2_IF_LT( a->i_satd_i16x16, a->i_satd_i16x16_dir[I_PRED_16x16_P], a->i_predict16x16, 3 );
+            }
         }
-    }
-    else
-    {
-        for( ; *predict_mode >= 0; predict_mode++ )
+        else
         {
-            int i_satd;
-            int i_mode = *predict_mode;
+            for( ; *predict_mode >= 0; predict_mode++ )
+            {
+                int i_satd;
+                int i_mode = *predict_mode;
 
-            if( h->mb.b_lossless )
-                x264_predict_lossless_16x16( h, 0, i_mode );
-            else
-                h->predict_16x16[i_mode]( p_dst );
+                if( h->mb.b_lossless )
+                    x264_predict_lossless_16x16( h, 0, i_mode );
+                else
+                    h->predict_16x16[i_mode]( p_dst );
 
-            i_satd = h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE ) +
-                     lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] );
-            COPY2_IF_LT( a->i_satd_i16x16, i_satd, a->i_predict16x16, i_mode );
-            a->i_satd_i16x16_dir[i_mode] = i_satd;
+                i_satd = h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE ) +
+                         lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] );
+                COPY2_IF_LT( a->i_satd_i16x16, i_satd, a->i_predict16x16, i_mode );
+                a->i_satd_i16x16_dir[i_mode] = i_satd;
+            }
         }
-    }
 
-    if( h->sh.i_type == SLICE_TYPE_B )
-        /* cavlc mb type prefix */
-        a->i_satd_i16x16 += lambda * i_mb_b_cost_table[I_16x16];
+        if( h->sh.i_type == SLICE_TYPE_B )
+            /* cavlc mb type prefix */
+            a->i_satd_i16x16 += lambda * i_mb_b_cost_table[I_16x16];
 
-    if( a->i_satd_i16x16 > i16x16_thresh )
-        return;
+        if( a->i_satd_i16x16 > i16x16_thresh )
+            return;
+    }
 
     uint16_t *cost_i4x4_mode = (uint16_t*)ALIGN((intptr_t)x264_cost_i4x4_mode,64) + a->i_qp*32 + 8;
     /* 8x8 prediction selection */
@@ -888,7 +903,7 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_satd_
             int i_best = COST_MAX;
             int i_pred_mode = x264_mb_predict_intra4x4_mode( h, 4*idx );
 
-            predict_mode = predict_8x8_mode_available( a->b_avoid_topright, h->mb.i_neighbour8[idx], idx );
+            const int8_t *predict_mode = predict_8x8_mode_available( a->b_avoid_topright, h->mb.i_neighbour8[idx], idx );
             h->predict_8x8_filter( p_dst_by, edge, h->mb.i_neighbour8[idx], ALL_NEIGHBORS );
 
             if( h->pixf.intra_mbcmp_x9_8x8 && predict_mode[8] >= 0 )
@@ -1003,7 +1018,7 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_satd_
             int i_best = COST_MAX;
             int i_pred_mode = x264_mb_predict_intra4x4_mode( h, idx );
 
-            predict_mode = predict_4x4_mode_available( a->b_avoid_topright, h->mb.i_neighbour4[idx], idx );
+            const int8_t *predict_mode = predict_4x4_mode_available( a->b_avoid_topright, h->mb.i_neighbour4[idx], idx );
 
             if( (h->mb.i_neighbour4[idx] & (MB_TOPRIGHT|MB_TOP)) == MB_TOP )
                 /* emulate missing topright samples */
@@ -2119,7 +2134,7 @@ static void x264_mb_analyse_inter_b16x16( x264_t *h, x264_mb_analysis_t *a )
         int cost00 = h->pixf.mbcmp[PIXEL_16x16]( h->mb.pic.p_fenc[0], FENC_STRIDE, pix0, 16 )
                    + ref_costs + l0_mv_cost + l1_mv_cost;
 
-        if( h->mb.b_chroma_me )
+        if( h->mb.b_chroma_me && cost00 < a->i_cost16x16bi )
         {
             ALIGNED_ARRAY_16( pixel, bi, [16*FENC_STRIDE] );