[vproc]: Pass HalTask between hal and vproc

Use HalTask to communicate between hal thread and vproc thread.

Change-Id: I4e87b7ca63bdf86e46045e31296ffa69958ae719
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2019-08-13 18:02:41 +08:00
parent 05bba59fa9
commit 003f8806af
8 changed files with 132 additions and 69 deletions

View File

@@ -168,7 +168,8 @@ static MPP_RET jpeg_judge_yuv_mode(JpegdCtx *ctx)
return ret; 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; RK_U8 lh, ll;
READ_BITS(gb, 8, &lh); READ_BITS(gb, 8, &lh);
READ_BITS(gb, 8, &ll); READ_BITS(gb, 8, &ll);

View File

@@ -52,6 +52,7 @@ struct MppDec_t {
MppBufSlots frame_slots; MppBufSlots frame_slots;
MppBufSlots packet_slots; MppBufSlots packet_slots;
HalTaskGroup tasks; HalTaskGroup tasks;
HalTaskGroup vproc_tasks;
// status flags // status flags
RK_U32 parser_work_count; RK_U32 parser_work_count;

View File

@@ -269,15 +269,18 @@ static void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags)
mpp_buf_slot_get_prop(slots, index, SLOT_FRAME_PTR, &frame); mpp_buf_slot_get_prop(slots, index, SLOT_FRAME_PTR, &frame);
if (mpp_frame_get_mode(frame) && dec->enable_deinterlace && if (mpp_frame_get_mode(frame) && dec->enable_deinterlace &&
NULL == dec->vproc) { 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) { if (ret) {
// When iep is failed to open disable deinterlace function to // When iep is failed to open disable deinterlace function to
// avoid noisy log. // avoid noisy log.
dec->enable_deinterlace = 0; dec->enable_deinterlace = 0;
dec->vproc = NULL; dec->vproc = NULL;
} else } else {
dec->vproc_tasks = cfg.task_group;
dec_vproc_start(dec->vproc); dec_vproc_start(dec->vproc);
} }
}
} else { } else {
// when post-process is needed and eos without slot index case // when post-process is needed and eos without slot index case
// we need to create a slot index for it // we need to create a slot index for it
@@ -285,9 +288,24 @@ static void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags)
mpp_assert(!change); mpp_assert(!change);
if (dec->vproc) { if (dec->vproc) {
mpp_buf_slot_get_unused(slots, &index); HalTaskGroup group = dec->vproc_tasks;
mpp_buf_slot_default_info(slots, index, &frame); HalTaskHnd hnd = NULL;
mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_READY); 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 { } else {
mpp_frame_init(&frame); mpp_frame_init(&frame);
fake_frame = 1; 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); mpp_frame_set_discard(frame, 0);
} }
if (change) { if (!change) {
/* NOTE: Set codec ready here for dequeue/enqueue */
mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_READY);
} else {
if (dec->use_preset_time_order) { if (dec->use_preset_time_order) {
MppPacket pkt = NULL; MppPacket pkt = NULL;
mpp->mTimeStamps->pull(&pkt, sizeof(pkt)); 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) { if (dec->vproc) {
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_set_flag(slots, index, SLOT_QUEUE_USE);
mpp_buf_slot_enqueue(slots, index, QUEUE_DEINTERLACE); 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); dec_vproc_signal(dec->vproc);
} else { } else {
// direct output -> copy a new MppFrame and output // direct output -> copy a new MppFrame and output

View File

@@ -131,6 +131,15 @@ typedef struct HalEncTaskFlag_t {
RK_U32 err; RK_U32 err;
} HalEncTaskFlag; } HalEncTaskFlag;
typedef union HalDecVprocTaskFlag_t {
RK_U32 val;
struct {
RK_U32 eos : 1;
RK_U32 info_change : 1;
};
} HalDecVprocTaskFlag;
typedef struct HalDecTask_t { typedef struct HalDecTask_t {
// set by parser to signal that it is valid // set by parser to signal that it is valid
RK_U32 valid; RK_U32 valid;
@@ -180,11 +189,19 @@ typedef struct HalEncTask_t {
} HalEncTask; } HalEncTask;
typedef struct HalDecVprocTask_t {
// input slot index for post-process
HalDecVprocTaskFlag flags;
RK_S32 input;
} HalDecVprocTask;
typedef struct HalTask_u { typedef struct HalTask_u {
HalTaskHnd hnd; HalTaskHnd hnd;
union { union {
HalDecTask dec; HalDecTask dec;
HalEncTask enc; HalEncTask enc;
HalDecVprocTask dec_vproc;
}; };
} HalTaskInfo; } HalTaskInfo;

View File

@@ -154,6 +154,7 @@ public:
*/ */
MppThread *mThreadCodec; MppThread *mThreadCodec;
MppThread *mThreadHal; MppThread *mThreadHal;
MppThread *mThreadVproc;
MppDec *mDec; MppDec *mDec;
MppEnc *mEnc; MppEnc *mEnc;

View File

@@ -67,6 +67,7 @@ Mpp::Mpp()
mInputTask(NULL), mInputTask(NULL),
mThreadCodec(NULL), mThreadCodec(NULL),
mThreadHal(NULL), mThreadHal(NULL),
mThreadVproc(NULL),
mDec(NULL), mDec(NULL),
mEnc(NULL), mEnc(NULL),
mType(MPP_CTX_BUTT), mType(MPP_CTX_BUTT),

View File

@@ -19,6 +19,11 @@
#include "hal_task.h" #include "hal_task.h"
typedef struct MppDecVprocCfg_t {
void *mpp;
HalTaskGroup task_group;
} MppDecVprocCfg;
typedef void* MppDecVprocCtx; typedef void* MppDecVprocCtx;
#ifdef __cplusplus #ifdef __cplusplus
@@ -35,7 +40,7 @@ extern "C" {
* dec_vproc_reset - reset process thread and discard all input * 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_deinit(MppDecVprocCtx ctx);
MPP_RET dec_vproc_start(MppDecVprocCtx ctx); MPP_RET dec_vproc_start(MppDecVprocCtx ctx);

View File

@@ -58,7 +58,6 @@ typedef struct MppDecVprocCtxImpl_t {
MppThread *thd; MppThread *thd;
RK_U32 reset; RK_U32 reset;
RK_S32 count;
IepCtx iep_ctx; IepCtx iep_ctx;
IepCmdParamDeiCfg dei_cfg; IepCmdParamDeiCfg dei_cfg;
@@ -120,34 +119,10 @@ static void dec_vproc_clr_prev(MppDecVprocCtxImpl *ctx)
static void dec_vproc_reset_queue(MppDecVprocCtxImpl *ctx) static void dec_vproc_reset_queue(MppDecVprocCtxImpl *ctx)
{ {
MppThread *thd = ctx->thd; 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"); vproc_dbg_reset("reset start\n");
dec_vproc_clr_prev(ctx); 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); thd->lock(THREAD_CONTROL);
ctx->reset = 0; ctx->reset = 0;
vproc_dbg_reset("reset signal\n"); 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) static void *dec_vproc_thread(void *data)
{ {
MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)data; MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)data;
HalTaskGroup tasks = ctx->task_group;
MppThread *thd = ctx->thd; MppThread *thd = ctx->thd;
Mpp *mpp = ctx->mpp; Mpp *mpp = ctx->mpp;
MppDec *dec = mpp->mDec; MppDec *dec = mpp->mDec;
MppBufSlots slots = dec->frame_slots; MppBufSlots slots = dec->frame_slots;
IepImg img; 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"); mpp_dbg(MPP_DBG_INFO, "mpp_dec_post_proc_thread started\n");
while (1) { while (1) {
RK_S32 index = -1;
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
{ {
@@ -231,42 +210,55 @@ static void *dec_vproc_thread(void *data)
if (MPP_THREAD_RUNNING != thd->get_status()) if (MPP_THREAD_RUNNING != thd->get_status())
break; break;
if (ctx->reset) { 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); dec_vproc_reset_queue(ctx);
continue; thd->unlock(THREAD_CONTROL);
} else {
ret = mpp_buf_slot_dequeue(slots, &index, QUEUE_DEINTERLACE);
if (ret) {
thd->wait(); thd->wait();
continue; continue;
} else {
ctx->count--;
}
} }
} }
// dequeue from deinterlace queue then send to mpp->mFrames if (task) {
if (index >= 0) { 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; 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); 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"); vproc_dbg_status("info change\n");
dec_vproc_put_frame(mpp, frm, NULL, -1); dec_vproc_put_frame(mpp, frm, NULL, -1);
dec_vproc_clr_prev(ctx); 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; continue;
} }
RK_U32 eos = mpp_frame_get_eos(frm); RK_S32 tmp = -1;
if (eos && NULL == mpp_frame_get_buffer(frm)) { mpp_buf_slot_dequeue(slots, &tmp, QUEUE_DEINTERLACE);
vproc_dbg_status("eos\n"); mpp_assert(tmp == index);
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;
}
if (!dec->reset_flag && ctx->iep_ctx) { if (!dec->reset_flag && ctx->iep_ctx) {
MppBufferGroup group = mpp->mFrameGroup; MppBufferGroup group = mpp->mFrameGroup;
@@ -354,6 +346,8 @@ static void *dec_vproc_thread(void *data)
if (eos) if (eos)
dec_vproc_clr_prev(ctx); 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"); 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; 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; MPP_RET ret = MPP_OK;
if (NULL == ctx || NULL == mpp) { if (NULL == ctx || NULL == cfg || NULL == cfg->mpp) {
mpp_err_f("found NULL input ctx %p mpp %p\n", ctx, mpp); mpp_err_f("found NULL input ctx %p mpp %p\n", ctx, cfg->mpp);
return MPP_ERR_NULL_PTR; return MPP_ERR_NULL_PTR;
} }
@@ -380,7 +374,7 @@ MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, void *mpp)
return MPP_ERR_MALLOC; return MPP_ERR_MALLOC;
} }
p->mpp = (Mpp *)mpp; p->mpp = (Mpp *)cfg->mpp;
p->slots = p->mpp->mDec->frame_slots; p->slots = p->mpp->mDec->frame_slots;
p->thd = new MppThread(dec_vproc_thread, p, "mpp_dec_vproc"); p->thd = new MppThread(dec_vproc_thread, p, "mpp_dec_vproc");
ret = hal_task_group_init(&p->task_group, 4); 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); MPP_FREE(p);
return MPP_ERR_MALLOC; return MPP_ERR_MALLOC;
} }
cfg->task_group = p->task_group;
ret = iep_init(&p->iep_ctx); ret = iep_init(&p->iep_ctx);
if (!p->thd || ret) { if (!p->thd || ret) {
mpp_err("failed to create context\n"); 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_idx = -1;
p->prev_frm = NULL; p->prev_frm = NULL;
// set to mpp for cross communication
p->mpp->mThreadVproc = p->thd;
} }
*ctx = p; *ctx = p;
@@ -508,7 +506,6 @@ MPP_RET dec_vproc_signal(MppDecVprocCtx ctx)
MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx; MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
if (p->thd) { if (p->thd) {
p->thd->lock(); p->thd->lock();
p->count++;
p->thd->signal(); p->thd->signal();
p->thd->unlock(); p->thd->unlock();
} }