aboutsummaryrefslogtreecommitdiff
path: root/decoder
diff options
context:
space:
mode:
authorManisha Jajoo <manisha.jajoo@ittiam.com>2020-08-13 11:20:23 +0530
committerManisha Jajoo <manisha.jajoo@ittiam.com>2020-08-31 22:00:10 +0530
commitc57a80373afc33537619d5097dd8b75634467c0c (patch)
tree546d759dc2c9c952dfa1d3b5b1177587debbd099 /decoder
parent44df5e300556d80b2bd32aefc7b54fc43222f9bb (diff)
downloadlibhevc-c57a80373afc33537619d5097dd8b75634467c0c.tar.gz
Decoder: add support for KEEP_THREADS_ACTIVE
Current design of HEVC Decoder creates new threads to process each frame. This CL adds support to reuse the threads across frames. Test: manual Bug: 167126301 Change-Id: Ic57133b25203dae9ed5d3d974e6137a733531da7
Diffstat (limited to 'decoder')
-rw-r--r--decoder/ihevcd_api.c83
-rw-r--r--decoder/ihevcd_decode.c14
-rw-r--r--decoder/ihevcd_process_slice.c102
-rw-r--r--decoder/ihevcd_structs.h37
-rwxr-xr-xdecoder/ihevcd_utils.c24
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
{