diff options
author | Ray Essick <essick@google.com> | 2020-10-09 22:23:38 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-10-09 22:23:38 +0000 |
commit | 57d4fdc39b967d694964744e0f579433f901141e (patch) | |
tree | 0bb8ce5a6b9c4b3b6f8c237d529df29abc2f874e /decoder | |
parent | fa4b60c764e8339845cdd908f0e14386b4c79ddc (diff) | |
parent | c57a80373afc33537619d5097dd8b75634467c0c (diff) | |
download | libhevc-57d4fdc39b967d694964744e0f579433f901141e.tar.gz |
Merge "Decoder: add support for KEEP_THREADS_ACTIVE"
Diffstat (limited to 'decoder')
-rw-r--r-- | decoder/ihevcd_api.c | 83 | ||||
-rw-r--r-- | decoder/ihevcd_decode.c | 14 | ||||
-rw-r--r-- | decoder/ihevcd_process_slice.c | 102 | ||||
-rw-r--r-- | decoder/ihevcd_structs.h | 37 | ||||
-rwxr-xr-x | decoder/ihevcd_utils.c | 24 |
5 files changed, 226 insertions, 34 deletions
diff --git a/decoder/ihevcd_api.c b/decoder/ihevcd_api.c index 134ed31..4d094be 100644 --- a/decoder/ihevcd_api.c +++ b/decoder/ihevcd_api.c @@ -1215,6 +1215,52 @@ WORD32 ihevcd_allocate_static_bufs(iv_obj_t **pps_codec_obj, (UWORD8 *)pv_buf + (i * handle_size); } +#ifdef KEEP_THREADS_ACTIVE + /* Request memory to hold mutex (start/done) for each processing thread */ + size = 2 * MAX_PROCESS_THREADS * ithread_get_mutex_lock_size(); + pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); + RETURN_IF((NULL == pv_buf), IV_FAIL); + memset(pv_buf, 0, size); + + for(i = 0; i < MAX_PROCESS_THREADS; i++) + { + WORD32 ret; + WORD32 mutex_size = ithread_get_mutex_lock_size(); + ps_codec->apv_proc_start_mutex[i] = + (UWORD8 *)pv_buf + (2 * i * mutex_size); + ps_codec->apv_proc_done_mutex[i] = + (UWORD8 *)pv_buf + ((2 * i + 1) * mutex_size); + + ret = ithread_mutex_init(ps_codec->apv_proc_start_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ret = ithread_mutex_init(ps_codec->apv_proc_done_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + } + + size = 2 * MAX_PROCESS_THREADS * ithread_get_cond_struct_size(); + pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); + RETURN_IF((NULL == pv_buf), IV_FAIL); + memset(pv_buf, 0, size); + + for(i = 0; i < MAX_PROCESS_THREADS; i++) + { + WORD32 ret; + WORD32 cond_size = ithread_get_cond_struct_size(); + ps_codec->apv_proc_start_condition[i] = + (UWORD8 *)pv_buf + (2 * i * cond_size); + ps_codec->apv_proc_done_condition[i] = + (UWORD8 *)pv_buf + ((2 * i + 1) * cond_size); + + ret = ithread_cond_init(ps_codec->apv_proc_start_condition[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ret = ithread_cond_init(ps_codec->apv_proc_done_condition[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + } + +#endif + /* Request memory for static bitstream buffer which holds bitstream after emulation prevention */ size = MIN_BITSBUF_SIZE; pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size + 16); //Alloc extra for parse optimization @@ -1433,6 +1479,43 @@ WORD32 ihevcd_free_static_bufs(iv_obj_t *ps_codec_obj) pf_aligned_free = ps_codec->pf_aligned_free; pv_mem_ctxt = ps_codec->pv_mem_ctxt; +#ifdef KEEP_THREADS_ACTIVE + /* Wait for threads */ + ps_codec->i4_break_threads = 1; + for(int i = 0; i < MAX_PROCESS_THREADS; i++) + { + WORD32 ret; + if(ps_codec->ai4_process_thread_created[i]) + { + ret = ithread_mutex_lock(ps_codec->apv_proc_start_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ps_codec->ai4_process_start[i] = 1; + ret = ithread_cond_signal(ps_codec->apv_proc_start_condition[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ret = ithread_mutex_unlock(ps_codec->apv_proc_start_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ithread_join(ps_codec->apv_process_thread_handle[i], NULL); + + ps_codec->ai4_process_thread_created[i] = 0; + } + ret = ithread_cond_destroy(ps_codec->apv_proc_start_condition[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ret = ithread_cond_destroy(ps_codec->apv_proc_done_condition[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ret = ithread_mutex_destroy(ps_codec->apv_proc_start_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ret = ithread_mutex_destroy(ps_codec->apv_proc_done_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + } + ALIGNED_FREE(ps_codec, ps_codec->apv_proc_start_mutex[0]); + ALIGNED_FREE(ps_codec, ps_codec->apv_proc_start_condition[0]); +#endif ALIGNED_FREE(ps_codec, ps_codec->apv_process_thread_handle[0]); ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_static); diff --git a/decoder/ihevcd_decode.c b/decoder/ihevcd_decode.c index 9f634b7..1eabb3b 100644 --- a/decoder/ihevcd_decode.c +++ b/decoder/ihevcd_decode.c @@ -907,8 +907,22 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) { if(ps_codec->ai4_process_thread_created[i]) { +#ifdef KEEP_THREADS_ACTIVE + ret = ithread_mutex_lock(ps_codec->apv_proc_done_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + while(!ps_codec->ai4_process_done[i]) + { + ithread_cond_wait(ps_codec->apv_proc_done_condition[i], + ps_codec->apv_proc_done_mutex[i]); + } + ps_codec->ai4_process_done[i] = 0; + ret = ithread_mutex_unlock(ps_codec->apv_proc_done_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); +#else ithread_join(ps_codec->apv_process_thread_handle[i], NULL); ps_codec->ai4_process_thread_created[i] = 0; +#endif } } diff --git a/decoder/ihevcd_process_slice.c b/decoder/ihevcd_process_slice.c index c5af08e..50b2c00 100644 --- a/decoder/ihevcd_process_slice.c +++ b/decoder/ihevcd_process_slice.c @@ -1591,56 +1591,98 @@ void ihevcd_init_proc_ctxt(process_ctxt_t *ps_proc, WORD32 tu_coeff_data_ofst) } void ihevcd_process_thread(process_ctxt_t *ps_proc) { + IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; { ithread_set_affinity(ps_proc->i4_id + 1); } + +#ifdef KEEP_THREADS_ACTIVE while(1) { - IHEVCD_ERROR_T ret; - proc_job_t s_job; + codec_t *ps_dec = ps_proc->ps_codec; + DEBUG("In ihevcd_process_thread \n"); - ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job, - sizeof(proc_job_t), 1); + ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[ps_proc->i4_id]); if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret) break; - ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt; - ps_proc->i4_ctb_x = s_job.i2_ctb_x; - ps_proc->i4_ctb_y = s_job.i2_ctb_y; - ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx; - - - - if(CMD_PROCESS == s_job.i4_cmd) + while(!ps_dec->ai4_process_start[ps_proc->i4_id]) { - ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst); - ihevcd_process(ps_proc); + ithread_cond_wait(ps_dec->apv_proc_start_condition[ps_proc->i4_id], + ps_dec->apv_proc_start_mutex[ps_proc->i4_id]); } - else if(CMD_FMTCONV == s_job.i4_cmd) + ps_dec->ai4_process_start[ps_proc->i4_id] = 0; + ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[ps_proc->i4_id]); + if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret) + break; + + DEBUG(" Got control at ihevcd_process_thread \n"); + + if(ps_dec->i4_break_threads == 1) + break; +#endif + while(1) { - sps_t *ps_sps; - codec_t *ps_codec; - ivd_out_bufdesc_t *ps_out_buffer; - WORD32 num_rows; + proc_job_t s_job; + + ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job, + sizeof(proc_job_t), 1); + if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret) + break; + + ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt; + ps_proc->i4_ctb_x = s_job.i2_ctb_x; + ps_proc->i4_ctb_y = s_job.i2_ctb_y; + ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx; - if(0 == ps_proc->i4_init_done) + + + if(CMD_PROCESS == s_job.i4_cmd) { - ihevcd_init_proc_ctxt(ps_proc, 0); + ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst); + ihevcd_process(ps_proc); } - ps_sps = ps_proc->ps_sps; - ps_codec = ps_proc->ps_codec; - ps_out_buffer = ps_proc->ps_out_buffer; - num_rows = 1 << ps_sps->i1_log2_ctb_size; + else if(CMD_FMTCONV == s_job.i4_cmd) + { + sps_t *ps_sps; + codec_t *ps_codec; + ivd_out_bufdesc_t *ps_out_buffer; + WORD32 num_rows; - num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size))); + if(0 == ps_proc->i4_init_done) + { + ihevcd_init_proc_ctxt(ps_proc, 0); + } + ps_sps = ps_proc->ps_sps; + ps_codec = ps_proc->ps_codec; + ps_out_buffer = ps_proc->ps_out_buffer; + num_rows = 1 << ps_sps->i1_log2_ctb_size; + + num_rows = MIN(num_rows, + (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)) + ); - if(num_rows < 0) - num_rows = 0; + if(num_rows < 0) + num_rows = 0; - ihevcd_fmt_conv(ps_proc->ps_codec, ps_proc, ps_out_buffer->pu1_bufs[0], ps_out_buffer->pu1_bufs[1], ps_out_buffer->pu1_bufs[2], - s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size, num_rows); + ihevcd_fmt_conv(ps_proc->ps_codec, ps_proc, ps_out_buffer->pu1_bufs[0], + ps_out_buffer->pu1_bufs[1], ps_out_buffer->pu1_bufs[2], + s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size, num_rows); + } } +#ifdef KEEP_THREADS_ACTIVE + ret = ithread_mutex_lock(ps_dec->apv_proc_done_mutex[ps_proc->i4_id]); + if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret) + break; + + ps_dec->ai4_process_done[ps_proc->i4_id] = 1; + ithread_cond_signal(ps_dec->apv_proc_done_condition[ps_proc->i4_id]); + + ret = ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[ps_proc->i4_id]); + if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret) + break; } +#endif //ithread_exit(0); return; } diff --git a/decoder/ihevcd_structs.h b/decoder/ihevcd_structs.h index 5b0837d..407818a 100644 --- a/decoder/ihevcd_structs.h +++ b/decoder/ihevcd_structs.h @@ -2039,6 +2039,43 @@ struct _codec_t */ parse_ctxt_t s_parse; +#ifdef KEEP_THREADS_ACTIVE + /** + * Condition variable to signal process start + */ + void *apv_proc_start_condition[MAX_PROCESS_THREADS]; + + /** + * Mutex used to keep the functions thread-safe + */ + void *apv_proc_start_mutex[MAX_PROCESS_THREADS]; + + /** + * Process state start- One for each thread + */ + WORD32 ai4_process_start[MAX_PROCESS_THREADS]; + + /** + * Condition variable to signal process done + */ + void *apv_proc_done_condition[MAX_PROCESS_THREADS]; + + /** + * Mutex used to keep the functions thread-safe + */ + void *apv_proc_done_mutex[MAX_PROCESS_THREADS]; + + /** + * Process state end- One for each thread + */ + WORD32 ai4_process_done[MAX_PROCESS_THREADS]; + + /** + * Flag to signal processing thread to exit + */ + WORD32 i4_break_threads; +#endif + /** * Processing context - One for each processing thread */ diff --git a/decoder/ihevcd_utils.c b/decoder/ihevcd_utils.c index fef3f74..b914a9b 100755 --- a/decoder/ihevcd_utils.c +++ b/decoder/ihevcd_utils.c @@ -1040,6 +1040,9 @@ IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) /* Reset the jobq to start of the jobq buffer */ ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq); +#ifdef KEEP_THREADS_ACTIVE + ps_codec->i4_break_threads = 0; +#endif ps_codec->s_parse.i4_pic_pu_idx = 0; ps_codec->s_parse.i4_pic_tu_idx = 0; @@ -1238,10 +1241,23 @@ IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; if(i < (ps_codec->i4_num_cores - 1)) { - ithread_create(ps_codec->apv_process_thread_handle[i], NULL, - (void *)ihevcd_process_thread, - (void *)&ps_codec->as_process[i]); - ps_codec->ai4_process_thread_created[i] = 1; + if (!ps_codec->ai4_process_thread_created[i]) + { + ithread_create(ps_codec->apv_process_thread_handle[i], NULL, + (void *)ihevcd_process_thread, + (void *)&ps_codec->as_process[i]); + ps_codec->ai4_process_thread_created[i] = 1; + } +#ifdef KEEP_THREADS_ACTIVE + ret = ithread_mutex_lock(ps_codec->apv_proc_start_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + + ps_codec->ai4_process_start[i] = 1; + ithread_cond_signal(ps_codec->apv_proc_start_condition[i]); + + ret = ithread_mutex_unlock(ps_codec->apv_proc_start_mutex[i]); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); +#endif } else { |