[mpp_enc]: Change encoder work thread flow

1. Add wait and status flag for encoder
2. Add notify for encoder
3. Use wait and notify for encoder task handling.

Change-Id: I6ce0f676084f7c27cc95d6abc56557bfa286ef87
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2019-08-30 17:40:40 +08:00
parent 60c82d6d7b
commit b165fcd4b0
6 changed files with 340 additions and 169 deletions

View File

@@ -65,7 +65,7 @@ typedef enum MppTaskStatus_e {
typedef struct MppTaskImpl_t {
const char *name;
struct list_head list;
MppTaskQueue *queue;
MppTaskQueue queue;
RK_S32 index;
MppTaskStatus status;

View File

@@ -251,7 +251,7 @@ MPP_RET _mpp_port_enqueue(const char *caller, MppPort port, MppTask task)
check_mpp_task_name(task);
mpp_assert(task_impl->queue == (MppTaskQueue *)queue);
mpp_assert(task_impl->queue == (MppTaskQueue)queue);
mpp_assert(task_impl->status == port_impl->next_on_dequeue);
curr = &queue->info[task_impl->status];
@@ -395,7 +395,7 @@ MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count)
setup_mpp_task_name(&tasks[i]);
INIT_LIST_HEAD(&tasks[i].list);
tasks[i].index = i;
tasks[i].queue = (MppTaskQueue *)queue;
tasks[i].queue = queue;
tasks[i].status = MPP_INPUT_PORT;
mpp_meta_get(&tasks[i].meta);

View File

@@ -155,6 +155,7 @@ struct MppEnc_t {
MppCodingType coding;
Controller controller;
MppHal hal;
void *mpp;
// common resource
MppBufSlots frame_slots;
@@ -164,12 +165,23 @@ struct MppEnc_t {
// internal status and protection
Mutex lock;
RK_U32 reset_flag;
sem_t enc_reset;
RK_U32 wait_count;
RK_U32 work_count;
RK_U32 status_flag;
RK_U32 notify_flag;
/* Encoder configure set */
MppEncCfgSet cfg;
MppEncCfgSet set;
};
typedef struct {
MppCodingType coding;
void *mpp;
} MppEncCfg;
#ifdef __cplusplus
extern "C" {
#endif
@@ -180,7 +192,7 @@ extern "C" {
void *mpp_enc_control_thread(void *data);
void *mpp_enc_hal_thread(void *data);
MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding);
MPP_RET mpp_enc_init(MppEnc **enc, MppEncCfg *cfg);
MPP_RET mpp_enc_deinit(MppEnc *enc);
MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param);
MPP_RET mpp_enc_notify(MppEnc *enc, RK_U32 flag);

View File

@@ -29,14 +29,60 @@
#define MPP_ENC_DBG_FUNCTION (0x00000001)
#define MPP_ENC_DBG_CONTROL (0x00000002)
#define MPP_ENC_DBG_STATUS (0x00000010)
#define MPP_ENC_DBG_DETAIL (0x00000020)
#define MPP_ENC_DBG_RESET (0x00000040)
#define MPP_ENC_DBG_NOTIFY (0x00000080)
RK_U32 mpp_enc_debug = 0;
#define mpp_enc_dbg(flag, fmt, ...) _mpp_dbg(mpp_enc_debug, flag, fmt, ## __VA_ARGS__)
#define mpp_enc_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_enc_debug, flag, fmt, ## __VA_ARGS__)
#define mpp_enc_dbg_func(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_FUNCTION, fmt, ## __VA_ARGS__)
#define mpp_enc_dbg_ctrl(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_CONTROL, fmt, ## __VA_ARGS__)
#define enc_dbg_func(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_FUNCTION, fmt, ## __VA_ARGS__)
#define enc_dbg_ctrl(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_CONTROL, fmt, ## __VA_ARGS__)
#define enc_dbg_status(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_STATUS, fmt, ## __VA_ARGS__)
#define enc_dbg_detail(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_DETAIL, fmt, ## __VA_ARGS__)
#define enc_dbg_notify(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_NOTIFY, fmt, ## __VA_ARGS__)
typedef union EncTaskWait_u {
RK_U32 val;
struct {
RK_U32 enc_frm_in : 1; // 0x0001 MPP_ENC_NOTIFY_FRAME_ENQUEUE
RK_U32 reserv0002 : 1; // 0x0002
RK_U32 reserv0004 : 1; // 0x0004
RK_U32 enc_pkt_out : 1; // 0x0008 MPP_ENC_NOTIFY_PACKET_ENQUEUE
RK_U32 reserv0010 : 1; // 0x0010
RK_U32 reserv0020 : 1; // 0x0020
RK_U32 reserv0040 : 1; // 0x0040
RK_U32 reserv0080 : 1; // 0x0080
RK_U32 reserv0100 : 1; // 0x0100
RK_U32 reserv0200 : 1; // 0x0200
RK_U32 reserv0400 : 1; // 0x0400
RK_U32 reserv0800 : 1; // 0x0800
RK_U32 reserv1000 : 1; // 0x1000
RK_U32 reserv2000 : 1; // 0x2000
RK_U32 reserv4000 : 1; // 0x4000
RK_U32 reserv8000 : 1; // 0x8000
};
} EncTaskWait;
typedef union EncTaskStatus_u {
RK_U32 val;
struct {
RK_U32 task_in_rdy : 1;
RK_U32 task_out_rdy : 1;
};
} EncTaskStatus;
typedef struct EncTask_t {
EncTaskStatus status;
EncTaskWait wait;
HalTaskInfo info;
} EncTask;
static void reset_hal_enc_task(HalEncTask *task)
{
@@ -78,42 +124,120 @@ static MPP_RET release_task_in_port(MppPort port)
return ret;
}
static MPP_RET check_enc_task_wait(MppEnc *enc, EncTask *task)
{
MPP_RET ret = MPP_OK;
RK_U32 notify = enc->notify_flag;
RK_U32 last_wait = enc->status_flag;
RK_U32 curr_wait = task->wait.val;
RK_U32 wait_chg = last_wait & (~curr_wait);
do {
if (enc->reset_flag)
break;
// NOTE: When condition is not fulfilled check nofify flag again
if (!curr_wait || (curr_wait & notify))
break;
ret = MPP_NOK;
} while (0);
enc_dbg_status("%p %08x -> %08x [%08x] notify %08x -> %s\n", enc,
last_wait, curr_wait, wait_chg, notify, (ret) ? ("wait") : ("work"));
enc->status_flag = task->wait.val;
enc->notify_flag = 0;
if (ret) {
enc->wait_count++;
} else {
enc->work_count++;
}
return ret;
}
void *mpp_enc_control_thread(void *data)
{
Mpp *mpp = (Mpp*)data;
MppEnc *enc = mpp->mEnc;
MppThread *thd_enc = mpp->mThreadCodec;
HalTaskInfo task_info;
HalEncTask *enc_task = &task_info.enc;
EncTask task;
HalTaskInfo *task_info = &task.info;
HalEncTask *hal_task = &task_info->enc;
MppPort input = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT);
MppPort output = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT);
MppTask mpp_task = NULL;
MppTask task_in = NULL;
MppTask task_out = NULL;
MPP_RET ret = MPP_OK;
MppFrame frame = NULL;
MppPacket packet = NULL;
MppBuffer mv_info = NULL;
memset(&task_info, 0, sizeof(HalTaskInfo));
memset(&task, 0, sizeof(task));
while (MPP_THREAD_RUNNING == thd_enc->get_status()) {
thd_enc->lock();
ret = mpp_port_dequeue(input, &mpp_task);
if (ret || NULL == mpp_task) {
while (1) {
{
AutoMutex autolock(thd_enc->mutex());
if (MPP_THREAD_RUNNING != thd_enc->get_status())
break;
if (check_enc_task_wait(enc, &task))
thd_enc->wait();
}
thd_enc->unlock();
if (mpp_task != NULL) {
mpp_task_meta_get_frame (mpp_task, KEY_INPUT_FRAME, &frame);
mpp_task_meta_get_packet(mpp_task, KEY_OUTPUT_PACKET, &packet);
mpp_task_meta_get_buffer(mpp_task, KEY_MOTION_INFO, &mv_info);
if (enc->reset_flag) {
{
AutoMutex autolock(thd_enc->mutex());
enc->status_flag = 0;
}
if (NULL == frame) {
mpp_port_enqueue(input, mpp_task);
AutoMutex autolock(thd_enc->mutex(THREAD_CONTROL));
enc->reset_flag = 0;
sem_post(&enc->enc_reset);
continue;
}
reset_hal_enc_task(enc_task);
// 1. check task in
if (!task.status.task_in_rdy) {
ret = mpp_port_poll(input, MPP_POLL_NON_BLOCK);
if (ret) {
task.wait.enc_frm_in = 1;
continue;
}
task.status.task_in_rdy = 1;
task.wait.enc_frm_in = 0;
}
enc_dbg_detail("task in ready\n");
// 2. get task out
if (!task.status.task_out_rdy) {
ret = mpp_port_poll(output, MPP_POLL_NON_BLOCK);
if (ret) {
task.wait.enc_pkt_out = 1;
continue;
}
task.status.task_out_rdy = 1;
task.wait.enc_pkt_out = 0;
}
enc_dbg_detail("task out ready\n");
ret = mpp_port_dequeue(input, &task_in);
mpp_assert(task_in);
mpp_task_meta_get_frame (task_in, KEY_INPUT_FRAME, &frame);
mpp_task_meta_get_packet(task_in, KEY_OUTPUT_PACKET, &packet);
mpp_task_meta_get_buffer(task_in, KEY_MOTION_INFO, &mv_info);
if (NULL == frame) {
mpp_port_enqueue(input, task_in);
continue;
}
reset_hal_enc_task(hal_task);
if (mpp_frame_get_buffer(frame)) {
/*
@@ -134,35 +258,39 @@ void *mpp_enc_control_thread(void *data)
mpp_packet_set_pts(packet, mpp_frame_get_pts(frame));
enc_task->input = mpp_frame_get_buffer(frame);
enc_task->output = mpp_packet_get_buffer(packet);
enc_task->mv_info = mv_info;
hal_task->input = mpp_frame_get_buffer(frame);
hal_task->output = mpp_packet_get_buffer(packet);
hal_task->mv_info = mv_info;
{
AutoMutex auto_lock(&enc->lock);
ret = controller_encode(mpp->mEnc->controller, enc_task);
ret = controller_encode(mpp->mEnc->controller, hal_task);
if (ret) {
mpp_err("mpp %p controller_encode failed return %d", mpp, ret);
goto TASK_END;
}
}
ret = mpp_hal_reg_gen((mpp->mEnc->hal), &task_info);
enc_dbg_detail("mpp_hal_reg_gen hal %p task %p\n", mpp->mEnc->hal, task_info);
ret = mpp_hal_reg_gen((mpp->mEnc->hal), task_info);
if (ret) {
mpp_err("mpp %p hal_reg_gen failed return %d", mpp, ret);
goto TASK_END;
}
ret = mpp_hal_hw_start((mpp->mEnc->hal), &task_info);
enc_dbg_detail("mpp_hal_hw_start hal %p task %p\n", mpp->mEnc->hal, task_info);
ret = mpp_hal_hw_start((mpp->mEnc->hal), task_info);
if (ret) {
mpp_err("mpp %p hal_hw_start failed return %d", mpp, ret);
goto TASK_END;
}
ret = mpp_hal_hw_wait((mpp->mEnc->hal), &task_info);
enc_dbg_detail("mpp_hal_hw_wait hal %p task %p\n", mpp->mEnc->hal, task_info);
ret = mpp_hal_hw_wait((mpp->mEnc->hal), task_info);
if (ret) {
mpp_err("mpp %p hal_hw_wait failed return %d", mpp, ret);
goto TASK_END;
}
TASK_END:
mpp_packet_set_length(packet, task_info.enc.length);
mpp_packet_set_length(packet, hal_task->length);
} else {
/*
* else init a empty packet for output
@@ -178,43 +306,44 @@ void *mpp_enc_control_thread(void *data)
* then enqueue task back to input port
* final user will release the mpp_frame they had input
*/
mpp_task_meta_set_frame(mpp_task, KEY_INPUT_FRAME, frame);
mpp_port_enqueue(input, mpp_task);
mpp_task = NULL;
mpp_task_meta_set_frame(task_in, KEY_INPUT_FRAME, frame);
mpp_port_enqueue(input, task_in);
// send finished task to output port
mpp_port_poll(output, MPP_POLL_BLOCK);
mpp_port_dequeue(output, &mpp_task);
ret = mpp_port_dequeue(output, &task_out);
/*
* mpp_task may be null if output port is awaken by Mpp::clear()
* task_in may be null if output port is awaken by Mpp::clear()
*/
if (mpp_task) {
if (task_out) {
//set motion info buffer to output task
if (mv_info)
mpp_task_meta_set_buffer(mpp_task, KEY_MOTION_INFO, mv_info);
mpp_task_meta_set_buffer(task_out, KEY_MOTION_INFO, mv_info);
mpp_task_meta_set_packet(mpp_task, KEY_OUTPUT_PACKET, packet);
mpp_task_meta_set_packet(task_out, KEY_OUTPUT_PACKET, packet);
{
RK_S32 is_intra = enc_task->is_intra;
RK_S32 is_intra = hal_task->is_intra;
RK_U32 flag = mpp_packet_get_flag(packet);
mpp_task_meta_set_s32(mpp_task, KEY_OUTPUT_INTRA, is_intra);
mpp_task_meta_set_s32(task_out, KEY_OUTPUT_INTRA, is_intra);
if (is_intra) {
mpp_packet_set_flag(packet, flag | MPP_PACKET_FLAG_INTRA);
}
}
// setup output task here
mpp_port_enqueue(output, mpp_task);
mpp_port_enqueue(output, task_out);
} else {
mpp_packet_deinit(&packet);
}
mpp_task = NULL;
task_in = NULL;
task_out = NULL;
packet = NULL;
frame = NULL;
}
task.status.val = 0;
}
// clear remain task in output port
@@ -224,9 +353,10 @@ void *mpp_enc_control_thread(void *data)
return NULL;
}
MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding)
MPP_RET mpp_enc_init(MppEnc **enc, MppEncCfg *cfg)
{
MPP_RET ret;
MppCodingType coding = cfg->coding;
MppBufSlots frame_slots = NULL;
MppBufSlots packet_slots = NULL;
Controller controller = NULL;
@@ -304,9 +434,13 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding)
p->coding = coding;
p->controller = controller;
p->hal = hal;
p->mpp = cfg->mpp;
p->tasks = hal_cfg.tasks;
p->frame_slots = frame_slots;
p->packet_slots = packet_slots;
sem_init(&p->enc_reset, 0, 0);
*enc = p;
return MPP_OK;
} while (0);
@@ -343,22 +477,53 @@ MPP_RET mpp_enc_deinit(MppEnc *enc)
enc->packet_slots = NULL;
}
sem_destroy(&enc->enc_reset);
mpp_free(enc);
return MPP_OK;
}
MPP_RET mpp_enc_reset(MppEnc *enc)
{
AutoMutex auto_lock(&enc->lock);
enc_dbg_func("%p in\n", enc);
if (NULL == enc) {
mpp_err_f("found NULL input enc\n");
return MPP_ERR_NULL_PTR;
}
Mpp *mpp = (Mpp *)enc->mpp;
MppThread *thd = mpp->mThreadCodec;
thd->lock(THREAD_CONTROL);
enc->reset_flag = 1;
mpp_enc_notify(enc, MPP_ENC_RESET);
thd->unlock(THREAD_CONTROL);
sem_wait(&enc->enc_reset);
mpp_assert(enc->reset_flag == 0);
return MPP_OK;
}
MPP_RET mpp_enc_notify(MppEnc *enc, RK_U32 flag)
{
// TODO
(void)enc;
(void)flag;
enc_dbg_func("%p in flag %08x\n", enc, flag);
Mpp *mpp = (Mpp *)enc->mpp;
MppThread *thd = mpp->mThreadCodec;
thd->lock();
{
RK_U32 old_flag = enc->notify_flag;
enc->notify_flag |= flag;
if ((old_flag != enc->notify_flag) &&
(enc->notify_flag & enc->status_flag)) {
enc_dbg_notify("%p status %08x notify %08x signal\n", enc,
enc->status_flag, enc->notify_flag);
thd->signal();
}
}
thd->unlock();
enc_dbg_func("%p out\n", enc);
return MPP_OK;
}
@@ -374,7 +539,7 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param)
switch (cmd) {
case MPP_ENC_SET_ALL_CFG : {
mpp_enc_dbg_ctrl("set all config\n");
enc_dbg_ctrl("set all config\n");
memcpy(&enc->set, param, sizeof(enc->set));
ret = controller_config(enc->controller, MPP_ENC_SET_RC_CFG, param);
@@ -393,11 +558,11 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param)
case MPP_ENC_GET_ALL_CFG : {
MppEncCfgSet *p = (MppEncCfgSet *)param;
mpp_enc_dbg_ctrl("get all config\n");
enc_dbg_ctrl("get all config\n");
memcpy(p, &enc->cfg, sizeof(*p));
} break;
case MPP_ENC_SET_PREP_CFG : {
mpp_enc_dbg_ctrl("set prep config\n");
enc_dbg_ctrl("set prep config\n");
memcpy(&enc->set.prep, param, sizeof(enc->set.prep));
ret = mpp_hal_control(enc->hal, cmd, param);
@@ -407,11 +572,11 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param)
case MPP_ENC_GET_PREP_CFG : {
MppEncPrepCfg *p = (MppEncPrepCfg *)param;
mpp_enc_dbg_ctrl("get prep config\n");
enc_dbg_ctrl("get prep config\n");
memcpy(p, &enc->cfg.prep, sizeof(*p));
} break;
case MPP_ENC_SET_RC_CFG : {
mpp_enc_dbg_ctrl("set rc config\n");
enc_dbg_ctrl("set rc config\n");
memcpy(&enc->set.rc, param, sizeof(enc->set.rc));
ret = controller_config(enc->controller, cmd, param);
@@ -424,11 +589,11 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param)
case MPP_ENC_GET_RC_CFG : {
MppEncRcCfg *p = (MppEncRcCfg *)param;
mpp_enc_dbg_ctrl("get rc config\n");
enc_dbg_ctrl("get rc config\n");
memcpy(p, &enc->cfg.rc, sizeof(*p));
} break;
case MPP_ENC_SET_CODEC_CFG : {
mpp_enc_dbg_ctrl("set codec config\n");
enc_dbg_ctrl("set codec config\n");
memcpy(&enc->set.codec, param, sizeof(enc->set.codec));
ret = mpp_hal_control(enc->hal, cmd, param);
@@ -437,48 +602,48 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param)
case MPP_ENC_GET_CODEC_CFG : {
MppEncCodecCfg *p = (MppEncCodecCfg *)param;
mpp_enc_dbg_ctrl("get codec config\n");
enc_dbg_ctrl("get codec config\n");
memcpy(p, &enc->cfg.codec, sizeof(*p));
} break;
case MPP_ENC_SET_IDR_FRAME : {
mpp_enc_dbg_ctrl("idr request\n");
enc_dbg_ctrl("idr request\n");
ret = controller_config(enc->controller, SET_IDR_FRAME, param);
} break;
case MPP_ENC_GET_EXTRA_INFO : {
mpp_enc_dbg_ctrl("get extra info\n");
enc_dbg_ctrl("get extra info\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_OSD_PLT_CFG : {
mpp_enc_dbg_ctrl("set osd plt\n");
enc_dbg_ctrl("set osd plt\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_OSD_DATA_CFG : {
mpp_enc_dbg_ctrl("set osd data\n");
enc_dbg_ctrl("set osd data\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_ROI_CFG : {
mpp_enc_dbg_ctrl("set roi data\n");
enc_dbg_ctrl("set roi data\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_SEI_CFG : {
mpp_enc_dbg_ctrl("set sei\n");
enc_dbg_ctrl("set sei\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_GET_SEI_DATA : {
mpp_enc_dbg_ctrl("get sei\n");
enc_dbg_ctrl("get sei\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_PRE_ALLOC_BUFF : {
mpp_enc_dbg_ctrl("pre alloc buff\n");
enc_dbg_ctrl("pre alloc buff\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_QP_RANGE : {
mpp_enc_dbg_ctrl("set qp range\n");
enc_dbg_ctrl("set qp range\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_CTU_QP: {
mpp_enc_dbg_ctrl("set ctu qp\n");
enc_dbg_ctrl("set ctu qp\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
default : {

View File

@@ -36,6 +36,8 @@
*/
#define MPP_INPUT_ENQUEUE (0x00000001)
#define MPP_OUTPUT_DEQUEUE (0x00000002)
#define MPP_INPUT_DEQUEUE (0x00000004)
#define MPP_OUTPUT_ENQUEUE (0x00000008)
#define MPP_RESET (0xFFFFFFFF)
/* mpp dec event flags */
@@ -53,6 +55,8 @@
/* 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_NOTIFY_FRAME_DEQUEUE (MPP_INPUT_DEQUEUE)
#define MPP_ENC_NOTIFY_PACKET_ENQUEUE (MPP_OUTPUT_ENQUEUE)
#define MPP_ENC_RESET (MPP_RESET)
/*

View File

@@ -135,7 +135,11 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
mFrames = new mpp_list((node_destructor)NULL);
mPackets = new mpp_list((node_destructor)mpp_packet_deinit);
mpp_enc_init(&mEnc, coding);
MppEncCfg cfg = {
coding,
this,
};
mpp_enc_init(&mEnc, &cfg);
mThreadCodec = new MppThread(mpp_enc_control_thread, this, "mpp_enc_ctrl");
//mThreadHal = new MppThread(mpp_enc_hal_thread, this, "mpp_enc_hal");
@@ -196,26 +200,6 @@ void Mpp::clear()
mpp_buffer_group_set_callback((MppBufferGroupImpl *)mFrameGroup,
NULL, NULL);
if (mType == MPP_CTX_ENC) {
if (mThreadCodec)
mThreadCodec->set_status(MPP_THREAD_STOPPING);
/* reset dequeued input task to idle status */
if (mInputTask) {
enqueue(MPP_PORT_INPUT, mInputTask);
mInputTask = NULL;
}
/*
* encode thread may block in dequeue output task
* so send sigal to awake it
*/
if (mOutputTaskQueue) {
MppPort port = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_INPUT);
mpp_port_awake(port);
}
}
if (mThreadCodec)
mThreadCodec->stop();
@@ -527,13 +511,16 @@ MPP_RET Mpp::dequeue(MppPortType type, MppTask *task)
MPP_RET ret = MPP_NOK;
MppTaskQueue port = NULL;
RK_U32 notify_flag = 0;
switch (type) {
case MPP_PORT_INPUT : {
port = mInputPort;
notify_flag = MPP_INPUT_DEQUEUE;
} break;
case MPP_PORT_OUTPUT : {
port = mOutputPort;
notify_flag = MPP_OUTPUT_DEQUEUE;
} break;
default : {
} break;
@@ -542,7 +529,7 @@ MPP_RET Mpp::dequeue(MppPortType type, MppTask *task)
if (port) {
ret = mpp_port_dequeue(port, task);
if (MPP_OK == ret)
notify(MPP_OUTPUT_DEQUEUE);
notify(notify_flag);
}
return ret;
@@ -555,13 +542,16 @@ MPP_RET Mpp::enqueue(MppPortType type, MppTask task)
MPP_RET ret = MPP_NOK;
MppTaskQueue port = NULL;
RK_U32 notify_flag = 0;
switch (type) {
case MPP_PORT_INPUT : {
port = mInputPort;
notify_flag = MPP_INPUT_ENQUEUE;
} break;
case MPP_PORT_OUTPUT : {
port = mOutputPort;
notify_flag = MPP_OUTPUT_ENQUEUE;
} break;
default : {
} break;
@@ -573,7 +563,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);
notify(notify_flag);
}
mThreadCodec->unlock();
}