From 033df0a8c719f991ab0e0bb0788bd4f08e8b91d7 Mon Sep 17 00:00:00 2001 From: Fiona Glaser Date: Thu, 16 Aug 2012 13:01:17 -0700 Subject: [PATCH] Fix mb_info_free with sliced threads x264 would free mb_info before it was completely done using it. --- 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 d64121c4..1f05e831 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 6afe8a7a..226634e5 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 6f652a15..4a93ac54 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 ) { -- 2.40.0