From fda27bf9f56f491b6451b66f4cba0a1a05c9887f Mon Sep 17 00:00:00 2001 From: Sushant Date: Tue, 21 Jul 2026 18:27:32 +0530 Subject: [PATCH] libavc: fix hanging issue for recon and deblocking thread The worker threads could hang waiting for macroblock maps if an error was encountered and worker thread exits early. Added check for the error and thread break flags in the wait loops, allowing the worker threads to abort cleanly. Bug: 472596363 Test: atest MctsMediaV2TestCases atest MctsMediaDecoderTestCases atest MctsMediaCodecTestCases atest VtsHalMediaC2V1_0TargetVideoDecTest Change-Id: I9265e17ae7501164501a3fd66c30b6b67b68104b (cherry picked from commit 70e21545b3bb5cfdc83ec1d7d60d30549b216011) --- decoder/ih264d_thread_compute_bs.c | 23 ++++++++++++++++++----- decoder/ih264d_thread_parse_decode.c | 18 +++++++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/decoder/ih264d_thread_compute_bs.c b/decoder/ih264d_thread_compute_bs.c index 6080e8cf..e1a4b3a5 100644 --- a/decoder/ih264d_thread_compute_bs.c +++ b/decoder/ih264d_thread_compute_bs.c @@ -340,7 +340,7 @@ void ih264d_check_mb_map_deblk(dec_struct_t *ps_dec, for(i = 0; i < deblk_mb_grp; i++) { WORD32 nop_cnt = 8*128; - while(u4_check_mb_map == 1) + while(u4_check_mb_map == 1 && ps_dec->i4_break_threads != 1 && ps_dec->i4_error_code == 0) { u4_mb_num = ps_dec->u4_cur_deblk_mb_num; /*we wait for the right mb because of intra pred data dependency*/ @@ -365,6 +365,10 @@ void ih264d_check_mb_map_deblk(dec_struct_t *ps_dec, } } } + if(ps_dec->i4_break_threads == 1 || ps_dec->i4_error_code != 0) + { + break; + } ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst, @@ -399,13 +403,13 @@ void ih264d_recon_deblk_slice(dec_struct_t *ps_dec, tfr_ctxt_t *ps_tfr_cxt) UWORD32 x_offset, y_offset; UWORD32 u4_slice_end; pad_mgr_t *ps_pad_mgr ; + WORD32 nop_cnt = 8*128; /*check for mb map of first mb in slice to ensure slice header is parsed*/ - while(1) + while(ps_dec->i4_break_threads != 1 && ps_dec->i4_error_code == 0) { UWORD32 u4_mb_num = ps_dec->cur_recon_mb_num; UWORD32 u4_cond = 0; - WORD32 nop_cnt = 8*128; CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_recon_mb_map, u4_cond); if(u4_cond) @@ -444,6 +448,10 @@ void ih264d_recon_deblk_slice(dec_struct_t *ps_dec, tfr_ctxt_t *ps_tfr_cxt) } } + if(ps_dec->i4_break_threads == 1 || ps_dec->i4_error_code != 0) + { + return; + } u4_max_addr = ps_dec->ps_cur_sps->u4_max_mb_addr; u1_mb_aff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; @@ -528,7 +536,7 @@ void ih264d_recon_deblk_slice(dec_struct_t *ps_dec, tfr_ctxt_t *ps_tfr_cxt) } - while(1) + while(ps_dec->i4_break_threads != 1 && ps_dec->i4_error_code == 0) { UWORD32 u4_cond = 0; UWORD32 u4_mb_num = ps_dec->cur_recon_mb_num + recon_mb_grp - 1; @@ -574,6 +582,10 @@ void ih264d_recon_deblk_slice(dec_struct_t *ps_dec, tfr_ctxt_t *ps_tfr_cxt) } } } + if(ps_dec->i4_break_threads == 1 || ps_dec->i4_error_code != 0) + { + return; + } for(j = 0; j < recon_mb_grp; j++) { @@ -724,7 +736,8 @@ void ih264d_recon_deblk_thread(dec_struct_t *ps_dec) DEBUG_THREADS_PRINTF(" Exit compute bs slice \n"); - if(ps_dec->cur_recon_mb_num > ps_dec->ps_cur_sps->u4_max_mb_addr) + if((ps_dec->cur_recon_mb_num > ps_dec->ps_cur_sps->u4_max_mb_addr) || + (ps_dec->i4_error_code != 0) || (ps_dec->i4_break_threads == 1)) { break; } diff --git a/decoder/ih264d_thread_parse_decode.c b/decoder/ih264d_thread_parse_decode.c index 5aabe1a3..c78696dc 100644 --- a/decoder/ih264d_thread_parse_decode.c +++ b/decoder/ih264d_thread_parse_decode.c @@ -225,7 +225,7 @@ WORD32 ih264d_decode_recon_tfr_nmb_thread(dec_struct_t * ps_dec, u2_cur_dec_mb_num = ps_dec->cur_dec_mb_num; - while(1) + while(ps_dec->i4_break_threads != 1 && ps_dec->i4_error_code == 0) { UWORD32 u4_max_mb = (UWORD32)(ps_dec->i2_dec_thread_mb_y + (1 << u1_mbaff)) * ps_dec->u2_frm_wd_in_mbs - 1; @@ -267,6 +267,10 @@ WORD32 ih264d_decode_recon_tfr_nmb_thread(dec_struct_t * ps_dec, } } } + if(ps_dec->i4_break_threads == 1 || ps_dec->i4_error_code != 0) + { + return NOT_OK; + } /* N Mb MC Loop */ for(i = 0; i < u4_num_mbs; i++) { @@ -446,15 +450,15 @@ WORD32 ih264d_decode_slice_thread(dec_struct_t *ps_dec) UWORD8 u1_field_pic; UWORD32 u4_frame_stride, x_offset, y_offset; WORD32 ret; + WORD32 nop_cnt = 8 * 128; tfr_ctxt_t *ps_trns_addr; /*check for mb map of first mb in slice to ensure slice header is parsed*/ - while(1) + while(ps_dec->i4_break_threads != 1 && ps_dec->i4_error_code == 0) { UWORD32 u4_mb_num = ps_dec->cur_dec_mb_num; UWORD32 u4_cond = 0; - WORD32 nop_cnt = 8 * 128; CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond); if(u4_cond) { @@ -489,6 +493,10 @@ WORD32 ih264d_decode_slice_thread(dec_struct_t *ps_dec) } } + if(ps_dec->i4_break_threads == 1 || ps_dec->i4_error_code != 0) + { + return NOT_OK; + } @@ -624,8 +632,8 @@ void ih264d_decode_picture_thread(dec_struct_t *ps_dec ) DEBUG_THREADS_PRINTF(" Exit ih264d_decode_slice_thread \n"); - if(ps_dec->cur_dec_mb_num - > ps_dec->ps_cur_sps->u4_max_mb_addr) + if((ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u4_max_mb_addr) || + (ps_dec->i4_error_code != 0) || (ps_dec->i4_break_threads == 1)) { /*Last slice in frame*/ break;