mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-27 19:10:21 +08:00
[mpp_enc]: Optimize encoder flow
1. Create hal_task_group in mpp_enc_hal. 2. Reduce EncAsyncTaskInfo copy in async flow. Change-Id: If81ffc72122f87eb6d2f83bb5ecd7de5400bc140 Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
@@ -80,6 +80,9 @@ typedef struct MppEncImpl_t {
|
|||||||
RK_U32 low_delay_part_mode;
|
RK_U32 low_delay_part_mode;
|
||||||
|
|
||||||
/* base task information */
|
/* base task information */
|
||||||
|
HalTaskGroup tasks;
|
||||||
|
HalTaskHnd hnd;
|
||||||
|
EncAsyncTaskInfo *async;
|
||||||
RK_U32 task_idx;
|
RK_U32 task_idx;
|
||||||
RK_S64 task_pts;
|
RK_S64 task_pts;
|
||||||
MppBuffer frm_buf;
|
MppBuffer frm_buf;
|
||||||
|
|||||||
@@ -56,62 +56,6 @@ typedef union EncAsyncWait_u {
|
|||||||
};
|
};
|
||||||
} EncAsyncWait;
|
} EncAsyncWait;
|
||||||
|
|
||||||
/* encoder internal work flow */
|
|
||||||
typedef union EncAsyncStatus_u {
|
|
||||||
RK_U32 val;
|
|
||||||
struct {
|
|
||||||
RK_U32 task_hnd_rdy : 1;
|
|
||||||
RK_U32 task_in_rdy : 1;
|
|
||||||
RK_U32 task_out_rdy : 1;
|
|
||||||
|
|
||||||
RK_U32 frm_pkt_rdy : 1;
|
|
||||||
|
|
||||||
RK_U32 hal_task_reset_rdy : 1; // reset hal task to start
|
|
||||||
RK_U32 rc_check_frm_drop : 1; // rc stage
|
|
||||||
RK_U32 pkt_buf_rdy : 1; // prepare pkt buf
|
|
||||||
|
|
||||||
RK_U32 enc_start : 1; // enc stage
|
|
||||||
RK_U32 refs_force_update : 1; // enc stage
|
|
||||||
RK_U32 low_delay_again : 1; // enc stage low delay output again
|
|
||||||
|
|
||||||
RK_U32 enc_backup : 1; // enc stage
|
|
||||||
RK_U32 enc_restore : 1; // reenc flow start point
|
|
||||||
RK_U32 enc_proc_dpb : 1; // enc stage
|
|
||||||
RK_U32 rc_frm_start : 1; // rc stage
|
|
||||||
RK_U32 check_type_reenc : 1; // flow checkpoint if reenc -> enc_restore
|
|
||||||
RK_U32 enc_proc_hal : 1; // enc stage
|
|
||||||
RK_U32 hal_get_task : 1; // hal stage
|
|
||||||
RK_U32 rc_hal_start : 1; // rc stage
|
|
||||||
RK_U32 hal_gen_reg : 1; // hal stage
|
|
||||||
RK_U32 hal_start : 1; // hal stage
|
|
||||||
RK_U32 hal_wait : 1; // hal stage NOTE: special in low delay mode
|
|
||||||
RK_U32 rc_hal_end : 1; // rc stage
|
|
||||||
RK_U32 hal_ret_task : 1; // hal stage
|
|
||||||
RK_U32 enc_update_hal : 1; // enc stage
|
|
||||||
RK_U32 rc_frm_end : 1; // rc stage
|
|
||||||
RK_U32 check_rc_reenc : 1; // flow checkpoint if reenc -> enc_restore
|
|
||||||
RK_U32 enc_done : 1; // done stage
|
|
||||||
RK_U32 slice_out_done : 1;
|
|
||||||
};
|
|
||||||
} EncAsyncStatus;
|
|
||||||
|
|
||||||
typedef struct EncAsyncTaskInfo_t {
|
|
||||||
RK_S32 seq_idx;
|
|
||||||
EncAsyncStatus status;
|
|
||||||
RK_S64 pts;
|
|
||||||
|
|
||||||
HalEncTask task;
|
|
||||||
EncRcTask rc;
|
|
||||||
MppEncRefFrmUsrCfg usr;
|
|
||||||
} EncAsyncTaskInfo;
|
|
||||||
|
|
||||||
typedef struct EncAsyncTask_t {
|
|
||||||
HalTaskGroup tasks;
|
|
||||||
HalTaskHnd hnd;
|
|
||||||
|
|
||||||
EncAsyncTaskInfo info;
|
|
||||||
} EncAsyncTask;
|
|
||||||
|
|
||||||
static RK_U8 uuid_version[16] = {
|
static RK_U8 uuid_version[16] = {
|
||||||
0x3d, 0x07, 0x6d, 0x45, 0x73, 0x0f, 0x41, 0xa8,
|
0x3d, 0x07, 0x6d, 0x45, 0x73, 0x0f, 0x41, 0xa8,
|
||||||
0xb1, 0xc4, 0x25, 0xd7, 0x97, 0x6b, 0xf1, 0xac,
|
0xb1, 0xc4, 0x25, 0xd7, 0x97, 0x6b, 0xf1, 0xac,
|
||||||
@@ -2159,18 +2103,18 @@ void *mpp_enc_thread(void *data)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void async_task_reset(EncAsyncTask *task)
|
static void async_task_reset(EncAsyncTaskInfo *task)
|
||||||
{
|
{
|
||||||
memset(&task->info, 0, sizeof(task->info));
|
memset(task, 0, sizeof(*task));
|
||||||
task->info.task.rc_task = &task->info.rc;
|
task->task.rc_task = &task->rc;
|
||||||
task->info.task.frm_cfg = &task->info.usr;
|
task->task.frm_cfg = &task->usr;
|
||||||
task->info.usr.force_flag = 0;
|
task->usr.force_flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void async_task_terminate(MppEncImpl *enc, EncAsyncTask *async)
|
static void async_task_terminate(MppEncImpl *enc, EncAsyncTaskInfo *async)
|
||||||
{
|
{
|
||||||
HalEncTask *hal_task = &async->info.task;
|
HalEncTask *hal_task = &async->task;
|
||||||
EncFrmStatus *frm = &async->info.rc.frm;
|
EncFrmStatus *frm = &async->rc.frm;
|
||||||
Mpp *mpp = (Mpp *)enc->mpp;
|
Mpp *mpp = (Mpp *)enc->mpp;
|
||||||
|
|
||||||
mpp_stopwatch_record(hal_task->stopwatch, "encode task done");
|
mpp_stopwatch_record(hal_task->stopwatch, "encode task done");
|
||||||
@@ -2271,9 +2215,9 @@ static void async_task_skip(MppEncImpl *enc)
|
|||||||
enc_dbg_detail("packet skip ready\n");
|
enc_dbg_detail("packet skip ready\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static MPP_RET check_async_frm_pkt(EncAsyncTask *async)
|
static MPP_RET check_async_frm_pkt(EncAsyncTaskInfo *async)
|
||||||
{
|
{
|
||||||
HalEncTask *hal_task = &async->info.task;
|
HalEncTask *hal_task = &async->task;
|
||||||
MppPacket packet = hal_task->packet;
|
MppPacket packet = hal_task->packet;
|
||||||
MppFrame frame = hal_task->frame;
|
MppFrame frame = hal_task->frame;
|
||||||
|
|
||||||
@@ -2304,9 +2248,9 @@ static MPP_RET check_async_frm_pkt(EncAsyncTask *async)
|
|||||||
return (NULL == frame || NULL == hal_task->input) ? MPP_NOK : MPP_OK;
|
return (NULL == frame || NULL == hal_task->input) ? MPP_NOK : MPP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MPP_RET check_async_pkt_buf(MppEncImpl *enc, EncAsyncTask *async)
|
static MPP_RET check_async_pkt_buf(MppEncImpl *enc, EncAsyncTaskInfo *async)
|
||||||
{
|
{
|
||||||
HalEncTask *hal_task = &async->info.task;
|
HalEncTask *hal_task = &async->task;
|
||||||
|
|
||||||
if (NULL == hal_task->output) {
|
if (NULL == hal_task->output) {
|
||||||
/* NOTE: set buffer w * h * 1.5 to avoid buffer overflow */
|
/* NOTE: set buffer w * h * 1.5 to avoid buffer overflow */
|
||||||
@@ -2341,27 +2285,30 @@ static MPP_RET check_async_pkt_buf(MppEncImpl *enc, EncAsyncTask *async)
|
|||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MPP_RET try_get_async_task(MppEncImpl *enc, EncAsyncTask *async, EncAsyncWait *wait)
|
static MPP_RET try_get_async_task(MppEncImpl *enc, EncAsyncWait *wait)
|
||||||
{
|
{
|
||||||
Mpp *mpp = (Mpp *)enc->mpp;
|
Mpp *mpp = (Mpp *)enc->mpp;
|
||||||
EncRcTask *rc_task = &async->info.rc;
|
EncAsyncTaskInfo *async = enc->async;
|
||||||
EncFrmStatus *frm = &rc_task->frm;
|
EncRcTask *rc_task = NULL;
|
||||||
MppEncHeaderStatus *hdr_status = &enc->hdr_status;
|
MppEncHeaderStatus *hdr_status = &enc->hdr_status;
|
||||||
HalEncTask *hal_task = &async->info.task;
|
HalEncTask *hal_task = NULL;
|
||||||
EncAsyncStatus *status = &async->info.status;
|
EncAsyncStatus *status = NULL;
|
||||||
MppStopwatch stopwatch = NULL;
|
MppStopwatch stopwatch = NULL;
|
||||||
MppPacket packet = hal_task->packet;
|
MppPacket packet = NULL;
|
||||||
MppFrame frame = hal_task->frame;
|
MppFrame frame = NULL;
|
||||||
RK_U32 seq_idx = 0;
|
RK_U32 seq_idx = 0;
|
||||||
MPP_RET ret = MPP_OK;
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
if (NULL == async->hnd) {
|
if (NULL == enc->hnd) {
|
||||||
hal_task_get_hnd(async->tasks, TASK_IDLE, &async->hnd);
|
hal_task_get_hnd(enc->tasks, TASK_IDLE, &enc->hnd);
|
||||||
if (async->hnd) {
|
if (enc->hnd) {
|
||||||
status->task_hnd_rdy = 1;
|
|
||||||
wait->task_hnd = 0;
|
wait->task_hnd = 0;
|
||||||
enc_dbg_detail("get hnd success\n");
|
enc_dbg_detail("get hnd success\n");
|
||||||
|
|
||||||
|
mpp_assert(enc->async == NULL);
|
||||||
|
async = (EncAsyncTaskInfo *)hal_task_hnd_get_data(enc->hnd);
|
||||||
async_task_reset(async);
|
async_task_reset(async);
|
||||||
|
enc->async = async;
|
||||||
} else {
|
} else {
|
||||||
wait->task_hnd = 1;
|
wait->task_hnd = 1;
|
||||||
enc_dbg_detail("get hnd failed\n");
|
enc_dbg_detail("get hnd failed\n");
|
||||||
@@ -2369,6 +2316,15 @@ static MPP_RET try_get_async_task(MppEncImpl *enc, EncAsyncTask *async, EncAsync
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mpp_assert(enc->hnd);
|
||||||
|
mpp_assert(enc->async);
|
||||||
|
|
||||||
|
hal_task = &async->task;
|
||||||
|
rc_task = &async->rc;
|
||||||
|
status = &async->status;
|
||||||
|
packet = hal_task->packet;
|
||||||
|
frame = hal_task->frame;
|
||||||
|
|
||||||
if (NULL == frame) {
|
if (NULL == frame) {
|
||||||
if (mpp->mFrmIn) {
|
if (mpp->mFrmIn) {
|
||||||
mpp_list *frm_in = mpp->mFrmIn;
|
mpp_list *frm_in = mpp->mFrmIn;
|
||||||
@@ -2436,17 +2392,19 @@ static MPP_RET try_get_async_task(MppEncImpl *enc, EncAsyncTask *async, EncAsync
|
|||||||
hal_task->stopwatch = stopwatch;
|
hal_task->stopwatch = stopwatch;
|
||||||
enc_dbg_detail("task frame packet ready\n");
|
enc_dbg_detail("task frame packet ready\n");
|
||||||
|
|
||||||
async->info.seq_idx = enc->task_idx++;
|
async->seq_idx = enc->task_idx++;
|
||||||
async->info.pts = mpp_frame_get_pts(hal_task->frame);
|
async->pts = mpp_frame_get_pts(hal_task->frame);
|
||||||
|
|
||||||
rc_task->frame = async->info.task.frame;
|
rc_task->frame = async->task.frame;
|
||||||
enc_dbg_detail("task seq idx %d start\n", seq_idx);
|
enc_dbg_detail("task seq idx %d start\n", seq_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
seq_idx = async->info.seq_idx;
|
seq_idx = async->seq_idx;
|
||||||
|
|
||||||
// 9. check frame drop by frame rate conversion
|
// 9. check frame drop by frame rate conversion
|
||||||
if (!status->rc_check_frm_drop) {
|
if (!status->rc_check_frm_drop) {
|
||||||
|
EncFrmStatus *frm = &rc_task->frm;
|
||||||
|
|
||||||
ENC_RUN_FUNC2(rc_frm_check_drop, enc->rc_ctx, rc_task, enc->mpp, ret);
|
ENC_RUN_FUNC2(rc_frm_check_drop, enc->rc_ctx, rc_task, enc->mpp, ret);
|
||||||
status->rc_check_frm_drop = 1;
|
status->rc_check_frm_drop = 1;
|
||||||
enc_dbg_detail("task %d drop %d\n", seq_idx, frm->drop);
|
enc_dbg_detail("task %d drop %d\n", seq_idx, frm->drop);
|
||||||
@@ -2513,7 +2471,7 @@ static MPP_RET try_get_async_task(MppEncImpl *enc, EncAsyncTask *async, EncAsync
|
|||||||
|
|
||||||
// 14. setup user_cfg to dpb
|
// 14. setup user_cfg to dpb
|
||||||
if (!status->refs_force_update) {
|
if (!status->refs_force_update) {
|
||||||
MppEncRefFrmUsrCfg *frm_cfg = &async->info.usr;
|
MppEncRefFrmUsrCfg *frm_cfg = &async->usr;
|
||||||
|
|
||||||
if (frm_cfg->force_flag) {
|
if (frm_cfg->force_flag) {
|
||||||
mpp_enc_refs_set_usr_cfg(enc->refs, frm_cfg);
|
mpp_enc_refs_set_usr_cfg(enc->refs, frm_cfg);
|
||||||
@@ -2540,19 +2498,20 @@ TASK_DONE:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MPP_RET proc_async_task(MppEncImpl *enc, EncAsyncTask *async)
|
static MPP_RET proc_async_task(MppEncImpl *enc)
|
||||||
{
|
{
|
||||||
Mpp *mpp = (Mpp*)enc->mpp;
|
Mpp *mpp = (Mpp*)enc->mpp;
|
||||||
EncImpl impl = enc->impl;
|
EncImpl impl = enc->impl;
|
||||||
MppEncHal hal = enc->enc_hal;
|
MppEncHal hal = enc->enc_hal;
|
||||||
MppEncHeaderStatus *hdr_status = &enc->hdr_status;
|
MppEncHeaderStatus *hdr_status = &enc->hdr_status;
|
||||||
EncAsyncStatus *status = &async->info.status;
|
EncAsyncTaskInfo *async = enc->async;
|
||||||
HalEncTask *hal_task = &async->info.task;
|
EncAsyncStatus *status = &async->status;
|
||||||
|
HalEncTask *hal_task = &async->task;
|
||||||
EncRcTask *rc_task = hal_task->rc_task;
|
EncRcTask *rc_task = hal_task->rc_task;
|
||||||
EncCpbStatus *cpb = &rc_task->cpb;
|
EncCpbStatus *cpb = &rc_task->cpb;
|
||||||
EncFrmStatus *frm = &rc_task->frm;
|
EncFrmStatus *frm = &rc_task->frm;
|
||||||
MppPacket packet = hal_task->packet;
|
MppPacket packet = hal_task->packet;
|
||||||
RK_U32 seq_idx = async->info.seq_idx;
|
RK_U32 seq_idx = async->seq_idx;
|
||||||
MPP_RET ret = MPP_OK;
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
mpp_assert(hal_task->valid);
|
mpp_assert(hal_task->valid);
|
||||||
@@ -2631,12 +2590,11 @@ static MPP_RET proc_async_task(MppEncImpl *enc, EncAsyncTask *async)
|
|||||||
|
|
||||||
SEND_TASK_INFO:
|
SEND_TASK_INFO:
|
||||||
status->enc_done = 0;
|
status->enc_done = 0;
|
||||||
hal_task_hnd_set_info(async->hnd, &async->info);
|
hal_task_hnd_set_status(enc->hnd, TASK_PROCESSING);
|
||||||
hal_task_hnd_set_status(async->hnd, TASK_PROCESSING);
|
|
||||||
enc_dbg_detail("task %d on processing ret %d\n", frm->seq_idx, ret);
|
enc_dbg_detail("task %d on processing ret %d\n", frm->seq_idx, ret);
|
||||||
|
|
||||||
async_task_reset(async);
|
enc->hnd = NULL;
|
||||||
async->hnd = NULL;
|
enc->async = NULL;
|
||||||
|
|
||||||
TASK_DONE:
|
TASK_DONE:
|
||||||
|
|
||||||
@@ -2744,26 +2702,13 @@ void *mpp_enc_async_thread(void *data)
|
|||||||
Mpp *mpp = (Mpp*)data;
|
Mpp *mpp = (Mpp*)data;
|
||||||
MppEncImpl *enc = (MppEncImpl *)mpp->mEnc;
|
MppEncImpl *enc = (MppEncImpl *)mpp->mEnc;
|
||||||
MppThread *thd_enc = enc->thread_enc;
|
MppThread *thd_enc = enc->thread_enc;
|
||||||
HalTaskGroup tasks = NULL;
|
|
||||||
EncAsyncTask task;
|
|
||||||
EncAsyncWait wait;
|
EncAsyncWait wait;
|
||||||
HalTaskHnd hnd = NULL;
|
|
||||||
MPP_RET ret = MPP_OK;
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
enc_dbg_func("thread start\n");
|
enc_dbg_func("thread start\n");
|
||||||
|
|
||||||
async_task_reset(&task);
|
|
||||||
task.hnd = NULL;
|
|
||||||
wait.val = 0;
|
wait.val = 0;
|
||||||
|
|
||||||
/* init two task for */
|
|
||||||
ret = hal_task_group_init(&tasks, 2, sizeof(EncAsyncTaskInfo));
|
|
||||||
if (ret) {
|
|
||||||
mpp_err_f("hal_task_group_init failed ret %d\n", ret);
|
|
||||||
goto DONE;;
|
|
||||||
}
|
|
||||||
task.tasks = tasks;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
{
|
{
|
||||||
AutoMutex autolock(thd_enc->mutex());
|
AutoMutex autolock(thd_enc->mutex());
|
||||||
@@ -2781,6 +2726,8 @@ void *mpp_enc_async_thread(void *data)
|
|||||||
// 1. process user control and reset flag
|
// 1. process user control and reset flag
|
||||||
if (enc->cmd_send != enc->cmd_recv || enc->reset_flag) {
|
if (enc->cmd_send != enc->cmd_recv || enc->reset_flag) {
|
||||||
mpp_list *frm_in = mpp->mFrmIn;
|
mpp_list *frm_in = mpp->mFrmIn;
|
||||||
|
HalTaskHnd hnd = NULL;
|
||||||
|
EncAsyncTaskInfo *info = NULL;
|
||||||
|
|
||||||
/* when process cmd or reset hold frame input */
|
/* when process cmd or reset hold frame input */
|
||||||
frm_in->lock();
|
frm_in->lock();
|
||||||
@@ -2788,13 +2735,12 @@ void *mpp_enc_async_thread(void *data)
|
|||||||
enc_dbg_detail("ctrl proc %d cmd %08x\n", enc->cmd_recv, enc->cmd);
|
enc_dbg_detail("ctrl proc %d cmd %08x\n", enc->cmd_recv, enc->cmd);
|
||||||
|
|
||||||
// wait all tasks done
|
// wait all tasks done
|
||||||
while (MPP_OK == hal_task_get_hnd(tasks, TASK_PROCESSING, &hnd)) {
|
while (MPP_OK == hal_task_get_hnd(enc->tasks, TASK_PROCESSING, &hnd)) {
|
||||||
EncAsyncTaskInfo info;
|
info = (EncAsyncTaskInfo *)hal_task_hnd_get_data(hnd);
|
||||||
|
|
||||||
hal_task_hnd_get_info(hnd, &info);
|
mpp_assert(!info->status.enc_done);
|
||||||
|
|
||||||
mpp_assert(!info.status.enc_done);
|
enc_async_wait_task(enc, info);
|
||||||
enc_async_wait_task(enc, &info);
|
|
||||||
hal_task_hnd_set_status(hnd, TASK_IDLE);
|
hal_task_hnd_set_status(hnd, TASK_IDLE);
|
||||||
wait.task_hnd = 0;
|
wait.task_hnd = 0;
|
||||||
}
|
}
|
||||||
@@ -2845,22 +2791,19 @@ void *mpp_enc_async_thread(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. try get a task to encode
|
// 2. try get a task to encode
|
||||||
ret = try_get_async_task(enc, &task, &wait);
|
ret = try_get_async_task(enc, &wait);
|
||||||
enc_dbg_detail("try_get_async_task ret %d\n", ret);
|
enc_dbg_detail("try_get_async_task ret %d\n", ret);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
hal_task_get_hnd(tasks, TASK_PROCESSING, &hnd);
|
HalTaskHnd hnd = NULL;
|
||||||
|
EncAsyncTaskInfo *info = NULL;
|
||||||
|
|
||||||
|
hal_task_get_hnd(enc->tasks, TASK_PROCESSING, &hnd);
|
||||||
if (hnd) {
|
if (hnd) {
|
||||||
EncAsyncTaskInfo info;
|
info = (EncAsyncTaskInfo *)hal_task_hnd_get_data(hnd);
|
||||||
|
|
||||||
hal_task_hnd_get_info(hnd, &info);
|
mpp_assert(!info->status.enc_done);
|
||||||
|
|
||||||
mpp_assert(!info.status.enc_done);
|
enc_async_wait_task(enc, info);
|
||||||
|
|
||||||
/* NOTE: update pointer in rc_task */
|
|
||||||
info.task.rc_task = &info.rc;
|
|
||||||
info.task.frm_cfg = &info.usr;
|
|
||||||
|
|
||||||
enc_async_wait_task(enc, &info);
|
|
||||||
hal_task_hnd_set_status(hnd, TASK_IDLE);
|
hal_task_hnd_set_status(hnd, TASK_IDLE);
|
||||||
wait.task_hnd = 0;
|
wait.task_hnd = 0;
|
||||||
}
|
}
|
||||||
@@ -2868,17 +2811,10 @@ void *mpp_enc_async_thread(void *data)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpp_assert(task.info.task.valid);
|
mpp_assert(enc->async);
|
||||||
|
mpp_assert(enc->async->task.valid);
|
||||||
|
|
||||||
proc_async_task(enc, &task);
|
proc_async_task(enc);
|
||||||
}
|
|
||||||
|
|
||||||
DONE:
|
|
||||||
enc_dbg_func("loop done\n");
|
|
||||||
|
|
||||||
if (tasks) {
|
|
||||||
ret = hal_task_group_deinit(tasks);
|
|
||||||
tasks = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enc_dbg_func("thread finish\n");
|
enc_dbg_func("thread finish\n");
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ MPP_RET mpp_enc_init_v2(MppEnc *enc, MppEncInitCfg *cfg)
|
|||||||
p->enc_hal = enc_hal;
|
p->enc_hal = enc_hal;
|
||||||
p->dev = enc_hal_cfg.dev;
|
p->dev = enc_hal_cfg.dev;
|
||||||
p->mpp = cfg->mpp;
|
p->mpp = cfg->mpp;
|
||||||
|
p->tasks = enc_hal_cfg.tasks;
|
||||||
p->sei_mode = MPP_ENC_SEI_MODE_ONE_SEQ;
|
p->sei_mode = MPP_ENC_SEI_MODE_ONE_SEQ;
|
||||||
p->version_info = get_mpp_version();
|
p->version_info = get_mpp_version();
|
||||||
p->version_length = strlen(p->version_info);
|
p->version_length = strlen(p->version_info);
|
||||||
|
|||||||
@@ -101,4 +101,53 @@ typedef struct HalEncTask_t {
|
|||||||
HalEncTaskFlag flags;
|
HalEncTaskFlag flags;
|
||||||
} HalEncTask;
|
} HalEncTask;
|
||||||
|
|
||||||
|
/* encoder internal work flow */
|
||||||
|
typedef union EncAsyncStatus_u {
|
||||||
|
RK_U32 val;
|
||||||
|
struct {
|
||||||
|
RK_U32 task_hnd_rdy : 1;
|
||||||
|
RK_U32 task_in_rdy : 1;
|
||||||
|
RK_U32 task_out_rdy : 1;
|
||||||
|
|
||||||
|
RK_U32 frm_pkt_rdy : 1;
|
||||||
|
|
||||||
|
RK_U32 hal_task_reset_rdy : 1; // reset hal task to start
|
||||||
|
RK_U32 rc_check_frm_drop : 1; // rc stage
|
||||||
|
RK_U32 pkt_buf_rdy : 1; // prepare pkt buf
|
||||||
|
|
||||||
|
RK_U32 enc_start : 1; // enc stage
|
||||||
|
RK_U32 refs_force_update : 1; // enc stage
|
||||||
|
RK_U32 low_delay_again : 1; // enc stage low delay output again
|
||||||
|
|
||||||
|
RK_U32 enc_backup : 1; // enc stage
|
||||||
|
RK_U32 enc_restore : 1; // reenc flow start point
|
||||||
|
RK_U32 enc_proc_dpb : 1; // enc stage
|
||||||
|
RK_U32 rc_frm_start : 1; // rc stage
|
||||||
|
RK_U32 check_type_reenc : 1; // flow checkpoint if reenc -> enc_restore
|
||||||
|
RK_U32 enc_proc_hal : 1; // enc stage
|
||||||
|
RK_U32 hal_get_task : 1; // hal stage
|
||||||
|
RK_U32 rc_hal_start : 1; // rc stage
|
||||||
|
RK_U32 hal_gen_reg : 1; // hal stage
|
||||||
|
RK_U32 hal_start : 1; // hal stage
|
||||||
|
RK_U32 hal_wait : 1; // hal stage NOTE: special in low delay mode
|
||||||
|
RK_U32 rc_hal_end : 1; // rc stage
|
||||||
|
RK_U32 hal_ret_task : 1; // hal stage
|
||||||
|
RK_U32 enc_update_hal : 1; // enc stage
|
||||||
|
RK_U32 rc_frm_end : 1; // rc stage
|
||||||
|
RK_U32 check_rc_reenc : 1; // flow checkpoint if reenc -> enc_restore
|
||||||
|
RK_U32 enc_done : 1; // done stage
|
||||||
|
RK_U32 slice_out_done : 1;
|
||||||
|
};
|
||||||
|
} EncAsyncStatus;
|
||||||
|
|
||||||
|
typedef struct EncAsyncTaskInfo_t {
|
||||||
|
RK_S32 seq_idx;
|
||||||
|
EncAsyncStatus status;
|
||||||
|
RK_S64 pts;
|
||||||
|
|
||||||
|
HalEncTask task;
|
||||||
|
EncRcTask rc;
|
||||||
|
MppEncRefFrmUsrCfg usr;
|
||||||
|
} EncAsyncTaskInfo;
|
||||||
|
|
||||||
#endif /* __HAL_ENC_TASK__ */
|
#endif /* __HAL_ENC_TASK__ */
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ typedef struct MppEncHalCfg_t {
|
|||||||
MppClientType type;
|
MppClientType type;
|
||||||
MppDev dev;
|
MppDev dev;
|
||||||
RK_S32 cap_recn_out;
|
RK_S32 cap_recn_out;
|
||||||
|
HalTaskGroup tasks;
|
||||||
} MppEncHalCfg;
|
} MppEncHalCfg;
|
||||||
|
|
||||||
typedef struct MppEncHalApi_t {
|
typedef struct MppEncHalApi_t {
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ typedef struct MppEncHalImpl_t {
|
|||||||
|
|
||||||
void *ctx;
|
void *ctx;
|
||||||
const MppEncHalApi *api;
|
const MppEncHalApi *api;
|
||||||
|
|
||||||
|
HalTaskGroup tasks;
|
||||||
} MppEncHalImpl;
|
} MppEncHalImpl;
|
||||||
|
|
||||||
MPP_RET mpp_enc_hal_init(MppEncHal *ctx, MppEncHalCfg *cfg)
|
MPP_RET mpp_enc_hal_init(MppEncHal *ctx, MppEncHalCfg *cfg)
|
||||||
@@ -78,6 +80,14 @@ MPP_RET mpp_enc_hal_init(MppEncHal *ctx, MppEncHalCfg *cfg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = hal_task_group_init(&p->tasks, cfg->task_cnt,
|
||||||
|
sizeof(EncAsyncTaskInfo));
|
||||||
|
if (ret) {
|
||||||
|
mpp_err_f("hal_task_group_init failed ret %d\n", ret);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg->tasks = p->tasks;
|
||||||
*ctx = p;
|
*ctx = p;
|
||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
}
|
}
|
||||||
@@ -100,6 +110,8 @@ MPP_RET mpp_enc_hal_deinit(MppEncHal ctx)
|
|||||||
MppEncHalImpl *p = (MppEncHalImpl*)ctx;
|
MppEncHalImpl *p = (MppEncHalImpl*)ctx;
|
||||||
p->api->deinit(p->ctx);
|
p->api->deinit(p->ctx);
|
||||||
mpp_free(p->ctx);
|
mpp_free(p->ctx);
|
||||||
|
if (p->tasks)
|
||||||
|
hal_task_group_deinit(p->tasks);
|
||||||
mpp_free(p);
|
mpp_free(p);
|
||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user