diff --git a/mpp/codec/dec/jpeg/jpegd_parser.c b/mpp/codec/dec/jpeg/jpegd_parser.c index 4c8644be..2b2a194b 100644 --- a/mpp/codec/dec/jpeg/jpegd_parser.c +++ b/mpp/codec/dec/jpeg/jpegd_parser.c @@ -168,7 +168,8 @@ static MPP_RET jpeg_judge_yuv_mode(JpegdCtx *ctx) return ret; } -static inline RK_U16 jpegd_read_len(BitReadCtx_t *gb) { +static inline RK_U16 jpegd_read_len(BitReadCtx_t *gb) +{ RK_U8 lh, ll; READ_BITS(gb, 8, &lh); READ_BITS(gb, 8, &ll); diff --git a/mpp/codec/inc/mpp_dec.h b/mpp/codec/inc/mpp_dec.h index e4568686..1079d7f0 100644 --- a/mpp/codec/inc/mpp_dec.h +++ b/mpp/codec/inc/mpp_dec.h @@ -52,6 +52,7 @@ struct MppDec_t { MppBufSlots frame_slots; MppBufSlots packet_slots; HalTaskGroup tasks; + HalTaskGroup vproc_tasks; // status flags RK_U32 parser_work_count; diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index b9bc8ef0..f85454d5 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -269,14 +269,17 @@ static void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags) mpp_buf_slot_get_prop(slots, index, SLOT_FRAME_PTR, &frame); if (mpp_frame_get_mode(frame) && dec->enable_deinterlace && NULL == dec->vproc) { - MPP_RET ret = dec_vproc_init(&dec->vproc, mpp); + MppDecVprocCfg cfg = { mpp, NULL }; + MPP_RET ret = dec_vproc_init(&dec->vproc, &cfg); if (ret) { // When iep is failed to open disable deinterlace function to // avoid noisy log. dec->enable_deinterlace = 0; dec->vproc = NULL; - } else + } else { + dec->vproc_tasks = cfg.task_group; dec_vproc_start(dec->vproc); + } } } else { // when post-process is needed and eos without slot index case @@ -285,9 +288,24 @@ static void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags) mpp_assert(!change); if (dec->vproc) { - mpp_buf_slot_get_unused(slots, &index); - mpp_buf_slot_default_info(slots, index, &frame); - mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_READY); + HalTaskGroup group = dec->vproc_tasks; + HalTaskHnd hnd = NULL; + HalTaskInfo task; + HalDecVprocTask *vproc_task = &task.dec_vproc; + + MPP_RET ret = hal_task_get_hnd(group, TASK_IDLE, &hnd); + + mpp_assert(ret == MPP_OK); + + vproc_task->flags.val = 0; + vproc_task->flags.eos = eos; + vproc_task->input = index; + + hal_task_hnd_set_info(hnd, &task); + hal_task_hnd_set_status(hnd, TASK_PROCESSING); + dec_vproc_signal(dec->vproc); + + return ; } else { mpp_frame_init(&frame); fake_frame = 1; @@ -305,10 +323,7 @@ static void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags) mpp_frame_set_discard(frame, 0); } - if (change) { - /* NOTE: Set codec ready here for dequeue/enqueue */ - mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_READY); - } else { + if (!change) { if (dec->use_preset_time_order) { MppPacket pkt = NULL; mpp->mTimeStamps->pull(&pkt, sizeof(pkt)); @@ -334,8 +349,33 @@ static void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags) } if (dec->vproc) { - mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, index, QUEUE_DEINTERLACE); + HalTaskGroup group = dec->vproc_tasks; + HalTaskHnd hnd = NULL; + HalTaskInfo task; + HalDecVprocTask *vproc_task = &task.dec_vproc; + MPP_RET ret = MPP_OK; + + do { + ret = hal_task_get_hnd(group, TASK_IDLE, &hnd); + if (ret) { + msleep(10); + } + } while (ret); + + mpp_assert(ret == MPP_OK); + + vproc_task->flags.eos = eos; + vproc_task->flags.info_change = change; + vproc_task->input = index; + + if (!change) { + mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, index, QUEUE_DEINTERLACE); + } + + hal_task_hnd_set_info(hnd, &task); + hal_task_hnd_set_status(hnd, TASK_PROCESSING); + dec_vproc_signal(dec->vproc); } else { // direct output -> copy a new MppFrame and output diff --git a/mpp/hal/inc/hal_task.h b/mpp/hal/inc/hal_task.h index 358ae9b7..878e8612 100644 --- a/mpp/hal/inc/hal_task.h +++ b/mpp/hal/inc/hal_task.h @@ -131,6 +131,15 @@ typedef struct HalEncTaskFlag_t { RK_U32 err; } HalEncTaskFlag; +typedef union HalDecVprocTaskFlag_t { + RK_U32 val; + + struct { + RK_U32 eos : 1; + RK_U32 info_change : 1; + }; +} HalDecVprocTaskFlag; + typedef struct HalDecTask_t { // set by parser to signal that it is valid RK_U32 valid; @@ -180,11 +189,19 @@ typedef struct HalEncTask_t { } HalEncTask; +typedef struct HalDecVprocTask_t { + // input slot index for post-process + HalDecVprocTaskFlag flags; + + RK_S32 input; +} HalDecVprocTask; + typedef struct HalTask_u { - HalTaskHnd hnd; + HalTaskHnd hnd; union { - HalDecTask dec; - HalEncTask enc; + HalDecTask dec; + HalEncTask enc; + HalDecVprocTask dec_vproc; }; } HalTaskInfo; diff --git a/mpp/inc/mpp.h b/mpp/inc/mpp.h index 03c0b48d..48be9ef0 100644 --- a/mpp/inc/mpp.h +++ b/mpp/inc/mpp.h @@ -154,6 +154,7 @@ public: */ MppThread *mThreadCodec; MppThread *mThreadHal; + MppThread *mThreadVproc; MppDec *mDec; MppEnc *mEnc; diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index 378b7dc5..76133e3b 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -67,6 +67,7 @@ Mpp::Mpp() mInputTask(NULL), mThreadCodec(NULL), mThreadHal(NULL), + mThreadVproc(NULL), mDec(NULL), mEnc(NULL), mType(MPP_CTX_BUTT), diff --git a/mpp/vproc/inc/mpp_dec_vproc.h b/mpp/vproc/inc/mpp_dec_vproc.h index ed22a57e..a27ef465 100644 --- a/mpp/vproc/inc/mpp_dec_vproc.h +++ b/mpp/vproc/inc/mpp_dec_vproc.h @@ -19,6 +19,11 @@ #include "hal_task.h" +typedef struct MppDecVprocCfg_t { + void *mpp; + HalTaskGroup task_group; +} MppDecVprocCfg; + typedef void* MppDecVprocCtx; #ifdef __cplusplus @@ -35,7 +40,7 @@ extern "C" { * dec_vproc_reset - reset process thread and discard all input */ -MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, void *mpp); +MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, MppDecVprocCfg *cfg); MPP_RET dec_vproc_deinit(MppDecVprocCtx ctx); MPP_RET dec_vproc_start(MppDecVprocCtx ctx); diff --git a/mpp/vproc/mpp_dec_vproc.cpp b/mpp/vproc/mpp_dec_vproc.cpp index 8db918ab..83a0bee4 100644 --- a/mpp/vproc/mpp_dec_vproc.cpp +++ b/mpp/vproc/mpp_dec_vproc.cpp @@ -58,7 +58,6 @@ typedef struct MppDecVprocCtxImpl_t { MppThread *thd; RK_U32 reset; - RK_S32 count; IepCtx iep_ctx; IepCmdParamDeiCfg dei_cfg; @@ -120,34 +119,10 @@ static void dec_vproc_clr_prev(MppDecVprocCtxImpl *ctx) static void dec_vproc_reset_queue(MppDecVprocCtxImpl *ctx) { MppThread *thd = ctx->thd; - Mpp *mpp = ctx->mpp; - MppDec *dec = mpp->mDec; - MppBufSlots slots = dec->frame_slots; - RK_S32 index = -1; - MPP_RET ret = MPP_OK; vproc_dbg_reset("reset start\n"); dec_vproc_clr_prev(ctx); - vproc_dbg_reset("reset loop start\n"); - // on reset just return all index - do { - ret = mpp_buf_slot_dequeue(slots, &index, QUEUE_DEINTERLACE); - if (MPP_OK == ret && index >= 0) { - MppFrame frame = NULL; - - mpp_buf_slot_get_prop(slots, index, SLOT_FRAME, &frame); - if (frame) - mpp_frame_deinit(&frame); - - mpp_buf_slot_clr_flag(slots, index, SLOT_QUEUE_USE); - ctx->count--; - vproc_dbg_status("reset index %d\n", index); - } - } while (ret == MPP_OK); - mpp_assert(ctx->count == 0); - - vproc_dbg_reset("reset loop done\n"); thd->lock(THREAD_CONTROL); ctx->reset = 0; vproc_dbg_reset("reset signal\n"); @@ -213,16 +188,20 @@ static void dec_vproc_start_dei(MppDecVprocCtxImpl *ctx, RK_U32 mode) static void *dec_vproc_thread(void *data) { MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)data; + HalTaskGroup tasks = ctx->task_group; MppThread *thd = ctx->thd; Mpp *mpp = ctx->mpp; MppDec *dec = mpp->mDec; MppBufSlots slots = dec->frame_slots; IepImg img; + HalTaskHnd task = NULL; + HalTaskInfo task_info; + HalDecVprocTask *task_vproc = &task_info.dec_vproc; + mpp_dbg(MPP_DBG_INFO, "mpp_dec_post_proc_thread started\n"); while (1) { - RK_S32 index = -1; MPP_RET ret = MPP_OK; { @@ -231,42 +210,55 @@ static void *dec_vproc_thread(void *data) if (MPP_THREAD_RUNNING != thd->get_status()) break; - if (ctx->reset) { - dec_vproc_reset_queue(ctx); + if (hal_task_get_hnd(tasks, TASK_PROCESSING, &task)) { + // process all task then do reset process + thd->lock(THREAD_CONTROL); + if (ctx->reset) + dec_vproc_reset_queue(ctx); + thd->unlock(THREAD_CONTROL); + + thd->wait(); continue; - } else { - ret = mpp_buf_slot_dequeue(slots, &index, QUEUE_DEINTERLACE); - if (ret) { - thd->wait(); - continue; - } else { - ctx->count--; - } } } - // dequeue from deinterlace queue then send to mpp->mFrames - if (index >= 0) { + if (task) { + ret = hal_task_hnd_get_info(task, &task_info); + + mpp_assert(ret == MPP_OK); + + RK_S32 index = task_vproc->input; + RK_U32 eos = task_vproc->flags.eos; + RK_U32 change = task_vproc->flags.info_change; MppFrame frm = NULL; + if (eos && index < 0) { + vproc_dbg_status("eos signal\n"); + + mpp_frame_init(&frm); + mpp_frame_set_eos(frm, eos); + dec_vproc_put_frame(mpp, frm, NULL, -1); + dec_vproc_clr_prev(ctx); + mpp_frame_deinit(&frm); + + hal_task_hnd_set_status(task, TASK_IDLE); + continue; + } + mpp_buf_slot_get_prop(slots, index, SLOT_FRAME_PTR, &frm); - if (mpp_frame_get_info_change(frm)) { + if (change) { vproc_dbg_status("info change\n"); dec_vproc_put_frame(mpp, frm, NULL, -1); dec_vproc_clr_prev(ctx); - mpp_buf_slot_clr_flag(ctx->slots, index, SLOT_QUEUE_USE); + + hal_task_hnd_set_status(task, TASK_IDLE); continue; } - RK_U32 eos = mpp_frame_get_eos(frm); - if (eos && NULL == mpp_frame_get_buffer(frm)) { - vproc_dbg_status("eos\n"); - dec_vproc_put_frame(mpp, frm, NULL, -1); - dec_vproc_clr_prev(ctx); - mpp_buf_slot_clr_flag(ctx->slots, index, SLOT_QUEUE_USE); - continue; - } + RK_S32 tmp = -1; + mpp_buf_slot_dequeue(slots, &tmp, QUEUE_DEINTERLACE); + mpp_assert(tmp == index); if (!dec->reset_flag && ctx->iep_ctx) { MppBufferGroup group = mpp->mFrameGroup; @@ -354,6 +346,8 @@ static void *dec_vproc_thread(void *data) if (eos) dec_vproc_clr_prev(ctx); + + hal_task_hnd_set_status(task, TASK_IDLE); } } mpp_dbg(MPP_DBG_INFO, "mpp_dec_post_proc_thread exited\n"); @@ -361,11 +355,11 @@ static void *dec_vproc_thread(void *data) return NULL; } -MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, void *mpp) +MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, MppDecVprocCfg *cfg) { MPP_RET ret = MPP_OK; - if (NULL == ctx || NULL == mpp) { - mpp_err_f("found NULL input ctx %p mpp %p\n", ctx, mpp); + if (NULL == ctx || NULL == cfg || NULL == cfg->mpp) { + mpp_err_f("found NULL input ctx %p mpp %p\n", ctx, cfg->mpp); return MPP_ERR_NULL_PTR; } @@ -380,7 +374,7 @@ MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, void *mpp) return MPP_ERR_MALLOC; } - p->mpp = (Mpp *)mpp; + p->mpp = (Mpp *)cfg->mpp; p->slots = p->mpp->mDec->frame_slots; p->thd = new MppThread(dec_vproc_thread, p, "mpp_dec_vproc"); ret = hal_task_group_init(&p->task_group, 4); @@ -390,6 +384,7 @@ MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, void *mpp) MPP_FREE(p); return MPP_ERR_MALLOC; } + cfg->task_group = p->task_group; ret = iep_init(&p->iep_ctx); if (!p->thd || ret) { mpp_err("failed to create context\n"); @@ -420,6 +415,9 @@ MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, void *mpp) p->prev_idx = -1; p->prev_frm = NULL; + + // set to mpp for cross communication + p->mpp->mThreadVproc = p->thd; } *ctx = p; @@ -508,7 +506,6 @@ MPP_RET dec_vproc_signal(MppDecVprocCtx ctx) MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx; if (p->thd) { p->thd->lock(); - p->count++; p->thd->signal(); p->thd->unlock(); }