Fix mb_info_free with sliced threads
authorFiona Glaser <fiona@x264.com>
Thu, 16 Aug 2012 20:01:17 +0000 (13:01 -0700)
committerFiona Glaser <fiona@x264.com>
Wed, 5 Sep 2012 18:59:46 +0000 (11:59 -0700)
x264 would free mb_info before it was completely done using it.

common/deblock.c
encoder/analyse.c
encoder/encoder.c

index d64121c..1f05e83 100644 (file)
@@ -506,9 +506,9 @@ void x264_frame_deblock_row( x264_t *h, int mb_y )
                 /* Any MB that was coded, or that analysis decided to skip, has quality commensurate with its QP.
                  * But if deblocking affects neighboring MBs that were force-skipped, blur might accumulate there.
                  * So reset their effective QP to max, to indicate that lack of guarantee. */
-                if( h->fenc->mb_info && M32( bs[0][0] ) )
+                if( h->fdec->mb_info && M32( bs[0][0] ) )
                 {
-#define RESET_EFFECTIVE_QP(xy) h->fdec->effective_qp[xy] |= 0xff * !!(h->fenc->mb_info[xy] & X264_MBINFO_CONSTANT);
+#define RESET_EFFECTIVE_QP(xy) h->fdec->effective_qp[xy] |= 0xff * !!(h->fdec->mb_info[xy] & X264_MBINFO_CONSTANT);
                     RESET_EFFECTIVE_QP(mb_xy);
                     RESET_EFFECTIVE_QP(h->mb.i_mb_left_xy[0]);
                 }
@@ -561,7 +561,7 @@ void x264_frame_deblock_row( x264_t *h, int mb_y )
                 int intra_deblock = intra_cur || intra_top;
 
                 /* This edge has been modified, reset effective qp to max. */
-                if( h->fenc->mb_info && M32( bs[1][0] ) )
+                if( h->fdec->mb_info && M32( bs[1][0] ) )
                 {
                     RESET_EFFECTIVE_QP(mb_xy);
                     RESET_EFFECTIVE_QP(h->mb.i_mb_top_xy);
index 6afe8a7..226634e 100644 (file)
@@ -3047,8 +3047,8 @@ intra_analysis:
         else
         {
             /* Special fast-skip logic using information from mb_info. */
-            if( h->fenc->mb_info && !SLICE_MBAFF && (h->fenc->mb_info[h->mb.i_mb_xy]&X264_MBINFO_CONSTANT) &&
-                 (h->fenc->i_frame - h->fref[0][0]->i_frame) == 1 && !h->sh.b_weighted_pred &&
+            if( h->fdec->mb_info && !SLICE_MBAFF && (h->fdec->mb_info[h->mb.i_mb_xy]&X264_MBINFO_CONSTANT) &&
+                 (h->fdec->i_frame - h->fref[0][0]->i_frame) == 1 && !h->sh.b_weighted_pred &&
                 h->fref[0][0]->effective_qp[h->mb.i_mb_xy] <= h->mb.i_qp )
             {
                 /* Use the P-SKIP MV if we can... */
index 6f652a1..4a93ac5 100644 (file)
@@ -2542,6 +2542,14 @@ reencode:
                 x264_fdec_filter_row( h, h->i_threadslice_start + (1 << SLICE_MBAFF), 2 );
             }
         }
+
+        /* Free mb info after the last thread's done using it */
+        if( h->fdec->mb_info_free && (!h->param.b_sliced_threads || h->i_thread_idx == (h->param.i_threads-1)) )
+        {
+            h->fdec->mb_info_free( h->fdec->mb_info );
+            h->fdec->mb_info = NULL;
+            h->fdec->mb_info_free = NULL;
+        }
     }
 
     return 0;
@@ -2966,6 +2974,11 @@ int     x264_encoder_encode( x264_t *h,
     h->fenc->b_kept_as_ref =
     h->fdec->b_kept_as_ref = i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE && h->param.i_keyint_max > 1;
 
+    h->fdec->mb_info = h->fenc->mb_info;
+    h->fdec->mb_info_free = h->fenc->mb_info_free;
+    h->fenc->mb_info = NULL;
+    h->fenc->mb_info_free = NULL;
+
     h->fdec->i_pts = h->fenc->i_pts;
     if( h->frames.i_bframe_delay )
     {
@@ -3241,13 +3254,6 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
 
     x264_emms();
 
-    if( h->fenc->mb_info_free )
-    {
-        h->fenc->mb_info_free( h->fenc->mb_info );
-        h->fenc->mb_info = NULL;
-        h->fenc->mb_info_free = NULL;
-    }
-
     /* generate buffering period sei and insert it into place */
     if( h->i_thread_frames > 1 && h->fenc->b_keyframe && h->sps->vui.b_nal_hrd_parameters_present )
     {