[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