]> git.sesse.net Git - x264/blobdiff - encoder/slicetype.c
Slightly faster predictor_difference_mmxext
[x264] / encoder / slicetype.c
index 63c3dcb6e4daf116696cd4f5641765e72a7a779b..c46aee5ead5030a6af99bb029402eca87d698ce5 100644 (file)
@@ -46,7 +46,7 @@ static void x264_lowres_context_init( x264_t *h, x264_mb_analysis_t *a )
     else
     {
         h->mb.i_me_method = X264_ME_DIA;
-        h->mb.i_subpel_refine = 3;
+        h->mb.i_subpel_refine = 2;
     }
     h->mb.b_chroma_me = 0;
 }
@@ -122,7 +122,7 @@ static NOINLINE unsigned int x264_weight_cost( x264_t *h, x264_frame_t *fenc, ui
     int i_lines = fenc->i_lines_lowres;
     int i_width = fenc->i_width_lowres;
     uint8_t *fenc_plane = fenc->lowres[0];
-    ALIGNED_8( uint8_t buf[8*8] );
+    ALIGNED_ARRAY_8( uint8_t, buf,[8*8] );
     int pixoff = 0;
     int i_mb = 0;
 
@@ -231,14 +231,13 @@ void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int
     if( weights[0].weightfn && b_lookahead )
     {
         //scale lowres in lookahead for slicetype_frame_cost
-        int i_padv = PADV<<h->param.b_interlaced;
         uint8_t *src = ref->buffer_lowres[0];
         uint8_t *dst = h->mb.p_weight_buf[0];
         int width = ref->i_width_lowres + PADH*2;
-        int height = ref->i_lines_lowres + i_padv*2;
+        int height = ref->i_lines_lowres + PADV*2;
         x264_weight_scale_plane( h, dst, ref->i_stride_lowres, src, ref->i_stride_lowres,
                                  width, height, &weights[0] );
-        fenc->weighted[0] = h->mb.p_weight_buf[0] + PADH + ref->i_stride_lowres * i_padv;
+        fenc->weighted[0] = h->mb.p_weight_buf[0] + PADH + ref->i_stride_lowres * PADV;
     }
 }
 
@@ -260,7 +259,7 @@ static int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
     int16_t (*fenc_mvs[2])[2] = { &frames[b]->lowres_mvs[0][b-p0-1][i_mb_xy], &frames[b]->lowres_mvs[1][p1-b-1][i_mb_xy] };
     int (*fenc_costs[2]) = { &frames[b]->lowres_mv_costs[0][b-p0-1][i_mb_xy], &frames[b]->lowres_mv_costs[1][p1-b-1][i_mb_xy] };
 
-    ALIGNED_8( uint8_t pix1[9*FDEC_STRIDE] );
+    ALIGNED_ARRAY_8( uint8_t, pix1,[9*FDEC_STRIDE] );
     uint8_t *pix2 = pix1+8;
     x264_me_t m[2];
     int i_bcost = COST_MAX;
@@ -303,14 +302,25 @@ static int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
     }
 #define TRY_BIDIR( mv0, mv1, penalty ) \
     { \
-        int stride1 = 16, stride2 = 16; \
-        uint8_t *src1, *src2; \
         int i_cost; \
-        src1 = h->mc.get_ref( pix1, &stride1, m[0].p_fref, m[0].i_stride[0], \
-                              (mv0)[0], (mv0)[1], 8, 8, w ); \
-        src2 = h->mc.get_ref( pix2, &stride2, m[1].p_fref, m[1].i_stride[0], \
-                              (mv1)[0], (mv1)[1], 8, 8, w ); \
-        h->mc.avg[PIXEL_8x8]( pix1, 16, src1, stride1, src2, stride2, i_bipred_weight ); \
+        if( h->param.analyse.i_subpel_refine <= 1 ) \
+        { \
+            int hpel_idx1 = (((mv0)[0]&2)>>1) + ((mv0)[1]&2); \
+            int hpel_idx2 = (((mv1)[0]&2)>>1) + ((mv1)[1]&2); \
+            uint8_t *src1 = m[0].p_fref[hpel_idx1] + ((mv0)[0]>>2) + ((mv0)[1]>>2) * m[0].i_stride[0]; \
+            uint8_t *src2 = m[1].p_fref[hpel_idx2] + ((mv1)[0]>>2) + ((mv1)[1]>>2) * m[1].i_stride[0]; \
+            h->mc.avg[PIXEL_8x8]( pix1, 16, src1, m[0].i_stride[0], src2, m[1].i_stride[0], i_bipred_weight ); \
+        } \
+        else \
+        { \
+            int stride1 = 16, stride2 = 16; \
+            uint8_t *src1, *src2; \
+            src1 = h->mc.get_ref( pix1, &stride1, m[0].p_fref, m[0].i_stride[0], \
+                                  (mv0)[0], (mv0)[1], 8, 8, w ); \
+            src2 = h->mc.get_ref( pix2, &stride2, m[1].p_fref, m[1].i_stride[0], \
+                                  (mv1)[0], (mv1)[1], 8, 8, w ); \
+            h->mc.avg[PIXEL_8x8]( pix1, 16, src1, stride1, src2, stride2, i_bipred_weight ); \
+        } \
         i_cost = penalty + h->pixf.mbcmp[PIXEL_8x8]( \
                            m[0].p_fenc[0], FENC_STRIDE, pix1, 16 ); \
         COPY2_IF_LT( i_bcost, i_cost, list_used, 3 ); \
@@ -321,6 +331,7 @@ static int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
     m[0].i_stride[0] = i_stride;
     m[0].p_fenc[0] = h->mb.pic.p_fenc[0];
     m[0].weight = w;
+    m[0].i_ref = 0;
     LOAD_HPELS_LUMA( m[0].p_fref, fref0->lowres );
     m[0].p_fref_w = m[0].p_fref[0];
     if( w[0].weightfn )
@@ -329,10 +340,13 @@ static int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
     if( b_bidir )
     {
         int16_t *mvr = fref1->lowres_mvs[0][p1-p0-1][i_mb_xy];
-        int dmv[2][2];
+        ALIGNED_ARRAY_8( int16_t, dmv,[2],[2] );
 
-        h->mc.memcpy_aligned( &m[1], &m[0], sizeof(x264_me_t) );
-        m[1].i_ref = p1;
+        m[1].i_pixel = PIXEL_8x8;
+        m[1].p_cost_mv = a->p_cost_mv;
+        m[1].i_stride[0] = i_stride;
+        m[1].p_fenc[0] = h->mb.pic.p_fenc[0];
+        m[1].i_ref = 0;
         m[1].weight = weight_none;
         LOAD_HPELS_LUMA( m[1].p_fref, fref1->lowres );
         m[1].p_fref_w = m[1].p_fref[0];
@@ -343,9 +357,11 @@ static int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
         dmv[1][1] = dmv[0][1] - mvr[1];
         CLIP_MV( dmv[0] );
         CLIP_MV( dmv[1] );
+        if( h->param.analyse.i_subpel_refine <= 1 )
+            M64( dmv ) &= ~0x0001000100010001ULL; /* mv & ~1 */
 
         TRY_BIDIR( dmv[0], dmv[1], 0 );
-        if( dmv[0][0] | dmv[0][1] | dmv[1][0] | dmv[1][1] )
+        if( M64( dmv ) )
         {
             int i_cost;
             h->mc.avg[PIXEL_8x8]( pix1, 16, m[0].p_fref[0], m[0].i_stride[0], m[1].p_fref[0], m[1].i_stride[0], i_bipred_weight );
@@ -920,7 +936,7 @@ static int scenecut_internal( x264_t *h, x264_mb_analysis_t *a, x264_frame_t **f
     int icost = frame->i_cost_est[0][0];
     int pcost = frame->i_cost_est[p1-p0][0];
     float f_bias;
-    int i_gop_size = frame->i_frame - h->lookahead->i_last_idr;
+    int i_gop_size = frame->i_frame - h->lookahead->i_last_keyframe;
     float f_thresh_max = h->param.i_scenecut_threshold / 100.0;
     /* magic numbers pulled out of thin air */
     float f_thresh_min = f_thresh_max * h->param.i_keyint_min
@@ -929,7 +945,7 @@ static int scenecut_internal( x264_t *h, x264_mb_analysis_t *a, x264_frame_t **f
 
     if( h->param.i_keyint_min == h->param.i_keyint_max )
         f_thresh_min= f_thresh_max;
-    if( i_gop_size < h->param.i_keyint_min / 4 )
+    if( i_gop_size < h->param.i_keyint_min / 4 || h->param.b_intra_refresh )
         f_bias = f_thresh_min / 4;
     else if( i_gop_size <= h->param.i_keyint_min )
         f_bias = f_thresh_min * i_gop_size / h->param.i_keyint_min;
@@ -1016,11 +1032,11 @@ void x264_slicetype_analyse( x264_t *h, int keyframe )
     if( !j )
         return;
 
-    keyint_limit = h->param.i_keyint_max - frames[0]->i_frame + h->lookahead->i_last_idr - 1;
-    orig_num_frames = num_frames = X264_MIN( j, keyint_limit );
+    keyint_limit = h->param.i_keyint_max - frames[0]->i_frame + h->lookahead->i_last_keyframe - 1;
+    orig_num_frames = num_frames = h->param.b_intra_refresh ? j : X264_MIN( j, keyint_limit );
 
     x264_lowres_context_init( h, &a );
-    idr_frame_type = frames[1]->i_frame - h->lookahead->i_last_idr >= h->param.i_keyint_min ? X264_TYPE_IDR : X264_TYPE_I;
+    idr_frame_type = frames[1]->i_frame - h->lookahead->i_last_keyframe >= h->param.i_keyint_min ? X264_TYPE_IDR : X264_TYPE_I;
 
     /* This is important psy-wise: if we have a non-scenecut keyframe,
      * there will be significant visual artifacts if the frames just before
@@ -1149,16 +1165,17 @@ void x264_slicetype_analyse( x264_t *h, int keyframe )
         x264_macroblock_tree( h, &a, frames, X264_MIN(num_frames, h->param.i_keyint_max), keyframe );
 
     /* Enforce keyframe limit. */
-    for( j = 0; j < num_frames; j++ )
-    {
-        if( ((j-keyint_limit) % h->param.i_keyint_max) == 0 )
+    if( !h->param.b_intra_refresh )
+        for( j = 0; j < num_frames; j++ )
         {
-            if( j && h->param.i_keyint_max > 1 )
-                frames[j]->i_type = X264_TYPE_P;
-            frames[j+1]->i_type = X264_TYPE_IDR;
-            reset_start = X264_MIN( reset_start, j+2 );
+            if( ((j-keyint_limit) % h->param.i_keyint_max) == 0 )
+            {
+                if( j && h->param.i_keyint_max > 1 )
+                    frames[j]->i_type = X264_TYPE_P;
+                frames[j+1]->i_type = X264_TYPE_IDR;
+                reset_start = X264_MIN( reset_start, j+2 );
+            }
         }
-    }
 
     if( h->param.rc.i_vbv_buffer_size )
         x264_vbv_lookahead( h, &a, frames, num_frames, keyframe );
@@ -1213,7 +1230,7 @@ void x264_slicetype_decide( x264_t *h )
         }
 
         /* Limit GOP size */
-        if( frm->i_frame - h->lookahead->i_last_idr >= h->param.i_keyint_max )
+        if( (!h->param.b_intra_refresh || frm->i_frame == 0) && frm->i_frame - h->lookahead->i_last_keyframe >= h->param.i_keyint_max )
         {
             if( frm->i_type == X264_TYPE_AUTO )
                 frm->i_type = X264_TYPE_IDR;
@@ -1223,7 +1240,8 @@ void x264_slicetype_decide( x264_t *h )
         if( frm->i_type == X264_TYPE_IDR )
         {
             /* Close GOP */
-            h->lookahead->i_last_idr = frm->i_frame;
+            h->lookahead->i_last_keyframe = frm->i_frame;
+            frm->b_keyframe = 1;
             if( bframes > 0 )
             {
                 bframes--;
@@ -1310,23 +1328,29 @@ void x264_slicetype_decide( x264_t *h )
 
     /* shift sequence to coded order.
        use a small temporary list to avoid shifting the entire next buffer around */
-    int i_dts = h->lookahead->next.list[0]->i_frame;
+    int i_coded = h->lookahead->next.list[0]->i_frame;
     if( bframes )
     {
         int index[] = { brefs+1, 1 };
         for( i = 0; i < bframes; i++ )
-            frames[ index[h->lookahead->next.list[i]->i_type == X264_TYPE_BREF]++ ] = h->lookahead->next.list[i];
+        {
+            int idx = index[h->lookahead->next.list[i]->i_type == X264_TYPE_BREF]++;
+            frames[idx] = h->lookahead->next.list[i];
+            frames[idx]->i_reordered_pts = h->lookahead->next.list[idx]->i_pts;
+        }
         frames[0] = h->lookahead->next.list[bframes];
+        frames[0]->i_reordered_pts = h->lookahead->next.list[0]->i_pts;
         memcpy( h->lookahead->next.list, frames, (bframes+1) * sizeof(x264_frame_t*) );
     }
     for( i = 0; i <= bframes; i++ )
-         h->lookahead->next.list[i]->i_dts = i_dts++;
+         h->lookahead->next.list[i]->i_coded = i_coded++;
 }
 
 int x264_rc_analyse_slice( x264_t *h )
 {
     int p0=0, p1, b;
     int cost;
+    x264_emms();
 
     if( IS_X264_TYPE_I(h->fenc->i_type) )
         p1 = b = 0;
@@ -1360,5 +1384,24 @@ int x264_rc_analyse_slice( x264_t *h )
     memcpy( h->fdec->i_row_satd, h->fenc->i_row_satd, h->sps->i_mb_height * sizeof(int) );
     if( !IS_X264_TYPE_I(h->fenc->i_type) )
         memcpy( h->fdec->i_row_satds[0][0], h->fenc->i_row_satds[0][0], h->sps->i_mb_height * sizeof(int) );
+
+    if( h->param.b_intra_refresh && h->param.rc.i_vbv_buffer_size && h->fenc->i_type == X264_TYPE_P )
+    {
+        int x, y;
+        int ip_factor = 256 * h->param.rc.f_ip_factor; /* fix8 */
+        for( y = 0; y < h->sps->i_mb_height; y++ )
+        {
+            int mb_xy = y * h->mb.i_mb_stride;
+            for( x = h->fdec->i_pir_start_col; x <= h->fdec->i_pir_end_col; x++, mb_xy++ )
+            {
+                int intra_cost = (h->fenc->i_intra_cost[mb_xy] * ip_factor) >> 8;
+                int inter_cost = h->fenc->lowres_costs[b-p0][p1-b][mb_xy];
+                int diff = intra_cost - inter_cost;
+                h->fdec->i_row_satd[y] += diff;
+                cost += diff;
+            }
+        }
+    }
+
     return cost;
 }