From c8394f0203d0b74ee1dd24d61d48516c8de32238 Mon Sep 17 00:00:00 2001 From: Randy Li Date: Tue, 1 Aug 2017 16:43:48 +0800 Subject: [PATCH] [mpp]: fixup for the deadlock in decoding When the input stream is full, it may happen: 1. Both mTheadHal(hal) and mThreadCodec(parser) is waiting a signal; 2. The previous task is not ready in parser; 3. A task is in idle and the other is done is the tasks group. If the parser has finished the checking on the task is done but has not enter into wait condition state yet, then the hal thread can't wake the parser later. Change-Id: I3b30e40bc1de7c5ca6d401084929cfd57ca00546 Signed-off-by: Randy Li Signed-off-by: Herman Chen --- mpp/codec/mpp_dec.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 9376439e..5393e977 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -101,7 +101,9 @@ static MPP_RET check_task_wait(MppDec *dec, DecTask *task) if (task->wait.task_hnd || task->wait.mpp_pkt_in || - task->wait.prev_task || + /* Re-check */ + (task->wait.prev_task && + !hal_task_check_empty(dec->tasks, TASK_PROC_DONE)) || task->wait.info_change || task->wait.dec_pic_buf) return MPP_NOK; @@ -606,6 +608,7 @@ void *mpp_dec_hal_thread(void *data) { Mpp *mpp = (Mpp*)data; MppThread *hal = mpp->mThreadHal; + MppThread *parser = mpp->mThreadCodec; MppDec *dec = mpp->mDec; HalTaskGroup tasks = dec->tasks; MppBufSlots frame_slots = dec->frame_slots; @@ -677,7 +680,11 @@ void *mpp_dec_hal_thread(void *data) mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); - // TODO: may have risk here + /* + * TODO: Locking the parser thread will prevent it fetching a + * new task. I wish there be a better way here. + */ + parser->lock(); hal_task_hnd_set_status(task, TASK_PROC_DONE); task = NULL; if (dec->parser_fast_mode) { @@ -687,6 +694,7 @@ void *mpp_dec_hal_thread(void *data) } } mpp->mThreadCodec->signal(); + parser->unlock(); mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT); for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) {