diff options
author | Harish Mahendrakar <harish.mahendrakar@ittiam.com> | 2023-08-08 08:35:04 -0700 |
---|---|---|
committer | Ray Essick <essick@google.com> | 2024-01-09 18:28:02 +0000 |
commit | 06e4615c5997244c1ba26bd8d7116af7e72a88d5 (patch) | |
tree | 31ecb08a3b960e6bd39cd711bbcc03398c60d8d4 | |
parent | 167fcb1131bb652723144df4d8c865e0926f7168 (diff) | |
download | libavc-06e4615c5997244c1ba26bd8d7116af7e72a88d5.tar.gz |
Upgrade libavc to v1.2.0
This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update libavc
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
Bug: 294918275
Test: atest CtsMediaV2TestCases
Merged-In: If23a6d3f5ee294b17ba621528428b27b54d25e71
Change-Id: If23a6d3f5ee294b17ba621528428b27b54d25e71
33 files changed, 466 insertions, 287 deletions
diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 91fa5ed..39f5d24 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -3,6 +3,9 @@ on: [pull_request] jobs: Fuzzing: runs-on: ubuntu-latest + strategy: + matrix: + sanitizer: [address, memory] steps: - name: Build Fuzzers id: build @@ -1,6 +1,6 @@ # This project was upgraded with external_updater. # Usage: tools/external_updater/updater.sh update libavc -# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md +# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md name: "libavc" description: "Android fork of the libavc library." @@ -9,11 +9,11 @@ third_party { type: GIT value: "https://github.com/ittiam-systems/libavc.git" } - version: "v1.1.1" + version: "v1.2.0" license_type: NOTICE last_upgrade_date { year: 2023 - month: 3 - day: 15 + month: 8 + day: 8 } } diff --git a/common/ithread.c b/common/ithread.c index d45bfed..6aa9961 100644 --- a/common/ithread.c +++ b/common/ithread.c @@ -210,7 +210,6 @@ WORD32 ithread_set_affinity(WORD32 core_id) } -#ifdef KEEP_THREADS_ACTIVE WORD32 ithread_get_cond_struct_size(void) { return (sizeof(pthread_cond_t)); @@ -235,4 +234,3 @@ WORD32 ithread_cond_signal(void *cond) { return pthread_cond_signal((pthread_cond_t *)cond); } -#endif diff --git a/common/ithread.h b/common/ithread.h index c2843f8..45e755f 100644 --- a/common/ithread.h +++ b/common/ithread.h @@ -98,7 +98,6 @@ WORD32 ithread_set_affinity(WORD32 core_id); void ithread_set_name(CHAR *pc_thread_name); -#ifdef KEEP_THREADS_ACTIVE WORD32 ithread_get_cond_struct_size(void); WORD32 ithread_cond_init(void *cond); @@ -108,6 +107,5 @@ WORD32 ithread_cond_destroy(void *cond); WORD32 ithread_cond_wait(void *cond, void *mutex); WORD32 ithread_cond_signal(void *cond); -#endif #endif /* _ITHREAD_H_ */ diff --git a/decoder/ih264d.h b/decoder/ih264d.h index b29b3b0..dba02b9 100644 --- a/decoder/ih264d.h +++ b/decoder/ih264d.h @@ -116,6 +116,11 @@ typedef struct { * enable_frm_info */ UWORD32 u4_enable_frame_info; + + /** + * enable_threads + */ + UWORD32 u4_keep_threads_active; }ih264d_create_ip_t; diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c index 221bf3e..315f701 100644 --- a/decoder/ih264d_api.c +++ b/decoder/ih264d_api.c @@ -1389,67 +1389,79 @@ void ih264d_init_decoder(void * ps_dec_params) ps_dec->init_done = 1; } -WORD32 ih264d_free_static_bufs(iv_obj_t *dec_hdl) + +WORD32 ih264d_join_threads(dec_struct_t *ps_dec) { - dec_struct_t *ps_dec; + if(ps_dec->i4_threads_active) + { + /* Wait for threads */ + ps_dec->i4_break_threads = 1; + if(ps_dec->u4_dec_thread_created) + { + ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); - void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); - void *pv_mem_ctxt; + ps_dec->ai4_process_start[0] = PROC_START; - ps_dec = (dec_struct_t *)dec_hdl->pv_codec_handle; - pf_aligned_free = ps_dec->pf_aligned_free; - pv_mem_ctxt = ps_dec->pv_mem_ctxt; + ithread_cond_signal(ps_dec->apv_proc_start_condition[0]); -#ifdef KEEP_THREADS_ACTIVE - /* Wait for threads */ - ps_dec->i4_break_threads = 1; - if(ps_dec->u4_dec_thread_created) - { - ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); + ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); - ps_dec->ai4_process_start[0] = PROC_START; + ithread_join(ps_dec->pv_dec_thread_handle, NULL); - ithread_cond_signal(ps_dec->apv_proc_start_condition[0]); + ps_dec->u4_dec_thread_created = 0; + } - ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); + if(ps_dec->u4_bs_deblk_thread_created) + { + ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); - ithread_join(ps_dec->pv_dec_thread_handle, NULL); + ps_dec->ai4_process_start[1] = PROC_START; - ps_dec->u4_dec_thread_created = 0; - } + ithread_cond_signal(ps_dec->apv_proc_start_condition[1]); - if(ps_dec->u4_bs_deblk_thread_created) - { - ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); + ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); - ps_dec->ai4_process_start[1] = PROC_START; + ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL); - ithread_cond_signal(ps_dec->apv_proc_start_condition[1]); + ps_dec->u4_bs_deblk_thread_created = 0; + } + } + return IV_SUCCESS; +} - ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); +WORD32 ih264d_free_static_bufs(iv_obj_t *dec_hdl) +{ + dec_struct_t *ps_dec; - ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL); + void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); + void *pv_mem_ctxt; - ps_dec->u4_bs_deblk_thread_created = 0; - } + ps_dec = (dec_struct_t *)dec_hdl->pv_codec_handle; + pf_aligned_free = ps_dec->pf_aligned_free; + pv_mem_ctxt = ps_dec->pv_mem_ctxt; - // destroy mutex and condition variable for both the threads - // 1. ih264d_decode_picture_thread - // 2. ih264d_recon_deblk_thread + if(ps_dec->i4_threads_active) { - UWORD32 i; - for(i = 0; i < 2; i++) + + ih264d_join_threads(ps_dec); + + // destroy mutex and condition variable for both the threads + // 1. ih264d_decode_picture_thread + // 2. ih264d_recon_deblk_thread { - ithread_cond_destroy(ps_dec->apv_proc_start_condition[i]); - ithread_cond_destroy(ps_dec->apv_proc_done_condition[i]); + UWORD32 i; + for(i = 0; i < 2; i++) + { + ithread_cond_destroy(ps_dec->apv_proc_start_condition[i]); + ithread_cond_destroy(ps_dec->apv_proc_done_condition[i]); - ithread_mutex_destroy(ps_dec->apv_proc_start_mutex[i]); - ithread_mutex_destroy(ps_dec->apv_proc_done_mutex[i]); + ithread_mutex_destroy(ps_dec->apv_proc_start_mutex[i]); + ithread_mutex_destroy(ps_dec->apv_proc_done_mutex[i]); + } } + PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_mutex[0]); + PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_condition[0]); } - PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_mutex[0]); - PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_condition[0]); -#endif PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sps); PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pps); @@ -1567,6 +1579,7 @@ WORD32 ih264d_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv ps_dec->pf_aligned_alloc = pf_aligned_alloc; ps_dec->pf_aligned_free = pf_aligned_free; ps_dec->pv_mem_ctxt = pv_mem_ctxt; + ps_dec->i4_threads_active = ps_create_ip->u4_keep_threads_active; size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS); @@ -1593,7 +1606,7 @@ WORD32 ih264d_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv memset(pv_buf, 0, size); ps_dec->pv_bs_deblk_thread_handle = pv_buf; -#ifdef KEEP_THREADS_ACTIVE + if(ps_dec->i4_threads_active) { UWORD32 i; /* Request memory to hold mutex (start/done) for both threads */ @@ -1644,7 +1657,6 @@ WORD32 ih264d_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv RETURN_IF((ret != IV_SUCCESS), ret); } } -#endif size = sizeof(dpb_manager_t); pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); @@ -2197,7 +2209,7 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) } ps_dec->u1_pic_decode_done = 0; -#ifdef KEEP_THREADS_ACTIVE + if(ps_dec->i4_threads_active) { UWORD32 i; ps_dec->i4_break_threads = 0; @@ -2212,10 +2224,10 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) RETURN_IF((ret != IV_SUCCESS), ret); } } -#else - ps_dec->u4_dec_thread_created = 0; - ps_dec->u4_bs_deblk_thread_created = 0; -#endif + else { + ps_dec->u4_dec_thread_created = 0; + ps_dec->u4_bs_deblk_thread_created = 0; + } ps_dec_op->u4_num_bytes_consumed = 0; ps_dec_op->i4_reorder_depth = -1; @@ -2842,12 +2854,13 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) } /* close deblock thread if it is not closed yet*/ -#ifndef KEEP_THREADS_ACTIVE - if(ps_dec->u4_num_cores == 3) + if(!ps_dec->i4_threads_active) { - ih264d_signal_bs_deblk_thread(ps_dec); + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } } -#endif { @@ -3671,6 +3684,7 @@ WORD32 ih264d_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) if(ps_dec != NULL) { + ih264d_join_threads(ps_dec); ih264d_init_decoder(ps_dec); } else diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c index 729e308..e97d09b 100644 --- a/decoder/ih264d_parse_pslice.c +++ b/decoder/ih264d_parse_pslice.c @@ -1578,17 +1578,18 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec, ps_dec->u4_dec_thread_created = 1; } -#ifdef KEEP_THREADS_ACTIVE - ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); - RETURN_IF((ret != IV_SUCCESS), ret); + if(ps_dec->i4_threads_active) + { + ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); + RETURN_IF((ret != IV_SUCCESS), ret); - ps_dec->ai4_process_start[0] = PROC_START; - ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[0]); - RETURN_IF((ret != IV_SUCCESS), ret); + ps_dec->ai4_process_start[0] = PROC_START; + ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[0]); + RETURN_IF((ret != IV_SUCCESS), ret); - ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); - RETURN_IF((ret != IV_SUCCESS), ret); -#endif + ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); + RETURN_IF((ret != IV_SUCCESS), ret); + } if((ps_dec->u4_num_cores == 3) && ((ps_dec->u4_app_disable_deblk_frm == 0) || ps_dec->i1_recon_in_thread3_flag) @@ -1600,20 +1601,21 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec, (void *)ps_dec); ps_dec->u4_bs_deblk_thread_created = 1; } -#ifdef KEEP_THREADS_ACTIVE - if (ps_dec->u4_bs_deblk_thread_created) + if(ps_dec->i4_threads_active) { - ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); - RETURN_IF((ret != IV_SUCCESS), ret); - - ps_dec->ai4_process_start[1] = PROC_START; - ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[1]); - RETURN_IF((ret != IV_SUCCESS), ret); - - ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); - RETURN_IF((ret != IV_SUCCESS), ret); + if (ps_dec->u4_bs_deblk_thread_created) + { + ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); + RETURN_IF((ret != IV_SUCCESS), ret); + + ps_dec->ai4_process_start[1] = PROC_START; + ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[1]); + RETURN_IF((ret != IV_SUCCESS), ret); + + ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); + RETURN_IF((ret != IV_SUCCESS), ret); + } } -#endif } } } diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index 87c59e9..5fe1b4e 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -1162,7 +1162,10 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, if(ps_dec->ps_cur_sps->u1_gaps_in_frame_num_value_allowed_flag) { - ih264d_decode_gaps_in_frame_num(ps_dec, u2_frame_num); + ret = ih264d_decode_gaps_in_frame_num(ps_dec, u2_frame_num); + if (ret != OK) { + return ERROR_DBP_MANAGER_T; + } } ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst; @@ -1591,17 +1594,18 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, ps_dec->u4_dec_thread_created = 1; } -#ifdef KEEP_THREADS_ACTIVE - ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); - RETURN_IF((ret != IV_SUCCESS), ret); + if(ps_dec->i4_threads_active) + { + ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); + RETURN_IF((ret != IV_SUCCESS), ret); - ps_dec->ai4_process_start[0] = PROC_START; - ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[0]); - RETURN_IF((ret != IV_SUCCESS), ret); + ps_dec->ai4_process_start[0] = PROC_START; + ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[0]); + RETURN_IF((ret != IV_SUCCESS), ret); - ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); - RETURN_IF((ret != IV_SUCCESS), ret); -#endif + ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); + RETURN_IF((ret != IV_SUCCESS), ret); + } if((ps_dec->u4_num_cores == 3) && ((ps_dec->u4_app_disable_deblk_frm == 0) || ps_dec->i1_recon_in_thread3_flag) @@ -1613,20 +1617,21 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, (void *)ps_dec); ps_dec->u4_bs_deblk_thread_created = 1; } -#ifdef KEEP_THREADS_ACTIVE - if (ps_dec->u4_bs_deblk_thread_created) + if(ps_dec->i4_threads_active) { - ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); - RETURN_IF((ret != IV_SUCCESS), ret); + if (ps_dec->u4_bs_deblk_thread_created) + { + ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); + RETURN_IF((ret != IV_SUCCESS), ret); - ps_dec->ai4_process_start[1] = PROC_START; - ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[1]); - RETURN_IF((ret != IV_SUCCESS), ret); + ps_dec->ai4_process_start[1] = PROC_START; + ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[1]); + RETURN_IF((ret != IV_SUCCESS), ret); - ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); - RETURN_IF((ret != IV_SUCCESS), ret); + ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); + RETURN_IF((ret != IV_SUCCESS), ret); + } } -#endif } } diff --git a/decoder/ih264d_structs.h b/decoder/ih264d_structs.h index bcab1ea..cc8e081 100644 --- a/decoder/ih264d_structs.h +++ b/decoder/ih264d_structs.h @@ -123,7 +123,6 @@ typedef enum COEFF_ABS_LEVEL_CAT_5_OFFSET = 0 } cabac_blk_cat_offset_t; -#ifdef KEEP_THREADS_ACTIVE typedef enum { PROC_INIT, @@ -131,7 +130,6 @@ typedef enum PROC_IN_PROGRESS, PROC_DONE, } proc_state_t; -#endif /** Structure for the MV bank */ typedef struct _mv_pred_t @@ -771,6 +769,8 @@ typedef struct _DecStruct UWORD8 *pu1_col_zero_flag; + UWORD8 i4_threads_active; /** Keeps thread active*/ + UWORD16 u2_pic_wd; /** Width of the picture being decoded */ UWORD16 u2_pic_ht; /** Height of the picture being decoded */ UWORD32 u4_total_mbs; /** Total MBs in the picture being decoded */ @@ -1315,7 +1315,6 @@ typedef struct _DecStruct UWORD32 u4_dec_thread_created; void *pv_dec_thread_handle; -#ifdef KEEP_THREADS_ACTIVE /** * Condition variable to signal process start - One for each thread */ @@ -1350,7 +1349,6 @@ typedef struct _DecStruct * Flag to signal processing thread to exit */ WORD32 i4_break_threads; -#endif volatile UWORD8 *pu1_dec_mb_map; volatile UWORD8 *pu1_recon_mb_map; diff --git a/decoder/ih264d_thread_compute_bs.c b/decoder/ih264d_thread_compute_bs.c index e647a60..961b1a6 100644 --- a/decoder/ih264d_thread_compute_bs.c +++ b/decoder/ih264d_thread_compute_bs.c @@ -692,27 +692,29 @@ void ih264d_recon_deblk_thread(dec_struct_t *ps_dec) UWORD32 yield_cnt = 0; + UWORD32 ret; ithread_set_name("ih264d_recon_deblk_thread"); while(1) { -#ifdef KEEP_THREADS_ACTIVE - UWORD32 ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); - if(OK != ret) - break; - - while(ps_dec->ai4_process_start[1] != PROC_START) + if(ps_dec->i4_threads_active) { - ithread_cond_wait(ps_dec->apv_proc_start_condition[1], - ps_dec->apv_proc_start_mutex[1]); - } - ps_dec->ai4_process_start[1] = PROC_IN_PROGRESS; + ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); + if(OK != ret) + break; - ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); - if(OK != ret || ps_dec->i4_break_threads == 1) - break; -#endif + while(ps_dec->ai4_process_start[1] != PROC_START) + { + ithread_cond_wait(ps_dec->apv_proc_start_condition[1], + ps_dec->apv_proc_start_mutex[1]); + } + ps_dec->ai4_process_start[1] = PROC_IN_PROGRESS; + + ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); + if(OK != ret || ps_dec->i4_break_threads == 1) + break; + } while(1) { @@ -748,8 +750,8 @@ void ih264d_recon_deblk_thread(dec_struct_t *ps_dec) ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; } - -#ifdef KEEP_THREADS_ACTIVE + if(ps_dec->i4_threads_active) + { ret = ithread_mutex_lock(ps_dec->apv_proc_done_mutex[1]); if(OK != ret) break; @@ -760,9 +762,11 @@ void ih264d_recon_deblk_thread(dec_struct_t *ps_dec) ret = ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[1]); if(OK != ret) break; -#else - break; -#endif + } + else + { + break; + } } } diff --git a/decoder/ih264d_thread_parse_decode.c b/decoder/ih264d_thread_parse_decode.c index 47571b3..7d56d16 100644 --- a/decoder/ih264d_thread_parse_decode.c +++ b/decoder/ih264d_thread_parse_decode.c @@ -596,22 +596,24 @@ void ih264d_decode_picture_thread(dec_struct_t *ps_dec ) while(1) { -#ifdef KEEP_THREADS_ACTIVE - WORD32 ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); - if(OK != ret) - break; - - while(ps_dec->ai4_process_start[0] != PROC_START) + WORD32 ret; + if(ps_dec->i4_threads_active) { - ithread_cond_wait(ps_dec->apv_proc_start_condition[0], - ps_dec->apv_proc_start_mutex[0]); - } - ps_dec->ai4_process_start[0] = PROC_IN_PROGRESS; + ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); + if(OK != ret) + break; - ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); - if(OK != ret || ps_dec->i4_break_threads == 1) - break; -#endif + while(ps_dec->ai4_process_start[0] != PROC_START) + { + ithread_cond_wait(ps_dec->apv_proc_start_condition[0], + ps_dec->apv_proc_start_mutex[0]); + } + ps_dec->ai4_process_start[0] = PROC_IN_PROGRESS; + + ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); + if(OK != ret || ps_dec->i4_break_threads == 1) + break; + } while(1) { /*Complete all writes before processing next slice*/ @@ -647,20 +649,23 @@ void ih264d_decode_picture_thread(dec_struct_t *ps_dec ) ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; } -#ifdef KEEP_THREADS_ACTIVE - ret = ithread_mutex_lock(ps_dec->apv_proc_done_mutex[0]); - if(OK != ret) - break; + if(ps_dec->i4_threads_active) + { + ret = ithread_mutex_lock(ps_dec->apv_proc_done_mutex[0]); + if(OK != ret) + break; - ps_dec->ai4_process_done[0] = PROC_DONE; - ithread_cond_signal(ps_dec->apv_proc_done_condition[0]); + ps_dec->ai4_process_done[0] = PROC_DONE; + ithread_cond_signal(ps_dec->apv_proc_done_condition[0]); - ret = ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[0]); - if(OK != ret) + ret = ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[0]); + if(OK != ret) + break; + } + else + { break; -#else - break; -#endif + } } } @@ -668,58 +673,64 @@ void ih264d_signal_decode_thread(dec_struct_t *ps_dec) { if(ps_dec->u4_dec_thread_created == 1) { -#ifdef KEEP_THREADS_ACTIVE - proc_state_t i4_process_state; - ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); - i4_process_state = ps_dec->ai4_process_start[0]; - ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); - - // only wait if the thread has started decoding - if(i4_process_state != PROC_INIT) + if(ps_dec->i4_threads_active) { - ithread_mutex_lock(ps_dec->apv_proc_done_mutex[0]); + proc_state_t i4_process_state; + ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); + i4_process_state = ps_dec->ai4_process_start[0]; + ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); - while(ps_dec->ai4_process_done[0] != PROC_DONE) + // only wait if the thread has started decoding + if(i4_process_state != PROC_INIT) { - ithread_cond_wait(ps_dec->apv_proc_done_condition[0], - ps_dec->apv_proc_done_mutex[0]); + ithread_mutex_lock(ps_dec->apv_proc_done_mutex[0]); + + while(ps_dec->ai4_process_done[0] != PROC_DONE) + { + ithread_cond_wait(ps_dec->apv_proc_done_condition[0], + ps_dec->apv_proc_done_mutex[0]); + } + ps_dec->ai4_process_done[0] = PROC_INIT; + ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[0]); } - ps_dec->ai4_process_done[0] = PROC_INIT; - ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[0]); } -#else - ithread_join(ps_dec->pv_dec_thread_handle, NULL); - ps_dec->u4_dec_thread_created = 0; -#endif + else + { + ithread_join(ps_dec->pv_dec_thread_handle, NULL); + ps_dec->u4_dec_thread_created = 0; + } } } void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec) { if(ps_dec->u4_bs_deblk_thread_created) { -#ifdef KEEP_THREADS_ACTIVE - proc_state_t i4_process_state; - ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); - i4_process_state = ps_dec->ai4_process_start[1]; - ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); - - // only wait if the thread has started deblking - if(i4_process_state != PROC_INIT) + if(ps_dec->i4_threads_active) { - ithread_mutex_lock(ps_dec->apv_proc_done_mutex[1]); + proc_state_t i4_process_state; + ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); + i4_process_state = ps_dec->ai4_process_start[1]; + ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); - while(ps_dec->ai4_process_done[1] != PROC_DONE) + // only wait if the thread has started deblking + if(i4_process_state != PROC_INIT) { - ithread_cond_wait(ps_dec->apv_proc_done_condition[1], - ps_dec->apv_proc_done_mutex[1]); + ithread_mutex_lock(ps_dec->apv_proc_done_mutex[1]); + + while(ps_dec->ai4_process_done[1] != PROC_DONE) + { + ithread_cond_wait(ps_dec->apv_proc_done_condition[1], + ps_dec->apv_proc_done_mutex[1]); + } + ps_dec->ai4_process_done[1] = PROC_INIT; + ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[1]); } - ps_dec->ai4_process_done[1] = PROC_INIT; - ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[1]); } -#else - ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL); - ps_dec->u4_bs_deblk_thread_created = 0; -#endif + else + { + ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL); + ps_dec->u4_bs_deblk_thread_created = 0; + } } } diff --git a/decoder/mvc/imvcd_defs.h b/decoder/mvc/imvcd_defs.h index 2bf5e54..0b8c976 100644 --- a/decoder/mvc/imvcd_defs.h +++ b/decoder/mvc/imvcd_defs.h @@ -34,6 +34,14 @@ is still greater than any possible value of u1_pic_buf_id */ #define IVP_PIC_BUF_ID UINT8_MAX -#define MIN_BITSTREAMS_BUF_SIZE 256000 +/* In FGC SEI + - Worst-case bits for all elements before 'num_intensity_intervals_minus1' = 47 + - Worst-case bits for all elements before 'film_grain_characteristics_repetition_period', not + including elements from previous line = 3 * (8 + 3 + 256 * (8 + 8 + 8 * 16)) = 110625 + - Worst-case bits for 'film_grain_characteristics_repetition_period' = 30 + Total of (47 + 110625 + 30) = 110702 byte */ +#define MAX_FGC_SEI_SIZE 110702 + +#define MIN_BITSTREAMS_BUF_SIZE (MAX_FGC_SEI_SIZE + 256000) #endif diff --git a/decoder/mvc/imvcd_dpb_manager.c b/decoder/mvc/imvcd_dpb_manager.c index b05a123..48c5072 100644 --- a/decoder/mvc/imvcd_dpb_manager.c +++ b/decoder/mvc/imvcd_dpb_manager.c @@ -1087,6 +1087,11 @@ void imvcd_dpb_normalise_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_ for(i = 0; i < u1_num_ref_bufs; i++) { + if(u1_num_bufs_modified >= MVC_MAX_REF_PICS) + { + return; + } + if(!(u2_buf_mod_bitfield & (1 << i))) { ps_dpb_mgr->aps_mod_dpb[u1_pred_lx][u1_num_bufs_modified++] = diff --git a/decoder/mvc/imvcd_slice_functions.c b/decoder/mvc/imvcd_slice_functions.c index e44f2a5..4308f4d 100644 --- a/decoder/mvc/imvcd_slice_functions.c +++ b/decoder/mvc/imvcd_slice_functions.c @@ -513,7 +513,6 @@ static WORD32 imvcd_decode_gaps_in_frame_num(mvc_dec_ctxt_t *ps_mvcd_ctxt) mvc_dpb_manager_t *ps_dpb_mgr = ps_mvcd_ctxt->ps_dpb_mgr; UWORD16 u2_frame_num = ps_cur_slice->u2_frame_num; - WORD32 i4_frame_gaps = 0; UWORD32 u4_next_frm_num = ps_view_ctxt->u2_prev_ref_frame_num + 1; UWORD32 u4_max_frm_num = ps_view_ctxt->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1; WORD32 *pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num; @@ -646,8 +645,6 @@ static WORD32 imvcd_decode_gaps_in_frame_num(mvc_dec_ctxt_t *ps_mvcd_ctxt) { u4_next_frm_num -= u4_max_frm_num; } - - i4_frame_gaps++; } return OK; @@ -1236,7 +1233,6 @@ static WORD32 imvcd_corrupted_slice_handler(mvc_dec_ctxt_t *ps_mvcd_ctxt) bool b_decode_nmb; UWORD8 u1_inter_mb_type; UWORD8 u1_deblk_mb_type; - UWORD32 u4_num_mbsNby2; UWORD16 i2_cur_mb_addr; UWORD32 u4_mb_skip_run; WORD32 i, j; @@ -1395,7 +1391,6 @@ static WORD32 imvcd_corrupted_slice_handler(mvc_dec_ctxt_t *ps_mvcd_ctxt) b_is_slice_end = false; b_tfr_n_mb = false; b_decode_nmb = false; - u4_num_mbsNby2 = 0; i2_cur_mb_addr = ps_view_ctxt->u2_total_mbs_coded; u4_mb_skip_run = u4_remaining_mbs; @@ -1457,7 +1452,6 @@ static WORD32 imvcd_corrupted_slice_handler(mvc_dec_ctxt_t *ps_mvcd_ctxt) i2_cur_mb_addr++; u4_num_mbs++; - u4_num_mbsNby2++; ps_parse_mb_data++; /****************************************************************/ @@ -1477,7 +1471,6 @@ static WORD32 imvcd_corrupted_slice_handler(mvc_dec_ctxt_t *ps_mvcd_ctxt) { ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb(ps_view_ctxt, u4_mb_idx, u4_num_mbs); - u4_num_mbsNby2 = 0; ps_parse_mb_data = ps_view_ctxt->ps_parse_mb_data; ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params; diff --git a/decoder/svc/isvcd_ii_pred.c b/decoder/svc/isvcd_ii_pred.c index 1a89608..4162803 100644 --- a/decoder/svc/isvcd_ii_pred.c +++ b/decoder/svc/isvcd_ii_pred.c @@ -117,11 +117,13 @@ WORD32 isvcd_ii_pred_res_init(void *pv_svc_dec) ps_ii_pred_ctxt->i4_ref_res_lyr_ht = ps_ii_pred_ctxt->i4_cur_res_lyr_ht; } - ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id]; - - ps_ii_pred_ctxt->pi2_ref_loc_x = ps_lyr_mem->pi2_ref_loc_x; - ps_ii_pred_ctxt->pi2_ref_loc_y = ps_lyr_mem->pi2_ref_loc_y; + if ((ps_ctxt->i4_res_id >= 0) && (ps_ctxt->i4_res_id <= 2)) + { + ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id]; + ps_ii_pred_ctxt->pi2_ref_loc_x = ps_lyr_mem->pi2_ref_loc_x; + ps_ii_pred_ctxt->pi2_ref_loc_y = ps_lyr_mem->pi2_ref_loc_y; + } /* Store the dimensions */ ps_ii_pred_ctxt->i4_cur_res_lyr_wd = ps_res_prms->i4_res_width; ps_ii_pred_ctxt->i4_cur_res_lyr_ht = ps_res_prms->i4_res_height; diff --git a/decoder/svc/isvcd_parse_ebslice.c b/decoder/svc/isvcd_parse_ebslice.c index 3a92dfe..d805764 100644 --- a/decoder/svc/isvcd_parse_ebslice.c +++ b/decoder/svc/isvcd_parse_ebslice.c @@ -487,6 +487,18 @@ WORD32 isvcd_mv_pred_ref_tfr_nby2_ebmb(dec_struct_t *ps_dec, UWORD8 u1_mb_idx, U /********************************************************/ u1_tmp_lx = (u1_lx << 1); i1_ref_idx = s_mvPred.i1_ref_frame[u1_lx]; + /********************************************************************/ + /* If reference index is inferred from the base layer and it is */ + /* exceeding the number of active reference in the current layer. */ + /* Then reference index is clipped to the max in the current layer */ + /********************************************************************/ + if(ps_svc_cur_mb_info->u1_base_mode_flag == 1) + { + if(i1_ref_idx > (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[u1_lx] - 1)) + { + i1_ref_idx = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[u1_lx] - 1; + } + } if(0 == ps_svc_cur_mb_info->u1_base_mode_flag) { i2_mv_x = ps_mv_nmb->i2_mv[u1_tmp_lx]; diff --git a/decoder/svc/isvcd_process_epslice.c b/decoder/svc/isvcd_process_epslice.c index d23aa5e..cbcce8c 100644 --- a/decoder/svc/isvcd_process_epslice.c +++ b/decoder/svc/isvcd_process_epslice.c @@ -340,6 +340,18 @@ WORD32 isvcd_mv_pred_ref_tfr_nby2_epmb(dec_struct_t *ps_dec, UWORD8 u1_mb_idx, U /* Populate the colpic info and reference frames */ i1_ref_idx = pi1_ref_idx[u1_blk_no]; + /********************************************************************/ + /* If reference index is inferred from the base layer and it is */ + /* exceeding the number of active reference in the current layer. */ + /* Then reference index is clipped to the max in the current layer */ + /********************************************************************/ + if(ps_svc_cur_mb_info->u1_base_mode_flag == 1) + { + if(i1_ref_idx > (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1)) + { + i1_ref_idx = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1; + } + } s_mvPred.i1_ref_frame[0] = i1_ref_idx; if((1 != ps_svc_cur_mb_info->u1_base_mode_flag) && diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index 055c6e2..c4c6050 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -1435,9 +1435,7 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, return IV_FAIL; } - if ((ps_ip->s_ive_ip.u4_me_speed_preset != FULL_SRCH) - && (ps_ip->s_ive_ip.u4_me_speed_preset != DMND_SRCH) - && (ps_ip->s_ive_ip.u4_me_speed_preset != HEX_SRCH)) + if (ps_ip->s_ive_ip.u4_me_speed_preset != DMND_SRCH) { ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c index 75a8335..1db0850 100644 --- a/encoder/ih264e_encode.c +++ b/encoder/ih264e_encode.c @@ -215,8 +215,8 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ih264e_video_encode_op_t *ps_video_encode_op = pv_api_op; /* i/o structures */ - inp_buf_t s_inp_buf; - out_buf_t s_out_buf; + inp_buf_t s_inp_buf = {}; + out_buf_t s_out_buf = {}; /* temp var */ WORD32 ctxt_sel = 0, i, i4_rc_pre_enc_skip; @@ -233,6 +233,15 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) /* This will later be updated to the actual input that gets encoded */ ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf; + if (ps_codec->i4_error_code & (1 << IVE_FATALERROR)) + { + error_status = ps_codec->i4_error_code & 0xFF; + SET_ERROR_ON_RETURN(error_status, + IVE_FATALERROR, + ps_video_encode_op->s_ive_op.u4_error_code, + IV_FAIL); + } + /* Check for output memory allocation size */ if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE) { @@ -243,6 +252,15 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) IV_FAIL); } + if (ps_codec->i4_init_done != 1) + { + error_status = IH264E_INIT_NOT_DONE; + SET_ERROR_ON_RETURN(error_status, + IVE_FATALERROR, + ps_video_encode_op->s_ive_op.u4_error_code, + IV_FAIL); + } + /* copy output info. to internal structure */ s_out_buf.s_bits_buf = ps_video_encode_ip->s_ive_ip.s_out_buf; s_out_buf.u4_is_last = 0; @@ -283,7 +301,7 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) { error_status = ih264e_codec_update_config(ps_codec, ps_cfg); SET_ERROR_ON_RETURN(error_status, - IVE_UNSUPPORTEDPARAM, + IVE_FATALERROR, ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); @@ -486,7 +504,7 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) /* error status */ SET_ERROR_ON_RETURN(error_status, - IVE_FATALERROR, + IVE_UNSUPPORTEDPARAM, ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); @@ -825,12 +843,12 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++) { - error_status = ps_codec->as_process[ctxt_sel + i].i4_error_code; - SET_ERROR_ON_RETURN(error_status, - IVE_FATALERROR, - ps_video_encode_op->s_ive_op.u4_error_code, - IV_FAIL); + error_status |= ps_codec->as_process[ctxt_sel + i].i4_error_code; } + SET_ERROR_ON_RETURN(error_status, + ((error_status == IH264E_BITSTREAM_BUFFER_OVERFLOW) ? + IVE_UNSUPPORTEDPARAM : IVE_FATALERROR), + ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); } else { diff --git a/encoder/ih264e_encode_header.h b/encoder/ih264e_encode_header.h index a028930..c4876b3 100644 --- a/encoder/ih264e_encode_header.h +++ b/encoder/ih264e_encode_header.h @@ -102,7 +102,6 @@ if(ps_entropy->i4_error_code != IH264E_SUCCESS) \ { \ DATA_SYNC(); \ - ps_codec->au4_entropy_thread_active[ctxt_sel] = 0; \ return ps_entropy->i4_error_code; \ } diff --git a/encoder/ih264e_error.h b/encoder/ih264e_error.h index a460e5a..05e8920 100644 --- a/encoder/ih264e_error.h +++ b/encoder/ih264e_error.h @@ -47,6 +47,7 @@ if (error != IH264E_SUCCESS) \ {\ out_status = ((1 << severity) | error);\ + ps_codec->i4_error_code = out_status;\ return (ret_code);\ } diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c index afb1bbd..cba5023 100644 --- a/encoder/ih264e_process.c +++ b/encoder/ih264e_process.c @@ -448,6 +448,7 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) { BITSTREAM_BYTE_ALIGN(ps_bitstrm); BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code); + RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel); ih264e_init_cabac_ctxt(ps_entropy); } } @@ -635,54 +636,9 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) ih264e_cabac_encode_terminate(ps_cabac_ctxt, 1); } - /* update current frame stats to rc library */ - { - /* number of bytes to stuff */ - WORD32 i4_stuff_bytes; - - /* update */ - i4_stuff_bytes = ih264e_update_rc_post_enc( - ps_codec, ctxt_sel, - (ps_proc->ps_codec->i4_poc == 0)); - - /* cbr rc - house keeping */ - if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]) - { - ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0; - } - else if (i4_stuff_bytes) - { - /* add filler nal units */ - ps_entropy->i4_error_code = ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuff_bytes); - RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel); - } - } - - /* - *Frame number is to be incremented only if the current frame is a - * reference frame. After each successful frame encode, we increment - * frame number by 1 - */ - if (!ps_codec->s_rate_control.post_encode_skip[ctxt_sel] - && ps_codec->u4_is_curr_frm_ref) - { - ps_codec->i4_frame_num++; - } - /********************************************************************/ - /* signal the output */ - /********************************************************************/ - ps_codec->as_out_buf[ctxt_sel].s_bits_buf.u4_bytes = - ps_entropy->ps_bitstrm->u4_strm_buf_offset; - DEBUG("entropy status %x", ps_entropy->i4_error_code); } - /* Dont execute any further instructions until store synchronization took place */ - DATA_SYNC(); - - /* allow threads to dequeue entropy jobs */ - ps_codec->au4_entropy_thread_active[ctxt_sel] = 0; - return ps_entropy->i4_error_code; } @@ -2427,6 +2383,12 @@ WORD32 ih264e_update_rc_post_enc(codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_i /* proc ctxt */ process_ctxt_t *ps_proc = &ps_codec->as_process[i4_proc_ctxt_sel_base]; + /* entropy context */ + entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy; + + /* Bitstream structure */ + bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm; + /* frame qp */ UWORD8 u1_frame_qp = ps_codec->u4_frame_qp; @@ -2505,7 +2467,35 @@ WORD32 ih264e_update_rc_post_enc(codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_i u1_frame_qp, &ps_codec->s_rate_control.num_intra_in_prev_frame, &ps_codec->s_rate_control.i4_avg_activity); - return i4_stuffing_byte; + + /* cbr rc - house keeping */ + if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]) + { + ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0; + } + else if (i4_stuffing_byte) + { + /* add filler nal units */ + ps_entropy->i4_error_code = ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuffing_byte); + } + + /* + * Frame number is to be incremented only if the current frame is a + * reference frame. After each successful frame encode, we increment + * frame number by 1 + */ + if (!ps_codec->s_rate_control.post_encode_skip[ctxt_sel] + && ps_codec->u4_is_curr_frm_ref) + { + ps_codec->i4_frame_num++; + } + /********************************************************************/ + /* signal the output */ + /********************************************************************/ + ps_codec->as_out_buf[ctxt_sel].s_bits_buf.u4_bytes = + ps_entropy->ps_bitstrm->u4_strm_buf_offset; + + return ps_entropy->i4_error_code; } /** @@ -2546,6 +2536,9 @@ WORD32 ih264e_process_thread(void *pv_proc) * the proc jobs are processed */ WORD32 is_blocking = 0; + /* codec context selector */ + WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS; + /* set affinity */ ithread_set_affinity(ps_proc->i4_id); @@ -2556,9 +2549,6 @@ WORD32 ih264e_process_thread(void *pv_proc) { int error = ithread_mutex_lock(ps_codec->pv_entropy_mutex); - /* codec context selector */ - WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS; - volatile UWORD32 *pu4_buf = &ps_codec->au4_entropy_thread_active[ctxt_sel]; /* have the lock */ @@ -2630,7 +2620,20 @@ WORKER: /* entropy code all mbs enlisted under the current job */ error_status = ih264e_entropy(ps_proc); - if(error_status !=IH264_SUCCESS) + + if ((s_job.i2_mb_y == ps_proc->i4_ht_mbs - 1) || error_status != IH264_SUCCESS) + { + error_status |= ih264e_update_rc_post_enc(ps_codec, ctxt_sel, + (ps_codec->i4_poc == 0)); + } + + /* Dont execute any further instructions until store synchronization took place */ + DATA_SYNC(); + + /* allow threads to dequeue entropy jobs */ + ps_codec->au4_entropy_thread_active[ctxt_sel] = 0; + + if (error_status != IH264_SUCCESS) { ps_proc->i4_error_code = error_status; return ret; diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c index d83b8be..cb5eb25 100644 --- a/encoder/ih264e_utils.c +++ b/encoder/ih264e_utils.c @@ -831,7 +831,6 @@ IH264E_ERROR_T ih264e_pic_buf_mgr_add_bufs(codec_t *ps_codec) if (pic_buf_size_allocated < 0) { - ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_PICBUF; return IH264E_INSUFFICIENT_MEM_PICBUF; } @@ -848,7 +847,6 @@ IH264E_ERROR_T ih264e_pic_buf_mgr_add_bufs(codec_t *ps_codec) if (0 != buf_ret) { - ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR; return IH264E_BUF_MGR_ERROR; } pu1_buf += (HPEL_PLANES_CNT - 1) * (chroma_samples + luma_samples); @@ -934,11 +932,7 @@ IH264E_ERROR_T ih264e_mv_buf_mgr_add_bufs(codec_t *ps_codec) if (mv_bank_size_allocated < 0) { - ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_MVBANK; - - error_status = IH264E_INSUFFICIENT_MEM_MVBANK; - - return error_status; + return IH264E_INSUFFICIENT_MEM_MVBANK; } ps_mv_buf->pu4_mb_pu_cnt = (UWORD32 *) pu1_buf; @@ -955,9 +949,7 @@ IH264E_ERROR_T ih264e_mv_buf_mgr_add_bufs(codec_t *ps_codec) if (IH264_SUCCESS != ret) { - ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR; - error_status = IH264E_BUF_MGR_ERROR; - return error_status; + return IH264E_BUF_MGR_ERROR; } ps_mv_buf++; @@ -1719,7 +1711,6 @@ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf) if (NULL == ps_mv_buf) { - ps_codec->i4_error_code = IH264E_NO_FREE_MVBANK; return IH264E_NO_FREE_MVBANK; } @@ -1751,7 +1742,6 @@ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf) if (NULL == ps_cur_pic) { - ps_codec->i4_error_code = IH264E_NO_FREE_PICBUF; return IH264E_NO_FREE_PICBUF; } @@ -2198,7 +2188,6 @@ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf) ret = ih264_list_queue(ps_codec->pv_proc_jobq, &s_job, 1); if (ret != IH264_SUCCESS) { - ps_codec->i4_error_code = ret; return IH264E_FAIL; } } diff --git a/encoder/svc/isvce_encode.c b/encoder/svc/isvce_encode.c index 25488ec..d3f6198 100644 --- a/encoder/svc/isvce_encode.c +++ b/encoder/svc/isvce_encode.c @@ -246,6 +246,12 @@ WORD32 isvce_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) isvce_codec_init(ps_codec); } + error_status = + isvce_svc_frame_params_validate(ps_codec->s_rate_control.apps_rate_control_api, + ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers); + SET_ERROR_ON_RETURN(error_status, IVE_UNSUPPORTEDPARAM, + ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); + /* parse configuration params */ for(i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++) { diff --git a/encoder/svc/isvce_process.c b/encoder/svc/isvce_process.c index 5aafff7..113dc38 100644 --- a/encoder/svc/isvce_process.c +++ b/encoder/svc/isvce_process.c @@ -2375,7 +2375,8 @@ WORD32 isvce_process(isvce_process_ctxt_t *ps_proc) ps_proc->ps_mb_info->u1_base_mode_flag = 0; } - isvce_mvp_idx_eval(ps_proc->ps_mb_info, ps_proc->ps_pred_mv, ps_proc->ps_ilp_mv->as_mv[0], + isvce_mvp_idx_eval(ps_proc->ps_mb_info, ps_proc->ps_pred_mv, + ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL, ps_proc->s_me_ctxt.pu1_mv_bits); /* 8x8 Tx is not supported, and I8x8 is also unsupported */ @@ -2472,7 +2473,8 @@ WORD32 isvce_process(isvce_process_ctxt_t *ps_proc) ps_sub_pic_rc_variables->u4_cbp = ps_proc->u4_cbp; ps_sub_pic_rc_variables->aps_mvps[0] = ps_proc->ps_pred_mv; #if MAX_MVP_IDX == 1 - ps_sub_pic_rc_variables->aps_mvps[1] = ps_proc->ps_ilp_mv->as_mv[0]; + ps_sub_pic_rc_variables->aps_mvps[1] = + ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL; #endif ps_sub_pic_rc_variables->apu1_nnzs[Y] = (UWORD8 *) ps_proc->au4_nnz; ps_sub_pic_rc_variables->apu1_nnzs[UV] = ps_proc->au1_chroma_nnz; diff --git a/encoder/svc/isvce_rc_mem_interface.c b/encoder/svc/isvce_rc_mem_interface.c index b021781..7431854 100644 --- a/encoder/svc/isvce_rc_mem_interface.c +++ b/encoder/svc/isvce_rc_mem_interface.c @@ -244,9 +244,9 @@ WORD32 isvce_get_rate_control_mem_tab(void *pv_rate_control, iv_mem_rec_t *ps_me refptr1[RC_MEM_FRAME_TIME] = &ps_rate_control->pps_frame_time; refptr1[RC_MEM_TIME_STAMP] = &ps_rate_control->pps_time_stamp; refptr1[RC_MEM_FRAME_RATE] = &ps_rate_control->pps_pd_frm_rate; - refptr1[RC_MEM_API_L0] = &ps_rate_control->apps_rate_control_api[0]; - refptr1[RC_MEM_API_L1] = &ps_rate_control->apps_rate_control_api[1]; - refptr1[RC_MEM_API_L2] = &ps_rate_control->apps_rate_control_api[2]; + refptr1[RC_MEM_API_L0] = (void **) &ps_rate_control->apps_rate_control_api[0]; + refptr1[RC_MEM_API_L1] = (void **) &ps_rate_control->apps_rate_control_api[1]; + refptr1[RC_MEM_API_L2] = (void **) &ps_rate_control->apps_rate_control_api[2]; } /* Get the total number of memtabs used by Frame time Module */ diff --git a/encoder/svc/isvce_structs.h b/encoder/svc/isvce_structs.h index 1acf2ed..25200f4 100644 --- a/encoder/svc/isvce_structs.h +++ b/encoder/svc/isvce_structs.h @@ -65,8 +65,23 @@ #include "ih264e_cabac_structs.h" #include "ih264e_defs.h" #include "ime_structs.h" + +/* Dependencies of 'irc_picture_type.h' */ #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" +#include "irc_mem_req_and_acq.h" + +/* Dependencies of 'irc_rate_control_api_structs' */ +#include "irc_picture_type.h" +#include "irc_rd_model.h" +#include "irc_vbr_storage_vbv.h" +#include "irc_est_sad.h" +#include "irc_bit_allocation.h" +#include "irc_mb_model_based.h" +#include "irc_cbr_buffer_control.h" +#include "irc_vbr_str_prms.h" +#include "irc_common.h" +#include "irc_rate_control_api_structs.h" #include "ih264e_structs.h" #include "isvce_cabac_structs.h" @@ -77,9 +92,6 @@ #include "isvce_pred_structs.h" #include "isvce_rc_utils.h" -#include "irc_cntrl_param.h" -#include "irc_frame_info_collector.h" - typedef struct svc_params_t { /** @@ -723,7 +735,7 @@ typedef struct isvce_entropy_ctxt_t */ typedef struct isvce_rate_control_ctxt_t { - void *apps_rate_control_api[MAX_NUM_SPATIAL_LAYERS]; + rate_control_api_t *apps_rate_control_api[MAX_NUM_SPATIAL_LAYERS]; void *pps_frame_time; diff --git a/encoder/svc/isvce_sub_pic_rc.c b/encoder/svc/isvce_sub_pic_rc.c index 92a66b7..b627355 100644 --- a/encoder/svc/isvce_sub_pic_rc.c +++ b/encoder/svc/isvce_sub_pic_rc.c @@ -710,7 +710,8 @@ UWORD8 isvce_sub_pic_rc_get_mb_qp(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt, UWO u4_num_mbs_sampled = ps_layer_state->u4_num_mbs_sampled; - if(u4_num_mbs_sampled < (MIN_SAMPLED_MB_RATIO * ps_layer_state->i4_num_mbs)) + if(u4_num_mbs_sampled < + ((UWORD32) ceil(MIN_SAMPLED_MB_RATIO * ((DOUBLE) ps_layer_state->i4_num_mbs)))) { ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex); @@ -720,9 +721,16 @@ UWORD8 isvce_sub_pic_rc_get_mb_qp(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt, UWO i4_cumulative_mb_bits = (WORD32) (ps_layer_state->s_cumulative_mb_bits.i8_header_bits + ps_layer_state->s_cumulative_mb_bits.i8_texture_bits); - d_bit_consumption_ratio = - (((DOUBLE) i4_cumulative_mb_bits) * ((DOUBLE) ps_layer_state->i4_num_mbs)) / - (((DOUBLE) ps_layer_state->u4_allocated_bits) * ((DOUBLE) u4_num_mbs_sampled)); + if((0 == ps_layer_state->u4_allocated_bits) || (0 == u4_num_mbs_sampled)) + { + d_bit_consumption_ratio = nextafter(BIT_RATIO_FOR_OVERCONSUMPTION, INFINITY); + } + else + { + d_bit_consumption_ratio = + (((DOUBLE) i4_cumulative_mb_bits) * ((DOUBLE) ps_layer_state->i4_num_mbs)) / + (((DOUBLE) ps_layer_state->u4_allocated_bits) * ((DOUBLE) u4_num_mbs_sampled)); + } ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex); diff --git a/encoder/svc/isvce_utils.c b/encoder/svc/isvce_utils.c index 904e4d3..5f4220d 100644 --- a/encoder/svc/isvce_utils.c +++ b/encoder/svc/isvce_utils.c @@ -518,6 +518,37 @@ WORD32 isvce_svc_inp_params_validate(isvce_init_ip_t *ps_ip, isvce_cfg_params_t ******************************************************************************* * * @brief +* Validates SVC frame-level input params +* +* @param[in] ps_cfg +* Cfg parameters +* +* @returns error code in conformance with 'IH264E_ERROR_T' +* +******************************************************************************* +*/ +WORD32 isvce_svc_frame_params_validate( + rate_control_api_t *aps_rate_control_api[MAX_NUM_SPATIAL_LAYERS], UWORD8 u1_num_spatial_layers) +{ + WORD32 i; + + /* RC requires total bits in a second to fit int32_t */ + for(i = 0; i < u1_num_spatial_layers; i++) + { + if((((UWORD64) irc_get_bits_per_frame(aps_rate_control_api[i])) * + irc_get_intra_frame_interval(aps_rate_control_api[i])) > ((UWORD64) INT32_MAX)) + { + return IH264E_BITRATE_NOT_SUPPORTED; + } + } + + return IV_SUCCESS; +} + +/** +******************************************************************************* +* +* @brief * Used to get reference picture buffer size for a given level and * and padding used * diff --git a/encoder/svc/isvce_utils.h b/encoder/svc/isvce_utils.h index a6dc9de..ad14446 100644 --- a/encoder/svc/isvce_utils.h +++ b/encoder/svc/isvce_utils.h @@ -46,6 +46,21 @@ #include "ih264_typedefs.h" #include "ih264e_bitstream.h" +/* Dependencies of 'irc_picture_type.h' */ +#include "irc_cntrl_param.h" +#include "irc_frame_info_collector.h" +#include "irc_mem_req_and_acq.h" +/* Dependencies of 'irc_rate_control_api_structs' */ +#include "irc_picture_type.h" +#include "irc_rd_model.h" +#include "irc_vbr_storage_vbv.h" +#include "irc_est_sad.h" +#include "irc_bit_allocation.h" +#include "irc_mb_model_based.h" +#include "irc_cbr_buffer_control.h" +#include "irc_vbr_str_prms.h" +#include "irc_common.h" +#include "irc_rate_control_api_structs.h" #include "isvc_macros.h" #include "isvc_structs.h" #include "isvce_defs.h" @@ -165,6 +180,9 @@ extern WORD32 isvce_svc_au_props_validate(svc_inp_params_t *ps_svc_inp_params, U extern WORD32 isvce_svc_inp_params_validate(isvce_init_ip_t *ps_ip, isvce_cfg_params_t *ps_cfg); +extern WORD32 isvce_svc_frame_params_validate( + rate_control_api_t *aps_rate_control_api[MAX_NUM_SPATIAL_LAYERS], UWORD8 u1_num_spatial_layers); + extern WORD32 isvce_get_total_svc_au_buf_size(svc_inp_params_t *ps_svc_inp_params, WORD32 i4_pic_size, WORD32 i4_level, WORD32 i4_horz_pad, WORD32 i4_vert_pad, diff --git a/fuzzer/avc_dec_fuzzer.cpp b/fuzzer/avc_dec_fuzzer.cpp index 4e0876e..2a021a0 100644 --- a/fuzzer/avc_dec_fuzzer.cpp +++ b/fuzzer/avc_dec_fuzzer.cpp @@ -118,6 +118,7 @@ void Codec::createCodec() { create_ip.s_ivd_create_ip_t.e_output_format = mColorFormat; create_ip.s_ivd_create_ip_t.pf_aligned_alloc = iv_aligned_malloc; create_ip.s_ivd_create_ip_t.pf_aligned_free = iv_aligned_free; + create_ip.u4_keep_threads_active = 1; create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL; create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t); create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t); @@ -251,7 +252,9 @@ void Codec::allocFrame() { void Codec::decodeHeader(const uint8_t *data, size_t size) { setParams(IVD_DECODE_HEADER); - while (size > 0) { + size_t numDecodeCalls = 0; + + while (size > 0 && numDecodeCalls < kMaxNumDecodeCalls) { IV_API_CALL_STATUS_T ret; ivd_video_decode_ip_t dec_ip{}; ivd_video_decode_op_t dec_op{}; @@ -275,6 +278,7 @@ void Codec::decodeHeader(const uint8_t *data, size_t size) { data += bytes_consumed; size -= bytes_consumed; + numDecodeCalls++; mWidth = std::min(dec_op.u4_pic_wd, (UWORD32)10240); mHeight = std::min(dec_op.u4_pic_ht, (UWORD32)10240); diff --git a/fuzzer/ossfuzz.sh b/fuzzer/ossfuzz.sh index e203fbd..2ebe03e 100755 --- a/fuzzer/ossfuzz.sh +++ b/fuzzer/ossfuzz.sh @@ -18,6 +18,12 @@ test "${SRC}" != "" || exit 1 test "${WORK}" != "" || exit 1 test "${OUT}" != "" || exit 1 +#Opt out of shift sanitizer in undefined sanitizer +if [[ $SANITIZER = *undefined* ]]; then + CFLAGS="$CFLAGS -fno-sanitize=shift" + CXXFLAGS="$CXXFLAGS -fno-sanitize=shift" +fi + # Build libavc build_dir=$WORK/build rm -rf ${build_dir} @@ -25,8 +31,10 @@ mkdir -p ${build_dir} pushd ${build_dir} cmake ${SRC}/libavc -DENABLE_SVC=1 -DENABLE_MVC=1 -make -j$(nproc) avc_dec_fuzzer svc_dec_fuzzer svc_enc_fuzzer +make -j$(nproc) avc_dec_fuzzer avc_enc_fuzzer mvc_dec_fuzzer svc_dec_fuzzer svc_enc_fuzzer cp ${build_dir}/avc_dec_fuzzer $OUT/ +cp ${build_dir}/avc_enc_fuzzer $OUT/ +cp ${build_dir}/mvc_dec_fuzzer $OUT/ cp ${build_dir}/svc_dec_fuzzer $OUT/ cp ${build_dir}/svc_enc_fuzzer $OUT/ popd diff --git a/test/decoder/main.c b/test/decoder/main.c index 6cbf466..e90bdac 100644 --- a/test/decoder/main.c +++ b/test/decoder/main.c @@ -230,6 +230,8 @@ typedef struct WORD32 quit; WORD32 paused; + /* Active threads present*/ + UWORD32 i4_active_threads; void *pv_disp_ctx; void *display_thread_handle; @@ -280,6 +282,8 @@ typedef enum SOC, PICLEN, PICLEN_FILE, + + KEEP_THREADS_ACTIVE, } ARGUMENT_T; typedef struct @@ -349,6 +353,8 @@ static const argument_t argument_mapping[] = "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR,ARMV8_GENERIC, X86_GENERIC, X86_SSSE3, X86_SSE4 \n" }, {"--", "--soc", SOC, "Set SOC. Supported values GENERIC, HISI_37X \n" }, + {"--", "--keep_threads_active", KEEP_THREADS_ACTIVE, + "Keep threads active"}, }; @@ -873,6 +879,7 @@ IV_API_CALL_STATUS_T get_version(void *codec_obj) /*****************************************************************************/ void codec_exit(CHAR *pc_err_message) { + printf("Summary\n"); printf("%s\n", pc_err_message); exit(-1); } @@ -1355,6 +1362,9 @@ void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value) case DISABLE_DEBLOCK_LEVEL: sscanf(value, "%d", &ps_app_ctx->u4_disable_dblk_level); break; + case KEEP_THREADS_ACTIVE: + sscanf(value, "%d", &ps_app_ctx->i4_active_threads); + break; case INVALID: default: @@ -2154,6 +2164,7 @@ int main(WORD32 argc, CHAR *argv[]) //s_app_ctx.u4_output_present = 0; s_app_ctx.u4_chksum_save_flag = 0; s_app_ctx.u4_frame_info_enable = 0; + s_app_ctx.i4_active_threads = 1; s_app_ctx.get_stride = &default_get_stride; @@ -2424,6 +2435,7 @@ int main(WORD32 argc, CHAR *argv[]) s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t); s_create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t); s_create_ip.u4_enable_frame_info = s_app_ctx.u4_frame_info_enable; + s_create_ip.u4_keep_threads_active = s_app_ctx.i4_active_threads; |