mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-19 23:44:33 +08:00
[mpp_dec]: Optimize mpp_dec condition wait
Optimize mpp_dec parser thread wait mechanism to reduce cpu overload. 1. Add mpp signal notify flag 2. Add mpp_dec wait status flag 3. Compare the notify flag with wait status flag. When there wait condition is fulfilled then signal parser thread to process. This will greatly reduce cpu overload by block wake up with no sense. Change-Id: I38da718e80d0487e0300e807bc87cdb1aa070471 Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
|
||||
typedef struct MppBufferImpl_t MppBufferImpl;
|
||||
typedef struct MppBufferGroupImpl_t MppBufferGroupImpl;
|
||||
typedef void (*MppBufCallback)(void *, void *);
|
||||
|
||||
// use index instead of pointer to avoid invalid pointer
|
||||
struct MppBufferImpl_t {
|
||||
@@ -83,7 +84,8 @@ struct MppBufferGroupImpl_t {
|
||||
MppAllocatorApi *alloc_api;
|
||||
|
||||
// thread that will be signal on buffer return
|
||||
void *listener;
|
||||
MppBufCallback callback;
|
||||
void *arg;
|
||||
|
||||
// buffer force clear mode flag
|
||||
RK_U32 clear_on_exit;
|
||||
@@ -145,7 +147,8 @@ MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size);
|
||||
MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type);
|
||||
MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p);
|
||||
MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p);
|
||||
MPP_RET mpp_buffer_group_set_listener(MppBufferGroupImpl *p, void *listener);
|
||||
MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p,
|
||||
MppBufCallback callback, void *arg);
|
||||
// mpp_buffer_group helper function
|
||||
void mpp_buffer_group_dump(MppBufferGroupImpl *p);
|
||||
void mpp_buffer_service_dump();
|
||||
|
@@ -328,10 +328,8 @@ MPP_RET mpp_buffer_create(const char *tag, const char *caller,
|
||||
*buffer = p;
|
||||
}
|
||||
|
||||
if (group->listener) {
|
||||
MppThread *thread = (MppThread *)group->listener;
|
||||
thread->signal();
|
||||
}
|
||||
if (group->callback)
|
||||
group->callback(group->arg, group);
|
||||
RET:
|
||||
MPP_BUF_FUNCTION_LEAVE();
|
||||
return ret;
|
||||
@@ -402,10 +400,8 @@ MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller)
|
||||
}
|
||||
}
|
||||
group->count_used--;
|
||||
if (group->listener) {
|
||||
MppThread *thread = (MppThread *)group->listener;
|
||||
thread->signal();
|
||||
}
|
||||
if (group->callback)
|
||||
group->callback(group->arg, group);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,7 +509,8 @@ MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buffer_group_set_listener(MppBufferGroupImpl *p, void *listener)
|
||||
MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p,
|
||||
MppBufCallback callback, void *arg)
|
||||
{
|
||||
AutoMutex auto_lock(MppBufferService::get_lock());
|
||||
if (NULL == p) {
|
||||
@@ -523,7 +520,8 @@ MPP_RET mpp_buffer_group_set_listener(MppBufferGroupImpl *p, void *listener)
|
||||
|
||||
MPP_BUF_FUNCTION_ENTER();
|
||||
|
||||
p->listener = listener;
|
||||
p->callback = callback;
|
||||
p->arg = arg;
|
||||
|
||||
MPP_BUF_FUNCTION_LEAVE();
|
||||
return MPP_OK;
|
||||
|
@@ -45,7 +45,6 @@ typedef struct {
|
||||
RK_U32 need_split;
|
||||
RK_U32 frame_count;
|
||||
RK_U32 internal_pts;
|
||||
IOInterruptCB notify_cb;
|
||||
|
||||
// parser context
|
||||
H263dParser parser;
|
||||
@@ -94,7 +93,6 @@ MPP_RET h263d_init(void *dec, ParserCfg *cfg)
|
||||
p->task_count = cfg->task_count = 2;
|
||||
p->need_split = cfg->need_split;
|
||||
p->internal_pts = cfg->internal_pts;
|
||||
p->notify_cb = cfg->notify_cb;
|
||||
p->stream = stream;
|
||||
p->stream_size = stream_size;
|
||||
p->task_pkt = task_pkt;
|
||||
|
@@ -1949,7 +1949,6 @@ MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg)
|
||||
s->slots = parser_cfg->frame_slots;
|
||||
|
||||
s->packet_slots = parser_cfg->packet_slots;
|
||||
s->notify_cb = parser_cfg->notify_cb;
|
||||
|
||||
if (h265dctx->extradata_size > 0 && h265dctx->extradata) {
|
||||
ret = hevc_parser_extradata(s);
|
||||
|
@@ -124,8 +124,6 @@ static MPP_RET m2vd_parser_init_ctx(M2VDParserContext *ctx, ParserCfg *cfg)
|
||||
ctx->packet_slots = cfg->packet_slots;
|
||||
ctx->frame_slots = cfg->frame_slots;
|
||||
|
||||
ctx->notify_cb = cfg->notify_cb;
|
||||
|
||||
mpp_buf_slot_setup(ctx->frame_slots, 16);
|
||||
|
||||
ctx->initFlag = 0;
|
||||
|
@@ -290,7 +290,6 @@ typedef struct M2VDParserContext_t {
|
||||
|
||||
MppBufSlots packet_slots;
|
||||
MppBufSlots frame_slots;
|
||||
IOInterruptCB notify_cb;
|
||||
RK_U32 cur_slot_index;
|
||||
|
||||
RK_U64 pts;
|
||||
|
@@ -45,7 +45,6 @@ typedef struct {
|
||||
RK_U32 need_split;
|
||||
RK_U32 frame_count;
|
||||
RK_U32 internal_pts;
|
||||
IOInterruptCB notify_cb;
|
||||
|
||||
// parser context
|
||||
Mpg4dParser parser;
|
||||
@@ -94,7 +93,6 @@ static MPP_RET mpg4d_init(void *dec, ParserCfg *cfg)
|
||||
p->task_count = cfg->task_count = 2;
|
||||
p->need_split = 1;//cfg->need_split;
|
||||
p->internal_pts = cfg->internal_pts;
|
||||
p->notify_cb = cfg->notify_cb;
|
||||
p->stream = stream;
|
||||
p->stream_size = stream_size;
|
||||
p->task_pkt = task_pkt;
|
||||
|
@@ -224,7 +224,6 @@ MPP_RET vp8d_parser_init(void *ctx, ParserCfg *parser_cfg)
|
||||
}
|
||||
p->packet_slots = parser_cfg->packet_slots;
|
||||
p->frame_slots = parser_cfg->frame_slots;
|
||||
p->notify_cb = parser_cfg->notify_cb;
|
||||
|
||||
mpp_buf_slot_setup(p->frame_slots, 15);
|
||||
|
||||
|
@@ -181,8 +181,6 @@ typedef struct VP8DParserContext {
|
||||
MppBufSlots packet_slots;
|
||||
MppBufSlots frame_slots;
|
||||
|
||||
IOInterruptCB notify_cb;
|
||||
|
||||
// FILE *fp_dbg_file[VP8D_DBG_FILE_NUM];
|
||||
FILE *fp_dbg_yuv;
|
||||
} VP8DParserContext_t;
|
||||
|
@@ -52,7 +52,6 @@ MPP_RET vp9d_init(void *ctx, ParserCfg *init)
|
||||
if ((ret = vp9d_parser_init(vp9_ctx, init)) != MPP_OK)
|
||||
goto _err_exit;
|
||||
|
||||
vp9_ctx->notify_cb = init->notify_cb;
|
||||
if ((ret = vp9d_split_init(vp9_ctx)) != MPP_OK)
|
||||
goto _err_exit;
|
||||
|
||||
|
@@ -99,7 +99,6 @@ typedef struct Vp9CodecContext {
|
||||
DXVA_PicParams_VP9 pic_params;
|
||||
// DXVA_Slice_VPx_Short slice_short;
|
||||
RK_S32 eos;
|
||||
IOInterruptCB notify_cb;
|
||||
} Vp9CodecContext;
|
||||
|
||||
#endif /*__VP9D_CODEC_H__*/
|
||||
|
@@ -40,7 +40,6 @@ typedef struct EncControllerInitCfg_t {
|
||||
|
||||
// output
|
||||
RK_S32 task_count;
|
||||
IOInterruptCB notify_cb;
|
||||
} ControllerCfg;
|
||||
|
||||
/*
|
||||
|
@@ -33,13 +33,19 @@ struct MppDec_t {
|
||||
MppBufSlots packet_slots;
|
||||
HalTaskGroup tasks;
|
||||
|
||||
// status flag
|
||||
// status flags
|
||||
RK_U32 parser_work_count;
|
||||
RK_U32 parser_wait_count;
|
||||
RK_U32 parser_status_flag;
|
||||
RK_U32 parser_notify_flag;
|
||||
RK_U32 hal_notify_flag;
|
||||
|
||||
RK_U32 reset_flag;
|
||||
RK_U32 parser_reset_done;
|
||||
RK_U32 hal_reset_done;
|
||||
RK_U32 vproc_reset_done;
|
||||
|
||||
// work mode flag
|
||||
// work mode flags
|
||||
RK_U32 parser_need_split;
|
||||
RK_U32 parser_fast_mode;
|
||||
RK_U32 parser_internal_pts;
|
||||
@@ -80,7 +86,7 @@ MPP_RET mpp_dec_deinit(MppDec *dec);
|
||||
MPP_RET mpp_dec_reset(MppDec *dec);
|
||||
MPP_RET mpp_dec_flush(MppDec *dec);
|
||||
MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param);
|
||||
MPP_RET mpp_dec_notify(void *ctx, void *info);
|
||||
MPP_RET mpp_dec_notify(MppDec *dec, RK_U32 flag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -185,7 +185,7 @@ void *mpp_enc_hal_thread(void *data);
|
||||
MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding);
|
||||
MPP_RET mpp_enc_deinit(MppEnc *enc);
|
||||
MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param);
|
||||
MPP_RET mpp_enc_notify(void *ctx, void *info);
|
||||
MPP_RET mpp_enc_notify(MppEnc *enc, RK_U32 flag);
|
||||
MPP_RET mpp_enc_reset(MppEnc *enc);
|
||||
|
||||
/*
|
||||
|
@@ -38,7 +38,6 @@ typedef struct DecParserInitCfg_t {
|
||||
RK_S32 task_count;
|
||||
RK_U32 need_split;
|
||||
RK_U32 internal_pts;
|
||||
IOInterruptCB notify_cb;
|
||||
} ParserCfg;
|
||||
|
||||
|
||||
|
@@ -38,27 +38,38 @@ static RK_U32 mpp_dec_debug = 0;
|
||||
#define MPP_DEC_DBG_STATUS (0x00000010)
|
||||
#define MPP_DEC_DBG_DETAIL (0x00000020)
|
||||
#define MPP_DEC_DBG_RESET (0x00000040)
|
||||
#define MPP_DEC_DBG_NOTIFY (0x00000080)
|
||||
|
||||
#define mpp_dec_dbg(flag, fmt, ...) _mpp_dbg(mpp_dec_debug, flag, fmt, ## __VA_ARGS__)
|
||||
#define mpp_dec_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_dec_debug, flag, fmt, ## __VA_ARGS__)
|
||||
|
||||
#define dec_dbg_func(fmt, ...) mpp_dec_dbg_f(MPP_DEC_DBG_FUNCTION, fmt, ## __VA_ARGS__)
|
||||
#define dec_dbg_stauts(fmt, ...) mpp_dec_dbg(MPP_DEC_DBG_STATUS, fmt, ## __VA_ARGS__)
|
||||
#define dec_dbg_status(fmt, ...) mpp_dec_dbg_f(MPP_DEC_DBG_STATUS, fmt, ## __VA_ARGS__)
|
||||
#define dec_dbg_detail(fmt, ...) mpp_dec_dbg(MPP_DEC_DBG_DETAIL, fmt, ## __VA_ARGS__)
|
||||
#define dec_dbg_reset(fmt, ...) mpp_dec_dbg(MPP_DEC_DBG_RESET, fmt, ## __VA_ARGS__)
|
||||
#define dec_dbg_notify(fmt, ...) mpp_dec_dbg_f(MPP_DEC_DBG_NOTIFY, fmt, ## __VA_ARGS__)
|
||||
|
||||
typedef union PaserTaskWait_u {
|
||||
RK_U32 val;
|
||||
struct {
|
||||
RK_U32 task_hnd : 1;
|
||||
RK_U32 dec_pkt_idx : 1;
|
||||
RK_U32 dec_pkt_buf : 1;
|
||||
RK_U32 prev_task : 1;
|
||||
RK_U32 info_change : 1;
|
||||
RK_U32 dec_pic_buf : 1;
|
||||
RK_U32 dec_slot_idx : 1;
|
||||
RK_U32 dis_que_full : 1;
|
||||
RK_U32 dec_all_done : 1;
|
||||
RK_U32 dec_pkt_in : 1; // 0x0001 MPP_DEC_NOTIFY_PACKET_ENQUEUE
|
||||
RK_U32 dis_que_full : 1; // 0x0002 MPP_DEC_NOTIFY_FRAME_DEQUEUE
|
||||
RK_U32 reserv0004 : 1; // 0x0004
|
||||
RK_U32 reserv0008 : 1; // 0x0008
|
||||
|
||||
RK_U32 ext_buf_grp : 1; // 0x0010 MPP_DEC_NOTIFY_EXT_BUF_GRP_READY
|
||||
RK_U32 info_change : 1; // 0x0020 MPP_DEC_NOTIFY_INFO_CHG_DONE
|
||||
RK_U32 dec_pic_buf : 1; // 0x0040 MPP_DEC_NOTIFY_BUFFER_VALID
|
||||
RK_U32 dec_all_done : 1; // 0x0080 MPP_DEC_NOTIFY_TASK_ALL_DONE
|
||||
|
||||
RK_U32 task_hnd : 1; // 0x0100 MPP_DEC_NOTIFY_TASK_HND_VALID
|
||||
RK_U32 prev_task : 1; // 0x0200 MPP_DEC_NOTIFY_TASK_PREV_DONE
|
||||
RK_U32 reserv0400 : 1; // 0x0400
|
||||
RK_U32 reserv0800 : 1; // 0x0800
|
||||
|
||||
RK_U32 dec_pkt_idx : 1; // 0x1000
|
||||
RK_U32 dec_pkt_buf : 1; // 0x2000
|
||||
RK_U32 dec_slot_idx : 1; // 0x4000
|
||||
};
|
||||
} PaserTaskWait;
|
||||
|
||||
@@ -115,21 +126,37 @@ static void dec_task_init(DecTask *task)
|
||||
*/
|
||||
static MPP_RET check_task_wait(MppDec *dec, DecTask *task)
|
||||
{
|
||||
if (dec->reset_flag)
|
||||
return MPP_OK;
|
||||
MPP_RET ret = MPP_OK;
|
||||
RK_U32 notify = dec->parser_notify_flag;
|
||||
RK_U32 last_wait = dec->parser_status_flag;
|
||||
RK_U32 curr_wait = task->wait.val;
|
||||
RK_U32 wait_chg = last_wait & (~curr_wait);
|
||||
|
||||
if (task->wait.task_hnd ||
|
||||
/* Re-check */
|
||||
(task->wait.prev_task &&
|
||||
!hal_task_check_empty(dec->tasks, TASK_PROC_DONE)) ||
|
||||
task->wait.info_change ||
|
||||
task->wait.dec_pic_buf ||
|
||||
task->wait.dis_que_full ||
|
||||
task->wait.dec_slot_idx ||
|
||||
task->wait.dec_all_done)
|
||||
return MPP_NOK;
|
||||
do {
|
||||
if (dec->reset_flag)
|
||||
break;
|
||||
|
||||
return MPP_OK;
|
||||
// NOTE: When condition is not fulfilled check nofify flag again
|
||||
if (!curr_wait || (curr_wait & notify))
|
||||
break;
|
||||
|
||||
// wait for condition
|
||||
ret = MPP_NOK;
|
||||
} while (0);
|
||||
|
||||
dec_dbg_status("%p %08x -> %08x [%08x] notify %08x -> %s\n", dec,
|
||||
last_wait, curr_wait, wait_chg, notify, (ret) ? ("wait") : ("work"));
|
||||
|
||||
dec->parser_status_flag = task->wait.val;
|
||||
dec->parser_notify_flag = 0;
|
||||
|
||||
if (ret) {
|
||||
dec->parser_wait_count++;
|
||||
} else {
|
||||
dec->parser_work_count++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task)
|
||||
@@ -159,6 +186,7 @@ static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task)
|
||||
hal_task_get_hnd(tasks, TASK_PROC_DONE, &tmp);
|
||||
hal_task_hnd_set_status(tmp, TASK_IDLE);
|
||||
}
|
||||
mpp_dec_notify(dec, MPP_DEC_NOTIFY_TASK_HND_VALID);
|
||||
|
||||
dec_dbg_reset("check hal processing empty\n");
|
||||
|
||||
@@ -200,7 +228,6 @@ static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task)
|
||||
|
||||
if (dec->mpp_pkt_in) {
|
||||
mpp_packet_deinit(&dec->mpp_pkt_in);
|
||||
mpp->mPacketGetCount++;
|
||||
dec->mpp_pkt_in = NULL;
|
||||
}
|
||||
|
||||
@@ -224,6 +251,8 @@ static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task)
|
||||
}
|
||||
|
||||
task->status.task_parsed_rdy = 0;
|
||||
// IMPORTANT: clear flag in MppDec context
|
||||
dec->parser_status_flag = 0;
|
||||
}
|
||||
|
||||
dec_task_init(task);
|
||||
@@ -392,10 +421,18 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task)
|
||||
* 2. get packet for parser preparing
|
||||
*/
|
||||
if (!dec->mpp_pkt_in && !task->status.curr_task_rdy) {
|
||||
MppQueue *packets = mpp->mPackets;
|
||||
mpp_list *packets = mpp->mPackets;
|
||||
AutoMutex autolock(packets->mutex());
|
||||
|
||||
if (packets->pull(&dec->mpp_pkt_in, sizeof(dec->mpp_pkt_in)))
|
||||
if (!packets->list_size()) {
|
||||
task->wait.dec_pkt_in = 1;
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
task->wait.dec_pkt_in = 0;
|
||||
packets->del_at_head(&dec->mpp_pkt_in, sizeof(dec->mpp_pkt_in));
|
||||
mpp->mPacketGetCount++;
|
||||
|
||||
if (dec->use_preset_time_order) {
|
||||
MppPacket pkt_in = NULL;
|
||||
mpp_packet_new(&pkt_in);
|
||||
@@ -405,7 +442,6 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task)
|
||||
mpp->mTimeStamps->push(&pkt_in, sizeof(pkt_in));
|
||||
}
|
||||
}
|
||||
mpp->mPacketGetCount++;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -524,12 +560,14 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task)
|
||||
return MPP_NOK;
|
||||
}
|
||||
}
|
||||
} else if (task->wait.dec_all_done) {
|
||||
if (!hal_task_check_empty(dec->tasks, TASK_PROCESSING)) {
|
||||
}
|
||||
|
||||
// for vp9 only wait all task is processed
|
||||
if (task->wait.dec_all_done) {
|
||||
if (!hal_task_check_empty(dec->tasks, TASK_PROCESSING))
|
||||
task->wait.dec_all_done = 0;
|
||||
} else {
|
||||
else
|
||||
return MPP_NOK;
|
||||
}
|
||||
}
|
||||
|
||||
dec_dbg_detail("check prev task pass\n");
|
||||
@@ -537,22 +575,12 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task)
|
||||
/* too many frame delay in dispaly queue */
|
||||
if (mpp->mFrames) {
|
||||
task->wait.dis_que_full = (mpp->mFrames->list_size() > 4) ? 1 : 0;
|
||||
task->wait.dis_que_full = 0;
|
||||
if (task->wait.dis_que_full)
|
||||
return MPP_ERR_DISPLAY_FULL;
|
||||
}
|
||||
dec_dbg_detail("check mframes pass\n");
|
||||
|
||||
/* 7.2 look for a unused hardware buffer for output */
|
||||
if (mpp->mFrameGroup) {
|
||||
RK_S32 unused = mpp_buffer_group_unused(mpp->mFrameGroup);
|
||||
|
||||
// NOTE: When dec post-process is enabled reserve 2 buffer for it.
|
||||
task->wait.dec_pic_buf = (dec->vproc) ? (unused < 3) : (unused < 1);
|
||||
if (task->wait.dec_pic_buf)
|
||||
return MPP_ERR_BUFFER_FULL;
|
||||
}
|
||||
dec_dbg_detail("check frame group count pass\n");
|
||||
|
||||
/* 7.3 wait for a unused slot index for decoder parse operation */
|
||||
task->wait.dec_slot_idx = (mpp_slots_get_unused_count(frame_slots)) ? (0) : (1);
|
||||
if (task->wait.dec_slot_idx)
|
||||
@@ -632,6 +660,17 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task)
|
||||
mpp_buffer_group_get_internal(&mpp->mFrameGroup, MPP_BUFFER_TYPE_ION);
|
||||
}
|
||||
|
||||
/* 10.1 look for a unused hardware buffer for output */
|
||||
if (mpp->mFrameGroup) {
|
||||
RK_S32 unused = mpp_buffer_group_unused(mpp->mFrameGroup);
|
||||
|
||||
// NOTE: When dec post-process is enabled reserve 2 buffer for it.
|
||||
task->wait.dec_pic_buf = (dec->vproc) ? (unused < 3) : (unused < 1);
|
||||
if (task->wait.dec_pic_buf)
|
||||
return MPP_ERR_BUFFER_FULL;
|
||||
}
|
||||
dec_dbg_detail("check frame group count pass\n");
|
||||
|
||||
/*
|
||||
* 11. do buffer operation according to usage information
|
||||
*
|
||||
@@ -675,6 +714,7 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task)
|
||||
|
||||
task->wait.dec_all_done = (dec->parser_fast_mode &&
|
||||
task_dec->flags.wait_done) ? 1 : 0;
|
||||
|
||||
task->status.dec_pkt_copy_rdy = 0;
|
||||
task->status.curr_task_rdy = 0;
|
||||
task->status.task_parsed_rdy = 0;
|
||||
@@ -709,11 +749,8 @@ void *mpp_dec_parser_thread(void *data)
|
||||
* 3. info change on progress
|
||||
* 3. no buffer on analyzing output task
|
||||
*/
|
||||
dec_dbg_stauts("%p wait status: 0x%08x\n", dec, task.wait.val);
|
||||
if (check_task_wait(dec, &task))
|
||||
parser->wait();
|
||||
|
||||
dec_dbg_stauts("%p done status: 0x%08x\n", dec, task.wait.val);
|
||||
}
|
||||
|
||||
if (dec->reset_flag) {
|
||||
@@ -726,9 +763,9 @@ void *mpp_dec_parser_thread(void *data)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (try_proc_dec_task(mpp, &task))
|
||||
continue;
|
||||
|
||||
// NOTE: ignore return value here is to fast response to reset.
|
||||
// Otherwise we can loop all dec task until it is failed.
|
||||
try_proc_dec_task(mpp, &task);
|
||||
}
|
||||
|
||||
mpp_dbg(MPP_DBG_INFO, "mpp_dec_parser_thread is going to exit\n");
|
||||
@@ -771,12 +808,15 @@ void *mpp_dec_hal_thread(void *data)
|
||||
continue;
|
||||
}
|
||||
|
||||
mpp_dec_notify(dec, MPP_DEC_NOTIFY_TASK_ALL_DONE);
|
||||
hal->wait();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (task) {
|
||||
RK_U32 notify_flag = MPP_DEC_NOTIFY_TASK_HND_VALID;
|
||||
|
||||
mpp->mTaskGetCount++;
|
||||
|
||||
hal_task_hnd_get_info(task, &task_info);
|
||||
@@ -793,7 +833,7 @@ void *mpp_dec_hal_thread(void *data)
|
||||
|
||||
hal_task_hnd_set_status(task, TASK_IDLE);
|
||||
task = NULL;
|
||||
mpp->mThreadCodec->signal();
|
||||
mpp_dec_notify(dec, notify_flag);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@@ -813,7 +853,7 @@ void *mpp_dec_hal_thread(void *data)
|
||||
mpp_dec_put_frame(mpp, -1, task_dec->flags);
|
||||
|
||||
hal_task_hnd_set_status(task, TASK_IDLE);
|
||||
mpp->mThreadCodec->signal();
|
||||
mpp_dec_notify(dec, notify_flag);
|
||||
task = NULL;
|
||||
continue;
|
||||
}
|
||||
@@ -831,7 +871,12 @@ void *mpp_dec_hal_thread(void *data)
|
||||
|
||||
hal_task_hnd_set_status(task, (dec->parser_fast_mode) ?
|
||||
(TASK_IDLE) : (TASK_PROC_DONE));
|
||||
mpp->mThreadCodec->signal();
|
||||
|
||||
if (dec->parser_fast_mode)
|
||||
notify_flag |= MPP_DEC_NOTIFY_TASK_HND_VALID;
|
||||
else
|
||||
notify_flag |= MPP_DEC_NOTIFY_TASK_PREV_DONE;
|
||||
|
||||
task = NULL;
|
||||
|
||||
mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT);
|
||||
@@ -843,6 +888,8 @@ void *mpp_dec_hal_thread(void *data)
|
||||
if (task_dec->flags.eos)
|
||||
mpp_dec_flush(dec);
|
||||
mpp_dec_push_display(mpp, task_dec->flags);
|
||||
|
||||
mpp_dec_notify(dec, notify_flag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1081,8 +1128,6 @@ MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg)
|
||||
}
|
||||
|
||||
mpp_buf_slot_setup(packet_slots, hal_task_count);
|
||||
cb.callBack = mpp_dec_notify;
|
||||
cb.opaque = p;
|
||||
ParserCfg parser_cfg = {
|
||||
coding,
|
||||
frame_slots,
|
||||
@@ -1090,7 +1135,6 @@ MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg)
|
||||
hal_task_count,
|
||||
cfg->need_split,
|
||||
cfg->internal_pts,
|
||||
cb,
|
||||
};
|
||||
|
||||
ret = mpp_parser_init(&parser, &parser_cfg);
|
||||
@@ -1135,7 +1179,7 @@ MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg)
|
||||
p->parser_internal_pts = cfg->internal_pts;
|
||||
p->enable_deinterlace = 1;
|
||||
*dec = p;
|
||||
dec_dbg_func("out\n");
|
||||
dec_dbg_func("%p out\n", p);
|
||||
return MPP_OK;
|
||||
} while (0);
|
||||
|
||||
@@ -1145,12 +1189,15 @@ MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg)
|
||||
|
||||
MPP_RET mpp_dec_deinit(MppDec *dec)
|
||||
{
|
||||
dec_dbg_func("in %p\n", dec);
|
||||
dec_dbg_func("%p in\n", dec);
|
||||
if (NULL == dec) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
dec_dbg_status("%p work %lu wait %lu\n", dec,
|
||||
dec->parser_work_count, dec->parser_wait_count);
|
||||
|
||||
if (dec->parser) {
|
||||
mpp_parser_deinit(dec->parser);
|
||||
dec->parser = NULL;
|
||||
@@ -1177,13 +1224,13 @@ MPP_RET mpp_dec_deinit(MppDec *dec)
|
||||
}
|
||||
|
||||
mpp_free(dec);
|
||||
dec_dbg_func("out\n");
|
||||
dec_dbg_func("%p out\n", dec);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_dec_reset(MppDec *dec)
|
||||
{
|
||||
dec_dbg_func("in %p\n", dec);
|
||||
dec_dbg_func("%p in\n", dec);
|
||||
if (NULL == dec) {
|
||||
mpp_err_f("found NULL input dec %p\n", dec);
|
||||
return MPP_ERR_NULL_PTR;
|
||||
@@ -1198,21 +1245,19 @@ MPP_RET mpp_dec_reset(MppDec *dec)
|
||||
dec->reset_flag = 1;
|
||||
|
||||
// signal parser thread to reset
|
||||
parser->lock();
|
||||
parser->signal();
|
||||
parser->unlock();
|
||||
mpp_dec_notify(dec, MPP_DEC_RESET);
|
||||
|
||||
parser->wait(THREAD_CONTROL);
|
||||
parser->unlock(THREAD_CONTROL);
|
||||
}
|
||||
|
||||
dec_dbg_func("out\n");
|
||||
dec_dbg_func("%p out\n", dec);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_dec_flush(MppDec *dec)
|
||||
{
|
||||
dec_dbg_func("in %p\n", dec);
|
||||
dec_dbg_func("%p in\n", dec);
|
||||
if (NULL == dec) {
|
||||
mpp_err_f("found NULL input dec %p\n", dec);
|
||||
return MPP_ERR_NULL_PTR;
|
||||
@@ -1221,22 +1266,36 @@ MPP_RET mpp_dec_flush(MppDec *dec)
|
||||
mpp_parser_flush(dec->parser);
|
||||
mpp_hal_flush(dec->hal);
|
||||
|
||||
dec_dbg_func("out\n");
|
||||
dec_dbg_func("%p out\n", dec);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_dec_notify(void *ctx, void *info)
|
||||
MPP_RET mpp_dec_notify(MppDec *dec, RK_U32 flag)
|
||||
{
|
||||
dec_dbg_func("in %p\n", ctx);
|
||||
(void)ctx;
|
||||
(void)info;
|
||||
dec_dbg_func("out\n");
|
||||
dec_dbg_func("%p in flag %08x\n", dec, flag);
|
||||
Mpp *mpp = (Mpp *)dec->mpp;
|
||||
MppThread *thd_dec = mpp->mThreadCodec;
|
||||
|
||||
thd_dec->lock();
|
||||
{
|
||||
RK_U32 old_flag = dec->parser_notify_flag;
|
||||
|
||||
dec->parser_notify_flag |= flag;
|
||||
if ((old_flag != dec->parser_notify_flag) &&
|
||||
(dec->parser_notify_flag & dec->parser_status_flag)) {
|
||||
dec_dbg_notify("%p status %08x notify %08x signal\n", dec,
|
||||
dec->parser_status_flag, dec->parser_notify_flag);
|
||||
thd_dec->signal();
|
||||
}
|
||||
}
|
||||
thd_dec->unlock();
|
||||
dec_dbg_func("%p out\n", dec);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param)
|
||||
{
|
||||
dec_dbg_func("in %p 0x%08x %p\n", dec, cmd, param);
|
||||
dec_dbg_func("%p in %08x %p\n", dec, cmd, param);
|
||||
if (NULL == dec) {
|
||||
mpp_err_f("found NULL input dec %p\n", dec);
|
||||
return MPP_ERR_NULL_PTR;
|
||||
@@ -1278,6 +1337,6 @@ MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param)
|
||||
} break;
|
||||
}
|
||||
|
||||
dec_dbg_func("out\n");
|
||||
dec_dbg_func("%p out\n", dec);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
@@ -266,15 +266,12 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding)
|
||||
}
|
||||
|
||||
mpp_buf_slot_setup(packet_slots, task_count);
|
||||
cb.callBack = mpp_enc_notify;
|
||||
cb.opaque = p;
|
||||
|
||||
ControllerCfg ctrl_cfg = {
|
||||
coding,
|
||||
&p->cfg,
|
||||
&p->set,
|
||||
task_count,
|
||||
cb,
|
||||
};
|
||||
|
||||
ret = controller_init(&controller, &ctrl_cfg);
|
||||
@@ -359,11 +356,11 @@ MPP_RET mpp_enc_reset(MppEnc *enc)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_enc_notify(void *ctx, void *info)
|
||||
MPP_RET mpp_enc_notify(MppEnc *enc, RK_U32 flag)
|
||||
{
|
||||
// TODO
|
||||
(void)ctx;
|
||||
(void)info;
|
||||
(void)enc;
|
||||
(void)flag;
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
|
@@ -160,12 +160,6 @@ typedef struct HalEncTask_t {
|
||||
|
||||
|
||||
typedef struct HalTask_u {
|
||||
RK_S64 codec_prepare[2];
|
||||
RK_S64 codec_parse[2];
|
||||
RK_S64 hal_gen[2];
|
||||
RK_S64 hal_start[2];
|
||||
RK_S64 hal_wait[2];
|
||||
|
||||
union {
|
||||
HalDecTask dec;
|
||||
HalEncTask enc;
|
||||
|
@@ -23,10 +23,35 @@
|
||||
#include "mpp_enc.h"
|
||||
#include "mpp_task.h"
|
||||
|
||||
#define MPP_DBG_FUNCTION (0x00000001)
|
||||
#define MPP_DBG_PACKET (0x00000002)
|
||||
#define MPP_DBG_FRAME (0x00000004)
|
||||
#define MPP_DBG_BUFFER (0x00000008)
|
||||
#define MPP_DBG_FUNCTION (0x00000001)
|
||||
#define MPP_DBG_PACKET (0x00000002)
|
||||
#define MPP_DBG_FRAME (0x00000004)
|
||||
#define MPP_DBG_BUFFER (0x00000008)
|
||||
|
||||
/*
|
||||
* mpp notify event flags
|
||||
* When event happens mpp will signal deocder / encoder with different flag.
|
||||
* These event will wake up the codec thread or hal thread
|
||||
*/
|
||||
#define MPP_INPUT_ENQUEUE (0x00000001)
|
||||
#define MPP_OUTPUT_DEQUEUE (0x00000002)
|
||||
#define MPP_RESET (0xFFFFFFFF)
|
||||
|
||||
/* mpp dec event flags */
|
||||
#define MPP_DEC_NOTIFY_PACKET_ENQUEUE (MPP_INPUT_ENQUEUE)
|
||||
#define MPP_DEC_NOTIFY_FRAME_DEQUEUE (MPP_OUTPUT_DEQUEUE)
|
||||
#define MPP_DEC_NOTIFY_EXT_BUF_GRP_READY (0x00000010)
|
||||
#define MPP_DEC_NOTIFY_INFO_CHG_DONE (0x00000020)
|
||||
#define MPP_DEC_NOTIFY_BUFFER_VALID (0x00000040)
|
||||
#define MPP_DEC_NOTIFY_TASK_ALL_DONE (0x00000080)
|
||||
#define MPP_DEC_NOTIFY_TASK_HND_VALID (0x00000100)
|
||||
#define MPP_DEC_NOTIFY_TASK_PREV_DONE (0x00000200)
|
||||
#define MPP_DEC_RESET (MPP_RESET)
|
||||
|
||||
/* mpp enc event flags */
|
||||
#define MPP_ENC_NOTIFY_FRAME_ENQUEUE (MPP_INPUT_ENQUEUE)
|
||||
#define MPP_ENC_NOTIFY_PACKET_DEQUEUE (MPP_OUTPUT_DEQUEUE)
|
||||
#define MPP_ENC_RESET (MPP_RESET)
|
||||
|
||||
/*
|
||||
* mpp hierarchy
|
||||
@@ -79,7 +104,10 @@ public:
|
||||
MPP_RET reset();
|
||||
MPP_RET control(MpiCmd cmd, MppParam param);
|
||||
|
||||
MppQueue *mPackets;
|
||||
MPP_RET notify(RK_U32 flag);
|
||||
MPP_RET notify(MppBufferGroup group);
|
||||
|
||||
mpp_list *mPackets;
|
||||
mpp_list *mFrames;
|
||||
MppQueue *mTimeStamps;
|
||||
/* counters for debug */
|
||||
|
74
mpp/mpp.cpp
74
mpp/mpp.cpp
@@ -34,6 +34,13 @@
|
||||
#define MPP_TEST_FRAME_SIZE SZ_1M
|
||||
#define MPP_TEST_PACKET_SIZE SZ_512K
|
||||
|
||||
static void mpp_notify_by_buffer_group(void *arg, void *group)
|
||||
{
|
||||
Mpp *mpp = (Mpp *)arg;
|
||||
|
||||
mpp->notify((MppBufferGroup) group);
|
||||
}
|
||||
|
||||
Mpp::Mpp()
|
||||
: mPackets(NULL),
|
||||
mFrames(NULL),
|
||||
@@ -81,7 +88,7 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
||||
mCoding = coding;
|
||||
switch (mType) {
|
||||
case MPP_CTX_DEC : {
|
||||
mPackets = new MppQueue((node_destructor)mpp_packet_deinit);
|
||||
mPackets = new mpp_list((node_destructor)mpp_packet_deinit);
|
||||
mFrames = new mpp_list((node_destructor)mpp_frame_deinit);
|
||||
mTimeStamps = new MppQueue((node_destructor)mpp_packet_deinit);
|
||||
|
||||
@@ -116,7 +123,7 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
||||
} break;
|
||||
case MPP_CTX_ENC : {
|
||||
mFrames = new mpp_list((node_destructor)NULL);
|
||||
mPackets = new MppQueue((node_destructor)mpp_packet_deinit);
|
||||
mPackets = new mpp_list((node_destructor)mpp_packet_deinit);
|
||||
|
||||
mpp_enc_init(&mEnc, coding);
|
||||
mThreadCodec = new MppThread(mpp_enc_control_thread, this, "mpp_enc_ctrl");
|
||||
@@ -177,7 +184,8 @@ void Mpp::clear()
|
||||
{
|
||||
// MUST: release listener here
|
||||
if (mFrameGroup)
|
||||
mpp_buffer_group_set_listener((MppBufferGroupImpl *)mFrameGroup, NULL);
|
||||
mpp_buffer_group_set_callback((MppBufferGroupImpl *)mFrameGroup,
|
||||
NULL, NULL);
|
||||
|
||||
if (mType == MPP_CTX_ENC) {
|
||||
if (mThreadCodec)
|
||||
@@ -270,8 +278,9 @@ MPP_RET Mpp::put_packet(MppPacket packet)
|
||||
|
||||
AutoMutex autoLock(mPackets->mutex());
|
||||
if (mExtraPacket) {
|
||||
mPackets->push(&mExtraPacket, sizeof(mExtraPacket));
|
||||
mPackets->add_at_tail(&mExtraPacket, sizeof(mExtraPacket));
|
||||
mExtraPacket = NULL;
|
||||
mPacketPutCount++;
|
||||
}
|
||||
|
||||
RK_U32 eos = mpp_packet_get_eos(packet);
|
||||
@@ -280,11 +289,13 @@ MPP_RET Mpp::put_packet(MppPacket packet)
|
||||
if (MPP_OK != mpp_packet_copy_init(&pkt, packet))
|
||||
return MPP_NOK;
|
||||
|
||||
mPackets->push(&pkt, sizeof(pkt));
|
||||
mPackets->add_at_tail(&pkt, sizeof(pkt));
|
||||
mPacketPutCount++;
|
||||
|
||||
// when packet has been send clear the length
|
||||
mpp_packet_set_length(packet, 0);
|
||||
|
||||
notify(MPP_INPUT_ENQUEUE);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
@@ -322,7 +333,7 @@ MPP_RET Mpp::get_frame(MppFrame *frame)
|
||||
if (mFrames->list_size()) {
|
||||
mFrames->del_at_head(&first, sizeof(frame));
|
||||
mFrameGetCount++;
|
||||
mThreadHal->signal();
|
||||
notify(MPP_OUTPUT_DEQUEUE);
|
||||
|
||||
if (mMultiFrame) {
|
||||
MppFrame prev = first;
|
||||
@@ -330,7 +341,7 @@ MPP_RET Mpp::get_frame(MppFrame *frame)
|
||||
while (mFrames->list_size()) {
|
||||
mFrames->del_at_head(&next, sizeof(frame));
|
||||
mFrameGetCount++;
|
||||
mThreadHal->signal();
|
||||
notify(MPP_OUTPUT_DEQUEUE);
|
||||
mpp_frame_set_next(prev, next);
|
||||
prev = next;
|
||||
}
|
||||
@@ -344,7 +355,7 @@ MPP_RET Mpp::get_frame(MppFrame *frame)
|
||||
// change too.
|
||||
AutoMutex autoPacketLock(mPackets->mutex());
|
||||
if (mPackets->list_size())
|
||||
mThreadCodec->signal();
|
||||
notify(MPP_INPUT_ENQUEUE);
|
||||
}
|
||||
|
||||
*frame = first;
|
||||
@@ -506,8 +517,11 @@ MPP_RET Mpp::dequeue(MppPortType type, MppTask *task)
|
||||
} break;
|
||||
}
|
||||
|
||||
if (port)
|
||||
if (port) {
|
||||
ret = mpp_port_dequeue(port, task);
|
||||
if (MPP_OK == ret)
|
||||
notify(MPP_OUTPUT_DEQUEUE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -537,6 +551,7 @@ MPP_RET Mpp::enqueue(MppPortType type, MppTask task)
|
||||
if (MPP_OK == ret) {
|
||||
// if enqueue success wait up thread
|
||||
mThreadCodec->signal();
|
||||
notify(MPP_INPUT_ENQUEUE);
|
||||
}
|
||||
mThreadCodec->unlock();
|
||||
}
|
||||
@@ -735,9 +750,11 @@ MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param)
|
||||
mpp_log("using external buffer group %p\n", mFrameGroup);
|
||||
|
||||
if (mThreadCodec) {
|
||||
ret = mpp_buffer_group_set_listener((MppBufferGroupImpl *)param,
|
||||
(void *)mThreadCodec);
|
||||
mThreadCodec->signal();
|
||||
ret = mpp_buffer_group_set_callback((MppBufferGroupImpl *)param,
|
||||
mpp_notify_by_buffer_group,
|
||||
(void *)this);
|
||||
|
||||
notify(MPP_DEC_NOTIFY_EXT_BUF_GRP_READY);
|
||||
} else {
|
||||
/*
|
||||
* NOTE: If frame buffer group is configured before decoder init
|
||||
@@ -759,7 +776,7 @@ MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param)
|
||||
mpp_log("set info change ready\n");
|
||||
|
||||
ret = mpp_buf_slot_ready(mDec->frame_slots);
|
||||
mThreadCodec->signal();
|
||||
notify(MPP_DEC_NOTIFY_INFO_CHG_DONE);
|
||||
} break;
|
||||
case MPP_DEC_SET_PARSER_SPLIT_MODE: {
|
||||
RK_U32 flag = *((RK_U32 *)param);
|
||||
@@ -808,3 +825,34 @@ MPP_RET Mpp::control_isp(MpiCmd cmd, MppParam param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET Mpp::notify(RK_U32 flag)
|
||||
{
|
||||
switch (mType) {
|
||||
case MPP_CTX_DEC : {
|
||||
return mpp_dec_notify(mDec, flag);
|
||||
} break;
|
||||
case MPP_CTX_ENC : {
|
||||
return mpp_enc_notify(mEnc, flag);
|
||||
} break;
|
||||
default : {
|
||||
mpp_err("unsupport context type %d\n", mType);
|
||||
} break;
|
||||
}
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
MPP_RET Mpp::notify(MppBufferGroup group)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
switch (mType) {
|
||||
case MPP_CTX_DEC : {
|
||||
if (group == mFrameGroup)
|
||||
ret = notify(MPP_DEC_NOTIFY_BUFFER_VALID);
|
||||
} break;
|
||||
default : {
|
||||
} break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user