[x264-devel] Fix mb_info_free with sliced threads

Jason Garrett-Glaser git at videolan.org
Wed Sep 5 21:07:21 CEST 2012


x264 | branch: master | Jason Garrett-Glaser <jason at x264.com> | Thu Aug 16 13:01:17 2012 -0700| [f6e9002dd03329b69ea56391b3f4197efca7a690] | committer: Jason Garrett-Glaser

Fix mb_info_free with sliced threads
x264 would free mb_info before it was completely done using it.

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=f6e9002dd03329b69ea56391b3f4197efca7a690
---

 common/deblock.c  |    6 +++---
 encoder/analyse.c |    4 ++--
 encoder/encoder.c |   20 +++++++++++++-------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/common/deblock.c b/common/deblock.c
index 6022ead..7603a69 100644
--- a/common/deblock.c
+++ b/common/deblock.c
@@ -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);
diff --git a/encoder/analyse.c b/encoder/analyse.c
index 4f37067..d396cc4 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -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... */
diff --git a/encoder/encoder.c b/encoder/encoder.c
index 944b8cf..095fef3 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -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 )
     {



More information about the x264-devel mailing list