mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-08 02:20:06 +08:00
refactor[osal]: Refactor more module from C++ to C
Refactor thread, list, queue and time module. Signed-off-by: Chandler Chen <chandler.chen@rock-chips.com> Signed-off-by: Hongjin Li <vic.hong@rock-chips.com> Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: I96c07e1549868085867502c8bb974ffd3875ea9d
This commit is contained in:
@@ -201,7 +201,7 @@ struct MppBufSlotEntry_t {
|
||||
};
|
||||
|
||||
struct MppBufSlotsImpl_t {
|
||||
Mutex *lock;
|
||||
MppMutex lock;
|
||||
RK_U32 slots_idx;
|
||||
|
||||
// status tracing
|
||||
@@ -385,8 +385,6 @@ static void prepare_info_set_legacy(MppBufSlotsImpl *impl, MppFrame frame,
|
||||
info_set->v_stride = hal_ver_stride;
|
||||
info_set->h_stride_by_pixel = hor_stride_pixel;
|
||||
info_set->size_total = size;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void prepare_info_set_by_sys_cfg(MppBufSlotsImpl *impl, MppFrame frame,
|
||||
@@ -589,8 +587,8 @@ static void buf_slot_logs_dump(MppBufSlotLogs *logs)
|
||||
|
||||
static void _dump_slots(const char *caller, MppBufSlotsImpl *impl)
|
||||
{
|
||||
RK_S32 i;
|
||||
MppBufSlotEntry *slot = impl->slots;
|
||||
RK_S32 i;
|
||||
|
||||
mpp_log("\ncaller %s is dumping slots\n", caller, impl->slots_idx);
|
||||
mpp_log("slots %d %p buffer count %d buffer size %d\n", impl->slots_idx,
|
||||
@@ -728,7 +726,9 @@ static void slot_ops_with_log(MppBufSlotsImpl *impl, MppBufSlotEntry *slot, MppB
|
||||
static void init_slot_entry(MppBufSlotsImpl *impl, RK_S32 pos, RK_S32 count)
|
||||
{
|
||||
MppBufSlotEntry *slot = impl->slots;
|
||||
for (RK_S32 i = 0; i < count; i++, slot++) {
|
||||
RK_S32 i;
|
||||
|
||||
for (i = 0; i < count; i++, slot++) {
|
||||
slot->slots = impl;
|
||||
INIT_LIST_HEAD(&slot->list);
|
||||
slot->index = pos + i;
|
||||
@@ -807,8 +807,7 @@ static void clear_slots_impl(MppBufSlotsImpl *impl)
|
||||
impl->logs = NULL;
|
||||
}
|
||||
|
||||
if (impl->lock)
|
||||
delete impl->lock;
|
||||
mpp_mutex_destroy(&impl->lock);
|
||||
|
||||
mpp_free(impl->slots);
|
||||
mpp_free(impl);
|
||||
@@ -816,12 +815,15 @@ static void clear_slots_impl(MppBufSlotsImpl *impl)
|
||||
|
||||
MPP_RET mpp_buf_slot_init(MppBufSlots *slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl;
|
||||
|
||||
if (!slots) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
MppBufSlotsImpl *impl = mpp_calloc(MppBufSlotsImpl, 1);
|
||||
if (NULL == impl) {
|
||||
|
||||
impl = mpp_calloc(MppBufSlotsImpl, 1);
|
||||
if (!impl) {
|
||||
*slots = NULL;
|
||||
return MPP_NOK;
|
||||
}
|
||||
@@ -836,9 +838,7 @@ MPP_RET mpp_buf_slot_init(MppBufSlots *slots)
|
||||
break;
|
||||
}
|
||||
|
||||
impl->lock = new Mutex();
|
||||
if (NULL == impl->lock)
|
||||
break;
|
||||
mpp_mutex_init(&impl->lock);
|
||||
|
||||
for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(impl->queue); i++) {
|
||||
INIT_LIST_HEAD(&impl->queue[i]);
|
||||
@@ -846,7 +846,7 @@ MPP_RET mpp_buf_slot_init(MppBufSlots *slots)
|
||||
|
||||
if (buf_slot_debug & BUF_SLOT_DBG_OPS_HISTORY) {
|
||||
impl->logs = buf_slot_logs_init(SLOT_OPS_MAX_COUNT);
|
||||
if (NULL == impl->logs)
|
||||
if (!impl->logs)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -879,7 +879,7 @@ MPP_RET mpp_buf_slot_init(MppBufSlots *slots)
|
||||
|
||||
MPP_RET mpp_buf_slot_deinit(MppBufSlots slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
if (!slots) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
@@ -890,17 +890,18 @@ MPP_RET mpp_buf_slot_deinit(MppBufSlots slots)
|
||||
|
||||
MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p setup: count %d\n", slots, count);
|
||||
buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p setup: count %d\n", impl, count);
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
if (NULL == impl->slots) {
|
||||
if (!impl->slots) {
|
||||
// first slot setup
|
||||
impl->buf_count = impl->new_count = count;
|
||||
impl->slots = mpp_calloc(MppBufSlotEntry, count);
|
||||
@@ -916,32 +917,41 @@ MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count)
|
||||
impl->new_count = count;
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
RK_U32 mpp_buf_slot_is_changed(MppBufSlots slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
RK_U32 info_changed = 0;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
return impl->info_changed;
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
info_changed = impl->info_changed;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return info_changed;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_ready(MppBufSlots slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p is ready now\n", slots);
|
||||
buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p is ready now\n", impl);
|
||||
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
slot_assert(impl, impl->slots);
|
||||
if (!impl->info_changed)
|
||||
mpp_log("found info change ready set without internal info change\n");
|
||||
@@ -961,64 +971,84 @@ MPP_RET mpp_buf_slot_ready(MppBufSlots slots)
|
||||
|
||||
impl->info_changed = 0;
|
||||
impl->info_change_slot_idx = -1;
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
size_t mpp_buf_slot_get_size(MppBufSlots slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
size_t size = 0;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
return impl->buf_size;
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
size = impl->buf_size;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
RK_S32 mpp_buf_slot_get_count(MppBufSlots slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
size_t count = 0;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
return impl->buf_count;
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
count = impl->buf_count;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_set_callback(MppBufSlots slots, MppCbCtx *cb_ctx)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
impl->callback = *cb_ctx;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index)
|
||||
{
|
||||
if (NULL == slots || NULL == index) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
MppBufSlotEntry *slot;
|
||||
RK_S32 i;
|
||||
|
||||
if (!impl || !index) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
RK_S32 i;
|
||||
MppBufSlotEntry *slot = impl->slots;
|
||||
slot = impl->slots;
|
||||
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
for (i = 0; i < impl->buf_count; i++, slot++) {
|
||||
if (!slot->status.on_used) {
|
||||
*index = i;
|
||||
slot_ops_with_log(impl, slot, SLOT_SET_ON_USE, NULL);
|
||||
slot_ops_with_log(impl, slot, SLOT_SET_NOT_READY, NULL);
|
||||
impl->used_count++;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
}
|
||||
@@ -1027,43 +1057,54 @@ MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index)
|
||||
mpp_err_f("failed to get a unused slot\n");
|
||||
dump_slots(impl);
|
||||
slot_assert(impl, 0);
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
slot_assert(impl, (index >= 0) && (index < impl->buf_count));
|
||||
slot_ops_with_log(impl, &impl->slots[index], set_flag_op[type], NULL);
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
MppBufSlotEntry *slot;
|
||||
RK_S32 unused = 0;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
RK_S32 unused = 0;
|
||||
{
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
slot_assert(impl, (index >= 0) && (index < impl->buf_count));
|
||||
MppBufSlotEntry *slot = &impl->slots[index];
|
||||
slot = &impl->slots[index];
|
||||
slot_ops_with_log(impl, slot, clr_flag_op[type], NULL);
|
||||
|
||||
if (type == SLOT_HAL_OUTPUT)
|
||||
impl->decode_count++;
|
||||
|
||||
unused = check_entry_unused(impl, slot);
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
if (unused)
|
||||
mpp_callback(&impl->callback, impl);
|
||||
@@ -1072,38 +1113,51 @@ MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType typ
|
||||
|
||||
MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
MppBufSlotEntry *slot;
|
||||
|
||||
if (!impl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
slot_assert(impl, (index >= 0) && (index < impl->buf_count));
|
||||
MppBufSlotEntry *slot = &impl->slots[index];
|
||||
slot = &impl->slots[index];
|
||||
slot_ops_with_log(impl, slot, (MppBufSlotOps)(SLOT_ENQUEUE + type), NULL);
|
||||
|
||||
// add slot to display list
|
||||
list_del_init(&slot->list);
|
||||
list_add_tail(&slot->list, &impl->queue[type]);
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type)
|
||||
{
|
||||
if (NULL == slots || NULL == index) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
MppBufSlotEntry *slot;
|
||||
|
||||
if (!impl || !index) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
if (list_empty(&impl->queue[type]))
|
||||
return MPP_NOK;
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
MppBufSlotEntry *slot = list_entry(impl->queue[type].next, MppBufSlotEntry, list);
|
||||
if (slot->status.not_ready)
|
||||
if (list_empty(&impl->queue[type])) {
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
slot = list_entry(impl->queue[type].next, MppBufSlotEntry, list);
|
||||
if (slot->status.not_ready) {
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
// make sure that this slot is just the next display slot
|
||||
list_del_init(&slot->list);
|
||||
@@ -1112,31 +1166,39 @@ MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType typ
|
||||
impl->display_count++;
|
||||
*index = slot->index;
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val)
|
||||
{
|
||||
if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
MppBufSlotEntry *slot;
|
||||
|
||||
if (!impl || !val || type >= SLOT_PROP_BUTT) {
|
||||
mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
|
||||
return MPP_ERR_UNKNOW;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
slot_assert(impl, (index >= 0) && (index < impl->buf_count));
|
||||
MppBufSlotEntry *slot = &impl->slots[index];
|
||||
slot = &impl->slots[index];
|
||||
slot_ops_with_log(impl, slot, set_val_op[type], val);
|
||||
|
||||
switch (type) {
|
||||
case SLOT_EOS: {
|
||||
RK_U32 eos = *(RK_U32*)val;
|
||||
|
||||
slot->eos = eos;
|
||||
if (slot->frame)
|
||||
mpp_frame_set_eos(slot->frame, eos);
|
||||
} break;
|
||||
case SLOT_FRAME: {
|
||||
MppFrame frame = val;
|
||||
MppFrameImpl *src;
|
||||
MppFrameImpl *dst;
|
||||
|
||||
slot_assert(impl, slot->status.not_ready);
|
||||
/*
|
||||
@@ -1150,11 +1212,11 @@ MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type
|
||||
*/
|
||||
generate_info_set(impl, frame, 0);
|
||||
|
||||
if (NULL == slot->frame)
|
||||
if (!slot->frame)
|
||||
mpp_frame_init(&slot->frame);
|
||||
|
||||
MppFrameImpl *src = (MppFrameImpl *)frame;
|
||||
MppFrameImpl *dst = (MppFrameImpl *)slot->frame;
|
||||
src = (MppFrameImpl *)frame;
|
||||
dst = (MppFrameImpl *)slot->frame;
|
||||
mpp_frame_copy(dst, src);
|
||||
// NOTE: stride from codec need to be change to hal stride
|
||||
// hor_stride and ver_stride can not be zero
|
||||
@@ -1188,9 +1250,10 @@ MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type
|
||||
} break;
|
||||
case SLOT_BUFFER: {
|
||||
MppBuffer buffer = val;
|
||||
|
||||
if (slot->buffer) {
|
||||
// NOTE: reset buffer only on stream buffer slot
|
||||
slot_assert(impl, NULL == slot->frame);
|
||||
slot_assert(impl, !slot->frame);
|
||||
mpp_buffer_put(slot->buffer);
|
||||
}
|
||||
mpp_buffer_inc_ref(buffer);
|
||||
@@ -1203,20 +1266,25 @@ MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type
|
||||
} break;
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val)
|
||||
{
|
||||
if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
MppBufSlotEntry *slot;
|
||||
|
||||
if (!impl || !val || type >= SLOT_PROP_BUTT) {
|
||||
mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
|
||||
return MPP_ERR_UNKNOW;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
slot_assert(impl, (index >= 0) && (index < impl->buf_count));
|
||||
MppBufSlotEntry *slot = &impl->slots[index];
|
||||
slot = &impl->slots[index];
|
||||
|
||||
switch (type) {
|
||||
case SLOT_EOS: {
|
||||
@@ -1228,7 +1296,7 @@ MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type
|
||||
|
||||
mpp_assert(slot->status.has_frame);
|
||||
if (slot->status.has_frame) {
|
||||
if (NULL == *frame )
|
||||
if (!*frame )
|
||||
mpp_frame_init(frame);
|
||||
if (*frame)
|
||||
mpp_frame_copy(*frame, slot->frame);
|
||||
@@ -1237,59 +1305,69 @@ MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type
|
||||
} break;
|
||||
case SLOT_FRAME_PTR: {
|
||||
MppFrame *frame = (MppFrame *)val;
|
||||
|
||||
mpp_assert(slot->status.has_frame);
|
||||
*frame = (slot->status.has_frame) ? (slot->frame) : (NULL);
|
||||
} break;
|
||||
case SLOT_BUFFER: {
|
||||
MppBuffer *buffer = (MppBuffer *)val;
|
||||
|
||||
*buffer = (slot->status.has_buffer) ? (slot->buffer) : (NULL);
|
||||
} break;
|
||||
default : {
|
||||
} break;
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_reset(MppBufSlots slots, RK_S32 index)
|
||||
{
|
||||
if (NULL == slots || index < 0) {
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
MppBufSlotEntry *slot;
|
||||
|
||||
if (!impl || index < 0) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p reset index %d\n", slots, index);
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
slot_assert(impl, (index >= 0) && (index < impl->buf_count));
|
||||
MppBufSlotEntry *slot = &impl->slots[index];
|
||||
slot = &impl->slots[index];
|
||||
|
||||
// make sure that this slot is just the next display slot
|
||||
list_del_init(&slot->list);
|
||||
slot_ops_with_log(impl, slot, SLOT_CLR_QUEUE_USE, NULL);
|
||||
slot_ops_with_log(impl, slot, SLOT_DEQUEUE, NULL);
|
||||
slot_ops_with_log(impl, slot, SLOT_CLR_ON_USE, NULL);
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_buf_slot_default_info(MppBufSlots slots, RK_S32 index, void *val)
|
||||
{
|
||||
if (NULL == slots || index < 0) {
|
||||
if (!slots || index < 0) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
slot_assert(impl, (index >= 0) && (index < impl->buf_count));
|
||||
MppBufSlotEntry *slot = &impl->slots[index];
|
||||
|
||||
slot_assert(impl, slot->status.not_ready);
|
||||
slot_assert(impl, NULL == slot->frame);
|
||||
slot_assert(impl, !slot->frame);
|
||||
slot_assert(impl, impl->info_set);
|
||||
|
||||
if (NULL == slot->frame) {
|
||||
if (!slot->frame) {
|
||||
mpp_frame_init(&slot->frame);
|
||||
mpp_frame_copy(slot->frame, impl->info_set);
|
||||
}
|
||||
@@ -1299,54 +1377,68 @@ MPP_RET mpp_buf_slot_default_info(MppBufSlots slots, RK_S32 index, void *val)
|
||||
|
||||
slot_ops_with_log(impl, slot, SLOT_CLR_NOT_READY, NULL);
|
||||
slot_ops_with_log(impl, slot, SLOT_SET_FRAME, slot->frame);
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
RK_U32 mpp_slots_is_empty(MppBufSlots slots, SlotQueueType type)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
RK_U32 is_empty = 0;
|
||||
if (!slots) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
return list_empty(&impl->queue[type]) ? 1 : 0;
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
is_empty = list_empty(&impl->queue[type]) ? 1 : 0;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
RK_S32 mpp_slots_get_used_count(MppBufSlots slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
RK_S32 used_count = 0;
|
||||
if (!slots) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return 0;
|
||||
}
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
return impl->used_count;
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
used_count = impl->used_count;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return used_count;
|
||||
}
|
||||
|
||||
RK_S32 mpp_slots_get_unused_count(MppBufSlots slots)
|
||||
{
|
||||
if (NULL == slots) {
|
||||
RK_S32 unused_count = 0;
|
||||
if (!slots) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
slot_assert(impl, (impl->used_count >= 0) && (impl->used_count <= impl->buf_count));
|
||||
return impl->buf_count - impl->used_count;
|
||||
unused_count = impl->buf_count - impl->used_count;
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return unused_count;
|
||||
}
|
||||
|
||||
MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val)
|
||||
{
|
||||
if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) {
|
||||
if (!slots || !val || type >= SLOTS_PROP_BUTT) {
|
||||
mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
|
||||
return MPP_ERR_UNKNOW;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
RK_U32 value = *((RK_U32*)val);
|
||||
switch (type) {
|
||||
case SLOTS_EOS: {
|
||||
@@ -1414,19 +1506,20 @@ MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val)
|
||||
default : {
|
||||
} break;
|
||||
}
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val)
|
||||
{
|
||||
if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) {
|
||||
if (!slots || !val || type >= SLOTS_PROP_BUTT) {
|
||||
mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
switch (type) {
|
||||
@@ -1449,6 +1542,7 @@ MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val)
|
||||
ret = MPP_NOK;
|
||||
} break;
|
||||
}
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "mpp_hash.h"
|
||||
#include "mpp_lock.h"
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_thread.h"
|
||||
#include "mpp_mem_pool.h"
|
||||
|
||||
#include "mpp_buffer_impl.h"
|
||||
@@ -58,6 +59,7 @@ private:
|
||||
RK_U32 total_size;
|
||||
RK_U32 total_max;
|
||||
|
||||
MppMutex mLock;
|
||||
// misc group for internal / externl buffer with different type
|
||||
RK_U32 misc[MPP_BUFFER_MODE_BUTT][MPP_BUFFER_TYPE_BUTT][MPP_ALLOCATOR_WITH_FLAG_NUM];
|
||||
RK_U32 misc_count;
|
||||
@@ -76,10 +78,6 @@ public:
|
||||
static MppBufferService instance;
|
||||
return &instance;
|
||||
}
|
||||
static Mutex *get_lock() {
|
||||
static Mutex lock;
|
||||
return &lock;
|
||||
}
|
||||
|
||||
MppBufferGroupImpl *get_group(const char *tag, const char *caller,
|
||||
MppBufferMode mode, MppBufferType type,
|
||||
@@ -93,6 +91,7 @@ public:
|
||||
void dec_total(RK_U32 size);
|
||||
RK_U32 get_total_now() { return total_size; };
|
||||
RK_U32 get_total_max() { return total_max; };
|
||||
MppMutex *get_lock() {return &mLock; };
|
||||
};
|
||||
|
||||
static const char *mode2str[MPP_BUFFER_MODE_BUTT] = {
|
||||
@@ -349,8 +348,11 @@ static MPP_RET inc_buffer_ref(MppBufferImpl *buffer, const char *caller)
|
||||
MppBufferGroupImpl *group = NULL;
|
||||
|
||||
{
|
||||
AutoMutex auto_lock(MppBufferService::get_lock());
|
||||
MppMutex *lock = MppBufferService::get_instance()->get_lock();
|
||||
|
||||
mpp_mutex_lock(lock);
|
||||
group = SEARCH_GROUP_BY_ID(buffer->group_id);
|
||||
mpp_mutex_unlock(lock);
|
||||
}
|
||||
// NOTE: when increasing ref_count the unused buffer must be under certain group
|
||||
mpp_assert(group);
|
||||
@@ -533,8 +535,11 @@ MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller)
|
||||
MppBufferGroupImpl *group = NULL;
|
||||
|
||||
{
|
||||
AutoMutex auto_lock(MppBufferService::get_lock());
|
||||
MppMutex *lock = MppBufferService::get_instance()->get_lock();
|
||||
|
||||
mpp_mutex_lock(lock);
|
||||
group = SEARCH_GROUP_BY_ID(buffer->group_id);
|
||||
mpp_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
mpp_assert(group);
|
||||
@@ -819,9 +824,11 @@ MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p,
|
||||
|
||||
void mpp_buffer_service_dump(const char *info)
|
||||
{
|
||||
AutoMutex auto_lock(MppBufferService::get_lock());
|
||||
MppMutex *lock = MppBufferService::get_instance()->get_lock();
|
||||
|
||||
mpp_mutex_lock(lock);
|
||||
MppBufferService::get_instance()->dump(info);
|
||||
mpp_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
void MppBufferService::inc_total(RK_U32 size)
|
||||
@@ -857,6 +864,7 @@ MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType
|
||||
MppBufferGroupImpl *misc;
|
||||
RK_U32 id;
|
||||
MppBufferType buf_type;
|
||||
MppMutex* lock = MppBufferService::get_instance()->get_lock();
|
||||
|
||||
buf_type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK);
|
||||
if (buf_type == MPP_BUFFER_TYPE_NORMAL)
|
||||
@@ -865,7 +873,7 @@ MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType
|
||||
mpp_assert(mode < MPP_BUFFER_MODE_BUTT);
|
||||
mpp_assert(buf_type < MPP_BUFFER_TYPE_BUTT);
|
||||
|
||||
AutoMutex auto_lock(MppBufferService::get_lock());
|
||||
mpp_mutex_lock(lock);
|
||||
|
||||
id = MppBufferService::get_instance()->get_misc(mode, type);
|
||||
if (!id) {
|
||||
@@ -883,6 +891,8 @@ MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType
|
||||
} else
|
||||
misc = MppBufferService::get_instance()->get_group_by_id(id);
|
||||
|
||||
mpp_mutex_unlock(lock);
|
||||
|
||||
return misc;
|
||||
}
|
||||
|
||||
@@ -910,6 +920,8 @@ MppBufferService::MppBufferService()
|
||||
|
||||
for (i = 0; i < (RK_S32)HASH_SIZE(mHashGroup); i++)
|
||||
INIT_HLIST_HEAD(&mHashGroup[i]);
|
||||
|
||||
mpp_mutex_init(&mLock);
|
||||
}
|
||||
|
||||
#include "mpp_time.h"
|
||||
@@ -920,6 +932,7 @@ MppBufferService::~MppBufferService()
|
||||
|
||||
finalizing = 1;
|
||||
|
||||
|
||||
// first remove legacy group which is the normal case
|
||||
if (misc_count) {
|
||||
mpp_log_f("cleaning misc group\n");
|
||||
@@ -966,6 +979,8 @@ MppBufferService::~MppBufferService()
|
||||
mpp_allocator_put(&(mAllocator[i][j]));
|
||||
}
|
||||
}
|
||||
|
||||
mpp_mutex_destroy(&mLock);
|
||||
}
|
||||
|
||||
RK_U32 MppBufferService::get_group_id()
|
||||
@@ -1039,10 +1054,12 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
|
||||
p->flags = (MppAllocFlagType)flag;
|
||||
|
||||
{
|
||||
AutoMutex auto_lock(get_lock());
|
||||
MppMutex* lock = MppBufferService::get_instance()->get_lock();
|
||||
MppAllocator allocator = NULL;
|
||||
MppAllocatorApi *alloc_api = NULL;
|
||||
|
||||
mpp_mutex_lock(lock);
|
||||
|
||||
allocator = mAllocator[buffer_type][flag];
|
||||
alloc_api = mAllocatorApi[buffer_type];
|
||||
|
||||
@@ -1056,6 +1073,8 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
|
||||
p->allocator = allocator;
|
||||
p->alloc_api = alloc_api;
|
||||
p->flags = mpp_allocator_get_flags(allocator);
|
||||
|
||||
mpp_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
if (!p->allocator || !p->alloc_api) {
|
||||
@@ -1088,9 +1107,9 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
|
||||
if (p->log_history_en)
|
||||
p->logs = buf_logs_init(BUFFER_OPS_MAX_COUNT);
|
||||
|
||||
AutoMutex auto_lock(get_lock());
|
||||
RK_U32 id = get_group_id();
|
||||
mpp_mutex_lock(&mLock);
|
||||
|
||||
RK_U32 id = get_group_id();
|
||||
if (tag) {
|
||||
snprintf(p->tag, sizeof(p->tag) - 1, "%s_%d", tag, id);
|
||||
} else {
|
||||
@@ -1109,6 +1128,8 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
|
||||
misc_count++;
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&mLock);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1132,10 +1153,8 @@ void MppBufferService::put_group(const char *caller, MppBufferGroupImpl *p)
|
||||
if (finished)
|
||||
return ;
|
||||
|
||||
Mutex *lock = get_lock();
|
||||
|
||||
if (!finalizing)
|
||||
lock->lock();
|
||||
mpp_mutex_lock(&mLock);
|
||||
|
||||
buf_grp_add_log(p, GRP_RELEASE, caller);
|
||||
|
||||
@@ -1184,7 +1203,7 @@ void MppBufferService::put_group(const char *caller, MppBufferGroupImpl *p)
|
||||
}
|
||||
|
||||
if (!finalizing)
|
||||
lock->unlock();
|
||||
mpp_mutex_unlock(&mLock);
|
||||
}
|
||||
|
||||
void MppBufferService::destroy_group(MppBufferGroupImpl *group)
|
||||
|
@@ -367,10 +367,10 @@ MPP_RET cluster_worker_init(ClusterWorker *p, MppCluster *cluster)
|
||||
p->cluster = cluster;
|
||||
p->state = WORKER_IDLE;
|
||||
snprintf(p->name, sizeof(p->name) - 1, "%d:W%d", cluster->pid, p->worker_id);
|
||||
thd = new MppThread(cluster->worker_func, p, p->name);
|
||||
thd = mpp_thread_create(cluster->worker_func, p, p->name);
|
||||
if (thd) {
|
||||
p->thd = thd;
|
||||
thd->start();
|
||||
mpp_thread_start(thd);
|
||||
ret = MPP_OK;
|
||||
}
|
||||
|
||||
@@ -380,8 +380,8 @@ MPP_RET cluster_worker_init(ClusterWorker *p, MppCluster *cluster)
|
||||
MPP_RET cluster_worker_deinit(ClusterWorker *p)
|
||||
{
|
||||
if (p->thd) {
|
||||
p->thd->stop();
|
||||
delete p->thd;
|
||||
mpp_thread_stop(p->thd);
|
||||
mpp_thread_destroy(p->thd);
|
||||
p->thd = NULL;
|
||||
}
|
||||
|
||||
@@ -546,18 +546,21 @@ static void *cluster_worker(void *data)
|
||||
RK_S32 task_count = 0;
|
||||
|
||||
cluster_dbg_lock("%s lock start\n", p->name);
|
||||
AutoMutex autolock(thd->mutex());
|
||||
mpp_thread_lock(thd, THREAD_WORK);
|
||||
cluster_dbg_lock("%s lock done\n", p->name);
|
||||
|
||||
if (MPP_THREAD_RUNNING != thd->get_status())
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(thd, THREAD_WORK)) {
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
task_count = cluster_worker_get_task(p);
|
||||
if (!task_count) {
|
||||
p->state = WORKER_IDLE;
|
||||
thd->wait();
|
||||
mpp_thread_wait(thd, THREAD_WORK);
|
||||
p->state = WORKER_RUNNING;
|
||||
}
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
}
|
||||
|
||||
cluster_worker_run_task(p);
|
||||
@@ -575,13 +578,17 @@ void cluster_signal_f(const char *caller, MppCluster *p)
|
||||
for (i = 0; i < p->worker_count; i++) {
|
||||
ClusterWorker *worker = &p->worker[i];
|
||||
MppThread *thd = worker->thd;
|
||||
AutoMutex auto_lock(thd->mutex());
|
||||
|
||||
mpp_thread_lock(thd, THREAD_WORK);
|
||||
|
||||
if (worker->state == WORKER_IDLE) {
|
||||
thd->signal();
|
||||
mpp_thread_signal(thd, THREAD_WORK);
|
||||
cluster_dbg_flow("%s signal\n", p->name);
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,7 +596,7 @@ class MppClusterServer;
|
||||
|
||||
MppClusterServer *cluster_server = NULL;
|
||||
|
||||
class MppClusterServer : Mutex
|
||||
class MppClusterServer
|
||||
{
|
||||
private:
|
||||
// avoid any unwanted function
|
||||
@@ -598,6 +605,7 @@ private:
|
||||
MppClusterServer(const MppClusterServer &);
|
||||
MppClusterServer &operator=(const MppClusterServer &);
|
||||
|
||||
MppMutex mutex;
|
||||
MppCluster *mClusters[VPU_CLIENT_BUTT];
|
||||
|
||||
public:
|
||||
@@ -617,6 +625,8 @@ MppClusterServer::MppClusterServer()
|
||||
|
||||
mpp_env_get_u32("mpp_cluster_debug", &mpp_cluster_debug, 0);
|
||||
mpp_env_get_u32("mpp_cluster_thd_cnt", &mpp_cluster_thd_cnt, 1);
|
||||
|
||||
mpp_mutex_init(&mutex);
|
||||
}
|
||||
|
||||
MppClusterServer::~MppClusterServer()
|
||||
@@ -625,6 +635,8 @@ MppClusterServer::~MppClusterServer()
|
||||
|
||||
for (i = 0; i < VPU_CLIENT_BUTT; i++)
|
||||
put((MppClientType)i);
|
||||
|
||||
mpp_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
MppCluster *MppClusterServer::get(MppClientType client_type)
|
||||
@@ -636,11 +648,13 @@ MppCluster *MppClusterServer::get(MppClientType client_type)
|
||||
goto done;
|
||||
|
||||
{
|
||||
AutoMutex auto_lock(this);
|
||||
mpp_mutex_lock(&mutex);
|
||||
|
||||
p = mClusters[client_type];
|
||||
if (p)
|
||||
if (p) {
|
||||
mpp_mutex_unlock(&mutex);
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = mpp_malloc(MppCluster, 1);
|
||||
if (p) {
|
||||
@@ -665,6 +679,8 @@ MppCluster *MppClusterServer::get(MppClientType client_type)
|
||||
mClusters[client_type] = p;
|
||||
cluster_dbg_flow("%s created\n", p->name);
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -678,16 +694,19 @@ done:
|
||||
|
||||
MPP_RET MppClusterServer::put(MppClientType client_type)
|
||||
{
|
||||
MppCluster *p;
|
||||
RK_S32 i;
|
||||
|
||||
if (client_type >= VPU_CLIENT_BUTT)
|
||||
return MPP_NOK;
|
||||
|
||||
AutoMutex auto_lock(this);
|
||||
MppCluster *p = mClusters[client_type];
|
||||
mpp_mutex_lock(&mutex);
|
||||
|
||||
if (!p)
|
||||
p = mClusters[client_type];
|
||||
if (!p) {
|
||||
mpp_mutex_unlock(&mutex);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
for (i = 0; i < p->worker_count; i++)
|
||||
cluster_worker_deinit(&p->worker[i]);
|
||||
@@ -696,6 +715,8 @@ MPP_RET MppClusterServer::put(MppClientType client_type)
|
||||
|
||||
mpp_free(p);
|
||||
|
||||
mpp_mutex_unlock(&mutex);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
|
@@ -54,16 +54,20 @@ private:
|
||||
MppEncCfgService &operator=(const MppEncCfgService &);
|
||||
|
||||
MppCfgInfoHead mHead;
|
||||
MppMutex mLock;
|
||||
MppTrie mTrie;
|
||||
RK_S32 mCfgSize;
|
||||
|
||||
public:
|
||||
static MppEncCfgService *get() {
|
||||
static Mutex lock;
|
||||
static MppEncCfgService instance;
|
||||
MppEncCfgService *ret;
|
||||
|
||||
AutoMutex auto_lock(&lock);
|
||||
return &instance;
|
||||
mpp_mutex_lock(&instance.mLock);
|
||||
ret = &instance;
|
||||
mpp_mutex_unlock(&instance.mLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MppTrieInfo *get_info(const char *name);
|
||||
@@ -306,6 +310,7 @@ MppEncCfgService::MppEncCfgService() :
|
||||
mHead.node_count = mpp_trie_get_node_count(mTrie);
|
||||
mHead.info_count = mpp_trie_get_info_count(mTrie);
|
||||
mHead.info_size = mpp_trie_get_buf_size(mTrie);
|
||||
mpp_mutex_init(&mLock);
|
||||
|
||||
mpp_enc_cfg_dbg_func("node cnt: %d\n", mHead.node_count);
|
||||
}
|
||||
@@ -316,6 +321,7 @@ MppEncCfgService::~MppEncCfgService()
|
||||
mpp_trie_deinit(mTrie);
|
||||
mTrie = NULL;
|
||||
}
|
||||
mpp_mutex_destroy(&mLock);
|
||||
}
|
||||
|
||||
MppTrieInfo *MppEncCfgService::get_info(const char *name)
|
||||
|
@@ -18,8 +18,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_frame_impl.h"
|
||||
#include "mpp_meta_impl.h"
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_list.h"
|
||||
#include "mpp_lock.h"
|
||||
#include "mpp_debug.h"
|
||||
|
||||
#include "mpp_meta_impl.h"
|
||||
#include "mpp_trie.h"
|
||||
|
@@ -40,13 +40,13 @@ typedef struct MppTaskStatusInfo_t {
|
||||
struct list_head list;
|
||||
RK_S32 count;
|
||||
MppTaskStatus status;
|
||||
Condition *cond;
|
||||
MppCond cond;
|
||||
} MppTaskStatusInfo;
|
||||
|
||||
typedef struct MppTaskQueueImpl_t {
|
||||
char name[32];
|
||||
void *mpp;
|
||||
Mutex *lock;
|
||||
MppMutex lock;
|
||||
RK_S32 task_count;
|
||||
RK_S32 ready; // flag for deinit
|
||||
|
||||
@@ -103,7 +103,7 @@ MPP_RET check_mpp_task_name(MppTask task)
|
||||
static MPP_RET mpp_port_init(MppTaskQueueImpl *queue, MppPortType type, MppPort *port)
|
||||
{
|
||||
MppPortImpl *impl = mpp_malloc(MppPortImpl, 1);
|
||||
if (NULL == impl) {
|
||||
if (!impl) {
|
||||
mpp_err_f("failed to malloc MppPort type %d\n", type);
|
||||
return MPP_ERR_MALLOC;
|
||||
}
|
||||
@@ -142,11 +142,11 @@ MPP_RET _mpp_port_poll(const char *caller, MppPort port, MppPollType timeout)
|
||||
{
|
||||
MppPortImpl *port_impl = (MppPortImpl *)port;
|
||||
MppTaskQueueImpl *queue = port_impl->queue;
|
||||
|
||||
AutoMutex auto_lock(queue->lock);
|
||||
MppTaskStatusInfo *curr = NULL;
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
mpp_mutex_lock(&queue->lock);
|
||||
|
||||
mpp_task_dbg_func("enter port %p\n", port);
|
||||
if (!queue->ready) {
|
||||
mpp_err("try to query when %s queue is not ready\n",
|
||||
@@ -171,20 +171,19 @@ MPP_RET _mpp_port_poll(const char *caller, MppPort port, MppPollType timeout)
|
||||
* positive - timeout value
|
||||
*/
|
||||
if (timeout) {
|
||||
mpp_assert(curr->cond);
|
||||
Condition *cond = curr->cond;
|
||||
MppCond *cond = &curr->cond;
|
||||
|
||||
if (timeout < 0) {
|
||||
mpp_task_dbg_flow("mpp %p %s from %s poll %s port block wait start\n",
|
||||
queue->mpp, queue->name, caller,
|
||||
port_type_str[port_impl->type]);
|
||||
|
||||
ret = (MPP_RET)cond->wait(queue->lock);
|
||||
ret = (MPP_RET)mpp_cond_wait(cond, &queue->lock);
|
||||
} else {
|
||||
mpp_task_dbg_flow("mpp %p %s from %s poll %s port %d timeout wait start\n",
|
||||
queue->mpp, queue->name, caller,
|
||||
port_type_str[port_impl->type], timeout);
|
||||
ret = (MPP_RET)cond->timedwait(queue->lock, timeout);
|
||||
ret = (MPP_RET)mpp_cond_timedwait(cond, &queue->lock, timeout);
|
||||
}
|
||||
|
||||
if (curr->count) {
|
||||
@@ -199,6 +198,7 @@ MPP_RET _mpp_port_poll(const char *caller, MppPort port, MppPollType timeout)
|
||||
port_type_str[port_impl->type], timeout, ret);
|
||||
}
|
||||
RET:
|
||||
mpp_mutex_unlock(&queue->lock);
|
||||
mpp_task_dbg_func("leave\n");
|
||||
return ret;
|
||||
}
|
||||
@@ -211,10 +211,10 @@ MPP_RET _mpp_port_move(const char *caller, MppPort port, MppTask task,
|
||||
MppTaskQueueImpl *queue = port_impl->queue;
|
||||
MppTaskStatusInfo *curr = NULL;
|
||||
MppTaskStatusInfo *next = NULL;
|
||||
|
||||
AutoMutex auto_lock(queue->lock);
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
mpp_mutex_lock(&queue->lock);
|
||||
|
||||
mpp_task_dbg_func("caller %s enter port %p task %p\n", caller, port, task);
|
||||
|
||||
if (!queue->ready) {
|
||||
@@ -242,11 +242,12 @@ MPP_RET _mpp_port_move(const char *caller, MppPort port, MppTask task,
|
||||
task_status_str[status]);
|
||||
task_impl->status = status;
|
||||
|
||||
next->cond->signal();
|
||||
mpp_cond_signal(&next->cond);
|
||||
mpp_task_dbg_func("signal port %p\n", next);
|
||||
ret = MPP_OK;
|
||||
RET:
|
||||
mpp_task_dbg_func("caller %s leave port %p task %p ret %d\n", caller, port, task, ret);
|
||||
mpp_mutex_unlock(&queue->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -259,10 +260,10 @@ MPP_RET _mpp_port_dequeue(const char *caller, MppPort port, MppTask *task)
|
||||
MppTaskStatusInfo *next = NULL;
|
||||
MppTaskImpl *task_impl = NULL;
|
||||
MppTask p = NULL;
|
||||
|
||||
AutoMutex auto_lock(queue->lock);
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
mpp_mutex_lock(&queue->lock);
|
||||
|
||||
mpp_task_dbg_func("caller %s enter port %p\n", caller, port);
|
||||
|
||||
if (!queue->ready) {
|
||||
@@ -307,6 +308,7 @@ MPP_RET _mpp_port_dequeue(const char *caller, MppPort port, MppTask *task)
|
||||
ret = MPP_OK;
|
||||
RET:
|
||||
mpp_task_dbg_func("caller %s leave port %p task %p ret %d\n", caller, port, *task, ret);
|
||||
mpp_mutex_unlock(&queue->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -318,15 +320,16 @@ MPP_RET _mpp_port_enqueue(const char *caller, MppPort port, MppTask task)
|
||||
MppTaskQueueImpl *queue = port_impl->queue;
|
||||
MppTaskStatusInfo *curr = NULL;
|
||||
MppTaskStatusInfo *next = NULL;
|
||||
|
||||
AutoMutex auto_lock(queue->lock);
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
mpp_mutex_lock(&queue->lock);
|
||||
|
||||
mpp_task_dbg_func("caller %s enter port %p task %p\n", caller, port, task);
|
||||
|
||||
if (!queue->ready) {
|
||||
mpp_err("try to enqueue when %s queue is not ready\n",
|
||||
port_type_str[port_impl->type]);
|
||||
mpp_mutex_unlock(&queue->lock);
|
||||
goto RET;
|
||||
}
|
||||
|
||||
@@ -350,11 +353,12 @@ MPP_RET _mpp_port_enqueue(const char *caller, MppPort port, MppTask task)
|
||||
task_status_str[port_impl->next_on_dequeue],
|
||||
task_status_str[port_impl->next_on_enqueue]);
|
||||
|
||||
next->cond->signal();
|
||||
mpp_cond_signal(&next->cond);
|
||||
mpp_task_dbg_func("signal port %p\n", next);
|
||||
ret = MPP_OK;
|
||||
RET:
|
||||
mpp_task_dbg_func("caller %s leave port %p task %p ret %d\n", caller, port, task, ret);
|
||||
mpp_mutex_unlock(&queue->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -369,11 +373,12 @@ MPP_RET _mpp_port_awake(const char *caller, MppPort port)
|
||||
MppTaskQueueImpl *queue = port_impl->queue;
|
||||
MppTaskStatusInfo *curr = NULL;
|
||||
if (queue) {
|
||||
AutoMutex auto_lock(queue->lock);
|
||||
mpp_mutex_lock(&queue->lock);
|
||||
curr = &queue->info[port_impl->status_curr];
|
||||
if (curr) {
|
||||
curr->cond->signal();
|
||||
mpp_cond_signal(&curr->cond);
|
||||
}
|
||||
mpp_mutex_unlock(&queue->lock);
|
||||
}
|
||||
|
||||
mpp_task_dbg_func("caller %s leave port %p\n", caller, port);
|
||||
@@ -382,15 +387,13 @@ MPP_RET _mpp_port_awake(const char *caller, MppPort port)
|
||||
|
||||
MPP_RET mpp_task_queue_init(MppTaskQueue *queue, void *mpp, const char *name)
|
||||
{
|
||||
if (NULL == queue) {
|
||||
if (!queue) {
|
||||
mpp_err_f("invalid NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MppTaskQueueImpl *p = NULL;
|
||||
Mutex *lock = NULL;
|
||||
Condition *cond[MPP_TASK_STATUS_BUTT] = { NULL };
|
||||
RK_S32 i;
|
||||
|
||||
mpp_env_get_u32("mpp_task_debug", &mpp_task_debug, 0);
|
||||
@@ -399,36 +402,20 @@ MPP_RET mpp_task_queue_init(MppTaskQueue *queue, void *mpp, const char *name)
|
||||
*queue = NULL;
|
||||
|
||||
p = mpp_calloc(MppTaskQueueImpl, 1);
|
||||
if (NULL == p) {
|
||||
if (!p) {
|
||||
mpp_err_f("malloc queue failed\n");
|
||||
goto RET;
|
||||
}
|
||||
|
||||
cond[MPP_INPUT_PORT] = new Condition();
|
||||
cond[MPP_INPUT_HOLD] = NULL;
|
||||
cond[MPP_OUTPUT_PORT] = new Condition();
|
||||
cond[MPP_OUTPUT_HOLD] = NULL;
|
||||
|
||||
if (NULL == cond[MPP_INPUT_PORT] ||
|
||||
NULL == cond[MPP_OUTPUT_PORT]) {
|
||||
mpp_err_f("new condition failed\n");
|
||||
goto RET;
|
||||
}
|
||||
|
||||
for (i = 0; i < MPP_TASK_STATUS_BUTT; i++) {
|
||||
INIT_LIST_HEAD(&p->info[i].list);
|
||||
p->info[i].count = 0;
|
||||
p->info[i].status = (MppTaskStatus)i;
|
||||
p->info[i].cond = cond[i];
|
||||
if (i == MPP_INPUT_PORT || i == MPP_OUTPUT_PORT)
|
||||
mpp_cond_init(&p->info[i].cond);
|
||||
}
|
||||
|
||||
lock = new Mutex();
|
||||
if (NULL == lock) {
|
||||
mpp_err_f("new lock failed\n");
|
||||
goto RET;
|
||||
}
|
||||
|
||||
p->lock = lock;
|
||||
mpp_mutex_init(&p->lock);
|
||||
|
||||
if (mpp_port_init(p, MPP_PORT_INPUT, &p->input))
|
||||
goto RET;
|
||||
@@ -447,12 +434,9 @@ MPP_RET mpp_task_queue_init(MppTaskQueue *queue, void *mpp, const char *name)
|
||||
ret = MPP_OK;
|
||||
RET:
|
||||
if (ret) {
|
||||
if (lock)
|
||||
delete lock;
|
||||
if (cond[MPP_INPUT_PORT])
|
||||
delete cond[MPP_INPUT_PORT];
|
||||
if (cond[MPP_OUTPUT_PORT])
|
||||
delete cond[MPP_OUTPUT_PORT];
|
||||
mpp_mutex_destroy(&p->lock);
|
||||
mpp_cond_destroy(&p->info[MPP_INPUT_PORT].cond);
|
||||
mpp_cond_destroy(&p->info[MPP_OUTPUT_PORT].cond);
|
||||
MPP_FREE(p);
|
||||
}
|
||||
|
||||
@@ -465,23 +449,28 @@ RET:
|
||||
MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count)
|
||||
{
|
||||
MppTaskQueueImpl *impl = (MppTaskQueueImpl *)queue;
|
||||
AutoMutex auto_lock(impl->lock);
|
||||
MppTaskStatusInfo *info;
|
||||
MppTaskImpl *tasks;
|
||||
RK_S32 i;
|
||||
|
||||
mpp_mutex_lock(&impl->lock);
|
||||
|
||||
// NOTE: queue can only be setup once
|
||||
mpp_assert(impl->tasks == NULL);
|
||||
mpp_assert(impl->task_count == 0);
|
||||
MppTaskImpl *tasks = mpp_calloc(MppTaskImpl, task_count);
|
||||
if (NULL == tasks) {
|
||||
tasks = mpp_calloc(MppTaskImpl, task_count);
|
||||
if (!tasks) {
|
||||
mpp_err_f("malloc tasks list failed\n");
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
return MPP_ERR_MALLOC;
|
||||
}
|
||||
|
||||
impl->tasks = tasks;
|
||||
impl->task_count = task_count;
|
||||
|
||||
MppTaskStatusInfo *info = &impl->info[MPP_INPUT_PORT];
|
||||
info = &impl->info[MPP_INPUT_PORT];
|
||||
|
||||
for (RK_S32 i = 0; i < task_count; i++) {
|
||||
for (i = 0; i < task_count; i++) {
|
||||
setup_mpp_task_name(&tasks[i]);
|
||||
INIT_LIST_HEAD(&tasks[i].list);
|
||||
tasks[i].index = i;
|
||||
@@ -493,22 +482,27 @@ MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count)
|
||||
info->count++;
|
||||
}
|
||||
impl->ready = 1;
|
||||
|
||||
mpp_mutex_unlock(&impl->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_task_queue_deinit(MppTaskQueue queue)
|
||||
{
|
||||
if (NULL == queue) {
|
||||
MppTaskQueueImpl *p = (MppTaskQueueImpl *)queue;
|
||||
|
||||
if (!p) {
|
||||
mpp_err_f("found NULL input queue\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppTaskQueueImpl *p = (MppTaskQueueImpl *)queue;
|
||||
p->lock->lock();
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
p->ready = 0;
|
||||
p->info[MPP_INPUT_PORT].cond->signal();
|
||||
p->info[MPP_OUTPUT_PORT].cond->signal();
|
||||
mpp_cond_signal(&p->info[MPP_INPUT_PORT].cond);
|
||||
mpp_cond_signal(&p->info[MPP_OUTPUT_PORT].cond);
|
||||
|
||||
if (p->tasks) {
|
||||
for (RK_S32 i = 0; i < p->task_count; i++) {
|
||||
MppMeta meta = p->tasks[i].meta;
|
||||
@@ -533,24 +527,19 @@ MPP_RET mpp_task_queue_deinit(MppTaskQueue queue)
|
||||
mpp_port_deinit(p->output);
|
||||
p->output = NULL;
|
||||
}
|
||||
p->lock->unlock();
|
||||
if (p->lock)
|
||||
delete p->lock;
|
||||
if (p->info[MPP_INPUT_PORT].cond) {
|
||||
delete p->info[MPP_INPUT_PORT].cond;
|
||||
p->info[MPP_INPUT_PORT].cond = NULL;
|
||||
}
|
||||
if (p->info[MPP_OUTPUT_PORT].cond) {
|
||||
delete p->info[MPP_OUTPUT_PORT].cond;
|
||||
p->info[MPP_OUTPUT_PORT].cond = NULL;
|
||||
}
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
mpp_mutex_destroy(&p->lock);
|
||||
|
||||
mpp_cond_destroy(&p->info[MPP_INPUT_PORT].cond);
|
||||
mpp_cond_destroy(&p->info[MPP_OUTPUT_PORT].cond);
|
||||
|
||||
mpp_free(p);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MppPort mpp_task_queue_get_port(MppTaskQueue queue, MppPortType type)
|
||||
{
|
||||
if (NULL == queue || type >= MPP_PORT_BUTT) {
|
||||
if (!queue || type >= MPP_PORT_BUTT) {
|
||||
mpp_err_f("invalid input queue %p type %d\n", queue, type);
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -94,7 +94,7 @@ struct MppDecImpl_t {
|
||||
MppDecCfgSet *cfg;
|
||||
|
||||
/* control process */
|
||||
MppMutexCond *cmd_lock;
|
||||
MppMutexCond cmd_lock;
|
||||
RK_U32 cmd_send;
|
||||
RK_U32 cmd_recv;
|
||||
MpiCmd cmd;
|
||||
|
@@ -100,7 +100,7 @@ typedef struct MppEncImpl_t {
|
||||
MppBuffer md_info;
|
||||
|
||||
// internal status and protection
|
||||
Mutex lock;
|
||||
MppMutex lock;
|
||||
RK_U32 reset_flag;
|
||||
sem_t enc_reset;
|
||||
|
||||
|
@@ -124,7 +124,7 @@ typedef struct RcDataNode_t {
|
||||
} RcDataNode;
|
||||
|
||||
typedef struct DataGroupImpl_t {
|
||||
Mutex *lock;
|
||||
MppMutex lock;
|
||||
|
||||
RK_S32 base_cnt;
|
||||
RK_S32 extra_cnt;
|
||||
|
@@ -369,7 +369,7 @@ void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags)
|
||||
dec_vproc_signal(dec->vproc);
|
||||
} else {
|
||||
// direct output -> copy a new MppFrame and output
|
||||
mpp_list *list = mpp->mFrmOut;
|
||||
MppList *list = mpp->mFrmOut;
|
||||
MppFrame out = NULL;
|
||||
|
||||
mpp_frame_init(&out);
|
||||
@@ -377,11 +377,11 @@ void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags)
|
||||
|
||||
mpp_dbg_pts("output frame pts %lld\n", mpp_frame_get_pts(out));
|
||||
|
||||
list->lock();
|
||||
list->add_at_tail(&out, sizeof(out));
|
||||
mpp_mutex_cond_lock(&list->cond_lock);
|
||||
mpp_list_add_at_tail(list, &out, sizeof(out));
|
||||
mpp->mFramePutCount++;
|
||||
list->signal();
|
||||
list->unlock();
|
||||
mpp_list_signal(list);
|
||||
mpp_mutex_cond_unlock(&list->cond_lock);
|
||||
|
||||
if (fake_frame)
|
||||
mpp_frame_deinit(&frame);
|
||||
@@ -411,7 +411,7 @@ RK_S32 mpp_dec_push_display(Mpp *mpp, HalDecTaskFlag flags)
|
||||
tmp.info_change = 0;
|
||||
|
||||
if (dec->thread_hal)
|
||||
dec->thread_hal->lock(THREAD_OUTPUT);
|
||||
mpp_thread_lock(dec->thread_hal, THREAD_OUTPUT);
|
||||
|
||||
while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) {
|
||||
/* deal with current frame */
|
||||
@@ -424,7 +424,7 @@ RK_S32 mpp_dec_push_display(Mpp *mpp, HalDecTaskFlag flags)
|
||||
}
|
||||
|
||||
if (dec->thread_hal)
|
||||
dec->thread_hal->unlock(THREAD_OUTPUT);
|
||||
mpp_thread_unlock(dec->thread_hal, THREAD_OUTPUT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -655,7 +655,7 @@ MPP_RET mpp_dec_init(MppDec *dec, MppDecInitCfg *cfg)
|
||||
mpp_clock_enable(p->clocks[i], p->statistics_en);
|
||||
}
|
||||
|
||||
p->cmd_lock = new MppMutexCond();
|
||||
mpp_mutex_cond_init(&p->cmd_lock);
|
||||
sem_init(&p->parser_reset, 0, 0);
|
||||
sem_init(&p->hal_reset, 0, 0);
|
||||
sem_init(&p->cmd_start, 0, 0);
|
||||
@@ -762,10 +762,7 @@ MPP_RET mpp_dec_deinit(MppDec ctx)
|
||||
dec->packet_slots = NULL;
|
||||
}
|
||||
|
||||
if (dec->cmd_lock) {
|
||||
delete dec->cmd_lock;
|
||||
dec->cmd_lock = NULL;
|
||||
}
|
||||
mpp_mutex_cond_destroy(&dec->cmd_lock);
|
||||
|
||||
sem_destroy(&dec->parser_reset);
|
||||
sem_destroy(&dec->hal_reset);
|
||||
@@ -811,18 +808,18 @@ MPP_RET mpp_dec_stop(MppDec ctx)
|
||||
dec_dbg_func("%p in\n", dec);
|
||||
|
||||
if (dec->thread_parser)
|
||||
dec->thread_parser->stop();
|
||||
mpp_thread_stop(dec->thread_parser);
|
||||
|
||||
if (dec->thread_hal)
|
||||
dec->thread_hal->stop();
|
||||
mpp_thread_stop(dec->thread_hal);
|
||||
|
||||
if (dec->thread_parser) {
|
||||
delete dec->thread_parser;
|
||||
mpp_thread_destroy(dec->thread_parser);
|
||||
dec->thread_parser = NULL;
|
||||
}
|
||||
|
||||
if (dec->thread_hal) {
|
||||
delete dec->thread_hal;
|
||||
mpp_thread_destroy(dec->thread_hal);
|
||||
dec->thread_hal = NULL;
|
||||
}
|
||||
|
||||
|
@@ -34,12 +34,12 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
MppBufSlots frame_slots = dec->frame_slots;
|
||||
MppBufSlots packet_slots = dec->packet_slots;
|
||||
HalDecTask *task_dec = &task->info.dec;
|
||||
MppMutexCond *cmd_lock = dec->cmd_lock;
|
||||
MppMutexCond *cmd_lock = &dec->cmd_lock;
|
||||
MppPacket input = dec->mpp_pkt_in;
|
||||
size_t stream_size = 0;
|
||||
RK_S32 output = 0;
|
||||
|
||||
AutoMutex auto_lock(cmd_lock->mutex());
|
||||
mpp_mutex_cond_lock(cmd_lock);
|
||||
|
||||
/*
|
||||
* 1. task no ready and last packet is done try process new input packet
|
||||
@@ -47,9 +47,11 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
if (input == NULL && !status->curr_task_rdy) {
|
||||
input = packet;
|
||||
|
||||
if (input == NULL)
|
||||
if (input == NULL) {
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (input)
|
||||
dec_dbg_detail("detail: %p input pkt %p len %d task ready %d\n", dec,
|
||||
@@ -93,6 +95,7 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
mpp_dec_put_frame(mpp, -1, task_dec->flags);
|
||||
output++;
|
||||
}
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
return (MPP_RET)output;
|
||||
}
|
||||
|
||||
@@ -209,6 +212,7 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
task->hal_pkt_buf_in = NULL;
|
||||
|
||||
dec_dbg_detail("detail: %p parse return no task with output %d\n", dec, output);
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
return (MPP_RET)output;
|
||||
}
|
||||
dec_dbg_detail("detail: %p check output index pass\n", dec);
|
||||
@@ -232,6 +236,7 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
status->info_task_gen_rdy = 1;
|
||||
dec_dbg_detail("detail: %p info change found return frame %d\n",
|
||||
dec, output);
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
return (MPP_RET)output;
|
||||
}
|
||||
dec->info_updated = 0;
|
||||
@@ -239,6 +244,7 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
|
||||
task->wait.info_change = mpp_buf_slot_is_changed(frame_slots);
|
||||
if (task->wait.info_change) {
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
return MPP_OK;
|
||||
} else {
|
||||
status->info_task_gen_rdy = 0;
|
||||
@@ -258,8 +264,9 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
// NOTE: When dec post-process is enabled reserve 2 buffer for it.
|
||||
task->wait.dec_pic_unusd = (dec->vproc) ? (unused < 3) : (unused < 1);
|
||||
if (task->wait.dec_pic_unusd) {
|
||||
cmd_lock->wait();
|
||||
mpp_mutex_cond_wait(cmd_lock);
|
||||
/* return here and process all the flow again */
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
}
|
||||
@@ -304,8 +311,10 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
}
|
||||
|
||||
task->wait.dec_pic_match = (NULL == task->hal_frm_buf_out);
|
||||
if (task->wait.dec_pic_match)
|
||||
if (task->wait.dec_pic_match) {
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
mpp_hal_reg_gen(dec->hal, &task->info);
|
||||
mpp_hal_hw_start(dec->hal, &task->info);
|
||||
@@ -341,6 +350,7 @@ MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
|
||||
dec_task_info_init(&task->info);
|
||||
task->hal_pkt_buf_in = NULL;
|
||||
task->hal_frm_buf_out = NULL;
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
|
||||
return (MPP_RET)output;
|
||||
}
|
||||
@@ -349,11 +359,11 @@ MPP_RET mpp_dec_reset_no_thread(MppDecImpl *dec)
|
||||
{
|
||||
DecTask *task = (DecTask *)dec->task_single;
|
||||
MppBufSlots frame_slots = dec->frame_slots;
|
||||
MppMutexCond *cmd_lock = dec->cmd_lock;
|
||||
MppMutexCond *cmd_lock = &dec->cmd_lock;
|
||||
HalDecTask *task_dec = &task->info.dec;
|
||||
RK_S32 index;
|
||||
|
||||
AutoMutex auto_lock(cmd_lock->mutex());
|
||||
mpp_mutex_cond_lock(cmd_lock);
|
||||
|
||||
task->status.curr_task_rdy = 0;
|
||||
task->status.prev_task_rdy = 1;
|
||||
@@ -414,7 +424,8 @@ MPP_RET mpp_dec_reset_no_thread(MppDecImpl *dec)
|
||||
dec->dec_out_frame_count = 0;
|
||||
dec->info_updated = 0;
|
||||
|
||||
cmd_lock->signal();
|
||||
mpp_mutex_cond_signal(cmd_lock);
|
||||
mpp_mutex_cond_unlock(cmd_lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -423,9 +434,7 @@ MPP_RET mpp_dec_notify_no_thread(MppDecImpl *dec, RK_U32 flag)
|
||||
{
|
||||
// Only notify buffer group control
|
||||
if (flag == (MPP_DEC_NOTIFY_BUFFER_VALID | MPP_DEC_NOTIFY_BUFFER_MATCH)) {
|
||||
MppMutexCond *cmd_lock = dec->cmd_lock;
|
||||
|
||||
cmd_lock->signal();
|
||||
mpp_mutex_cond_signal(&dec->cmd_lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
@@ -435,10 +444,14 @@ MPP_RET mpp_dec_notify_no_thread(MppDecImpl *dec, RK_U32 flag)
|
||||
MPP_RET mpp_dec_control_no_thread(MppDecImpl *dec, MpiCmd cmd, void *param)
|
||||
{
|
||||
// cmd_lock is used to sync all async operations
|
||||
AutoMutex auto_lock(dec->cmd_lock->mutex());
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
mpp_mutex_cond_lock(&dec->cmd_lock);
|
||||
dec->cmd_send++;
|
||||
return mpp_dec_proc_cfg(dec, cmd, param);
|
||||
ret = mpp_dec_proc_cfg(dec, cmd, param);
|
||||
mpp_mutex_cond_unlock(&dec->cmd_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MppDecModeApi dec_api_no_thread = {
|
||||
|
@@ -147,10 +147,10 @@ static RK_U32 reset_parser_thread(Mpp *mpp, DecTask *task)
|
||||
|
||||
mpp_assert(hal);
|
||||
|
||||
hal->lock();
|
||||
mpp_thread_lock(hal, THREAD_WORK);
|
||||
dec->hal_reset_post++;
|
||||
hal->signal();
|
||||
hal->unlock();
|
||||
mpp_thread_signal(hal, THREAD_WORK);
|
||||
mpp_thread_unlock(hal, THREAD_WORK);
|
||||
|
||||
sem_wait(&dec->hal_reset);
|
||||
|
||||
@@ -242,11 +242,11 @@ static void mpp_dec_put_task(Mpp *mpp, DecTask *task)
|
||||
MppDecImpl *dec = (MppDecImpl *)mpp->mDec;
|
||||
|
||||
hal_task_hnd_set_info(task->hnd, &task->info);
|
||||
dec->thread_hal->lock();
|
||||
mpp_thread_lock(dec->thread_hal, THREAD_WORK);
|
||||
hal_task_hnd_set_status(task->hnd, TASK_PROCESSING);
|
||||
mpp->mTaskPutCount++;
|
||||
dec->thread_hal->signal();
|
||||
dec->thread_hal->unlock();
|
||||
mpp_thread_signal(dec->thread_hal, THREAD_WORK);
|
||||
mpp_thread_unlock(dec->thread_hal, THREAD_WORK);
|
||||
task->hnd = NULL;
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ static void reset_hal_thread(Mpp *mpp)
|
||||
flag.val = 0;
|
||||
mpp_dec_flush(dec);
|
||||
|
||||
dec->thread_hal->lock(THREAD_OUTPUT);
|
||||
mpp_thread_lock(dec->thread_hal, THREAD_OUTPUT);
|
||||
while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) {
|
||||
mpp_dec_put_frame(mpp, index, flag);
|
||||
mpp_buf_slot_clr_flag(frame_slots, index, SLOT_QUEUE_USE);
|
||||
@@ -277,7 +277,7 @@ static void reset_hal_thread(Mpp *mpp)
|
||||
}
|
||||
}
|
||||
|
||||
dec->thread_hal->unlock(THREAD_OUTPUT);
|
||||
mpp_thread_unlock(dec->thread_hal, THREAD_OUTPUT);
|
||||
}
|
||||
|
||||
static MPP_RET try_get_input_packet(Mpp *mpp, DecTask *task)
|
||||
@@ -482,7 +482,7 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task)
|
||||
|
||||
/* too many frame delay in dispaly queue */
|
||||
if (mpp->mFrmOut) {
|
||||
task->wait.dis_que_full = (mpp->mFrmOut->list_size() > 4) ? 1 : 0;
|
||||
task->wait.dis_que_full = (mpp_list_size(mpp->mFrmOut) > 4) ? 1 : 0;
|
||||
if (task->wait.dis_que_full)
|
||||
return MPP_ERR_DISPLAY_FULL;
|
||||
}
|
||||
@@ -708,10 +708,11 @@ void *mpp_dec_parser_thread(void *data)
|
||||
mpp_clock_start(dec->clocks[DEC_PRS_TOTAL]);
|
||||
|
||||
while (1) {
|
||||
{
|
||||
AutoMutex autolock(parser->mutex());
|
||||
if (MPP_THREAD_RUNNING != parser->get_status())
|
||||
mpp_thread_lock(parser, THREAD_WORK);
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(parser, THREAD_WORK)) {
|
||||
mpp_thread_unlock(parser, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* parser thread need to wait at cases below:
|
||||
@@ -722,10 +723,10 @@ void *mpp_dec_parser_thread(void *data)
|
||||
*/
|
||||
if (check_task_wait(dec, &task)) {
|
||||
mpp_clock_start(dec->clocks[DEC_PRS_WAIT]);
|
||||
parser->wait();
|
||||
mpp_thread_wait(parser, THREAD_WORK);
|
||||
mpp_clock_pause(dec->clocks[DEC_PRS_WAIT]);
|
||||
}
|
||||
}
|
||||
mpp_thread_unlock(parser, THREAD_WORK);
|
||||
|
||||
// process user control
|
||||
if (dec->cmd_send != dec->cmd_recv) {
|
||||
@@ -746,9 +747,10 @@ void *mpp_dec_parser_thread(void *data)
|
||||
if (dec->reset_flag) {
|
||||
reset_parser_thread(mpp, &task);
|
||||
|
||||
AutoMutex autolock(parser->mutex(THREAD_CONTROL));
|
||||
mpp_thread_lock(parser, THREAD_CONTROL);
|
||||
dec->reset_flag = 0;
|
||||
sem_post(&dec->parser_reset);
|
||||
mpp_thread_unlock(parser, THREAD_CONTROL);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -790,10 +792,11 @@ void *mpp_dec_hal_thread(void *data)
|
||||
|
||||
while (1) {
|
||||
/* hal thread wait for dxva interface intput first */
|
||||
{
|
||||
AutoMutex work_lock(hal->mutex());
|
||||
if (MPP_THREAD_RUNNING != hal->get_status())
|
||||
mpp_thread_lock(hal, THREAD_WORK);
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(hal, THREAD_WORK)) {
|
||||
mpp_thread_unlock(hal, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hal_task_get_hnd(tasks, TASK_PROCESSING, &task)) {
|
||||
// process all task then do reset process
|
||||
@@ -803,16 +806,18 @@ void *mpp_dec_hal_thread(void *data)
|
||||
dec_dbg_reset("reset: hal reset done\n");
|
||||
dec->hal_reset_done++;
|
||||
sem_post(&dec->hal_reset);
|
||||
mpp_thread_unlock(hal, THREAD_WORK);
|
||||
continue;
|
||||
}
|
||||
|
||||
mpp_dec_notify(dec, MPP_DEC_NOTIFY_TASK_ALL_DONE);
|
||||
mpp_clock_start(dec->clocks[DEC_HAL_WAIT]);
|
||||
hal->wait();
|
||||
mpp_thread_wait(hal, THREAD_WORK);
|
||||
mpp_clock_pause(dec->clocks[DEC_HAL_WAIT]);
|
||||
mpp_thread_unlock(hal, THREAD_WORK);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
mpp_thread_unlock(hal, THREAD_WORK);
|
||||
|
||||
if (task) {
|
||||
RK_U32 notify_flag = MPP_DEC_NOTIFY_TASK_HND_VALID;
|
||||
@@ -930,14 +935,15 @@ void *mpp_dec_advanced_thread(void *data)
|
||||
MppPacket packet = NULL;
|
||||
|
||||
while (1) {
|
||||
{
|
||||
AutoMutex autolock(thd_dec->mutex());
|
||||
if (MPP_THREAD_RUNNING != thd_dec->get_status())
|
||||
mpp_thread_lock(thd_dec, THREAD_WORK);
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(thd_dec, THREAD_WORK)) {
|
||||
mpp_thread_unlock(thd_dec, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (check_task_wait(dec, &task))
|
||||
thd_dec->wait();
|
||||
}
|
||||
mpp_thread_wait(thd_dec, THREAD_WORK);
|
||||
mpp_thread_unlock(thd_dec, THREAD_WORK);
|
||||
|
||||
// process user control
|
||||
if (dec->cmd_send != dec->cmd_recv) {
|
||||
@@ -1094,7 +1100,7 @@ void *mpp_dec_advanced_thread(void *data)
|
||||
*/
|
||||
DEC_OUT:
|
||||
if (task.status.mpp_in_frm_at_pkt) {
|
||||
mpp_list *list = mpp->mFrmOut;
|
||||
MppList *list = mpp->mFrmOut;
|
||||
MppMeta meta = mpp_frame_get_meta(frame);
|
||||
|
||||
if (meta)
|
||||
@@ -1102,11 +1108,11 @@ void *mpp_dec_advanced_thread(void *data)
|
||||
|
||||
mpp_dbg_pts("output frame pts %lld\n", mpp_frame_get_pts(frame));
|
||||
|
||||
list->lock();
|
||||
list->add_at_tail(&frame, sizeof(frame));
|
||||
mpp_mutex_cond_lock(&list->cond_lock);
|
||||
mpp_list_add_at_tail(list, &frame, sizeof(frame));
|
||||
mpp->mFramePutCount++;
|
||||
list->signal();
|
||||
list->unlock();
|
||||
mpp_list_signal(list);
|
||||
mpp_mutex_cond_unlock(&list->cond_lock);
|
||||
|
||||
mpp_port_enqueue(input, mpp_task);
|
||||
mpp_task = NULL;
|
||||
@@ -1147,17 +1153,17 @@ void *mpp_dec_advanced_thread(void *data)
|
||||
MPP_RET mpp_dec_start_normal(MppDecImpl *dec)
|
||||
{
|
||||
if (dec->coding != MPP_VIDEO_CodingMJPEG) {
|
||||
dec->thread_parser = new MppThread(mpp_dec_parser_thread,
|
||||
dec->thread_parser = mpp_thread_create(mpp_dec_parser_thread,
|
||||
dec->mpp, "mpp_dec_parser");
|
||||
dec->thread_parser->start();
|
||||
dec->thread_hal = new MppThread(mpp_dec_hal_thread,
|
||||
mpp_thread_start(dec->thread_parser);
|
||||
dec->thread_hal = mpp_thread_create(mpp_dec_hal_thread,
|
||||
dec->mpp, "mpp_dec_hal");
|
||||
|
||||
dec->thread_hal->start();
|
||||
mpp_thread_start(dec->thread_hal);
|
||||
} else {
|
||||
dec->thread_parser = new MppThread(mpp_dec_advanced_thread,
|
||||
dec->thread_parser = mpp_thread_create(mpp_dec_advanced_thread,
|
||||
dec->mpp, "mpp_dec_parser");
|
||||
dec->thread_parser->start();
|
||||
mpp_thread_start(dec->thread_parser);
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
@@ -1169,11 +1175,11 @@ MPP_RET mpp_dec_reset_normal(MppDecImpl *dec)
|
||||
|
||||
if (dec->coding != MPP_VIDEO_CodingMJPEG) {
|
||||
// set reset flag
|
||||
parser->lock(THREAD_CONTROL);
|
||||
mpp_thread_lock(parser, THREAD_CONTROL);
|
||||
dec->reset_flag = 1;
|
||||
// signal parser thread to reset
|
||||
mpp_dec_notify(dec, MPP_DEC_RESET);
|
||||
parser->unlock(THREAD_CONTROL);
|
||||
mpp_thread_unlock(parser, THREAD_CONTROL);
|
||||
sem_wait(&dec->parser_reset);
|
||||
}
|
||||
|
||||
@@ -1193,7 +1199,7 @@ MPP_RET mpp_dec_notify_normal(MppDecImpl *dec, RK_U32 flag)
|
||||
if (!thd_dec)
|
||||
return MPP_NOK;
|
||||
|
||||
thd_dec->lock();
|
||||
mpp_thread_lock(thd_dec, THREAD_WORK);
|
||||
if (flag == MPP_DEC_CONTROL) {
|
||||
dec->parser_notify_flag |= flag;
|
||||
notify = 1;
|
||||
@@ -1209,9 +1215,9 @@ MPP_RET mpp_dec_notify_normal(MppDecImpl *dec, RK_U32 flag)
|
||||
if (notify) {
|
||||
dec_dbg_notify("%p status %08x notify control signal\n", dec,
|
||||
dec->parser_wait_flag, dec->parser_notify_flag);
|
||||
thd_dec->signal();
|
||||
mpp_thread_signal(thd_dec, THREAD_WORK);
|
||||
}
|
||||
thd_dec->unlock();
|
||||
mpp_thread_unlock(thd_dec, THREAD_WORK);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -1219,7 +1225,7 @@ MPP_RET mpp_dec_notify_normal(MppDecImpl *dec, RK_U32 flag)
|
||||
MPP_RET mpp_dec_control_normal(MppDecImpl *dec, MpiCmd cmd, void *param)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
AutoMutex auto_lock(dec->cmd_lock->mutex());
|
||||
mpp_mutex_cond_lock(&dec->cmd_lock);
|
||||
|
||||
dec->cmd = cmd;
|
||||
dec->param = param;
|
||||
@@ -1232,6 +1238,7 @@ MPP_RET mpp_dec_control_normal(MppDecImpl *dec, MpiCmd cmd, void *param)
|
||||
mpp_dec_notify_normal(dec, MPP_DEC_CONTROL);
|
||||
sem_post(&dec->cmd_start);
|
||||
sem_wait(&dec->cmd_done);
|
||||
mpp_mutex_cond_unlock(&dec->cmd_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -536,13 +536,13 @@ MPP_RET mpp_enc_callback(const char *caller, void *ctx, RK_S32 cmd, void *param)
|
||||
mpp_assert(enc->task_out);
|
||||
} else {
|
||||
if (mpp->mPktOut) {
|
||||
mpp_list *pkt_out = mpp->mPktOut;
|
||||
MppList *pkt_out = mpp->mPktOut;
|
||||
|
||||
AutoMutex autoLock(pkt_out->mutex());
|
||||
|
||||
pkt_out->add_at_tail(&impl, sizeof(impl));
|
||||
mpp_mutex_cond_lock(&pkt_out->cond_lock);
|
||||
mpp_list_add_at_tail(pkt_out, &impl, sizeof(impl));
|
||||
mpp->mPacketPutCount++;
|
||||
pkt_out->signal();
|
||||
mpp_list_signal(pkt_out);
|
||||
mpp_mutex_cond_unlock(&pkt_out->cond_lock);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@@ -2633,14 +2633,17 @@ void *mpp_enc_thread(void *data)
|
||||
enc->time_base = mpp_time();
|
||||
|
||||
while (1) {
|
||||
{
|
||||
AutoMutex autolock(thd_enc->mutex());
|
||||
if (MPP_THREAD_RUNNING != thd_enc->get_status())
|
||||
mpp_thread_lock(thd_enc, THREAD_WORK);
|
||||
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(thd_enc, THREAD_WORK)) {
|
||||
mpp_thread_unlock(thd_enc, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (check_enc_task_wait(enc, &wait))
|
||||
thd_enc->wait();
|
||||
}
|
||||
mpp_thread_wait(thd_enc, THREAD_WORK);
|
||||
|
||||
mpp_thread_unlock(thd_enc, THREAD_WORK);
|
||||
|
||||
// When encoder is not on encoding process external config and reset
|
||||
if (!status->enc_start) {
|
||||
@@ -2672,19 +2675,20 @@ void *mpp_enc_thread(void *data)
|
||||
// 2. process reset
|
||||
if (enc->reset_flag) {
|
||||
enc_dbg_detail("thread reset start\n");
|
||||
{
|
||||
AutoMutex autolock(thd_enc->mutex());
|
||||
|
||||
mpp_thread_lock(thd_enc, THREAD_WORK);
|
||||
enc->status_flag = 0;
|
||||
}
|
||||
mpp_thread_unlock(thd_enc, THREAD_WORK);
|
||||
|
||||
enc->frm_cfg.force_flag |= ENC_FORCE_IDR;
|
||||
enc->frm_cfg.force_idr++;
|
||||
|
||||
AutoMutex autolock(thd_enc->mutex(THREAD_CONTROL));
|
||||
mpp_thread_lock(thd_enc, THREAD_CONTROL);
|
||||
enc->reset_flag = 0;
|
||||
sem_post(&enc->enc_reset);
|
||||
enc_dbg_detail("thread reset done\n");
|
||||
wait.val = 0;
|
||||
mpp_thread_unlock(thd_enc, THREAD_CONTROL);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2746,7 +2750,7 @@ static void async_task_terminate(MppEncImpl *enc, EncAsyncTaskInfo *async)
|
||||
enc_dbg_detail("task %d enqueue packet pts %lld\n", frm->seq_idx, enc->task_pts);
|
||||
|
||||
if (mpp->mPktOut) {
|
||||
mpp_list *pkt_out = mpp->mPktOut;
|
||||
MppList *pkt_out = mpp->mPktOut;
|
||||
|
||||
if (enc->frame) {
|
||||
MppMeta meta = mpp_packet_get_meta(pkt);
|
||||
@@ -2758,13 +2762,14 @@ static void async_task_terminate(MppEncImpl *enc, EncAsyncTaskInfo *async)
|
||||
enc->frame = NULL;
|
||||
}
|
||||
|
||||
AutoMutex autolock(pkt_out->mutex());
|
||||
mpp_mutex_cond_lock(&pkt_out->cond_lock);
|
||||
|
||||
pkt_out->add_at_tail(&pkt, sizeof(pkt));
|
||||
mpp_list_add_at_tail(pkt_out, &pkt, sizeof(pkt));
|
||||
mpp->mPacketPutCount++;
|
||||
pkt_out->signal();
|
||||
mpp_list_signal(pkt_out);
|
||||
mpp_assert(pkt);
|
||||
|
||||
mpp_mutex_cond_unlock(&pkt_out->cond_lock);
|
||||
enc_dbg_detail("packet out ready\n");
|
||||
}
|
||||
}
|
||||
@@ -2780,7 +2785,7 @@ static void async_task_skip(MppEncImpl *enc)
|
||||
MppFrame frm = NULL;
|
||||
MppPacket pkt = NULL;
|
||||
|
||||
mpp->mFrmIn->del_at_head(&frm, sizeof(frm));
|
||||
mpp_list_del_at_head(mpp->mFrmIn, &frm, sizeof(frm));
|
||||
mpp->mFrameGetCount++;
|
||||
|
||||
mpp_assert(frm);
|
||||
@@ -2816,14 +2821,14 @@ static void async_task_skip(MppEncImpl *enc)
|
||||
mpp_meta_set_frame(meta, KEY_INPUT_FRAME, frm);
|
||||
|
||||
if (mpp->mPktOut) {
|
||||
mpp_list *pkt_out = mpp->mPktOut;
|
||||
MppList *pkt_out = mpp->mPktOut;
|
||||
|
||||
pkt_out->lock();
|
||||
mpp_mutex_cond_lock(&pkt_out->cond_lock);
|
||||
mpp_stopwatch_record(stopwatch, "skip task output");
|
||||
pkt_out->add_at_tail(&pkt, sizeof(pkt));
|
||||
mpp_list_add_at_tail(pkt_out, &pkt, sizeof(pkt));
|
||||
mpp->mPacketPutCount++;
|
||||
pkt_out->signal();
|
||||
pkt_out->unlock();
|
||||
mpp_list_signal(pkt_out);
|
||||
mpp_mutex_cond_unlock(&pkt_out->cond_lock);
|
||||
}
|
||||
|
||||
enc_dbg_detail("packet skip ready\n");
|
||||
@@ -2943,12 +2948,14 @@ static MPP_RET try_get_async_task(MppEncImpl *enc, EncAsyncWait *wait)
|
||||
|
||||
if (NULL == frame) {
|
||||
if (mpp->mFrmIn) {
|
||||
mpp_list *frm_in = mpp->mFrmIn;
|
||||
AutoMutex autolock(frm_in->mutex());
|
||||
MppList *frm_in = mpp->mFrmIn;
|
||||
|
||||
mpp_mutex_cond_lock(&frm_in->cond_lock);
|
||||
|
||||
if (mpp_list_size(frm_in)) {
|
||||
mpp_list_del_at_head(frm_in, &frame, sizeof(frame));
|
||||
mpp_list_signal(frm_in);
|
||||
|
||||
if (frm_in->list_size()) {
|
||||
frm_in->del_at_head(&frame, sizeof(frame));
|
||||
frm_in->signal();
|
||||
mpp->mFrameGetCount++;
|
||||
|
||||
mpp_assert(frame);
|
||||
@@ -2963,6 +2970,8 @@ static MPP_RET try_get_async_task(MppEncImpl *enc, EncAsyncWait *wait)
|
||||
|
||||
hal_task->frame = frame;
|
||||
}
|
||||
|
||||
mpp_mutex_cond_unlock(&frm_in->cond_lock);
|
||||
}
|
||||
|
||||
if (NULL == frame) {
|
||||
@@ -3330,13 +3339,15 @@ TASK_DONE:
|
||||
set_enc_info_to_packet(enc, hal_task);
|
||||
|
||||
if (mpp->mPktOut) {
|
||||
mpp_list *pkt_out = mpp->mPktOut;
|
||||
MppList *pkt_out = mpp->mPktOut;
|
||||
|
||||
AutoMutex autoLock(pkt_out->mutex());
|
||||
mpp_mutex_cond_lock(&pkt_out->cond_lock);
|
||||
|
||||
pkt_out->add_at_tail(&pkt, sizeof(pkt));
|
||||
mpp_list_add_at_tail(pkt_out, &pkt, sizeof(pkt));
|
||||
mpp->mPacketPutCount++;
|
||||
pkt_out->signal();
|
||||
mpp_list_signal(pkt_out);
|
||||
|
||||
mpp_mutex_cond_unlock(&pkt_out->cond_lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -3355,25 +3366,26 @@ void *mpp_enc_async_thread(void *data)
|
||||
wait.val = 0;
|
||||
|
||||
while (1) {
|
||||
{
|
||||
AutoMutex autolock(thd_enc->mutex());
|
||||
if (MPP_THREAD_RUNNING != thd_enc->get_status())
|
||||
mpp_thread_lock(thd_enc, THREAD_WORK);
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(thd_enc, THREAD_WORK)) {
|
||||
mpp_thread_unlock(thd_enc, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (check_enc_async_wait(enc, &wait)) {
|
||||
enc_dbg_detail("wait start\n");
|
||||
thd_enc->wait();
|
||||
mpp_thread_wait(thd_enc, THREAD_WORK);
|
||||
enc_dbg_detail("wait done\n");
|
||||
}
|
||||
}
|
||||
mpp_thread_unlock(thd_enc, THREAD_WORK);
|
||||
|
||||
// When encoder is not on encoding process external config and reset
|
||||
// 1. process user control and reset flag
|
||||
if (enc->cmd_send != enc->cmd_recv || enc->reset_flag) {
|
||||
mpp_list *frm_in = mpp->mFrmIn;
|
||||
MppList *frm_in = mpp->mFrmIn;
|
||||
|
||||
/* when process cmd or reset hold frame input */
|
||||
frm_in->lock();
|
||||
mpp_mutex_cond_lock(&frm_in->cond_lock);
|
||||
|
||||
enc_dbg_detail("ctrl proc %d cmd %08x\n", enc->cmd_recv, enc->cmd);
|
||||
|
||||
@@ -3406,24 +3418,26 @@ void *mpp_enc_async_thread(void *data)
|
||||
enc_dbg_detail("thread reset start\n");
|
||||
|
||||
/* skip the frames in input queue */
|
||||
while (frm_in->list_size())
|
||||
while (mpp_list_size(frm_in))
|
||||
async_task_skip(enc);
|
||||
|
||||
{
|
||||
AutoMutex autolock(thd_enc->mutex());
|
||||
mpp_thread_lock(thd_enc, THREAD_WORK);
|
||||
enc->status_flag = 0;
|
||||
mpp_thread_unlock(thd_enc, THREAD_WORK);
|
||||
}
|
||||
|
||||
enc->frm_cfg.force_flag |= ENC_FORCE_IDR;
|
||||
enc->frm_cfg.force_idr++;
|
||||
|
||||
AutoMutex autolock(thd_enc->mutex(THREAD_CONTROL));
|
||||
mpp_thread_lock(thd_enc, THREAD_CONTROL);
|
||||
enc->reset_flag = 0;
|
||||
sem_post(&enc->enc_reset);
|
||||
enc_dbg_detail("thread reset done\n");
|
||||
mpp_thread_unlock(thd_enc, THREAD_CONTROL);
|
||||
}
|
||||
SYNC_DONE:
|
||||
frm_in->unlock();
|
||||
mpp_mutex_cond_unlock(&frm_in->cond_lock);
|
||||
wait.val = 0;
|
||||
continue;
|
||||
}
|
||||
|
@@ -143,6 +143,7 @@ MPP_RET mpp_enc_init_v2(MppEnc *enc, MppEncInitCfg *cfg)
|
||||
sem_init(&p->enc_reset, 0, 0);
|
||||
sem_init(&p->cmd_start, 0, 0);
|
||||
sem_init(&p->cmd_done, 0, 0);
|
||||
mpp_mutex_init(&p->lock);
|
||||
|
||||
*enc = p;
|
||||
return ret;
|
||||
@@ -160,6 +161,8 @@ MPP_RET mpp_enc_deinit_v2(MppEnc ctx)
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
mpp_mutex_destroy(&enc->lock);
|
||||
|
||||
if (enc->hal_info) {
|
||||
hal_info_deinit(enc->hal_info);
|
||||
enc->hal_info = NULL;
|
||||
@@ -217,8 +220,8 @@ MPP_RET mpp_enc_start_v2(MppEnc ctx)
|
||||
snprintf(name, sizeof(name) - 1, "mpp_%se_%d",
|
||||
strof_coding_type(enc->coding), getpid());
|
||||
|
||||
enc->thread_enc = new MppThread(mpp_enc_thread, enc->mpp, name);
|
||||
enc->thread_enc->start();
|
||||
enc->thread_enc = mpp_thread_create(mpp_enc_thread, enc->mpp, name);
|
||||
mpp_thread_start(enc->thread_enc);
|
||||
|
||||
enc_dbg_func("%p out\n", enc);
|
||||
|
||||
@@ -235,8 +238,8 @@ MPP_RET mpp_enc_start_async(MppEnc ctx)
|
||||
snprintf(name, sizeof(name) - 1, "mpp_%se_%d",
|
||||
strof_coding_type(enc->coding), getpid());
|
||||
|
||||
enc->thread_enc = new MppThread(mpp_enc_async_thread, enc->mpp, name);
|
||||
enc->thread_enc->start();
|
||||
enc->thread_enc = mpp_thread_create(mpp_enc_async_thread, enc->mpp, name);
|
||||
mpp_thread_start(enc->thread_enc);
|
||||
|
||||
enc_dbg_func("%p out\n", enc);
|
||||
|
||||
@@ -251,8 +254,8 @@ MPP_RET mpp_enc_stop_v2(MppEnc ctx)
|
||||
enc_dbg_func("%p in\n", enc);
|
||||
|
||||
if (enc->thread_enc) {
|
||||
enc->thread_enc->stop();
|
||||
delete enc->thread_enc;
|
||||
mpp_thread_stop(enc->thread_enc);
|
||||
mpp_thread_destroy(enc->thread_enc);
|
||||
enc->thread_enc = NULL;
|
||||
}
|
||||
|
||||
@@ -264,19 +267,22 @@ MPP_RET mpp_enc_stop_v2(MppEnc ctx)
|
||||
MPP_RET mpp_enc_reset_v2(MppEnc ctx)
|
||||
{
|
||||
MppEncImpl *enc = (MppEncImpl *)ctx;
|
||||
MppThread *thd;
|
||||
|
||||
enc_dbg_func("%p in\n", enc);
|
||||
|
||||
if (NULL == enc) {
|
||||
mpp_err_f("found NULL input enc\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppThread *thd = enc->thread_enc;
|
||||
thd = enc->thread_enc;
|
||||
|
||||
thd->lock(THREAD_CONTROL);
|
||||
mpp_thread_lock(thd, THREAD_CONTROL);
|
||||
enc->reset_flag = 1;
|
||||
mpp_enc_notify_v2(enc, MPP_ENC_RESET);
|
||||
thd->unlock(THREAD_CONTROL);
|
||||
mpp_thread_unlock(thd, THREAD_CONTROL);
|
||||
|
||||
sem_wait(&enc->enc_reset);
|
||||
mpp_assert(enc->reset_flag == 0);
|
||||
|
||||
@@ -286,16 +292,16 @@ MPP_RET mpp_enc_reset_v2(MppEnc ctx)
|
||||
MPP_RET mpp_enc_notify_v2(MppEnc ctx, RK_U32 flag)
|
||||
{
|
||||
MppEncImpl *enc = (MppEncImpl *)ctx;
|
||||
|
||||
enc_dbg_func("%p in flag %08x\n", enc, flag);
|
||||
MppThread *thd = enc->thread_enc;
|
||||
|
||||
thd->lock();
|
||||
enc_dbg_func("%p in flag %08x\n", enc, flag);
|
||||
|
||||
mpp_thread_lock(thd, THREAD_WORK);
|
||||
if (flag == MPP_ENC_CONTROL) {
|
||||
enc->notify_flag |= flag;
|
||||
enc_dbg_notify("%p status %08x notify control signal\n", enc,
|
||||
enc->status_flag);
|
||||
thd->signal();
|
||||
mpp_thread_signal(thd, THREAD_WORK);
|
||||
} else {
|
||||
RK_U32 old_flag = enc->notify_flag;
|
||||
|
||||
@@ -304,10 +310,10 @@ MPP_RET mpp_enc_notify_v2(MppEnc ctx, RK_U32 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();
|
||||
mpp_thread_signal(thd, THREAD_WORK);
|
||||
}
|
||||
}
|
||||
thd->unlock();
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
enc_dbg_func("%p out\n", enc);
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -321,6 +327,7 @@ MPP_RET mpp_enc_notify_v2(MppEnc ctx, RK_U32 flag)
|
||||
MPP_RET mpp_enc_control_v2(MppEnc ctx, MpiCmd cmd, void *param)
|
||||
{
|
||||
MppEncImpl *enc = (MppEncImpl *)ctx;
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
if (NULL == enc) {
|
||||
mpp_err_f("found NULL enc\n");
|
||||
@@ -332,8 +339,7 @@ MPP_RET mpp_enc_control_v2(MppEnc ctx, MpiCmd cmd, void *param)
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
AutoMutex auto_lock(&enc->lock);
|
||||
MPP_RET ret = MPP_OK;
|
||||
mpp_mutex_lock(&enc->lock);
|
||||
|
||||
enc_dbg_ctrl("sending cmd %d param %p\n", cmd, param);
|
||||
|
||||
@@ -392,6 +398,9 @@ MPP_RET mpp_enc_control_v2(MppEnc ctx, MpiCmd cmd, void *param)
|
||||
} break;
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&enc->lock);
|
||||
|
||||
enc_dbg_ctrl("sending cmd %d done\n", cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "mpp_env.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_rc.h"
|
||||
|
||||
|
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "mpp_env.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#include "rc_base.h"
|
||||
|
@@ -81,12 +81,11 @@ static void rc_data_node_init(DataGroupImpl *p, RcDataNode *node, RK_S32 slot_id
|
||||
|
||||
MPP_RET rc_data_group_init(DataGroupImpl *p, RK_S32 base_cnt, RK_S32 extra_cnt)
|
||||
{
|
||||
p->lock = new Mutex();
|
||||
mpp_mutex_init(&p->lock);
|
||||
|
||||
node_group_init(&p->node, sizeof(RcDataNode), base_cnt);
|
||||
node_group_init(&p->extra, sizeof(RcDataExtra), extra_cnt);
|
||||
|
||||
mpp_assert(p->lock);
|
||||
mpp_assert(p->node);
|
||||
mpp_assert(p->extra);
|
||||
|
||||
@@ -100,14 +99,13 @@ MPP_RET rc_data_group_init(DataGroupImpl *p, RK_S32 base_cnt, RK_S32 extra_cnt)
|
||||
|
||||
MPP_RET rc_data_group_deinit(DataGroupImpl *p)
|
||||
{
|
||||
mpp_assert(p->lock);
|
||||
mpp_assert(p->node);
|
||||
mpp_assert(p->extra);
|
||||
|
||||
node_group_deinit(p->node);
|
||||
node_group_deinit(p->extra);
|
||||
|
||||
delete p->lock;
|
||||
mpp_mutex_destroy(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -184,10 +182,13 @@ RcDataNode *rc_data_group_get_node_by_status(DataGroupImpl *p, RcDataStatus stat
|
||||
void rc_data_group_put_node(DataGroupImpl *p, RcDataNode *node)
|
||||
{
|
||||
RcDataIndexes *indexes = &p->indexes;
|
||||
RcDataHead *head = &node->head;
|
||||
RcDataHead *head;
|
||||
RcDataStatus data_status;
|
||||
|
||||
AutoMutex auto_lock(p->lock);
|
||||
RcDataStatus data_status = head->data_status;
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
head = &node->head;
|
||||
data_status = head->data_status;
|
||||
|
||||
list_del_init(&head->status);
|
||||
indexes->status_cnt[data_status]--;
|
||||
@@ -259,6 +260,7 @@ void rc_data_group_put_node(DataGroupImpl *p, RcDataNode *node)
|
||||
list_add_tail(&head->status, &indexes->status[data_status]);
|
||||
indexes->status_cnt[data_status]++;
|
||||
head->data_status = data_status;
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
}
|
||||
|
||||
RcData rc_data_get_next(DataGroup grp)
|
||||
|
@@ -70,29 +70,35 @@ RcImplApiService::RcImplApiService()
|
||||
INIT_LIST_HEAD(&mApis);
|
||||
mApiCount = 0;
|
||||
|
||||
mpp_mutex_init(&lock);
|
||||
for (i = 0; i < MPP_ARRAY_ELEMS(rc_apis); i++)
|
||||
api_add(rc_apis[i]);
|
||||
}
|
||||
|
||||
RcImplApiService::~RcImplApiService()
|
||||
{
|
||||
AutoMutex auto_lock(get_lock());
|
||||
RcImplApiNode *pos, *n;
|
||||
|
||||
mpp_mutex_lock(&lock);
|
||||
|
||||
list_for_each_entry_safe(pos, n, &mApis, RcImplApiNode, list) {
|
||||
MPP_FREE(pos);
|
||||
mApiCount--;
|
||||
}
|
||||
|
||||
mpp_assert(mApiCount == 0);
|
||||
|
||||
mpp_mutex_unlock(&lock);
|
||||
mpp_mutex_destroy(&lock);
|
||||
}
|
||||
|
||||
MPP_RET RcImplApiService::api_add(const RcImplApi *api)
|
||||
{
|
||||
AutoMutex auto_lock(get_lock());
|
||||
mpp_mutex_lock(&lock);
|
||||
|
||||
if (NULL == api) {
|
||||
mpp_err_f("unable to register NULL api\n");
|
||||
mpp_mutex_unlock(&lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
@@ -104,6 +110,7 @@ MPP_RET RcImplApiService::api_add(const RcImplApi *api)
|
||||
node = mpp_malloc(RcImplApiNode, 1);
|
||||
if (NULL == node) {
|
||||
mpp_err_f("failed to create api node\n");
|
||||
mpp_mutex_unlock(&lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
@@ -118,16 +125,19 @@ MPP_RET RcImplApiService::api_add(const RcImplApi *api)
|
||||
}
|
||||
|
||||
set_node_api(node, api);
|
||||
mpp_mutex_unlock(&lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
RcImplApi *RcImplApiService::api_get(MppCodingType type, const char *name)
|
||||
{
|
||||
AutoMutex auto_lock(get_lock());
|
||||
mpp_mutex_lock(&lock);
|
||||
|
||||
if (!mApiCount)
|
||||
if (!mApiCount) {
|
||||
mpp_mutex_unlock(&lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
RcImplApiNode *pos, *n;
|
||||
@@ -136,22 +146,24 @@ RcImplApi *RcImplApiService::api_get(MppCodingType type, const char *name)
|
||||
if (type == pos->type &&
|
||||
!strncmp(name, pos->name, sizeof(pos->name) - 1)) {
|
||||
rc_dbg_impl("rc impl %s is selected\n", pos->name);
|
||||
mpp_mutex_unlock(&lock);
|
||||
return &pos->api;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc_dbg_impl("failed to find rc impl %s type %x\n", name, type);
|
||||
mpp_mutex_unlock(&lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MPP_RET RcImplApiService::api_get_all(RcApiBrief *brief, RK_S32 *count, RK_S32 max_count)
|
||||
{
|
||||
RK_S32 cnt = 0;
|
||||
RcImplApiNode *pos, *n;
|
||||
RK_S32 cnt = 0;
|
||||
|
||||
AutoMutex auto_lock(get_lock());
|
||||
mpp_mutex_lock(&lock);
|
||||
|
||||
list_for_each_entry_safe(pos, n, &mApis, RcImplApiNode, list) {
|
||||
if (cnt >= max_count)
|
||||
@@ -161,6 +173,7 @@ MPP_RET RcImplApiService::api_get_all(RcApiBrief *brief, RK_S32 *count, RK_S32 m
|
||||
}
|
||||
|
||||
*count = cnt;
|
||||
mpp_mutex_unlock(&lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -168,10 +181,10 @@ MPP_RET RcImplApiService::api_get_all(RcApiBrief *brief, RK_S32 *count, RK_S32 m
|
||||
MPP_RET RcImplApiService::api_get_by_type(RcApiBrief *brief, RK_S32 *count,
|
||||
RK_S32 max_count, MppCodingType type)
|
||||
{
|
||||
RK_S32 cnt = 0;
|
||||
RcImplApiNode *pos, *n;
|
||||
RK_S32 cnt = 0;
|
||||
|
||||
AutoMutex auto_lock(get_lock());
|
||||
mpp_mutex_lock(&lock);
|
||||
|
||||
list_for_each_entry_safe(pos, n, &mApis, RcImplApiNode, list) {
|
||||
if (cnt >= max_count)
|
||||
@@ -184,6 +197,7 @@ MPP_RET RcImplApiService::api_get_by_type(RcApiBrief *brief, RK_S32 *count,
|
||||
}
|
||||
|
||||
*count = cnt;
|
||||
mpp_mutex_unlock(&lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -195,14 +209,18 @@ MPP_RET rc_api_add(const RcImplApi *api)
|
||||
|
||||
MPP_RET rc_brief_get_all(RcApiQueryAll *query)
|
||||
{
|
||||
RcApiBrief *brief;
|
||||
RK_S32 *count;
|
||||
RK_S32 max_count;
|
||||
|
||||
if (NULL == query) {
|
||||
mpp_err_f("invalide NULL query input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
RcApiBrief *brief = query->brief;
|
||||
RK_S32 *count = &query->count;
|
||||
RK_S32 max_count = query->max_count;
|
||||
brief = query->brief;
|
||||
count = &query->count;
|
||||
max_count = query->max_count;
|
||||
|
||||
if (NULL == brief || max_count <= 0) {
|
||||
mpp_err_f("invalide brief buffer %p max count %d\n", brief, max_count);
|
||||
@@ -214,15 +232,20 @@ MPP_RET rc_brief_get_all(RcApiQueryAll *query)
|
||||
|
||||
MPP_RET rc_brief_get_by_type(RcApiQueryType *query)
|
||||
{
|
||||
RcApiBrief *brief;
|
||||
RK_S32 *count;
|
||||
RK_S32 max_count;
|
||||
MppCodingType type;
|
||||
|
||||
if (NULL == query) {
|
||||
mpp_err_f("invalide NULL query input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
RcApiBrief *brief = query->brief;
|
||||
RK_S32 *count = &query->count;
|
||||
RK_S32 max_count = query->max_count;
|
||||
MppCodingType type = query->type;
|
||||
brief = query->brief;
|
||||
count = &query->count;
|
||||
max_count = query->max_count;
|
||||
type = query->type;
|
||||
|
||||
if (NULL == brief || max_count <= 0) {
|
||||
mpp_err_f("invalide brief buffer %p max count %d type %x\n",
|
||||
|
@@ -33,6 +33,7 @@ private:
|
||||
RcImplApiService(const RcImplApiService &);
|
||||
RcImplApiService &operator=(const RcImplApiService &);
|
||||
|
||||
MppMutex lock;
|
||||
RK_U32 mApiCount;
|
||||
|
||||
struct list_head mApis;
|
||||
@@ -40,12 +41,12 @@ private:
|
||||
public:
|
||||
static RcImplApiService *get_instance() {
|
||||
static RcImplApiService instance;
|
||||
AutoMutex auto_lock(get_lock());
|
||||
return &instance;
|
||||
}
|
||||
static Mutex *get_lock() {
|
||||
static Mutex lock;
|
||||
return &lock;
|
||||
RcImplApiService * ret;
|
||||
|
||||
mpp_mutex_lock(&instance.lock);
|
||||
ret = &instance;
|
||||
mpp_mutex_unlock(&instance.lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET api_add(const RcImplApi *api);
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
MPP_RET api_get_all(RcApiBrief *brief, RK_S32 *count, RK_S32 max_count);
|
||||
MPP_RET api_get_by_type(RcApiBrief *brief, RK_S32 *count,
|
||||
RK_S32 max_count, MppCodingType type);
|
||||
MppMutex *get_lock() {return &lock; };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -135,10 +135,10 @@ public:
|
||||
MPP_RET notify(RK_U32 flag);
|
||||
MPP_RET notify(MppBufferGroup group);
|
||||
|
||||
mpp_list *mPktIn;
|
||||
mpp_list *mPktOut;
|
||||
mpp_list *mFrmIn;
|
||||
mpp_list *mFrmOut;
|
||||
MppList *mPktIn;
|
||||
MppList *mPktOut;
|
||||
MppList *mFrmIn;
|
||||
MppList *mFrmOut;
|
||||
/* counters for debug */
|
||||
RK_U32 mPacketPutCount;
|
||||
RK_U32 mPacketGetCount;
|
||||
|
155
mpp/mpp.cpp
155
mpp/mpp.cpp
@@ -185,8 +185,8 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
||||
|
||||
switch (mType) {
|
||||
case MPP_CTX_DEC : {
|
||||
mPktIn = new mpp_list(list_wraper_packet);
|
||||
mFrmOut = new mpp_list(list_wraper_frame);
|
||||
mPktIn = mpp_list_create(list_wraper_packet);
|
||||
mFrmOut = mpp_list_create(list_wraper_frame);
|
||||
|
||||
if (mInputTimeout == MPP_POLL_BUTT)
|
||||
mInputTimeout = MPP_POLL_NON_BLOCK;
|
||||
@@ -227,8 +227,8 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
||||
mInitDone = 1;
|
||||
} break;
|
||||
case MPP_CTX_ENC : {
|
||||
mPktOut = new mpp_list(list_wraper_packet);
|
||||
mFrmIn = new mpp_list(list_wraper_frame);
|
||||
mPktOut = mpp_list_create(list_wraper_packet);
|
||||
mFrmIn = mpp_list_create(list_wraper_frame);
|
||||
|
||||
if (mInputTimeout == MPP_POLL_BUTT)
|
||||
mInputTimeout = MPP_POLL_BLOCK;
|
||||
@@ -337,19 +337,19 @@ void Mpp::clear()
|
||||
}
|
||||
|
||||
if (mPktIn) {
|
||||
delete mPktIn;
|
||||
mpp_list_destroy(mPktIn);
|
||||
mPktIn = NULL;
|
||||
}
|
||||
if (mPktOut) {
|
||||
delete mPktOut;
|
||||
mpp_list_destroy(mPktOut);
|
||||
mPktOut = NULL;
|
||||
}
|
||||
if (mFrmIn) {
|
||||
delete mFrmIn;
|
||||
mpp_list_destroy(mFrmIn);
|
||||
mFrmIn = NULL;
|
||||
}
|
||||
if (mFrmOut) {
|
||||
delete mFrmOut;
|
||||
mpp_list_destroy(mFrmOut);
|
||||
mFrmOut = NULL;
|
||||
}
|
||||
|
||||
@@ -519,33 +519,37 @@ RET:
|
||||
|
||||
MPP_RET Mpp::get_frame(MppFrame *frame)
|
||||
{
|
||||
MppFrame frm = NULL;
|
||||
|
||||
if (!mInitDone)
|
||||
return MPP_ERR_INIT;
|
||||
|
||||
AutoMutex autoFrameLock(mFrmOut->mutex());
|
||||
MppFrame frm = NULL;
|
||||
mpp_mutex_cond_lock(&mFrmOut->cond_lock);
|
||||
|
||||
if (0 == mFrmOut->list_size()) {
|
||||
if (0 == mpp_list_size(mFrmOut)) {
|
||||
if (mOutputTimeout) {
|
||||
if (mOutputTimeout < 0) {
|
||||
/* block wait */
|
||||
mFrmOut->wait();
|
||||
mpp_list_wait(mFrmOut);
|
||||
} else {
|
||||
RK_S32 ret = mFrmOut->wait(mOutputTimeout);
|
||||
RK_S32 ret = mpp_list_wait_timed(mFrmOut, mOutputTimeout);
|
||||
if (ret) {
|
||||
if (ret == ETIMEDOUT)
|
||||
if (ret == ETIMEDOUT) {
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
return MPP_ERR_TIMEOUT;
|
||||
else
|
||||
} else {
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mFrmOut->list_size()) {
|
||||
if (mpp_list_size(mFrmOut)) {
|
||||
MppBuffer buffer;
|
||||
|
||||
mFrmOut->del_at_head(&frm, sizeof(frame));
|
||||
mpp_list_del_at_head(mFrmOut, &frm, sizeof(frame));
|
||||
mFrameGetCount++;
|
||||
notify(MPP_OUTPUT_DEQUEUE);
|
||||
|
||||
@@ -559,15 +563,17 @@ MPP_RET Mpp::get_frame(MppFrame *frame)
|
||||
// There is no way to wake up parser thread to continue decoding.
|
||||
// The put_packet only signal sem on may be it better to use sem on info
|
||||
// change too.
|
||||
AutoMutex autoPacketLock(mPktIn->mutex());
|
||||
if (mPktIn->list_size())
|
||||
mpp_mutex_cond_lock(&mPktIn->cond_lock);
|
||||
if (mpp_list_size(mPktIn))
|
||||
notify(MPP_INPUT_ENQUEUE);
|
||||
mpp_mutex_cond_unlock(&mPktIn->cond_lock);
|
||||
}
|
||||
|
||||
*frame = frm;
|
||||
|
||||
// dump output
|
||||
mpp_ops_dec_get_frm(mDump, frm);
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -579,13 +585,13 @@ MPP_RET Mpp::get_frame_noblock(MppFrame *frame)
|
||||
if (!mInitDone)
|
||||
return MPP_ERR_INIT;
|
||||
|
||||
mFrmOut->lock();
|
||||
if (mFrmOut->list_size()) {
|
||||
mFrmOut->del_at_head(&first, sizeof(frame));
|
||||
mpp_mutex_cond_lock(&mFrmOut->cond_lock);
|
||||
if (mpp_list_size(mFrmOut)) {
|
||||
mpp_list_del_at_head(mFrmOut, &first, sizeof(frame));
|
||||
mpp_buffer_sync_ro_begin(mpp_frame_get_buffer(first));
|
||||
mFrameGetCount++;
|
||||
}
|
||||
mFrmOut->unlock();
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
*frame = first;
|
||||
|
||||
return MPP_OK;
|
||||
@@ -608,18 +614,19 @@ MPP_RET Mpp::decode(MppPacket packet, MppFrame *frame)
|
||||
* But if the output mode is block then we need to send packet first
|
||||
*/
|
||||
if (!mOutputTimeout) {
|
||||
AutoMutex autoFrameLock(mFrmOut->mutex());
|
||||
|
||||
if (mFrmOut->list_size()) {
|
||||
mpp_mutex_cond_lock(&mFrmOut->cond_lock);
|
||||
if (mpp_list_size(mFrmOut)) {
|
||||
MppBuffer buffer;
|
||||
|
||||
mFrmOut->del_at_head(frame, sizeof(*frame));
|
||||
mpp_list_del_at_head(mFrmOut, frame, sizeof(*frame));
|
||||
buffer = mpp_frame_get_buffer(*frame);
|
||||
if (buffer)
|
||||
mpp_buffer_sync_ro_begin(buffer);
|
||||
mFrameGetCount++;
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -631,20 +638,18 @@ MPP_RET Mpp::decode(MppPacket packet, MppFrame *frame)
|
||||
pkt_done = 1;
|
||||
|
||||
/* always try getting frame */
|
||||
{
|
||||
AutoMutex autoFrameLock(mFrmOut->mutex());
|
||||
|
||||
if (mFrmOut->list_size()) {
|
||||
mpp_mutex_cond_lock(&mFrmOut->cond_lock);
|
||||
if (mpp_list_size(mFrmOut)) {
|
||||
MppBuffer buffer;
|
||||
|
||||
mFrmOut->del_at_head(frame, sizeof(*frame));
|
||||
mpp_list_del_at_head(mFrmOut, frame, sizeof(*frame));
|
||||
buffer = mpp_frame_get_buffer(*frame);
|
||||
if (buffer)
|
||||
mpp_buffer_sync_ro_begin(buffer);
|
||||
mFrameGetCount++;
|
||||
frm_rdy = 1;
|
||||
}
|
||||
}
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
|
||||
/* return on flow error */
|
||||
if (ret < 0)
|
||||
@@ -859,55 +864,58 @@ MPP_RET Mpp::put_frame_async(MppFrame frame)
|
||||
if (NULL == mFrmIn)
|
||||
return MPP_NOK;
|
||||
|
||||
if (mFrmIn->trylock())
|
||||
if (mpp_mutex_cond_trylock(&mFrmIn->cond_lock))
|
||||
return MPP_NOK;
|
||||
|
||||
/* NOTE: the max input queue length is 2 */
|
||||
if (mFrmIn->wait_le(10, 1)) {
|
||||
mFrmIn->unlock();
|
||||
if (mpp_list_wait_le(mFrmIn, 10, 1)) {
|
||||
mpp_mutex_cond_unlock(&mFrmIn->cond_lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
mFrmIn->add_at_tail(&frame, sizeof(frame));
|
||||
mpp_list_add_at_tail(mFrmIn, &frame, sizeof(frame));
|
||||
mFramePutCount++;
|
||||
|
||||
notify(MPP_INPUT_ENQUEUE);
|
||||
mFrmIn->unlock();
|
||||
mpp_mutex_cond_unlock(&mFrmIn->cond_lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET Mpp::get_packet_async(MppPacket *packet)
|
||||
{
|
||||
AutoMutex autoPacketLock(mPktOut->mutex());
|
||||
|
||||
mpp_mutex_cond_lock(&mPktOut->cond_lock);
|
||||
*packet = NULL;
|
||||
if (0 == mPktOut->list_size()) {
|
||||
if (0 == mpp_list_size(mPktOut)) {
|
||||
if (mOutputTimeout) {
|
||||
if (mOutputTimeout < 0) {
|
||||
/* block wait */
|
||||
mPktOut->wait();
|
||||
mpp_list_wait(mPktOut);
|
||||
} else {
|
||||
RK_S32 ret = mPktOut->wait(mOutputTimeout);
|
||||
RK_S32 ret = mpp_list_wait_timed(mPktOut, mOutputTimeout);
|
||||
|
||||
if (ret) {
|
||||
if (ret == ETIMEDOUT)
|
||||
if (ret == ETIMEDOUT) {
|
||||
mpp_mutex_cond_unlock(&mPktOut->cond_lock);
|
||||
return MPP_ERR_TIMEOUT;
|
||||
else
|
||||
} else {
|
||||
mpp_mutex_cond_unlock(&mPktOut->cond_lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* NOTE: in non-block mode the sleep is to avoid user's dead loop */
|
||||
msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (mPktOut->list_size()) {
|
||||
if (mpp_list_size(mPktOut)) {
|
||||
MppPacket pkt = NULL;
|
||||
MppPacketImpl *impl = NULL;
|
||||
RK_U32 offset;
|
||||
|
||||
mPktOut->del_at_head(&pkt, sizeof(pkt));
|
||||
mpp_list_del_at_head(mPktOut, &pkt, sizeof(pkt));
|
||||
mPacketGetCount++;
|
||||
notify(MPP_OUTPUT_DEQUEUE);
|
||||
|
||||
@@ -917,25 +925,26 @@ MPP_RET Mpp::get_packet_async(MppPacket *packet)
|
||||
offset = (RK_U32)((char *)impl->pos - (char *)impl->data);
|
||||
mpp_buffer_sync_ro_partial_begin(impl->buffer, offset, impl->length);
|
||||
} else {
|
||||
AutoMutex autoFrameLock(mFrmIn->mutex());
|
||||
|
||||
if (mFrmIn->list_size())
|
||||
mpp_mutex_cond_lock(&mFrmIn->cond_lock);
|
||||
if (mpp_list_size(mFrmIn))
|
||||
notify(MPP_INPUT_ENQUEUE);
|
||||
mpp_mutex_cond_unlock(&mFrmIn->cond_lock);
|
||||
|
||||
mpp_mutex_cond_unlock(&mPktOut->cond_lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
mpp_mutex_cond_unlock(&mPktOut->cond_lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET Mpp::poll(MppPortType type, MppPollType timeout)
|
||||
{
|
||||
MppTaskQueue port = NULL;
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
if (!mInitDone)
|
||||
return MPP_ERR_INIT;
|
||||
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MppTaskQueue port = NULL;
|
||||
|
||||
set_io_mode(MPP_IO_MODE_TASK);
|
||||
|
||||
switch (type) {
|
||||
@@ -957,12 +966,12 @@ MPP_RET Mpp::poll(MppPortType type, MppPollType timeout)
|
||||
|
||||
MPP_RET Mpp::dequeue(MppPortType type, MppTask *task)
|
||||
{
|
||||
if (!mInitDone)
|
||||
return MPP_ERR_INIT;
|
||||
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MppTaskQueue port = NULL;
|
||||
RK_U32 notify_flag = 0;
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
if (!mInitDone)
|
||||
return MPP_ERR_INIT;
|
||||
|
||||
set_io_mode(MPP_IO_MODE_TASK);
|
||||
|
||||
@@ -990,12 +999,12 @@ MPP_RET Mpp::dequeue(MppPortType type, MppTask *task)
|
||||
|
||||
MPP_RET Mpp::enqueue(MppPortType type, MppTask task)
|
||||
{
|
||||
if (!mInitDone)
|
||||
return MPP_ERR_INIT;
|
||||
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MppTaskQueue port = NULL;
|
||||
RK_U32 notify_flag = 0;
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
if (!mInitDone)
|
||||
return MPP_ERR_INIT;
|
||||
|
||||
set_io_mode(MPP_IO_MODE_TASK);
|
||||
|
||||
@@ -1116,10 +1125,11 @@ MPP_RET Mpp::reset()
|
||||
* To avoid this case happen we need to save it on reset beginning
|
||||
* then restore it on reset end.
|
||||
*/
|
||||
mPktIn->lock();
|
||||
while (mPktIn->list_size()) {
|
||||
mpp_mutex_cond_lock(&mPktIn->cond_lock);
|
||||
while (mpp_list_size(mPktIn)) {
|
||||
MppPacket pkt = NULL;
|
||||
mPktIn->del_at_head(&pkt, sizeof(pkt));
|
||||
|
||||
mpp_list_del_at_head(mPktIn, &pkt, sizeof(pkt));
|
||||
mPacketGetCount++;
|
||||
|
||||
RK_U32 flags = mpp_packet_get_flag(pkt);
|
||||
@@ -1132,14 +1142,14 @@ MPP_RET Mpp::reset()
|
||||
mpp_packet_deinit(&pkt);
|
||||
}
|
||||
}
|
||||
mPktIn->flush();
|
||||
mPktIn->unlock();
|
||||
mpp_list_flush(mPktIn);
|
||||
mpp_mutex_cond_unlock(&mPktIn->cond_lock);
|
||||
|
||||
mpp_dec_reset(mDec);
|
||||
|
||||
mFrmOut->lock();
|
||||
mFrmOut->flush();
|
||||
mFrmOut->unlock();
|
||||
mpp_mutex_cond_lock(&mFrmOut->cond_lock);
|
||||
mpp_list_flush(mFrmOut);
|
||||
mpp_mutex_cond_unlock(&mFrmOut->cond_lock);
|
||||
|
||||
mpp_port_awake(mUsrInPort);
|
||||
mpp_port_awake(mUsrOutPort);
|
||||
@@ -1341,9 +1351,10 @@ MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param)
|
||||
ret = mpp_dec_set_cfg_by_cmd(mDecCfg, cmd, param);
|
||||
} break;
|
||||
case MPP_DEC_GET_STREAM_COUNT: {
|
||||
AutoMutex autoLock(mPktIn->mutex());
|
||||
*((RK_S32 *)param) = mPktIn->list_size();
|
||||
mpp_mutex_cond_lock(&mPktIn->cond_lock);
|
||||
*((RK_S32 *)param) = mpp_list_size(mPktIn);
|
||||
ret = MPP_OK;
|
||||
mpp_mutex_cond_unlock(&mPktIn->cond_lock);
|
||||
} break;
|
||||
case MPP_DEC_GET_VPUMEM_USED_COUNT :
|
||||
case MPP_DEC_SET_OUTPUT_FORMAT :
|
||||
|
@@ -47,7 +47,7 @@ typedef enum MppOpsType_e {
|
||||
|
||||
/* dump data */
|
||||
typedef struct MppDumpImpl_t {
|
||||
Mutex *lock;
|
||||
MppMutex lock;
|
||||
RK_U32 log_version;
|
||||
RK_U32 debug;
|
||||
pid_t tid;
|
||||
@@ -303,7 +303,7 @@ MPP_RET mpp_dump_init(MppDump *info)
|
||||
mpp_env_get_u32("mpp_dump_height", &p->dump_height, 0);
|
||||
p->dump_size = p->dump_width * p->dump_height * 3 / 2;
|
||||
|
||||
p->lock = new Mutex();
|
||||
mpp_mutex_init(&p->lock);
|
||||
p->debug = mpp_debug;
|
||||
p->tid = syscall(SYS_gettid);
|
||||
p->log_version = 0;
|
||||
@@ -324,10 +324,7 @@ MPP_RET mpp_dump_deinit(MppDump *info)
|
||||
MPP_FCLOSE(p->fp_ops);
|
||||
MPP_FREE(p->fp_buf);
|
||||
|
||||
if (p->lock) {
|
||||
delete p->lock;
|
||||
p->lock = NULL;
|
||||
}
|
||||
mpp_mutex_destroy(&p->lock);
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
@@ -335,11 +332,12 @@ MPP_RET mpp_dump_deinit(MppDump *info)
|
||||
|
||||
MPP_RET mpp_ops_init(MppDump info, MppCtxType type, MppCodingType coding)
|
||||
{
|
||||
MppDumpImpl *p = (MppDumpImpl *)info;
|
||||
|
||||
if (NULL == info)
|
||||
return MPP_OK;
|
||||
|
||||
MppDumpImpl *p = (MppDumpImpl *)info;
|
||||
AutoMutex auto_lock(p->lock);
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
p->type = type;
|
||||
p->coding = coding;
|
||||
@@ -373,6 +371,8 @@ MPP_RET mpp_ops_init(MppDump info, MppCtxType type, MppCodingType coding)
|
||||
if (p->fp_ops)
|
||||
ops_log(p->fp_ops, "%d,%s,%d,%d\n", p->idx++, "init", type, coding);
|
||||
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
@@ -383,7 +383,8 @@ MPP_RET mpp_ops_dec_put_pkt(MppDump info, MppPacket pkt)
|
||||
return MPP_OK;
|
||||
|
||||
RK_U32 length = mpp_packet_get_length(pkt);
|
||||
AutoMutex auto_lock(p->lock);
|
||||
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
if (p->fp_in) {
|
||||
fwrite(mpp_packet_get_data(pkt), 1, length, p->fp_in);
|
||||
@@ -396,16 +397,19 @@ MPP_RET mpp_ops_dec_put_pkt(MppDump info, MppPacket pkt)
|
||||
p->pkt_offset += length;
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_ops_dec_get_frm(MppDump info, MppFrame frame)
|
||||
{
|
||||
MppDumpImpl *p = (MppDumpImpl *)info;
|
||||
|
||||
if (NULL == p || NULL == frame || NULL == p->fp_out)
|
||||
return MPP_OK;
|
||||
|
||||
AutoMutex auto_lock(p->lock);
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
MppBuffer buf = mpp_frame_get_buffer(frame);
|
||||
RK_S32 fd = (buf) ? mpp_buffer_get_fd(buf) : (-1);
|
||||
@@ -420,6 +424,7 @@ MPP_RET mpp_ops_dec_get_frm(MppDump info, MppFrame frame)
|
||||
|
||||
if (NULL == buf || fd < 0) {
|
||||
mpp_err("failed to dump frame\n");
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
@@ -432,6 +437,7 @@ MPP_RET mpp_ops_dec_get_frm(MppDump info, MppFrame frame)
|
||||
|
||||
mpp_log("yuv_info: [%d:%d] pts %lld", width, height, pts);
|
||||
}
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -439,10 +445,11 @@ MPP_RET mpp_ops_dec_get_frm(MppDump info, MppFrame frame)
|
||||
MPP_RET mpp_ops_enc_put_frm(MppDump info, MppFrame frame)
|
||||
{
|
||||
MppDumpImpl *p = (MppDumpImpl *)info;
|
||||
|
||||
if (NULL == p || NULL == frame || NULL == p->fp_in)
|
||||
return MPP_OK;
|
||||
|
||||
AutoMutex auto_lock(p->lock);
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
dump_frame(p->fp_in, frame, p->fp_buf, p->dump_width, p->dump_height);
|
||||
|
||||
@@ -454,36 +461,43 @@ MPP_RET mpp_ops_enc_put_frm(MppDump info, MppFrame frame)
|
||||
mpp_log("yuv_info: [%d:%d] pts %lld", width, height, pts);
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_ops_enc_get_pkt(MppDump info, MppPacket pkt)
|
||||
{
|
||||
MppDumpImpl *p = (MppDumpImpl *)info;
|
||||
|
||||
if (NULL == p || NULL == pkt)
|
||||
return MPP_OK;
|
||||
|
||||
RK_U32 length = mpp_packet_get_length(pkt);
|
||||
AutoMutex auto_lock(p->lock);
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
if (p->fp_out) {
|
||||
fwrite(mpp_packet_get_data(pkt), 1, length, p->fp_out);
|
||||
fflush(p->fp_out);
|
||||
}
|
||||
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_ops_ctrl(MppDump info, MpiCmd cmd)
|
||||
{
|
||||
MppDumpImpl *p = (MppDumpImpl *)info;
|
||||
|
||||
if (NULL == p)
|
||||
return MPP_OK;
|
||||
|
||||
AutoMutex auto_lock(p->lock);
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
if (p->fp_ops)
|
||||
ops_log(p->fp_ops, "%d,%s,%d\n", p->idx, "ctrl", cmd);
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -491,13 +505,15 @@ MPP_RET mpp_ops_ctrl(MppDump info, MpiCmd cmd)
|
||||
MPP_RET mpp_ops_reset(MppDump info)
|
||||
{
|
||||
MppDumpImpl *p = (MppDumpImpl *)info;
|
||||
|
||||
if (NULL == p)
|
||||
return MPP_OK;
|
||||
|
||||
AutoMutex auto_lock(p->lock);
|
||||
mpp_mutex_lock(&p->lock);
|
||||
|
||||
if (p->fp_ops)
|
||||
ops_log(p->fp_ops, "%d,%s\n", p->idx, "rst");
|
||||
mpp_mutex_unlock(&p->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
@@ -113,7 +113,7 @@ typedef struct MppDecVprocCtxImpl_t {
|
||||
|
||||
static void dec_vproc_put_frame(Mpp *mpp, MppFrame frame, MppBuffer buf, RK_S64 pts, RK_U32 err)
|
||||
{
|
||||
mpp_list *list = mpp->mFrmOut;
|
||||
MppList *list = mpp->mFrmOut;
|
||||
MppFrame out = NULL;
|
||||
MppFrameImpl *impl = NULL;
|
||||
|
||||
@@ -127,16 +127,16 @@ static void dec_vproc_put_frame(Mpp *mpp, MppFrame frame, MppBuffer buf, RK_S64
|
||||
|
||||
impl->errinfo |= err;
|
||||
|
||||
list->lock();
|
||||
list->add_at_tail(&out, sizeof(out));
|
||||
mpp_mutex_cond_lock(&list->cond_lock);
|
||||
mpp_list_add_at_tail(list, &out, sizeof(out));
|
||||
|
||||
mpp->mFramePutCount++;
|
||||
vproc_dbg_out("Output frame[%d]:poc %d, pts %lld, err 0x%x, dis %x, buf ptr %p\n",
|
||||
mpp->mFramePutCount, mpp_frame_get_poc(out), mpp_frame_get_pts(out),
|
||||
mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame),
|
||||
mpp_buffer_get_ptr(impl->buffer));
|
||||
list->signal();
|
||||
list->unlock();
|
||||
mpp_mutex_cond_signal(&list->cond_lock);
|
||||
mpp_mutex_cond_unlock(&list->cond_lock);
|
||||
|
||||
if (mpp->mDec)
|
||||
mpp_dec_callback(mpp->mDec, MPP_DEC_EVENT_ON_FRM_READY, out);
|
||||
@@ -844,17 +844,17 @@ static void *dec_vproc_thread(void *data)
|
||||
while (1) {
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
{
|
||||
AutoMutex autolock(thd->mutex());
|
||||
|
||||
if (MPP_THREAD_RUNNING != thd->get_status())
|
||||
mpp_thread_lock(thd, THREAD_WORK);
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(thd, THREAD_WORK)) {
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx->task_wait.val && !ctx->reset) {
|
||||
vproc_dbg_status("vproc thread wait %d", ctx->task_wait.val);
|
||||
thd->wait();
|
||||
}
|
||||
mpp_thread_wait(thd, THREAD_WORK);
|
||||
}
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
|
||||
if (!ctx->task_status.task_rdy) {
|
||||
if (hal_task_get_hnd(tasks, TASK_PROCESSING, &task)) {
|
||||
@@ -864,9 +864,9 @@ static void *dec_vproc_thread(void *data)
|
||||
|
||||
dec_vproc_clr_prev(ctx);
|
||||
|
||||
thd->lock(THREAD_CONTROL);
|
||||
mpp_thread_lock(thd, THREAD_CONTROL);
|
||||
ctx->reset = 0;
|
||||
thd->unlock(THREAD_CONTROL);
|
||||
mpp_thread_unlock(thd, THREAD_CONTROL);
|
||||
sem_post(&ctx->reset_sem);
|
||||
ctx->task_wait.val = 0;
|
||||
|
||||
@@ -991,12 +991,12 @@ MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, MppDecVprocCfg *cfg)
|
||||
p->pre_ff_mode = IEP2_FF_MODE_UND;
|
||||
p->mpp = (Mpp *)cfg->mpp;
|
||||
p->slots = ((MppDecImpl *)p->mpp->mDec)->frame_slots;
|
||||
p->thd = new MppThread(dec_vproc_thread, p, "mpp_dec_vproc");
|
||||
p->thd = mpp_thread_create(dec_vproc_thread, p, "mpp_dec_vproc");
|
||||
sem_init(&p->reset_sem, 0, 0);
|
||||
ret = hal_task_group_init(&p->task_group, TASK_BUTT, 4, sizeof(HalDecVprocTask));
|
||||
if (ret) {
|
||||
mpp_err_f("create task group failed\n");
|
||||
delete p->thd;
|
||||
mpp_thread_destroy(p->thd);
|
||||
MPP_FREE(p);
|
||||
return MPP_ERR_MALLOC;
|
||||
}
|
||||
@@ -1005,7 +1005,7 @@ MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, MppDecVprocCfg *cfg)
|
||||
p->com_ctx = get_iep_ctx();
|
||||
if (!p->com_ctx) {
|
||||
mpp_err("failed to require context\n");
|
||||
delete p->thd;
|
||||
mpp_thread_destroy(p->thd);
|
||||
|
||||
if (p->task_group) {
|
||||
hal_task_group_deinit(p->task_group);
|
||||
@@ -1032,7 +1032,7 @@ MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, MppDecVprocCfg *cfg)
|
||||
if (!p->thd || ret) {
|
||||
mpp_err("failed to create context\n");
|
||||
if (p->thd) {
|
||||
delete p->thd;
|
||||
mpp_thread_destroy(p->thd);
|
||||
p->thd = NULL;
|
||||
}
|
||||
|
||||
@@ -1106,8 +1106,7 @@ MPP_RET dec_vproc_deinit(MppDecVprocCtx ctx)
|
||||
|
||||
MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
|
||||
if (p->thd) {
|
||||
p->thd->stop();
|
||||
delete p->thd;
|
||||
mpp_thread_destroy(p->thd);
|
||||
p->thd = NULL;
|
||||
}
|
||||
|
||||
@@ -1142,7 +1141,7 @@ MPP_RET dec_vproc_start(MppDecVprocCtx ctx)
|
||||
MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
|
||||
|
||||
if (p->thd)
|
||||
p->thd->start();
|
||||
mpp_thread_start(p->thd);
|
||||
else
|
||||
mpp_err("failed to start dec vproc thread\n");
|
||||
|
||||
@@ -1161,7 +1160,7 @@ MPP_RET dec_vproc_stop(MppDecVprocCtx ctx)
|
||||
MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
|
||||
|
||||
if (p->thd)
|
||||
p->thd->stop();
|
||||
mpp_thread_stop(p->thd);
|
||||
else
|
||||
mpp_err("failed to stop dec vproc thread\n");
|
||||
|
||||
@@ -1179,9 +1178,9 @@ MPP_RET dec_vproc_signal(MppDecVprocCtx ctx)
|
||||
|
||||
MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
|
||||
if (p->thd) {
|
||||
p->thd->lock();
|
||||
p->thd->signal();
|
||||
p->thd->unlock();
|
||||
mpp_thread_lock(p->thd, THREAD_WORK);
|
||||
mpp_thread_signal(p->thd, THREAD_WORK);
|
||||
mpp_thread_unlock(p->thd, THREAD_WORK);
|
||||
}
|
||||
|
||||
vproc_dbg_func("out\n");
|
||||
@@ -1202,12 +1201,12 @@ MPP_RET dec_vproc_reset(MppDecVprocCtx ctx)
|
||||
|
||||
vproc_dbg_reset("reset contorl start\n");
|
||||
// wait reset finished
|
||||
thd->lock();
|
||||
thd->lock(THREAD_CONTROL);
|
||||
mpp_thread_lock(thd, THREAD_WORK);
|
||||
mpp_thread_lock(thd, THREAD_CONTROL);
|
||||
p->reset = 1;
|
||||
thd->signal();
|
||||
thd->unlock(THREAD_CONTROL);
|
||||
thd->unlock();
|
||||
mpp_thread_signal(thd, THREAD_WORK);
|
||||
mpp_thread_unlock(thd, THREAD_CONTROL);
|
||||
mpp_thread_unlock(thd, THREAD_WORK);
|
||||
|
||||
vproc_dbg_reset("reset contorl wait\n");
|
||||
sem_wait(&p->reset_sem);
|
||||
|
@@ -36,14 +36,14 @@ add_library(osal OBJECT
|
||||
mpp_callback.cpp
|
||||
mpp_eventfd.cpp
|
||||
mpp_dmabuf.cpp
|
||||
mpp_thread.cpp
|
||||
mpp_thread.c
|
||||
mpp_compat.cpp
|
||||
mpp_common.cpp
|
||||
mpp_queue.cpp
|
||||
mpp_queue.c
|
||||
mpp_trace.c
|
||||
mpp_lock.cpp
|
||||
mpp_time.cpp
|
||||
mpp_list.cpp
|
||||
mpp_time.c
|
||||
mpp_list.c
|
||||
mpp_mem.c
|
||||
mpp_env.cpp
|
||||
mpp_log.cpp
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "mpp_device_debug.h"
|
||||
#include "mpp_service_impl.h"
|
||||
#include "mpp_server.h"
|
||||
#include "mpp_thread.h"
|
||||
|
||||
#define MAX_BATCH_TASK 8
|
||||
#define MAX_SESSION_TASK 4
|
||||
@@ -88,7 +89,7 @@ struct MppDevTask_t {
|
||||
};
|
||||
|
||||
struct MppDevBatTask_t {
|
||||
MppMutexCond *cond;
|
||||
MppMutexCond cond;
|
||||
|
||||
/* link to server */
|
||||
struct list_head link_server;
|
||||
@@ -113,7 +114,7 @@ struct MppDevBatTask_t {
|
||||
};
|
||||
|
||||
struct MppDevSession_t {
|
||||
MppMutexCond *cond;
|
||||
MppMutexCond cond_lock;
|
||||
|
||||
/* hash table to server */
|
||||
struct list_head list_server;
|
||||
@@ -134,7 +135,7 @@ struct MppDevSession_t {
|
||||
};
|
||||
|
||||
struct MppDevBatServ_t {
|
||||
Mutex *lock;
|
||||
MppMutex lock;
|
||||
|
||||
RK_S32 server_fd;
|
||||
RK_U32 batch_id;
|
||||
@@ -239,7 +240,7 @@ void batch_send(MppDevBatServ *server, MppDevBatTask *batch)
|
||||
void process_task(void *p)
|
||||
{
|
||||
MppDevBatServ *server = (MppDevBatServ *)p;
|
||||
Mutex *lock = server->lock;
|
||||
MppMutex *lock = &server->lock;
|
||||
RK_S32 ret = MPP_OK;
|
||||
MppDevTask *task;
|
||||
MppDevBatTask *batch;
|
||||
@@ -284,10 +285,10 @@ void process_task(void *p)
|
||||
|
||||
mpp_serv_dbg_flow("batch %d:%d session %d ready and remove\n",
|
||||
batch->batch_id, task->batch_slot_id, session->client);
|
||||
session->cond->lock();
|
||||
mpp_mutex_cond_lock(&session->cond_lock);
|
||||
session->task_done++;
|
||||
session->cond->signal();
|
||||
session->cond->unlock();
|
||||
mpp_mutex_cond_signal(&session->cond_lock);
|
||||
mpp_mutex_cond_unlock(&session->cond_lock);
|
||||
if (session->ctx && session->ctx->dev_cb)
|
||||
mpp_callback(session->ctx->dev_cb, NULL);
|
||||
|
||||
@@ -320,13 +321,13 @@ void process_task(void *p)
|
||||
} while (1);
|
||||
|
||||
/* 2. get prending task to fill */
|
||||
lock->lock();
|
||||
mpp_mutex_lock(lock);
|
||||
pending = server->pending_count;
|
||||
if (!pending && !server->batch_run && !server->session_count) {
|
||||
mpp_timer_set_enable(server->timer, 0);
|
||||
mpp_serv_dbg_flow("stop timer\n");
|
||||
}
|
||||
lock->unlock();
|
||||
mpp_mutex_unlock(lock);
|
||||
|
||||
mpp_serv_dbg_flow("pending %d running %d free %d max %d process start\n",
|
||||
pending, server->batch_run, server->batch_free, server->batch_max_count);
|
||||
@@ -379,11 +380,11 @@ try_proc_pending_task:
|
||||
mpp_assert(pending);
|
||||
|
||||
task = NULL;
|
||||
lock->lock();
|
||||
mpp_mutex_lock(lock);
|
||||
task = list_first_entry_or_null(&server->pending_task, MppDevTask, link_server);
|
||||
list_del_init(&task->link_server);
|
||||
server->pending_count--;
|
||||
lock->unlock();
|
||||
mpp_mutex_unlock(lock);
|
||||
pending--;
|
||||
|
||||
/* first task and setup new batch id */
|
||||
@@ -473,7 +474,7 @@ MPP_RET send_task(MppDevMppService *ctx)
|
||||
MppDevBatServ *server = session->server;
|
||||
|
||||
/* get free task from session and add to run list */
|
||||
session->cond->lock();
|
||||
mpp_mutex_cond_lock(&session->cond_lock);
|
||||
/* get a free task and setup */
|
||||
task = list_first_entry_or_null(&session->list_done, MppDevTask, link_session);
|
||||
mpp_assert(task);
|
||||
@@ -485,9 +486,9 @@ MPP_RET send_task(MppDevMppService *ctx)
|
||||
list_add_tail(&task->link_session, &session->list_wait);
|
||||
|
||||
session->task_wait++;
|
||||
session->cond->unlock();
|
||||
mpp_mutex_cond_unlock(&session->cond_lock);
|
||||
|
||||
server->lock->lock();
|
||||
mpp_mutex_lock(&server->lock);
|
||||
task->task_id = server->task_id++;
|
||||
list_del_init(&task->link_server);
|
||||
list_add_tail(&task->link_server, &server->pending_task);
|
||||
@@ -496,7 +497,7 @@ MPP_RET send_task(MppDevMppService *ctx)
|
||||
session->client, task->slot_idx, server->pending_count);
|
||||
|
||||
mpp_timer_set_enable(server->timer, 1);
|
||||
server->lock->unlock();
|
||||
mpp_mutex_unlock(&server->lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -516,15 +517,15 @@ MPP_RET wait_task(MppDevMppService *ctx, RK_S64 timeout)
|
||||
task = list_first_entry_or_null(&session->list_wait, MppDevTask, link_session);
|
||||
mpp_assert(task);
|
||||
|
||||
session->cond->lock();
|
||||
mpp_mutex_cond_lock(&session->cond_lock);
|
||||
if (session->task_wait != session->task_done) {
|
||||
mpp_serv_dbg_flow("session %d wait %d start %d:%d\n", session->client,
|
||||
task->task_id, session->task_wait, session->task_done);
|
||||
session->cond->wait();
|
||||
mpp_mutex_cond_wait(&session->cond_lock);
|
||||
}
|
||||
mpp_serv_dbg_flow("session %d wait %d done %d:%d\n", session->client,
|
||||
task->task_id, session->task_wait, session->task_done);
|
||||
session->cond->unlock();
|
||||
mpp_mutex_cond_unlock(&session->cond_lock);
|
||||
|
||||
list_del_init(&task->link_session);
|
||||
list_add_tail(&task->link_session, &session->list_done);
|
||||
@@ -534,7 +535,7 @@ MPP_RET wait_task(MppDevMppService *ctx, RK_S64 timeout)
|
||||
return (MPP_RET)ret;
|
||||
}
|
||||
|
||||
class MppDevServer : Mutex
|
||||
class MppDevServer
|
||||
{
|
||||
private:
|
||||
// avoid any unwanted function
|
||||
@@ -565,6 +566,7 @@ public:
|
||||
return &inst;
|
||||
}
|
||||
|
||||
MppMutex lock;
|
||||
MppDevBatServ *bat_server_get(MppClientType client_type);
|
||||
MPP_RET bat_server_put(MppClientType client_type);
|
||||
|
||||
@@ -628,6 +630,7 @@ MppDevServer::MppDevServer() :
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
mpp_mutex_init(&lock);
|
||||
|
||||
memset(mBatServer, 0, sizeof(mBatServer));
|
||||
}
|
||||
@@ -639,6 +642,8 @@ MppDevServer::~MppDevServer()
|
||||
for (i = 0; i < VPU_CLIENT_BUTT; i++)
|
||||
bat_server_put((MppClientType)i);
|
||||
|
||||
mpp_mutex_destroy(&lock);
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
@@ -661,15 +666,18 @@ MppDevBatServ *MppDevServer::bat_server_get(MppClientType client_type)
|
||||
{
|
||||
MppDevBatServ *server = NULL;
|
||||
|
||||
AutoMutex auto_lock(this);
|
||||
mpp_mutex_lock(&lock);
|
||||
|
||||
server = mBatServer[client_type];
|
||||
if (server)
|
||||
if (server) {
|
||||
mpp_mutex_unlock(&lock);
|
||||
return server;
|
||||
}
|
||||
|
||||
server = mpp_calloc(MppDevBatServ, 1);
|
||||
if (NULL == server) {
|
||||
mpp_err("mpp server failed to get bat server\n");
|
||||
mpp_mutex_unlock(&lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -690,11 +698,7 @@ MppDevBatServ *MppDevServer::bat_server_get(MppClientType client_type)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
server->lock = new Mutex();
|
||||
if (NULL == server->lock) {
|
||||
mpp_err("mpp server get bat server failed to create mutex\n");
|
||||
goto failed;
|
||||
}
|
||||
mpp_mutex_init(&server->lock);
|
||||
|
||||
mpp_timer_set_callback(server->timer, mpp_server_thread, server);
|
||||
/* 10ms */
|
||||
@@ -709,6 +713,7 @@ MppDevBatServ *MppDevServer::bat_server_get(MppClientType client_type)
|
||||
server->max_task_in_batch = mMaxTaskInBatch;
|
||||
|
||||
mBatServer[client_type] = server;
|
||||
mpp_mutex_unlock(&lock);
|
||||
return server;
|
||||
|
||||
failed:
|
||||
@@ -722,12 +727,10 @@ failed:
|
||||
close(server->server_fd);
|
||||
server->server_fd = -1;
|
||||
}
|
||||
if (server->lock) {
|
||||
delete server->lock;
|
||||
server->lock = NULL;
|
||||
}
|
||||
mpp_mutex_destroy(&server->lock);
|
||||
}
|
||||
MPP_FREE(server);
|
||||
mpp_mutex_unlock(&lock);
|
||||
return server;
|
||||
}
|
||||
|
||||
@@ -735,10 +738,13 @@ MPP_RET MppDevServer::bat_server_put(MppClientType client_type)
|
||||
{
|
||||
MppDevBatTask *batch, *n;
|
||||
MppDevBatServ *server = NULL;
|
||||
AutoMutex auto_lock(this);
|
||||
|
||||
if (NULL == mBatServer[client_type])
|
||||
mpp_mutex_lock(&lock);
|
||||
|
||||
if (NULL == mBatServer[client_type]) {
|
||||
mpp_mutex_unlock(&lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
server = mBatServer[client_type];
|
||||
mBatServer[client_type] = NULL;
|
||||
@@ -765,11 +771,10 @@ MPP_RET MppDevServer::bat_server_put(MppClientType client_type)
|
||||
close(server->server_fd);
|
||||
server->server_fd = -1;
|
||||
}
|
||||
if (server->lock) {
|
||||
delete server->lock;
|
||||
server->lock = NULL;
|
||||
}
|
||||
mpp_mutex_destroy(&server->lock);
|
||||
MPP_FREE(server);
|
||||
mpp_mutex_unlock(&lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
@@ -796,9 +801,11 @@ MPP_RET MppDevServer::attach(MppDevMppService *ctx)
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
AutoMutex auto_lock(server->lock);
|
||||
if (ctx->serv_ctx)
|
||||
mpp_mutex_lock(&lock);
|
||||
if (ctx->serv_ctx) {
|
||||
mpp_mutex_unlock(&lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MppDevSession *session = (MppDevSession *)mpp_mem_pool_get(mSessionPool);
|
||||
INIT_LIST_HEAD(&session->list_server);
|
||||
@@ -808,7 +815,7 @@ MPP_RET MppDevServer::attach(MppDevMppService *ctx)
|
||||
session->ctx = ctx;
|
||||
session->server = server;
|
||||
session->client = ctx->client;
|
||||
session->cond = new MppMutexCond();
|
||||
mpp_mutex_cond_init(&session->cond_lock);
|
||||
session->task_wait = 0;
|
||||
session->task_done = 0;
|
||||
|
||||
@@ -839,6 +846,7 @@ MPP_RET MppDevServer::attach(MppDevMppService *ctx)
|
||||
|
||||
server->batch_max_count++;
|
||||
server->session_count++;
|
||||
mpp_mutex_unlock(&lock);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -857,9 +865,11 @@ MPP_RET MppDevServer::detach(MppDevMppService *ctx)
|
||||
|
||||
mpp_assert(server);
|
||||
|
||||
AutoMutex auto_lock(server->lock);
|
||||
if (NULL == ctx->serv_ctx)
|
||||
mpp_mutex_lock(&lock);
|
||||
if (NULL == ctx->serv_ctx) {
|
||||
mpp_mutex_unlock(&lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
ctx->server = ctx->client;
|
||||
ctx->serv_ctx = NULL;
|
||||
@@ -873,15 +883,13 @@ MPP_RET MppDevServer::detach(MppDevMppService *ctx)
|
||||
|
||||
list_del_init(&session->list_server);
|
||||
|
||||
if (session->cond) {
|
||||
delete session->cond;
|
||||
session->cond = NULL;
|
||||
}
|
||||
mpp_mutex_cond_destroy(&session->cond_lock);
|
||||
|
||||
mpp_mem_pool_put(mSessionPool, session);
|
||||
server->batch_max_count++;
|
||||
server->session_count++;
|
||||
|
||||
mpp_mutex_unlock(&lock);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
|
@@ -1,17 +1,6 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright (c) 2015 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __MPP_LIST_H__
|
||||
@@ -23,71 +12,65 @@
|
||||
#include "mpp_thread.h"
|
||||
|
||||
/*
|
||||
* two list structures are defined, one for C++, the other for C
|
||||
* two list structures are defined here:
|
||||
* 1. MppList : list with key
|
||||
* 2. struct list_head : typical list head
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// desctructor of list node
|
||||
typedef void *(*node_destructor)(void *);
|
||||
|
||||
struct mpp_list_node;
|
||||
|
||||
class mpp_list : public MppMutexCond
|
||||
{
|
||||
public:
|
||||
mpp_list(node_destructor func = NULL);
|
||||
~mpp_list();
|
||||
|
||||
// for FIFO or FILO implement
|
||||
// adding functions support simple structure like C struct or C++ class pointer,
|
||||
// do not support C++ object
|
||||
RK_S32 add_at_head(void *data, RK_S32 size);
|
||||
RK_S32 add_at_tail(void *data, RK_S32 size);
|
||||
// deleting function will copy the stored data to input pointer with size as size
|
||||
// if NULL is passed to deleting functions, the node will be delete directly
|
||||
RK_S32 del_at_head(void *data, RK_S32 size);
|
||||
RK_S32 del_at_tail(void *data, RK_S32 size);
|
||||
|
||||
// direct fifo operation
|
||||
RK_S32 fifo_wr(void *data, RK_S32 size);
|
||||
RK_S32 fifo_rd(void *data, RK_S32 *size);
|
||||
|
||||
// for status check
|
||||
RK_S32 list_is_empty();
|
||||
RK_S32 list_size();
|
||||
|
||||
// for vector implement - not implemented yet
|
||||
// adding function will return a key
|
||||
RK_S32 add_by_key(void *data, RK_S32 size, RK_U32 *key);
|
||||
RK_S32 del_by_key(void *data, RK_S32 size, RK_U32 key);
|
||||
RK_S32 show_by_key(void *data, RK_U32 key);
|
||||
|
||||
RK_S32 flush();
|
||||
|
||||
// for list wait
|
||||
MPP_RET wait_lt(RK_S64 timeout, RK_S32 val);
|
||||
MPP_RET wait_le(RK_S64 timeout, RK_S32 val);
|
||||
MPP_RET wait_gt(RK_S64 timeout, RK_S32 val);
|
||||
MPP_RET wait_ge(RK_S64 timeout, RK_S32 val);
|
||||
|
||||
private:
|
||||
node_destructor destroy;
|
||||
struct mpp_list_node *head;
|
||||
RK_S32 count;
|
||||
static RK_U32 keys;
|
||||
static RK_U32 get_key();
|
||||
|
||||
mpp_list(const mpp_list &);
|
||||
mpp_list &operator=(const mpp_list &);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct MppListNode_t MppListNode;
|
||||
// desctructor of list node
|
||||
typedef void *(*node_destructor)(void *);
|
||||
|
||||
struct MppListNode_t {
|
||||
MppListNode *prev;
|
||||
MppListNode *next;
|
||||
rk_u32 key;
|
||||
rk_s32 size;
|
||||
};
|
||||
|
||||
typedef struct MppList_t {
|
||||
MppListNode *head;
|
||||
int count;
|
||||
node_destructor destroy;
|
||||
MppMutexCond cond_lock;
|
||||
rk_u32 keys;
|
||||
} MppList;
|
||||
|
||||
int mpp_list_add_at_head(MppList *list, void *data, int size);
|
||||
int mpp_list_add_at_tail(MppList *list, void *data, int size);
|
||||
int mpp_list_del_at_head(MppList *list, void *data, int size);
|
||||
int mpp_list_del_at_tail(MppList *list, void *data, int size);
|
||||
|
||||
rk_s32 mpp_list_fifo_wr(MppList *list, void *data, rk_s32 size);
|
||||
rk_s32 mpp_list_fifo_rd(MppList *list, void *data, rk_s32 *size);
|
||||
|
||||
int mpp_list_is_empty(MppList *list);
|
||||
int mpp_list_size(MppList *list);
|
||||
|
||||
rk_s32 mpp_list_add_by_key(MppList *list, void *data, rk_s32 size, rk_u32 *key);
|
||||
rk_s32 mpp_list_del_by_key(MppList *list, void *data, rk_s32 size, rk_u32 key);
|
||||
rk_s32 mpp_list_show_by_key(MppList *list, void *data, rk_u32 key);
|
||||
|
||||
void mpp_list_flush(MppList *list);
|
||||
|
||||
MPP_RET mpp_list_wait(MppList* list);
|
||||
MPP_RET mpp_list_wait_timed(MppList *list, rk_s64 timeout);
|
||||
MPP_RET mpp_list_wait_lt(MppList *list, rk_s64 timeout, rk_s32 val);
|
||||
MPP_RET mpp_list_wait_le(MppList *list, rk_s64 timeout, rk_s32 val);
|
||||
MPP_RET mpp_list_wait_gt(MppList *list, rk_s64 timeout, rk_s32 val);
|
||||
MPP_RET mpp_list_wait_ge(MppList *list, rk_s64 timeout, rk_s32 val);
|
||||
|
||||
void mpp_list_signal(MppList *list);
|
||||
rk_u32 mpp_list_get_key(MppList *list);
|
||||
|
||||
MppList *mpp_list_create(node_destructor func);
|
||||
void mpp_list_destroy(MppList *list);
|
||||
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
@@ -203,9 +186,9 @@ static __inline int list_empty(struct list_head *head)
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
typedef RK_S32 (*list_cmp_func_t)(void *, const struct list_head *, const struct list_head *);
|
||||
typedef rk_s32 (*ListCmpFunc)(void *, const struct list_head *, const struct list_head *);
|
||||
|
||||
void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);
|
||||
void list_sort(void *priv, struct list_head *head, ListCmpFunc cmp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -1,17 +1,6 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2017 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright (c) 2017 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __MPP_QUEUE_H__
|
||||
@@ -19,17 +8,10 @@
|
||||
|
||||
#include "mpp_list.h"
|
||||
|
||||
class MppQueue: public mpp_list
|
||||
{
|
||||
private:
|
||||
sem_t mQueuePending;
|
||||
int mFlushFlag;
|
||||
public:
|
||||
MppQueue(node_destructor func);
|
||||
~MppQueue();
|
||||
RK_S32 push(void *data, RK_S32 size);
|
||||
RK_S32 pull(void *data, RK_S32 size);
|
||||
RK_S32 flush();
|
||||
};
|
||||
typedef struct MppQueue_t {
|
||||
MppList* list;
|
||||
sem_t queue_pending;
|
||||
int flush_flag;
|
||||
} MppQueue;
|
||||
|
||||
#endif
|
||||
|
@@ -1,62 +1,34 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File : mpp_thread.h
|
||||
* Description : thread library for different OS
|
||||
* Author : herman.chen@rock-chips.com
|
||||
* Date : 9:47 2015/7/27
|
||||
* Copyright (c) 2015 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __MPP_THREAD_H__
|
||||
#define __MPP_THREAD_H__
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32CE__)
|
||||
|
||||
/*
|
||||
* NOTE: POSIX Threads for Win32
|
||||
* Downloaded from http://www.sourceware.org/pthreads-win32/
|
||||
*/
|
||||
#include "semaphore.h"
|
||||
#include "pthread.h"
|
||||
#pragma comment(lib, "pthreadVC2.lib")
|
||||
|
||||
/*
|
||||
* add pthread_setname_np for windows
|
||||
*/
|
||||
int pthread_setname_np(pthread_t thread, const char *name);
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rk_type.h"
|
||||
|
||||
#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
||||
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define THREAD_NAME_LEN 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *(*MppThreadFunc)(void *);
|
||||
|
||||
typedef enum {
|
||||
typedef enum MppThreadStatus_e {
|
||||
MPP_THREAD_UNINITED,
|
||||
MPP_THREAD_READY,
|
||||
MPP_THREAD_RUNNING,
|
||||
@@ -64,246 +36,86 @@ typedef enum {
|
||||
MPP_THREAD_STOPPING,
|
||||
} MppThreadStatus;
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef struct MppMutex_t {
|
||||
pthread_mutex_t m_lock;
|
||||
} MppMutex;
|
||||
|
||||
#include "mpp_debug.h"
|
||||
typedef struct MppCond_t {
|
||||
pthread_cond_t m_cond;
|
||||
} MppCond;
|
||||
|
||||
class Mutex;
|
||||
class Condition;
|
||||
typedef struct MppMutexCond_t {
|
||||
MppMutex m_lock;
|
||||
MppCond m_cond;
|
||||
} MppMutexCond;
|
||||
|
||||
/*
|
||||
* for shorter type name and function name
|
||||
*/
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
int trylock();
|
||||
|
||||
class Autolock
|
||||
{
|
||||
public:
|
||||
inline Autolock(Mutex* mutex, RK_U32 enable = 1) :
|
||||
mEnabled(enable),
|
||||
mLock(mutex) {
|
||||
if (mLock && mEnabled)
|
||||
mLock->lock();
|
||||
}
|
||||
inline ~Autolock() {
|
||||
if (mLock && mEnabled)
|
||||
mLock->unlock();
|
||||
}
|
||||
private:
|
||||
RK_S32 mEnabled;
|
||||
Mutex *mLock;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class Condition;
|
||||
|
||||
pthread_mutex_t mMutex;
|
||||
|
||||
Mutex(const Mutex &);
|
||||
Mutex &operator = (const Mutex&);
|
||||
};
|
||||
|
||||
inline Mutex::Mutex()
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mMutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
inline Mutex::~Mutex()
|
||||
{
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
inline void Mutex::lock()
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
}
|
||||
inline void Mutex::unlock()
|
||||
{
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
inline int Mutex::trylock()
|
||||
{
|
||||
return pthread_mutex_trylock(&mMutex);
|
||||
}
|
||||
|
||||
typedef Mutex::Autolock AutoMutex;
|
||||
|
||||
|
||||
/*
|
||||
* for shorter type name and function name
|
||||
*/
|
||||
class Condition
|
||||
{
|
||||
public:
|
||||
Condition();
|
||||
Condition(int type);
|
||||
~Condition();
|
||||
RK_S32 wait(Mutex& mutex);
|
||||
RK_S32 wait(Mutex* mutex);
|
||||
RK_S32 timedwait(Mutex& mutex, RK_S64 timeout);
|
||||
RK_S32 timedwait(Mutex* mutex, RK_S64 timeout);
|
||||
RK_S32 signal();
|
||||
RK_S32 broadcast();
|
||||
|
||||
private:
|
||||
pthread_cond_t mCond;
|
||||
};
|
||||
|
||||
inline Condition::Condition()
|
||||
{
|
||||
pthread_cond_init(&mCond, NULL);
|
||||
}
|
||||
inline Condition::~Condition()
|
||||
{
|
||||
pthread_cond_destroy(&mCond);
|
||||
}
|
||||
inline RK_S32 Condition::wait(Mutex& mutex)
|
||||
{
|
||||
return pthread_cond_wait(&mCond, &mutex.mMutex);
|
||||
}
|
||||
inline RK_S32 Condition::wait(Mutex* mutex)
|
||||
{
|
||||
return pthread_cond_wait(&mCond, &mutex->mMutex);
|
||||
}
|
||||
inline RK_S32 Condition::timedwait(Mutex& mutex, RK_S64 timeout)
|
||||
{
|
||||
return timedwait(&mutex, timeout);
|
||||
}
|
||||
inline RK_S32 Condition::timedwait(Mutex* mutex, RK_S64 timeout)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME_COARSE, &ts);
|
||||
|
||||
ts.tv_sec += timeout / 1000;
|
||||
ts.tv_nsec += (timeout % 1000) * 1000000;
|
||||
/* Prevent the out of range at nanoseconds field */
|
||||
ts.tv_sec += ts.tv_nsec / 1000000000;
|
||||
ts.tv_nsec %= 1000000000;
|
||||
|
||||
return pthread_cond_timedwait(&mCond, &mutex->mMutex, &ts);
|
||||
}
|
||||
inline RK_S32 Condition::signal()
|
||||
{
|
||||
return pthread_cond_signal(&mCond);
|
||||
}
|
||||
inline RK_S32 Condition::broadcast()
|
||||
{
|
||||
return pthread_cond_broadcast(&mCond);
|
||||
}
|
||||
|
||||
class MppMutexCond
|
||||
{
|
||||
public:
|
||||
MppMutexCond() {};
|
||||
~MppMutexCond() {};
|
||||
|
||||
void lock() { mLock.lock(); }
|
||||
void unlock() { mLock.unlock(); }
|
||||
int trylock() { return mLock.trylock(); }
|
||||
void wait() { mCondition.wait(mLock); }
|
||||
RK_S32 wait(RK_S64 timeout) { return mCondition.timedwait(mLock, timeout); }
|
||||
void signal() { mCondition.signal(); }
|
||||
void broadcast() { mCondition.broadcast(); }
|
||||
Mutex *mutex() { return &mLock; }
|
||||
|
||||
private:
|
||||
Mutex mLock;
|
||||
Condition mCondition;
|
||||
};
|
||||
|
||||
// Thread lock / signal is distinguished by its source
|
||||
typedef enum MppThreadSignal_e {
|
||||
THREAD_WORK, // for working loop
|
||||
THREAD_INPUT, // for thread input
|
||||
THREAD_OUTPUT, // for thread output
|
||||
THREAD_CONTROL, // for thread async control (reset)
|
||||
typedef enum MppThreadSignalId_e {
|
||||
THREAD_WORK,
|
||||
THREAD_INPUT,
|
||||
THREAD_OUTPUT,
|
||||
THREAD_CONTROL,
|
||||
THREAD_SIGNAL_BUTT,
|
||||
} MppThreadSignal;
|
||||
} MppThreadSignalId;
|
||||
|
||||
#define THREAD_NORMAL 0
|
||||
#define THRE 0
|
||||
typedef struct MppThread_t {
|
||||
pthread_t thd;
|
||||
MppMutexCond mutex_cond[THREAD_SIGNAL_BUTT];
|
||||
MppThreadStatus thd_status[THREAD_SIGNAL_BUTT];
|
||||
MppThreadFunc func;
|
||||
char name[THREAD_NAME_LEN];
|
||||
void *m_ctx;
|
||||
} MppThread;
|
||||
|
||||
class MppThread
|
||||
{
|
||||
public:
|
||||
MppThread(MppThreadFunc func, void *ctx, const char *name = NULL);
|
||||
~MppThread() {};
|
||||
// Mutex functions
|
||||
void mpp_mutex_init(MppMutex *mutex);
|
||||
void mpp_mutex_destroy(MppMutex *mutex);
|
||||
void mpp_mutex_lock(MppMutex *mutex);
|
||||
void mpp_mutex_unlock(MppMutex *mutex);
|
||||
int mpp_mutex_trylock(MppMutex *mutex);
|
||||
|
||||
MppThreadStatus get_status(MppThreadSignal id = THREAD_WORK);
|
||||
void set_status(MppThreadStatus status, MppThreadSignal id = THREAD_WORK);
|
||||
void dump_status();
|
||||
// Condition functions
|
||||
void mpp_cond_init(MppCond *condition);
|
||||
void mpp_cond_destroy(MppCond *condition);
|
||||
rk_s32 mpp_cond_wait(MppCond *condition, MppMutex *mutex);
|
||||
rk_s32 mpp_cond_timedwait(MppCond *condition, MppMutex *mutex, rk_s64 timeout);
|
||||
rk_s32 mpp_cond_signal(MppCond *condition);
|
||||
rk_s32 mpp_cond_broadcast(MppCond *condition);
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
// Mutex-Condition functions
|
||||
void mpp_mutex_cond_init(MppMutexCond *mutexCond);
|
||||
void mpp_mutex_cond_destroy(MppMutexCond *mutexCond);
|
||||
void mpp_mutex_cond_lock(MppMutexCond *mutexCond);
|
||||
void mpp_mutex_cond_unlock(MppMutexCond *mutexCond);
|
||||
int mpp_mutex_cond_trylock(MppMutexCond *mutexCond);
|
||||
rk_s32 mpp_mutex_cond_wait(MppMutexCond *mutexCond);
|
||||
rk_s32 mpp_mutex_cond_timedwait(MppMutexCond *mutexCond, rk_s64 timeout);
|
||||
void mpp_mutex_cond_signal(MppMutexCond *mutexCond);
|
||||
void mpp_mutex_cond_broadcast(MppMutexCond *mutexCond);
|
||||
|
||||
void lock(MppThreadSignal id = THREAD_WORK) {
|
||||
mpp_assert(id < THREAD_SIGNAL_BUTT);
|
||||
mMutexCond[id].lock();
|
||||
}
|
||||
// Thread functions
|
||||
void mpp_thread_init(MppThread *thread, MppThreadFunc func, void *ctx, const char *name);
|
||||
void mpp_thread_set_status(MppThread *thread, MppThreadStatus status, MppThreadSignalId id);
|
||||
MppThreadStatus mpp_thread_get_status(MppThread *thread, MppThreadSignalId id);
|
||||
void mpp_thread_lock(MppThread *thread, MppThreadSignalId id);
|
||||
void mpp_thread_unlock(MppThread *thread, MppThreadSignalId id);
|
||||
void mpp_thread_wait(MppThread *thread, MppThreadSignalId id);
|
||||
void mpp_thread_signal(MppThread *thread, MppThreadSignalId id);
|
||||
|
||||
void unlock(MppThreadSignal id = THREAD_WORK) {
|
||||
mpp_assert(id < THREAD_SIGNAL_BUTT);
|
||||
mMutexCond[id].unlock();
|
||||
}
|
||||
MppThread *mpp_thread_create(MppThreadFunc func, void *ctx, const char *name);
|
||||
void mpp_thread_destroy(MppThread *thread);
|
||||
void mpp_thread_start(MppThread *thread);
|
||||
void mpp_thread_stop(MppThread *thread);
|
||||
|
||||
void wait(MppThreadSignal id = THREAD_WORK) {
|
||||
mpp_assert(id < THREAD_SIGNAL_BUTT);
|
||||
MppThreadStatus status = mStatus[id];
|
||||
|
||||
mStatus[id] = MPP_THREAD_WAITING;
|
||||
mMutexCond[id].wait();
|
||||
|
||||
// check the status is not changed then restore status
|
||||
if (mStatus[id] == MPP_THREAD_WAITING)
|
||||
mStatus[id] = status;
|
||||
}
|
||||
|
||||
void signal(MppThreadSignal id = THREAD_WORK) {
|
||||
mpp_assert(id < THREAD_SIGNAL_BUTT);
|
||||
mMutexCond[id].signal();
|
||||
}
|
||||
|
||||
Mutex *mutex(MppThreadSignal id = THREAD_WORK) {
|
||||
mpp_assert(id < THREAD_SIGNAL_BUTT);
|
||||
return mMutexCond[id].mutex();
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_t mThread;
|
||||
MppMutexCond mMutexCond[THREAD_SIGNAL_BUTT];
|
||||
MppThreadStatus mStatus[THREAD_SIGNAL_BUTT];
|
||||
|
||||
MppThreadFunc mFunction;
|
||||
char mName[THREAD_NAME_LEN];
|
||||
void *mContext;
|
||||
|
||||
MppThread();
|
||||
MppThread(const MppThread &);
|
||||
MppThread &operator=(const MppThread &);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* status transaction:
|
||||
* new
|
||||
* create
|
||||
* v
|
||||
* MPP_THREAD_UNINITED
|
||||
* v
|
||||
* setup
|
||||
* v
|
||||
* delete <- MPP_THREAD_READY <-------------------+
|
||||
* destroy <- MPP_THREAD_READY <-------------------+
|
||||
* v |
|
||||
* start |
|
||||
* v |
|
||||
@@ -339,8 +151,8 @@ void mpp_sthd_put(MppSThd thd);
|
||||
|
||||
MppSThdStatus mpp_sthd_get_status(MppSThd thd);
|
||||
const char* mpp_sthd_get_name(MppSThd thd);
|
||||
RK_S32 mpp_sthd_get_idx(MppSThd thd);
|
||||
RK_S32 mpp_sthd_check(MppSThd thd);
|
||||
rk_s32 mpp_sthd_get_idx(MppSThd thd);
|
||||
rk_s32 mpp_sthd_check(MppSThd thd);
|
||||
|
||||
void mpp_sthd_setup(MppSThd thd, MppSThdFunc func, void *ctx);
|
||||
|
||||
@@ -357,14 +169,18 @@ void mpp_sthd_signal(MppSThd thd);
|
||||
void mpp_sthd_broadcast(MppSThd thd);
|
||||
|
||||
/* multi-thread group with same callback and context */
|
||||
MppSThdGrp mpp_sthd_grp_get(const char *name, RK_S32 count);
|
||||
MppSThdGrp mpp_sthd_grp_get(const char *name, rk_s32 count);
|
||||
void mpp_sthd_grp_put(MppSThdGrp grp);
|
||||
|
||||
void mpp_sthd_grp_setup(MppSThdGrp grp, MppSThdFunc func, void *ctx);
|
||||
MppSThd mpp_sthd_grp_get_each(MppSThdGrp grp, RK_S32 idx);
|
||||
MppSThd mpp_sthd_grp_get_each(MppSThdGrp grp, rk_s32 idx);
|
||||
|
||||
void mpp_sthd_grp_start(MppSThdGrp grp);
|
||||
void mpp_sthd_grp_stop(MppSThdGrp grp);
|
||||
void mpp_sthd_grp_stop_sync(MppSThdGrp grp);
|
||||
|
||||
#endif /*__MPP_THREAD_H__*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,33 +1,16 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright (c) 2015 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __MPP_TIME_H__
|
||||
#define __MPP_TIME_H__
|
||||
|
||||
#include "rk_type.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mpp_thread.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32CE__)
|
||||
#include <windows.h>
|
||||
#define msleep Sleep
|
||||
#define sleep(x) Sleep((x)*1000)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define msleep(x) usleep((x)*1000)
|
||||
#endif
|
||||
|
||||
typedef void* MppClock;
|
||||
typedef void* MppTimer;
|
||||
@@ -37,8 +20,8 @@ typedef void* MppStopwatch;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
RK_S64 mpp_time();
|
||||
void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, const char *fmt);
|
||||
rk_s64 mpp_time();
|
||||
void mpp_time_diff(rk_s64 start, rk_s64 end, rk_s64 limit, const char *fmt);
|
||||
|
||||
/*
|
||||
* Clock create / destroy / enable / disable function
|
||||
@@ -48,7 +31,7 @@ void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, const char *fmt);
|
||||
*/
|
||||
MppClock mpp_clock_get(const char *name);
|
||||
void mpp_clock_put(MppClock clock);
|
||||
void mpp_clock_enable(MppClock clock, RK_U32 enable);
|
||||
void mpp_clock_enable(MppClock clock, rk_u32 enable);
|
||||
|
||||
/*
|
||||
* Clock basic operation function:
|
||||
@@ -56,9 +39,9 @@ void mpp_clock_enable(MppClock clock, RK_U32 enable);
|
||||
* pause : let clock pause and return the diff to start time
|
||||
* reset : let clock counter to all zero
|
||||
*/
|
||||
RK_S64 mpp_clock_start(MppClock clock);
|
||||
RK_S64 mpp_clock_pause(MppClock clock);
|
||||
RK_S64 mpp_clock_reset(MppClock clock);
|
||||
rk_s64 mpp_clock_start(MppClock clock);
|
||||
rk_s64 mpp_clock_pause(MppClock clock);
|
||||
rk_s64 mpp_clock_reset(MppClock clock);
|
||||
|
||||
/*
|
||||
* These clock helper function can only be call when clock is paused:
|
||||
@@ -66,8 +49,8 @@ RK_S64 mpp_clock_reset(MppClock clock);
|
||||
* mpp_clock_get_count - Return clock sum up counter value
|
||||
* mpp_clock_get_name - Return clock name
|
||||
*/
|
||||
RK_S64 mpp_clock_get_sum(MppClock clock);
|
||||
RK_S64 mpp_clock_get_count(MppClock clock);
|
||||
rk_s64 mpp_clock_get_sum(MppClock clock);
|
||||
rk_s64 mpp_clock_get_count(MppClock clock);
|
||||
const char *mpp_clock_get_name(MppClock clock);
|
||||
|
||||
/*
|
||||
@@ -87,8 +70,8 @@ const char *mpp_clock_get_name(MppClock clock);
|
||||
*/
|
||||
MppTimer mpp_timer_get(const char *name);
|
||||
void mpp_timer_set_callback(MppTimer timer, MppThreadFunc func, void *ctx);
|
||||
void mpp_timer_set_timing(MppTimer timer, RK_S32 initial, RK_S32 interval);
|
||||
void mpp_timer_set_enable(MppTimer timer, RK_S32 enable);
|
||||
void mpp_timer_set_timing(MppTimer timer, rk_s32 initial, rk_s32 interval);
|
||||
void mpp_timer_set_enable(MppTimer timer, rk_s32 enable);
|
||||
void mpp_timer_put(MppTimer timer);
|
||||
|
||||
/*
|
||||
@@ -104,35 +87,13 @@ void mpp_timer_put(MppTimer timer);
|
||||
* 5. mpp_stopwatch_put (show events and time)
|
||||
*/
|
||||
MppStopwatch mpp_stopwatch_get(const char *name);
|
||||
void mpp_stopwatch_set_show_on_exit(MppStopwatch stopwatch, RK_S32 show_on_exit);
|
||||
void mpp_stopwatch_set_show_on_exit(MppStopwatch stopwatch, rk_s32 show_on_exit);
|
||||
void mpp_stopwatch_record(MppStopwatch stopwatch, const char *event);
|
||||
void mpp_stopwatch_put(MppStopwatch timer);
|
||||
RK_S64 mpp_stopwatch_elapsed_time(MppStopwatch stopwatch);
|
||||
rk_s64 mpp_stopwatch_elapsed_time(MppStopwatch stopwatch);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
class AutoTiming
|
||||
{
|
||||
public:
|
||||
AutoTiming(const char *name = "AutoTiming");
|
||||
~AutoTiming();
|
||||
private:
|
||||
const char *mName;
|
||||
RK_S64 mStart;
|
||||
RK_S64 mEnd;
|
||||
|
||||
AutoTiming(const AutoTiming &);
|
||||
AutoTiming &operator = (const AutoTiming&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define AUTO_TIMER_STRING(name, cnt) name ## cnt
|
||||
#define AUTO_TIMER_NAME_STRING(name, cnt) AUTO_TIMER_STRING(name, cnt)
|
||||
#define AUTO_TIMER_NAME(name) AUTO_TIMER_NAME_STRING(name, __COUNTER__)
|
||||
#define AUTO_TIMING() AutoTiming AUTO_TIMER_NAME(auto_timing)(__FUNCTION__)
|
||||
|
||||
#endif /*__MPP_TIME_H__*/
|
||||
|
598
osal/mpp_list.c
Normal file
598
osal/mpp_list.c
Normal file
@@ -0,0 +1,598 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright (c) 2015 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "mpp_list"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_list.h"
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#define LIST_DEBUG(fmt, ...) mpp_log(fmt, ## __VA_ARGS__)
|
||||
#define LIST_ERROR(fmt, ...) mpp_err(fmt, ## __VA_ARGS__)
|
||||
|
||||
static inline void list_node_init(MppListNode *node)
|
||||
{
|
||||
node->prev = node->next = node;
|
||||
}
|
||||
|
||||
static inline void list_node_init_with_key_and_size(MppListNode *node, rk_u32 key, rk_s32 size)
|
||||
{
|
||||
list_node_init(node);
|
||||
node->key = key;
|
||||
node->size = size;
|
||||
}
|
||||
|
||||
static MppListNode* create_list(void *data, rk_s32 size, rk_u32 key)
|
||||
{
|
||||
MppListNode *node = mpp_malloc_size(MppListNode, sizeof(MppListNode) + size);
|
||||
|
||||
if (node) {
|
||||
void *dst = (void*)(node + 1);
|
||||
list_node_init_with_key_and_size(node, key, size);
|
||||
memcpy(dst, data, size);
|
||||
} else {
|
||||
LIST_ERROR("failed to allocate list node");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static inline void _mpp_list_add(MppListNode * _new, MppListNode * prev, MppListNode * next)
|
||||
{
|
||||
next->prev = _new;
|
||||
_new->next = next;
|
||||
_new->prev = prev;
|
||||
prev->next = _new;
|
||||
}
|
||||
|
||||
static inline void mpp_list_add(MppListNode *_new, MppListNode *head)
|
||||
{
|
||||
_mpp_list_add(_new, head, head->next);
|
||||
}
|
||||
|
||||
static inline void mpp_list_add_tail(MppListNode *_new, MppListNode *head)
|
||||
{
|
||||
_mpp_list_add(_new, head->prev, head);
|
||||
}
|
||||
|
||||
int mpp_list_add_at_head(MppList *list, void *data, int size)
|
||||
{
|
||||
rk_s32 ret = -EINVAL;
|
||||
|
||||
if (list->head) {
|
||||
MppListNode *node = create_list(data, size, 0);
|
||||
if (node) {
|
||||
mpp_list_add(node, list->head);
|
||||
list->count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mpp_list_add_at_tail(MppList *list, void *data, int size)
|
||||
{
|
||||
rk_s32 ret = -EINVAL;
|
||||
|
||||
if (list->head) {
|
||||
MppListNode *node = create_list(data, size, 0);
|
||||
|
||||
if (node) {
|
||||
mpp_list_add_tail(node, list->head);
|
||||
list->count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void release_list(MppListNode*node, void *data, rk_s32 size)
|
||||
{
|
||||
void *src = (void*)(node + 1);
|
||||
|
||||
if (node->size == size) {
|
||||
if (data)
|
||||
memcpy(data, src, size);
|
||||
} else {
|
||||
LIST_ERROR("node size check failed when release_list");
|
||||
size = (size < node->size) ? (size) : (node->size);
|
||||
if (data)
|
||||
memcpy(data, src, size);
|
||||
}
|
||||
mpp_free(node);
|
||||
}
|
||||
|
||||
static inline void _mpp_list_del(MppListNode *prev, MppListNode *next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
static inline void mpp_list_del_init(MppListNode *node)
|
||||
{
|
||||
_mpp_list_del(node->prev, node->next);
|
||||
list_node_init(node);
|
||||
}
|
||||
|
||||
static inline void _list_del_node_no_lock(MppListNode *node, void *data, rk_s32 size)
|
||||
{
|
||||
mpp_list_del_init(node);
|
||||
release_list(node, data, size);
|
||||
}
|
||||
|
||||
int mpp_list_del_at_head(MppList *list, void *data, int size)
|
||||
{
|
||||
rk_s32 ret = -EINVAL;
|
||||
|
||||
if (list->head && list->count) {
|
||||
_list_del_node_no_lock(list->head->next, data, size);
|
||||
list->count--;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mpp_list_del_at_tail(MppList *list, void *data, int size)
|
||||
{
|
||||
rk_s32 ret = -EINVAL;
|
||||
|
||||
if (list->head && list->count) {
|
||||
_list_del_node_no_lock(list->head->prev, data, size);
|
||||
list->count--;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static MppListNode* create_list_with_size(void *data, rk_s32 size, rk_u32 key)
|
||||
{
|
||||
MppListNode *node = mpp_malloc_size(MppListNode, sizeof(MppListNode) + sizeof(size) + size);
|
||||
|
||||
if (node) {
|
||||
rk_s32 *dst = (rk_s32 *)(node + 1);
|
||||
list_node_init_with_key_and_size(node, key, size);
|
||||
*dst++ = size;
|
||||
memcpy(dst, data, size);
|
||||
} else {
|
||||
LIST_ERROR("failed to allocate list node");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
rk_s32 mpp_list_fifo_wr(MppList *list, void *data, rk_s32 size)
|
||||
{
|
||||
rk_s32 ret = -EINVAL;
|
||||
|
||||
if (list && list->head) {
|
||||
MppListNode *node = create_list_with_size(data, size, 0);
|
||||
|
||||
if (node) {
|
||||
mpp_list_add_tail(node, list->head);
|
||||
list->count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void release_list_with_size(MppListNode* node, void *data, rk_s32 *size)
|
||||
{
|
||||
rk_s32 *src = (rk_s32*)(node + 1);
|
||||
rk_s32 data_size = *src++;
|
||||
|
||||
*size = data_size;
|
||||
|
||||
if (data)
|
||||
memcpy(data, src, data_size);
|
||||
|
||||
mpp_free(node);
|
||||
}
|
||||
|
||||
rk_s32 mpp_list_fifo_rd(MppList *list, void *data, rk_s32 *size)
|
||||
{
|
||||
rk_s32 ret = -EINVAL;
|
||||
|
||||
if (list && list->head && list->count) {
|
||||
MppListNode *node = list->head->next;
|
||||
|
||||
mpp_list_del_init(node);
|
||||
release_list_with_size(node, data, size);
|
||||
list->count--;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mpp_list_is_empty(MppList *list)
|
||||
{
|
||||
return list->count == 0;
|
||||
}
|
||||
|
||||
int mpp_list_size(MppList *list)
|
||||
{
|
||||
return list->count;
|
||||
}
|
||||
|
||||
rk_s32 mpp_list_add_by_key(MppList *list, void *data, rk_s32 size, rk_u32 *key)
|
||||
{
|
||||
rk_s32 ret = 0;
|
||||
|
||||
if (list->head) {
|
||||
MppListNode *node;
|
||||
rk_u32 list_key = mpp_list_get_key(list);
|
||||
|
||||
*key = list_key;
|
||||
node = create_list(data, size, list_key);
|
||||
if (node) {
|
||||
mpp_list_add_tail(node, list->head);
|
||||
list->count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
rk_s32 mpp_list_del_by_key(MppList *list, void *data, rk_s32 size, rk_u32 key)
|
||||
{
|
||||
rk_s32 ret = 0;
|
||||
|
||||
if (list && list->head && list->count) {
|
||||
MppListNode *tmp = list->head->next;
|
||||
|
||||
ret = -EINVAL;
|
||||
while (tmp->next != list->head) {
|
||||
if (tmp->key == key) {
|
||||
_list_del_node_no_lock(tmp, data, size);
|
||||
list->count--;
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
rk_s32 mpp_list_show_by_key(MppList *list, void *data, rk_u32 key)
|
||||
{
|
||||
rk_s32 ret = -EINVAL;
|
||||
|
||||
(void)list;
|
||||
(void)data;
|
||||
(void)key;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mpp_list_flush(MppList* list)
|
||||
{
|
||||
if (list->head) {
|
||||
while (list->count) {
|
||||
MppListNode* node = list->head->next;
|
||||
|
||||
mpp_list_del_init(node);
|
||||
|
||||
if (list->destroy) {
|
||||
list->destroy((void*)(node + 1));
|
||||
}
|
||||
|
||||
mpp_free(node);
|
||||
list->count--;
|
||||
}
|
||||
}
|
||||
|
||||
mpp_list_signal(list);
|
||||
}
|
||||
|
||||
MPP_RET mpp_list_wait(MppList* list)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mpp_mutex_cond_wait(&list->cond_lock);
|
||||
|
||||
if (ret == 0) {
|
||||
return MPP_OK;
|
||||
} else if (ret == ETIMEDOUT) {
|
||||
return MPP_NOK;
|
||||
} else {
|
||||
return MPP_NOK;
|
||||
}
|
||||
}
|
||||
|
||||
MPP_RET mpp_list_wait_timed(MppList *list, rk_s64 timeout)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = (MPP_RET)mpp_mutex_cond_timedwait(&list->cond_lock, timeout);
|
||||
|
||||
if (ret == 0) {
|
||||
return MPP_OK;
|
||||
} else if (ret == ETIMEDOUT) {
|
||||
return MPP_NOK;
|
||||
} else {
|
||||
return MPP_NOK;
|
||||
}
|
||||
}
|
||||
|
||||
MPP_RET mpp_list_wait_lt(MppList *list, rk_s64 timeout, rk_s32 val)
|
||||
{
|
||||
if (list->count < val)
|
||||
return MPP_OK;
|
||||
|
||||
if (timeout < 0) {
|
||||
return mpp_list_wait(list);
|
||||
} else {
|
||||
return mpp_list_wait_timed(list, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
MPP_RET mpp_list_wait_le(MppList *list, rk_s64 timeout, rk_s32 val)
|
||||
{
|
||||
if (list->count <= val)
|
||||
return MPP_OK;
|
||||
|
||||
if (timeout < 0) {
|
||||
return mpp_list_wait(list);
|
||||
} else {
|
||||
return mpp_list_wait_timed(list, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
MPP_RET mpp_list_wait_gt(MppList *list, rk_s64 timeout, rk_s32 val)
|
||||
{
|
||||
if (list->count > val)
|
||||
return MPP_OK;
|
||||
|
||||
if (timeout < 0) {
|
||||
return mpp_list_wait(list);
|
||||
} else {
|
||||
return mpp_list_wait_timed(list, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
MPP_RET mpp_list_wait_ge(MppList *list, rk_s64 timeout, rk_s32 val)
|
||||
{
|
||||
if (list->count >= val)
|
||||
return MPP_OK;
|
||||
|
||||
if (timeout < 0) {
|
||||
return mpp_list_wait(list);
|
||||
} else {
|
||||
return mpp_list_wait_timed(list, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void mpp_list_signal(MppList *list)
|
||||
{
|
||||
mpp_mutex_cond_signal(&list->cond_lock);
|
||||
}
|
||||
|
||||
rk_u32 mpp_list_get_key(MppList *list)
|
||||
{
|
||||
return list->keys++;
|
||||
}
|
||||
|
||||
MppList *mpp_list_create(node_destructor func)
|
||||
{
|
||||
MppList *list = mpp_malloc(MppList, 1);
|
||||
|
||||
if (list == NULL) {
|
||||
LIST_ERROR("Failed to allocate memory for mpp_list.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->destroy = func;
|
||||
list->count = 0;
|
||||
|
||||
list->head = mpp_malloc(MppListNode, 1);
|
||||
if (list->head == NULL) {
|
||||
LIST_ERROR("Failed to allocate memory for list header.\n");
|
||||
mpp_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_node_init_with_key_and_size(list->head, 0, 0);
|
||||
|
||||
mpp_mutex_cond_init(&list->cond_lock);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void mpp_list_destroy(MppList *list)
|
||||
{
|
||||
MppListNode *node;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
mpp_list_flush(list);
|
||||
|
||||
node = list->head->next;
|
||||
while (node != list->head) {
|
||||
MppListNode *next = node->next;
|
||||
|
||||
mpp_free(node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
mpp_mutex_cond_destroy(&list->cond_lock);
|
||||
|
||||
mpp_free(list->head);
|
||||
list->head = NULL;
|
||||
|
||||
mpp_free(list);
|
||||
list = NULL;
|
||||
}
|
||||
|
||||
/* list sort porting from kernel list_sort.c */
|
||||
|
||||
/*
|
||||
* Returns a list organized in an intermediate format suited
|
||||
* to chaining of merge() calls: null-terminated, no reserved or
|
||||
* sentinel head node, "prev" links not maintained.
|
||||
*/
|
||||
static struct list_head *merge(void *priv, ListCmpFunc cmp,
|
||||
struct list_head *a, struct list_head *b)
|
||||
{
|
||||
struct list_head *head, **tail = &head;
|
||||
|
||||
for (;;) {
|
||||
/* if equal, take 'a' -- important for sort stability */
|
||||
if (cmp(priv, a, b) <= 0) {
|
||||
*tail = a;
|
||||
tail = &a->next;
|
||||
a = a->next;
|
||||
if (!a) {
|
||||
*tail = b;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
*tail = b;
|
||||
tail = &b->next;
|
||||
b = b->next;
|
||||
if (!b) {
|
||||
*tail = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
/*
|
||||
* Combine final list merge with restoration of standard doubly-linked
|
||||
* list structure. This approach duplicates code from merge(), but
|
||||
* runs faster than the tidier alternatives of either a separate final
|
||||
* prev-link restoration pass, or maintaining the prev links
|
||||
* throughout.
|
||||
*/
|
||||
static void merge_final(void *priv, ListCmpFunc cmp, struct list_head *head,
|
||||
struct list_head *a, struct list_head *b)
|
||||
{
|
||||
struct list_head *tail = head;
|
||||
rk_u8 count = 0;
|
||||
|
||||
for (;;) {
|
||||
/* if equal, take 'a' -- important for sort stability */
|
||||
if (cmp(priv, a, b) <= 0) {
|
||||
tail->next = a;
|
||||
a->prev = tail;
|
||||
tail = a;
|
||||
a = a->next;
|
||||
if (!a)
|
||||
break;
|
||||
} else {
|
||||
tail->next = b;
|
||||
b->prev = tail;
|
||||
tail = b;
|
||||
b = b->next;
|
||||
if (!b) {
|
||||
b = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish linking remainder of list b on to tail */
|
||||
tail->next = b;
|
||||
do {
|
||||
/*
|
||||
* If the merge is highly unbalanced (e.g. the input is
|
||||
* already sorted), this loop may run many iterations.
|
||||
* Continue callbacks to the client even though no
|
||||
* element comparison is needed, so the client's cmp()
|
||||
* routine can invoke cond_resched() periodically.
|
||||
*/
|
||||
if (!++count)
|
||||
cmp(priv, b, b);
|
||||
b->prev = tail;
|
||||
tail = b;
|
||||
b = b->next;
|
||||
} while (b);
|
||||
|
||||
/* And the final links to make a circular doubly-linked list */
|
||||
tail->next = head;
|
||||
head->prev = tail;
|
||||
}
|
||||
|
||||
void list_sort(void *priv, struct list_head *head, ListCmpFunc cmp)
|
||||
{
|
||||
struct list_head *list = head->next, *pending = NULL;
|
||||
size_t count = 0; /* Count of pending */
|
||||
|
||||
if (list == head->prev) /* Zero or one elements */
|
||||
return;
|
||||
|
||||
/* Convert to a null-terminated singly-linked list. */
|
||||
head->prev->next = NULL;
|
||||
|
||||
/*
|
||||
* Data structure invariants:
|
||||
* - All lists are singly linked and null-terminated; prev
|
||||
* pointers are not maintained.
|
||||
* - pending is a prev-linked "list of lists" of sorted
|
||||
* sublists awaiting further merging.
|
||||
* - Each of the sorted sublists is power-of-two in size.
|
||||
* - Sublists are sorted by size and age, smallest & newest at front.
|
||||
* - There are zero to two sublists of each size.
|
||||
* - A pair of pending sublists are merged as soon as the number
|
||||
* of following pending elements equals their size (i.e.
|
||||
* each time count reaches an odd multiple of that size).
|
||||
* That ensures each later final merge will be at worst 2:1.
|
||||
* - Each round consists of:
|
||||
* - Merging the two sublists selected by the highest bit
|
||||
* which flips when count is incremented, and
|
||||
* - Adding an element from the input as a size-1 sublist.
|
||||
*/
|
||||
do {
|
||||
size_t bits;
|
||||
struct list_head **tail = &pending;
|
||||
|
||||
/* Find the least-significant clear bit in count */
|
||||
for (bits = count; bits & 1; bits >>= 1)
|
||||
tail = &(*tail)->prev;
|
||||
/* Do the indicated merge */
|
||||
if (bits) {
|
||||
struct list_head *a = *tail, *b = a->prev;
|
||||
|
||||
a = merge(priv, cmp, b, a);
|
||||
/* Install the merged result in place of the inputs */
|
||||
a->prev = b->prev;
|
||||
*tail = a;
|
||||
}
|
||||
|
||||
/* Move one element from input list to pending */
|
||||
list->prev = pending;
|
||||
pending = list;
|
||||
list = list->next;
|
||||
pending->next = NULL;
|
||||
count++;
|
||||
} while (list);
|
||||
|
||||
/* End of input; merge together all the pending lists. */
|
||||
list = pending;
|
||||
pending = pending->prev;
|
||||
for (;;) {
|
||||
struct list_head *next = pending->prev;
|
||||
|
||||
if (!next)
|
||||
break;
|
||||
list = merge(priv, cmp, pending, list);
|
||||
pending = next;
|
||||
}
|
||||
/* The final merge, rebuilding prev links */
|
||||
merge_final(priv, cmp, head, pending, list);
|
||||
}
|
@@ -1,722 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "mpp_list"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_list.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
|
||||
#define LIST_DEBUG(fmt, ...) mpp_log(fmt, ## __VA_ARGS__)
|
||||
#define LIST_ERROR(fmt, ...) mpp_err(fmt, ## __VA_ARGS__)
|
||||
|
||||
RK_U32 mpp_list::keys = 0;
|
||||
|
||||
typedef struct mpp_list_node {
|
||||
mpp_list_node* prev;
|
||||
mpp_list_node* next;
|
||||
RK_U32 key;
|
||||
RK_S32 size;
|
||||
} mpp_list_node;
|
||||
|
||||
static inline void list_node_init(mpp_list_node *node)
|
||||
{
|
||||
node->prev = node->next = node;
|
||||
}
|
||||
|
||||
static inline void list_node_init_with_key_and_size(mpp_list_node *node, RK_U32 key, RK_S32 size)
|
||||
{
|
||||
list_node_init(node);
|
||||
node->key = key;
|
||||
node->size = size;
|
||||
}
|
||||
|
||||
static mpp_list_node* create_list(void *data, RK_S32 size, RK_U32 key)
|
||||
{
|
||||
mpp_list_node *node = (mpp_list_node*)malloc(sizeof(mpp_list_node) + size);
|
||||
if (node) {
|
||||
void *dst = (void*)(node + 1);
|
||||
list_node_init_with_key_and_size(node, key, size);
|
||||
memcpy(dst, data, size);
|
||||
} else {
|
||||
LIST_ERROR("failed to allocate list node");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static inline void _mpp_list_add(mpp_list_node * _new, mpp_list_node * prev, mpp_list_node * next)
|
||||
{
|
||||
next->prev = _new;
|
||||
_new->next = next;
|
||||
_new->prev = prev;
|
||||
prev->next = _new;
|
||||
}
|
||||
|
||||
static inline void mpp_list_add(mpp_list_node *_new, mpp_list_node *head)
|
||||
{
|
||||
_mpp_list_add(_new, head, head->next);
|
||||
}
|
||||
|
||||
static inline void mpp_list_add_tail(mpp_list_node *_new, mpp_list_node *head)
|
||||
{
|
||||
_mpp_list_add(_new, head->prev, head);
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::add_at_head(void *data, RK_S32 size)
|
||||
{
|
||||
RK_S32 ret = -EINVAL;
|
||||
if (head) {
|
||||
mpp_list_node *node = create_list(data, size, 0);
|
||||
if (node) {
|
||||
mpp_list_add(node, head);
|
||||
count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::add_at_tail(void *data, RK_S32 size)
|
||||
{
|
||||
RK_S32 ret = -EINVAL;
|
||||
if (head) {
|
||||
mpp_list_node *node = create_list(data, size, 0);
|
||||
if (node) {
|
||||
mpp_list_add_tail(node, head);
|
||||
count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void release_list(mpp_list_node*node, void *data, RK_S32 size)
|
||||
{
|
||||
void *src = (void*)(node + 1);
|
||||
if (node->size == size) {
|
||||
if (data)
|
||||
memcpy(data, src, size);
|
||||
} else {
|
||||
LIST_ERROR("node size check failed when release_list");
|
||||
size = (size < node->size) ? (size) : (node->size);
|
||||
if (data)
|
||||
memcpy(data, src, size);
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
|
||||
static inline void _mpp_list_del(mpp_list_node *prev, mpp_list_node *next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
static inline void mpp_list_del_init(mpp_list_node *node)
|
||||
{
|
||||
_mpp_list_del(node->prev, node->next);
|
||||
list_node_init(node);
|
||||
}
|
||||
|
||||
static inline void _list_del_node_no_lock(mpp_list_node *node, void *data, RK_S32 size)
|
||||
{
|
||||
mpp_list_del_init(node);
|
||||
release_list(node, data, size);
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::del_at_head(void *data, RK_S32 size)
|
||||
{
|
||||
RK_S32 ret = -EINVAL;
|
||||
if (head && count) {
|
||||
_list_del_node_no_lock(head->next, data, size);
|
||||
count--;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::del_at_tail(void *data, RK_S32 size)
|
||||
{
|
||||
RK_S32 ret = -EINVAL;
|
||||
if (head && count) {
|
||||
_list_del_node_no_lock(head->prev, data, size);
|
||||
count--;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static mpp_list_node* create_list_with_size(void *data, RK_S32 size, RK_U32 key)
|
||||
{
|
||||
mpp_list_node *node = (mpp_list_node*)malloc(sizeof(mpp_list_node) +
|
||||
sizeof(size) + size);
|
||||
if (node) {
|
||||
RK_S32 *dst = (RK_S32 *)(node + 1);
|
||||
list_node_init_with_key_and_size(node, key, size);
|
||||
*dst++ = size;
|
||||
memcpy(dst, data, size);
|
||||
} else {
|
||||
LIST_ERROR("failed to allocate list node");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::fifo_wr(void *data, RK_S32 size)
|
||||
{
|
||||
RK_S32 ret = -EINVAL;
|
||||
if (head) {
|
||||
mpp_list_node *node = create_list_with_size(data, size, 0);
|
||||
if (node) {
|
||||
mpp_list_add_tail(node, head);
|
||||
count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void release_list_with_size(mpp_list_node* node, void *data, RK_S32 *size)
|
||||
{
|
||||
RK_S32 *src = (RK_S32*)(node + 1);
|
||||
RK_S32 data_size = *src++;
|
||||
|
||||
*size = data_size;
|
||||
|
||||
if (data)
|
||||
memcpy(data, src, data_size);
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::fifo_rd(void *data, RK_S32 *size)
|
||||
{
|
||||
RK_S32 ret = -EINVAL;
|
||||
if (head && count) {
|
||||
mpp_list_node *node = head->next;
|
||||
|
||||
mpp_list_del_init(node);
|
||||
release_list_with_size(node, data, size);
|
||||
count--;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::list_is_empty()
|
||||
{
|
||||
RK_S32 ret = (count == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::list_size()
|
||||
{
|
||||
RK_S32 ret = count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::add_by_key(void *data, RK_S32 size, RK_U32 *key)
|
||||
{
|
||||
RK_S32 ret = 0;
|
||||
if (head) {
|
||||
RK_U32 list_key = get_key();
|
||||
*key = list_key;
|
||||
mpp_list_node *node = create_list(data, size, list_key);
|
||||
if (node) {
|
||||
mpp_list_add_tail(node, head);
|
||||
count++;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::del_by_key(void *data, RK_S32 size, RK_U32 key)
|
||||
{
|
||||
RK_S32 ret = 0;
|
||||
if (head && count) {
|
||||
struct mpp_list_node *tmp = head->next;
|
||||
ret = -EINVAL;
|
||||
while (tmp->next != head) {
|
||||
if (tmp->key == key) {
|
||||
_list_del_node_no_lock(tmp, data, size);
|
||||
count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
RK_S32 mpp_list::show_by_key(void *data, RK_U32 key)
|
||||
{
|
||||
RK_S32 ret = -EINVAL;
|
||||
(void)data;
|
||||
(void)key;
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 mpp_list::flush()
|
||||
{
|
||||
if (head) {
|
||||
while (count) {
|
||||
mpp_list_node* node = head->next;
|
||||
mpp_list_del_init(node);
|
||||
if (destroy) {
|
||||
destroy((void*)(node + 1));
|
||||
}
|
||||
free(node);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
signal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MPP_RET mpp_list::wait_lt(RK_S64 timeout, RK_S32 val)
|
||||
{
|
||||
if (list_size() < val)
|
||||
return MPP_OK;
|
||||
|
||||
if (!timeout)
|
||||
return MPP_NOK;
|
||||
|
||||
if (timeout < 0)
|
||||
wait();
|
||||
else
|
||||
wait(timeout);
|
||||
|
||||
return list_size() < val ? MPP_OK : MPP_NOK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_list::wait_le(RK_S64 timeout, RK_S32 val)
|
||||
{
|
||||
if (list_size() <= val)
|
||||
return MPP_OK;
|
||||
|
||||
if (!timeout)
|
||||
return MPP_NOK;
|
||||
|
||||
if (timeout < 0)
|
||||
wait();
|
||||
else
|
||||
wait(timeout);
|
||||
|
||||
return list_size() <= val ? MPP_OK : MPP_NOK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_list::wait_gt(RK_S64 timeout, RK_S32 val)
|
||||
{
|
||||
if (list_size() > val)
|
||||
return MPP_OK;
|
||||
|
||||
if (!timeout)
|
||||
return MPP_NOK;
|
||||
|
||||
if (timeout < 0)
|
||||
wait();
|
||||
else
|
||||
wait(timeout);
|
||||
|
||||
return list_size() > val ? MPP_OK : MPP_NOK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_list::wait_ge(RK_S64 timeout, RK_S32 val)
|
||||
{
|
||||
if (list_size() >= val)
|
||||
return MPP_OK;
|
||||
|
||||
if (!timeout)
|
||||
return MPP_NOK;
|
||||
|
||||
if (timeout < 0)
|
||||
wait();
|
||||
else
|
||||
wait(timeout);
|
||||
|
||||
return list_size() >= val ? MPP_OK : MPP_NOK;
|
||||
}
|
||||
|
||||
RK_U32 mpp_list::get_key()
|
||||
{
|
||||
return keys++;
|
||||
}
|
||||
|
||||
mpp_list::mpp_list(node_destructor func)
|
||||
: destroy(NULL),
|
||||
head(NULL),
|
||||
count(0)
|
||||
{
|
||||
destroy = func;
|
||||
head = (mpp_list_node*)malloc(sizeof(mpp_list_node));
|
||||
if (NULL == head) {
|
||||
LIST_ERROR("failed to allocate list header");
|
||||
} else {
|
||||
list_node_init_with_key_and_size(head, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
mpp_list::~mpp_list()
|
||||
{
|
||||
flush();
|
||||
if (head) free(head);
|
||||
head = NULL;
|
||||
destroy = NULL;
|
||||
}
|
||||
|
||||
/* list sort porting from kernel list_sort.c */
|
||||
|
||||
/*
|
||||
* Returns a list organized in an intermediate format suited
|
||||
* to chaining of merge() calls: null-terminated, no reserved or
|
||||
* sentinel head node, "prev" links not maintained.
|
||||
*/
|
||||
static struct list_head *merge(void *priv, list_cmp_func_t cmp,
|
||||
struct list_head *a, struct list_head *b)
|
||||
{
|
||||
struct list_head *head, **tail = &head;
|
||||
|
||||
for (;;) {
|
||||
/* if equal, take 'a' -- important for sort stability */
|
||||
if (cmp(priv, a, b) <= 0) {
|
||||
*tail = a;
|
||||
tail = &a->next;
|
||||
a = a->next;
|
||||
if (!a) {
|
||||
*tail = b;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
*tail = b;
|
||||
tail = &b->next;
|
||||
b = b->next;
|
||||
if (!b) {
|
||||
*tail = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
/*
|
||||
* Combine final list merge with restoration of standard doubly-linked
|
||||
* list structure. This approach duplicates code from merge(), but
|
||||
* runs faster than the tidier alternatives of either a separate final
|
||||
* prev-link restoration pass, or maintaining the prev links
|
||||
* throughout.
|
||||
*/
|
||||
static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,
|
||||
struct list_head *a, struct list_head *b)
|
||||
{
|
||||
struct list_head *tail = head;
|
||||
RK_U8 count = 0;
|
||||
|
||||
for (;;) {
|
||||
/* if equal, take 'a' -- important for sort stability */
|
||||
if (cmp(priv, a, b) <= 0) {
|
||||
tail->next = a;
|
||||
a->prev = tail;
|
||||
tail = a;
|
||||
a = a->next;
|
||||
if (!a)
|
||||
break;
|
||||
} else {
|
||||
tail->next = b;
|
||||
b->prev = tail;
|
||||
tail = b;
|
||||
b = b->next;
|
||||
if (!b) {
|
||||
b = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish linking remainder of list b on to tail */
|
||||
tail->next = b;
|
||||
do {
|
||||
/*
|
||||
* If the merge is highly unbalanced (e.g. the input is
|
||||
* already sorted), this loop may run many iterations.
|
||||
* Continue callbacks to the client even though no
|
||||
* element comparison is needed, so the client's cmp()
|
||||
* routine can invoke cond_resched() periodically.
|
||||
*/
|
||||
if (!++count)
|
||||
cmp(priv, b, b);
|
||||
b->prev = tail;
|
||||
tail = b;
|
||||
b = b->next;
|
||||
} while (b);
|
||||
|
||||
/* And the final links to make a circular doubly-linked list */
|
||||
tail->next = head;
|
||||
head->prev = tail;
|
||||
}
|
||||
|
||||
void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp)
|
||||
{
|
||||
struct list_head *list = head->next, *pending = NULL;
|
||||
size_t count = 0; /* Count of pending */
|
||||
|
||||
if (list == head->prev) /* Zero or one elements */
|
||||
return;
|
||||
|
||||
/* Convert to a null-terminated singly-linked list. */
|
||||
head->prev->next = NULL;
|
||||
|
||||
/*
|
||||
* Data structure invariants:
|
||||
* - All lists are singly linked and null-terminated; prev
|
||||
* pointers are not maintained.
|
||||
* - pending is a prev-linked "list of lists" of sorted
|
||||
* sublists awaiting further merging.
|
||||
* - Each of the sorted sublists is power-of-two in size.
|
||||
* - Sublists are sorted by size and age, smallest & newest at front.
|
||||
* - There are zero to two sublists of each size.
|
||||
* - A pair of pending sublists are merged as soon as the number
|
||||
* of following pending elements equals their size (i.e.
|
||||
* each time count reaches an odd multiple of that size).
|
||||
* That ensures each later final merge will be at worst 2:1.
|
||||
* - Each round consists of:
|
||||
* - Merging the two sublists selected by the highest bit
|
||||
* which flips when count is incremented, and
|
||||
* - Adding an element from the input as a size-1 sublist.
|
||||
*/
|
||||
do {
|
||||
size_t bits;
|
||||
struct list_head **tail = &pending;
|
||||
|
||||
/* Find the least-significant clear bit in count */
|
||||
for (bits = count; bits & 1; bits >>= 1)
|
||||
tail = &(*tail)->prev;
|
||||
/* Do the indicated merge */
|
||||
if (bits) {
|
||||
struct list_head *a = *tail, *b = a->prev;
|
||||
|
||||
a = merge(priv, cmp, b, a);
|
||||
/* Install the merged result in place of the inputs */
|
||||
a->prev = b->prev;
|
||||
*tail = a;
|
||||
}
|
||||
|
||||
/* Move one element from input list to pending */
|
||||
list->prev = pending;
|
||||
pending = list;
|
||||
list = list->next;
|
||||
pending->next = NULL;
|
||||
count++;
|
||||
} while (list);
|
||||
|
||||
/* End of input; merge together all the pending lists. */
|
||||
list = pending;
|
||||
pending = pending->prev;
|
||||
for (;;) {
|
||||
struct list_head *next = pending->prev;
|
||||
|
||||
if (!next)
|
||||
break;
|
||||
list = merge(priv, cmp, pending, list);
|
||||
pending = next;
|
||||
}
|
||||
/* The final merge, rebuilding prev links */
|
||||
merge_final(priv, cmp, head, pending, list);
|
||||
}
|
||||
|
||||
#if BUILD_RK_LIST_TEST
|
||||
#include "vpu_mem.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOOP_RK_LIST 600
|
||||
|
||||
#define COUNT_ADD 100
|
||||
#define COUNT_DEL 99
|
||||
|
||||
volatile int err = 0;
|
||||
|
||||
static int mpp_list_fifo_test(mpp_list *list_0)
|
||||
{
|
||||
int count;
|
||||
VPUMemLinear_t m;
|
||||
for (count = 0; count < COUNT_ADD; count++) {
|
||||
err |= VPUMallocLinear(&m, 100);
|
||||
if (err) {
|
||||
printf("VPUMallocLinear in mpp_list_fifo_test\n");
|
||||
break;
|
||||
}
|
||||
err |= list_0->add_at_head(&m, sizeof(m));
|
||||
if (err) {
|
||||
printf("add_at_head in mpp_list_fifo_test\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
for (count = 0; count < COUNT_DEL; count++) {
|
||||
err |= list_0->del_at_tail(&m, sizeof(m));
|
||||
if (err) {
|
||||
printf("del_at_tail in mpp_list_fifo_test\n");
|
||||
break;
|
||||
}
|
||||
err |= VPUFreeLinear(&m);
|
||||
if (err) {
|
||||
printf("VPUFreeLinear in mpp_list_fifo_test\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mpp_list_filo_test(mpp_list *list_0)
|
||||
{
|
||||
int count;
|
||||
VPUMemLinear_t m;
|
||||
for (count = 0; count < COUNT_ADD + COUNT_DEL; count++) {
|
||||
if (count & 1) {
|
||||
err |= list_0->del_at_head(&m, sizeof(m));
|
||||
if (err) {
|
||||
printf("del_at_head in mpp_list_filo_test\n");
|
||||
break;
|
||||
}
|
||||
err |= VPUFreeLinear(&m);
|
||||
if (err) {
|
||||
printf("VPUFreeLinear in mpp_list_fifo_test\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
err |= VPUMallocLinear(&m, 100);
|
||||
if (err) {
|
||||
printf("VPUMallocLinear in mpp_list_filo_test\n");
|
||||
break;
|
||||
}
|
||||
err |= list_0->add_at_head(&m, sizeof(m));
|
||||
if (err) {
|
||||
printf("add_at_head in mpp_list_fifo_test\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void *mpp_list_test_loop_0(void *pdata)
|
||||
{
|
||||
int i;
|
||||
mpp_list *list_0 = (mpp_list *)pdata;
|
||||
|
||||
printf("mpp_list test 0 loop start\n");
|
||||
for (i = 0; i < LOOP_RK_LIST; i++) {
|
||||
err |= mpp_list_filo_test(list_0);
|
||||
if (err) break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
printf("thread: found vpu mem operation err %d\n", err);
|
||||
} else {
|
||||
printf("thread: test done and found no err\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int mpp_list_test_0()
|
||||
{
|
||||
int i, err = 0;
|
||||
printf("mpp_list test 0 FIFO start\n");
|
||||
|
||||
mpp_list *list_0 = new mpp_list((node_destructor)VPUFreeLinear);
|
||||
|
||||
pthread_t mThread;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
pthread_create(&mThread, &attr, mpp_list_test_loop_0, (void*)list_0);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
for (i = 0; i < LOOP_RK_LIST; i++) {
|
||||
err |= mpp_list_fifo_test(list_0);
|
||||
if (err) break;
|
||||
}
|
||||
if (err) {
|
||||
printf("main : found mpp_list operation err %d\n", err);
|
||||
} else {
|
||||
printf("main : test done and found no err\n");
|
||||
}
|
||||
|
||||
void *dummy;
|
||||
pthread_join(mThread, &dummy);
|
||||
|
||||
printf("mpp_list test 0 end size %d\n", list_0->list_size());
|
||||
delete list_0;
|
||||
return err;
|
||||
}
|
||||
|
||||
#define TOTAL_RK_LIST_TEST_COUNT 1
|
||||
|
||||
typedef int (*RK_LIST_TEST_FUNC)(void);
|
||||
RK_LIST_TEST_FUNC test_func[TOTAL_RK_LIST_TEST_COUNT] = {
|
||||
mpp_list_test_0,
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, start = 0, end = 0;
|
||||
if (argc < 2) {
|
||||
end = TOTAL_RK_LIST_TEST_COUNT;
|
||||
} else if (argc == 2) {
|
||||
start = atoi(argv[1]);
|
||||
end = start + 1;
|
||||
} else if (argc == 3) {
|
||||
start = atoi(argv[1]);
|
||||
end = atoi(argv[2]);
|
||||
} else {
|
||||
printf("too many argc %d\n", argc);
|
||||
return -1;
|
||||
}
|
||||
if (start < 0 || start > TOTAL_RK_LIST_TEST_COUNT || end < 0 || end > TOTAL_RK_LIST_TEST_COUNT) {
|
||||
printf("invalid input: start %d end %d\n", start, end);
|
||||
return -1;
|
||||
}
|
||||
for (i = start; i < end; i++) {
|
||||
int err = test_func[i]();
|
||||
if (err) {
|
||||
printf("test case %d return err %d\n", i, err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
66
osal/mpp_queue.c
Normal file
66
osal/mpp_queue.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright (c) 2017 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_queue.h"
|
||||
|
||||
MppQueue* mpp_queue_create(node_destructor func)
|
||||
{
|
||||
MppQueue *queue = mpp_malloc(MppQueue, 1);
|
||||
|
||||
queue->list = mpp_list_create(func);
|
||||
sem_init(&queue->queue_pending, 0, 0);
|
||||
queue->flush_flag = 0;
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
void mpp_queue_destroy(MppQueue *queue)
|
||||
{
|
||||
mpp_list_destroy(queue->list);
|
||||
mpp_free(queue);
|
||||
}
|
||||
|
||||
rk_s32 mpp_queue_push(MppQueue *queue, void *data, rk_s32 size)
|
||||
{
|
||||
rk_s32 ret = rk_ok;
|
||||
|
||||
ret = mpp_list_add_at_tail(queue->list, data, size);
|
||||
queue->flush_flag = 0;
|
||||
sem_post(&queue->queue_pending);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
rk_s32 mpp_queue_pull(MppQueue *queue, void *data, rk_s32 size)
|
||||
{
|
||||
rk_s32 ret = rk_ok;
|
||||
|
||||
if (!queue->flush_flag)
|
||||
sem_wait(&queue->queue_pending);
|
||||
|
||||
mpp_mutex_cond_lock(&queue->list->cond_lock);
|
||||
if (!mpp_list_size(queue->list)) {
|
||||
mpp_mutex_cond_unlock(&queue->list->cond_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mpp_list_del_at_head(queue->list, data, size);
|
||||
mpp_mutex_cond_unlock(&queue->list->cond_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
rk_s32 mpp_queue_flush(MppQueue *queue)
|
||||
{
|
||||
if (queue->flush_flag)
|
||||
return 0;
|
||||
|
||||
queue->flush_flag = 1;
|
||||
sem_post(&queue->queue_pending);
|
||||
mpp_list_flush(queue->list);
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mpp_err.h"
|
||||
#include "mpp_queue.h"
|
||||
|
||||
MppQueue::MppQueue(node_destructor func)
|
||||
: mpp_list(func), mFlushFlag(0)
|
||||
{
|
||||
sem_init(&mQueuePending, 0, 0);
|
||||
}
|
||||
|
||||
MppQueue::~MppQueue()
|
||||
{
|
||||
sem_destroy (&mQueuePending);
|
||||
}
|
||||
|
||||
RK_S32 MppQueue::push(void *data, RK_S32 size)
|
||||
{
|
||||
RK_S32 ret = 0;
|
||||
|
||||
ret = mpp_list::add_at_tail(data, size);
|
||||
mFlushFlag = 0;
|
||||
sem_post(&mQueuePending);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 MppQueue::pull(void *data, RK_S32 size)
|
||||
{
|
||||
if (!mFlushFlag)
|
||||
sem_wait(&mQueuePending);
|
||||
{
|
||||
AutoMutex autoLock(mpp_list::mutex());
|
||||
if (!mpp_list::list_size())
|
||||
return MPP_NOK;
|
||||
|
||||
return mpp_list::del_at_head(data, size);
|
||||
}
|
||||
return MPP_ERR_INIT;
|
||||
}
|
||||
|
||||
RK_S32 MppQueue::flush()
|
||||
{
|
||||
if (mFlushFlag)
|
||||
return 0;
|
||||
|
||||
mFlushFlag = 1;
|
||||
sem_post(&mQueuePending);
|
||||
return mpp_list::flush();
|
||||
}
|
@@ -1,162 +1,288 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright (c) 2015 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "mpp_thread"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_lock.h"
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_thread.h"
|
||||
|
||||
#define MPP_THREAD_DBG_FUNCTION (0x00000001)
|
||||
#define THREAD_DBG_FUNC (0x00000001)
|
||||
|
||||
static RK_U32 thread_debug = 0;
|
||||
static rk_u32 thread_debug = 0;
|
||||
|
||||
#define thread_dbg(flag, fmt, ...) _mpp_dbg(thread_debug, flag, fmt, ## __VA_ARGS__)
|
||||
|
||||
MppThread::MppThread(MppThreadFunc func, void *ctx, const char *name)
|
||||
: mFunction(func),
|
||||
mContext(ctx)
|
||||
MppThread *mpp_thread_create(MppThreadFunc func, void *ctx, const char *name)
|
||||
{
|
||||
mStatus[THREAD_WORK] = MPP_THREAD_UNINITED;
|
||||
mStatus[THREAD_INPUT] = MPP_THREAD_RUNNING;
|
||||
mStatus[THREAD_OUTPUT] = MPP_THREAD_RUNNING;
|
||||
mStatus[THREAD_CONTROL] = MPP_THREAD_RUNNING;
|
||||
MppThread *thread = mpp_malloc(MppThread, 1);
|
||||
|
||||
if (name)
|
||||
strncpy(mName, name, sizeof(mName) - 1);
|
||||
else
|
||||
snprintf(mName, sizeof(mName) - 1, "mpp_thread");
|
||||
if (thread) {
|
||||
thread->func = func;
|
||||
thread->m_ctx = ctx;
|
||||
|
||||
thread->thd_status[THREAD_WORK] = MPP_THREAD_UNINITED;
|
||||
thread->thd_status[THREAD_INPUT] = MPP_THREAD_RUNNING;
|
||||
thread->thd_status[THREAD_OUTPUT] = MPP_THREAD_RUNNING;
|
||||
thread->thd_status[THREAD_CONTROL] = MPP_THREAD_RUNNING;
|
||||
|
||||
if (name) {
|
||||
strncpy(thread->name, name, THREAD_NAME_LEN - 1);
|
||||
thread->name[THREAD_NAME_LEN - 1] = '\0';
|
||||
} else {
|
||||
snprintf(thread->name, THREAD_NAME_LEN, "MppThread");
|
||||
}
|
||||
for (int i = 0; i < THREAD_SIGNAL_BUTT; i++) {
|
||||
mpp_mutex_cond_init(&thread->mutex_cond[i]);
|
||||
}
|
||||
}
|
||||
|
||||
MppThreadStatus MppThread::get_status(MppThreadSignal id)
|
||||
{
|
||||
return mStatus[id];
|
||||
return thread;
|
||||
}
|
||||
|
||||
void MppThread::set_status(MppThreadStatus status, MppThreadSignal id)
|
||||
void mpp_thread_dump_status(MppThread *thread)
|
||||
{
|
||||
mStatus[id] = status;
|
||||
mpp_log("thread %s status: %d %d %d %d\n", thread->name,
|
||||
thread->thd_status[THREAD_WORK], thread->thd_status[THREAD_INPUT],
|
||||
thread->thd_status[THREAD_OUTPUT], thread->thd_status[THREAD_CONTROL]);
|
||||
}
|
||||
|
||||
void MppThread::dump_status()
|
||||
{
|
||||
mpp_log("thread %s status: %d %d %d %d\n", mName,
|
||||
mStatus[THREAD_WORK], mStatus[THREAD_INPUT], mStatus[THREAD_OUTPUT],
|
||||
mStatus[THREAD_CONTROL]);
|
||||
}
|
||||
|
||||
void MppThread::start()
|
||||
void mpp_thread_start(MppThread *thread)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
if (MPP_THREAD_UNINITED == get_status()) {
|
||||
// NOTE: set status here first to avoid unexpected loop quit racing condition
|
||||
set_status(MPP_THREAD_RUNNING);
|
||||
if (0 == pthread_create(&mThread, &attr, mFunction, mContext)) {
|
||||
#ifndef ARMLINUX
|
||||
RK_S32 ret = pthread_setname_np(mThread, mName);
|
||||
if (ret)
|
||||
mpp_err("thread %p setname %s failed\n", mFunction, mName);
|
||||
#endif
|
||||
|
||||
thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n",
|
||||
mName, mFunction, mContext);
|
||||
} else
|
||||
set_status(MPP_THREAD_UNINITED);
|
||||
if (mpp_thread_get_status(thread, THREAD_WORK) == MPP_THREAD_UNINITED) {
|
||||
mpp_thread_set_status(thread, MPP_THREAD_RUNNING, THREAD_WORK);
|
||||
if (0 == pthread_create(&thread->thd, &attr, thread->func, thread->m_ctx)) {
|
||||
#ifndef __linux__
|
||||
int ret = pthread_setname_np(thread->thd, thread->name);
|
||||
if (ret) {
|
||||
mpp_err("thread %p setname %s failed\n", thread->func, thread->name);
|
||||
}
|
||||
#endif
|
||||
thread_dbg(THREAD_DBG_FUNC, "thread %s %p context %p create success\n",
|
||||
thread->name, thread->func, thread->m_ctx);
|
||||
} else {
|
||||
mpp_thread_set_status(thread, MPP_THREAD_UNINITED, THREAD_WORK);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
void MppThread::stop()
|
||||
void mpp_thread_stop(MppThread *thread)
|
||||
{
|
||||
if (MPP_THREAD_UNINITED != get_status()) {
|
||||
lock();
|
||||
set_status(MPP_THREAD_STOPPING);
|
||||
thread_dbg(MPP_THREAD_DBG_FUNCTION,
|
||||
"MPP_THREAD_STOPPING status set mThread %p", this);
|
||||
signal();
|
||||
unlock();
|
||||
if (mpp_thread_get_status(thread, THREAD_WORK) != MPP_THREAD_UNINITED) {
|
||||
void *dummy;
|
||||
pthread_join(mThread, &dummy);
|
||||
thread_dbg(MPP_THREAD_DBG_FUNCTION,
|
||||
"thread %s %p context %p destroy success\n",
|
||||
mName, mFunction, mContext);
|
||||
|
||||
set_status(MPP_THREAD_UNINITED);
|
||||
mpp_thread_lock(thread, THREAD_WORK);
|
||||
mpp_thread_set_status(thread, MPP_THREAD_STOPPING, THREAD_WORK);
|
||||
|
||||
thread_dbg(THREAD_DBG_FUNC, "MPP_THREAD_STOPPING status set thd %p\n", (void *)thread);
|
||||
mpp_thread_signal(thread, THREAD_WORK);
|
||||
mpp_thread_unlock(thread, THREAD_WORK);
|
||||
|
||||
pthread_join(thread->thd, &dummy);
|
||||
thread_dbg(THREAD_DBG_FUNC, "thread %s %p context %p destroy success\n", thread->name, thread->func, thread->m_ctx);
|
||||
|
||||
mpp_thread_set_status(thread, MPP_THREAD_UNINITED, THREAD_WORK);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32CE__)
|
||||
//
|
||||
// Usage: SetThreadName ((DWORD)-1, "MainThread");
|
||||
//
|
||||
#include <windows.h>
|
||||
const DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||
|
||||
#pragma pack(push,8)
|
||||
typedef struct tagTHREADNAME_INFO {
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
} THREADNAME_INFO;
|
||||
#pragma pack(pop)
|
||||
|
||||
void SetThreadName(DWORD dwThreadID, const char* threadName)
|
||||
void mpp_thread_destroy(MppThread *thread)
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = threadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6320 6322)
|
||||
__try {
|
||||
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
if (thread) {
|
||||
mpp_thread_stop(thread);
|
||||
mpp_free(thread);
|
||||
}
|
||||
#pragma warning(pop)
|
||||
}
|
||||
|
||||
|
||||
#ifndef ARMLINUX
|
||||
/*
|
||||
* add pthread_setname_np for windows
|
||||
*/
|
||||
int pthread_setname_np(pthread_t thread, const char *name)
|
||||
void mpp_mutex_init(MppMutex *mutex)
|
||||
{
|
||||
DWORD dwThreadID = pthread_getw32threadid_np(thread);
|
||||
SetThreadName(dwThreadID, name);
|
||||
return 0;
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mutex->m_lock, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
void mpp_mutex_destroy(MppMutex *mutex)
|
||||
{
|
||||
pthread_mutex_destroy(&mutex->m_lock);
|
||||
}
|
||||
|
||||
void mpp_mutex_lock(MppMutex *mutex)
|
||||
{
|
||||
pthread_mutex_lock(&mutex->m_lock);
|
||||
}
|
||||
|
||||
void mpp_mutex_unlock(MppMutex *mutex)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex->m_lock);
|
||||
}
|
||||
|
||||
int mpp_mutex_trylock(MppMutex *mutex)
|
||||
{
|
||||
return pthread_mutex_trylock(&mutex->m_lock);
|
||||
}
|
||||
|
||||
// MppCond functions
|
||||
void mpp_cond_init(MppCond *condition)
|
||||
{
|
||||
pthread_cond_init(&condition->m_cond, NULL);
|
||||
}
|
||||
|
||||
void mpp_cond_destroy(MppCond *condition)
|
||||
{
|
||||
pthread_cond_destroy(&condition->m_cond);
|
||||
}
|
||||
|
||||
rk_s32 mpp_cond_wait(MppCond *condition, MppMutex *mutex)
|
||||
{
|
||||
return pthread_cond_wait(&condition->m_cond, &mutex->m_lock);
|
||||
}
|
||||
|
||||
rk_s32 mpp_cond_timedwait(MppCond *condition, MppMutex *mutex, rk_s64 timeout)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
|
||||
ts.tv_sec += timeout / 1000;
|
||||
ts.tv_nsec += (timeout % 1000) * 1000000;
|
||||
ts.tv_sec += ts.tv_nsec / 1000000000;
|
||||
ts.tv_nsec %= 1000000000;
|
||||
|
||||
return pthread_cond_timedwait(&condition->m_cond, &mutex->m_lock, &ts);
|
||||
}
|
||||
|
||||
rk_s32 mpp_cond_signal(MppCond *condition)
|
||||
{
|
||||
return pthread_cond_signal(&condition->m_cond);
|
||||
}
|
||||
|
||||
rk_s32 mpp_cond_broadcast(MppCond *condition)
|
||||
{
|
||||
return pthread_cond_broadcast(&condition->m_cond);
|
||||
}
|
||||
|
||||
// MppMutexCond functions
|
||||
void mpp_mutex_cond_init(MppMutexCond *mutexCond)
|
||||
{
|
||||
mpp_mutex_init(&mutexCond->m_lock);
|
||||
mpp_cond_init(&mutexCond->m_cond);
|
||||
}
|
||||
|
||||
void mpp_mutex_cond_destroy(MppMutexCond *mutexCond)
|
||||
{
|
||||
mpp_mutex_destroy(&mutexCond->m_lock);
|
||||
mpp_cond_destroy(&mutexCond->m_cond);
|
||||
}
|
||||
|
||||
void mpp_mutex_cond_lock(MppMutexCond *mutexCond)
|
||||
{
|
||||
mpp_mutex_lock(&mutexCond->m_lock);
|
||||
}
|
||||
|
||||
void mpp_mutex_cond_unlock(MppMutexCond *mutexCond)
|
||||
{
|
||||
mpp_mutex_unlock(&mutexCond->m_lock);
|
||||
}
|
||||
|
||||
int mpp_mutex_cond_trylock(MppMutexCond *mutexCond)
|
||||
{
|
||||
return mpp_mutex_trylock(&mutexCond->m_lock);
|
||||
}
|
||||
|
||||
rk_s32 mpp_mutex_cond_wait(MppMutexCond *mutexCond)
|
||||
{
|
||||
return mpp_cond_wait(&mutexCond->m_cond, &mutexCond->m_lock);
|
||||
}
|
||||
|
||||
rk_s32 mpp_mutex_cond_timedwait(MppMutexCond *mutexCond, rk_s64 timeout)
|
||||
{
|
||||
return mpp_cond_timedwait(&mutexCond->m_cond, &mutexCond->m_lock, timeout);
|
||||
}
|
||||
|
||||
void mpp_mutex_cond_signal(MppMutexCond *mutexCond)
|
||||
{
|
||||
mpp_cond_signal(&mutexCond->m_cond);
|
||||
}
|
||||
|
||||
void mpp_mutex_cond_broadcast(MppMutexCond *mutexCond)
|
||||
{
|
||||
mpp_cond_broadcast(&mutexCond->m_cond);
|
||||
}
|
||||
|
||||
// MppThread functions
|
||||
void mpp_thread_init(MppThread *thread, MppThreadFunc func, void *ctx, const char *name)
|
||||
{
|
||||
thread->func = func;
|
||||
thread->m_ctx = ctx;
|
||||
if (name) {
|
||||
strncpy(thread->name, name, THREAD_NAME_LEN - 1);
|
||||
thread->name[THREAD_NAME_LEN - 1] = '\0';
|
||||
}
|
||||
for (int i = 0; i < THREAD_SIGNAL_BUTT; i++) {
|
||||
mpp_mutex_cond_init(&thread->mutex_cond[i]);
|
||||
thread->thd_status[i] = MPP_THREAD_UNINITED;
|
||||
}
|
||||
}
|
||||
|
||||
void mpp_thread_set_status(MppThread *thread, MppThreadStatus status, MppThreadSignalId id)
|
||||
{
|
||||
assert(id < THREAD_SIGNAL_BUTT);
|
||||
thread->thd_status[id] = status;
|
||||
}
|
||||
|
||||
MppThreadStatus mpp_thread_get_status(MppThread *thread, MppThreadSignalId id)
|
||||
{
|
||||
assert(id < THREAD_SIGNAL_BUTT);
|
||||
return thread->thd_status[id];
|
||||
}
|
||||
|
||||
void mpp_thread_lock(MppThread *thread, MppThreadSignalId id)
|
||||
{
|
||||
assert(id < THREAD_SIGNAL_BUTT);
|
||||
mpp_mutex_cond_lock(&thread->mutex_cond[id]);
|
||||
}
|
||||
|
||||
void mpp_thread_unlock(MppThread *thread, MppThreadSignalId id)
|
||||
{
|
||||
assert(id < THREAD_SIGNAL_BUTT);
|
||||
mpp_mutex_cond_unlock(&thread->mutex_cond[id]);
|
||||
}
|
||||
|
||||
void mpp_thread_wait(MppThread *thread, MppThreadSignalId id)
|
||||
{
|
||||
assert(id < THREAD_SIGNAL_BUTT);
|
||||
MppThreadStatus status = thread->thd_status[id];
|
||||
thread->thd_status[id] = MPP_THREAD_WAITING;
|
||||
mpp_mutex_cond_wait(&thread->mutex_cond[id]);
|
||||
|
||||
if (thread->thd_status[id] == MPP_THREAD_WAITING)
|
||||
thread->thd_status[id] = status;
|
||||
}
|
||||
|
||||
void mpp_thread_signal(MppThread *thread, MppThreadSignalId id)
|
||||
{
|
||||
assert(id < THREAD_SIGNAL_BUTT);
|
||||
mpp_mutex_cond_signal(&thread->mutex_cond[id]);
|
||||
}
|
||||
|
||||
typedef struct MppSThdImpl_t {
|
||||
char *name;
|
||||
MppSThdFunc func;
|
||||
MppSThdStatus status;
|
||||
RK_S32 idx;
|
||||
rk_s32 idx;
|
||||
pthread_t thd;
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t cond;
|
||||
@@ -165,7 +291,7 @@ typedef struct MppSThdImpl_t {
|
||||
|
||||
typedef struct MppSThdGrpImpl_t {
|
||||
char name[THREAD_NAME_LEN];
|
||||
RK_S32 count;
|
||||
rk_s32 count;
|
||||
MppSThdStatus status;
|
||||
pthread_mutex_t lock;
|
||||
MppSThdImpl thds[];
|
||||
@@ -185,15 +311,15 @@ static const char *state2str(MppSThdStatus state)
|
||||
return state < MPP_STHD_BUTT ? strof_sthd_status[state] : strof_sthd_status[MPP_STHD_BUTT];
|
||||
}
|
||||
|
||||
static RK_S32 check_sthd(const char *name, MppSThdImpl *thd)
|
||||
static rk_s32 check_sthd(const char *name, MppSThdImpl *thd)
|
||||
{
|
||||
if (!thd) {
|
||||
mpp_err("MppSThd NULL found at %s\n", name);
|
||||
mpp_err("mpp_sthd NULL found at %s\n", name);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
if (thd->ctx.thd != thd) {
|
||||
mpp_err("MppSThd check %p:%p mismatch at %s\n", thd->ctx.thd, thd, name);
|
||||
mpp_err("mpp_sthd check %p:%p mismatch at %s\n", thd->ctx.thd, thd, name);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
@@ -202,7 +328,7 @@ static RK_S32 check_sthd(const char *name, MppSThdImpl *thd)
|
||||
|
||||
#define CHECK_STHD(thd) check_sthd(__FUNCTION__, (MppSThdImpl *)(thd))
|
||||
|
||||
static void mpp_sthd_init(MppSThdImpl *thd, RK_S32 idx)
|
||||
static void mpp_sthd_init(MppSThdImpl *thd, rk_s32 idx)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
@@ -248,7 +374,7 @@ static MPP_RET mpp_sthd_create(MppSThdImpl *thd)
|
||||
if (ret)
|
||||
mpp_err("%s %p setname failed\n", thd->thd, thd->func);
|
||||
|
||||
thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n",
|
||||
thread_dbg(THREAD_DBG_FUNC, "thread %s %p context %p create success\n",
|
||||
thd->name, thd->func, thd->ctx.ctx);
|
||||
ret = MPP_OK;
|
||||
} else {
|
||||
@@ -262,7 +388,7 @@ static MPP_RET mpp_sthd_create(MppSThdImpl *thd)
|
||||
|
||||
MppSThd mpp_sthd_get(const char *name)
|
||||
{
|
||||
RK_S32 size = MPP_ALIGN(sizeof(MppSThdImpl), 8) + THREAD_NAME_LEN;
|
||||
rk_s32 size = MPP_ALIGN(sizeof(MppSThdImpl), 8) + THREAD_NAME_LEN;
|
||||
MppSThdImpl *thd = mpp_calloc_size(MppSThdImpl, size);
|
||||
|
||||
if (!thd) {
|
||||
@@ -312,7 +438,7 @@ const char* mpp_sthd_get_name(MppSThd thd)
|
||||
return impl->name;
|
||||
}
|
||||
|
||||
RK_S32 mpp_sthd_get_idx(MppSThd thd)
|
||||
rk_s32 mpp_sthd_get_idx(MppSThd thd)
|
||||
{
|
||||
MppSThdImpl *impl = (MppSThdImpl *)thd;
|
||||
|
||||
@@ -321,7 +447,7 @@ RK_S32 mpp_sthd_get_idx(MppSThd thd)
|
||||
return impl->idx;
|
||||
}
|
||||
|
||||
RK_S32 mpp_sthd_check(MppSThd thd)
|
||||
rk_s32 mpp_sthd_check(MppSThd thd)
|
||||
{
|
||||
return CHECK_STHD(thd);
|
||||
}
|
||||
@@ -483,18 +609,18 @@ void mpp_sthd_broadcast(MppSThd thd)
|
||||
pthread_cond_broadcast(&impl->cond);
|
||||
}
|
||||
|
||||
MppSThdGrp mpp_sthd_grp_get(const char *name, RK_S32 count)
|
||||
MppSThdGrp mpp_sthd_grp_get(const char *name, rk_s32 count)
|
||||
{
|
||||
MppSThdGrpImpl *grp = NULL;
|
||||
|
||||
if (count > 0) {
|
||||
RK_S32 elem_size = MPP_ALIGN(sizeof(MppSThdImpl), 8);
|
||||
RK_S32 total_size = MPP_ALIGN(sizeof(MppSThdGrpImpl), 8) + count * elem_size;
|
||||
rk_s32 elem_size = MPP_ALIGN(sizeof(MppSThdImpl), 8);
|
||||
rk_s32 total_size = MPP_ALIGN(sizeof(MppSThdGrpImpl), 8) + count * elem_size;
|
||||
|
||||
grp = mpp_calloc_size(MppSThdGrpImpl, total_size);
|
||||
if (grp) {
|
||||
pthread_mutexattr_t attr;
|
||||
RK_S32 i;
|
||||
rk_s32 i;
|
||||
|
||||
if (!name)
|
||||
name = "mpp_sthd_grp";
|
||||
@@ -525,7 +651,7 @@ MppSThdGrp mpp_sthd_grp_get(const char *name, RK_S32 count)
|
||||
void mpp_sthd_grp_put(MppSThdGrp grp)
|
||||
{
|
||||
MppSThdGrpImpl *impl = (MppSThdGrpImpl *)grp;
|
||||
RK_S32 i;
|
||||
rk_s32 i;
|
||||
|
||||
mpp_assert(impl);
|
||||
mpp_assert(impl->status == MPP_STHD_UNINITED || impl->status == MPP_STHD_READY);
|
||||
@@ -552,7 +678,7 @@ void mpp_sthd_grp_setup(MppSThdGrp grp, MppSThdFunc func, void *ctx)
|
||||
case MPP_STHD_UNINITED :
|
||||
case MPP_STHD_READY : {
|
||||
MppSThdStatus next = func ? MPP_STHD_READY : MPP_STHD_UNINITED;
|
||||
RK_S32 i;
|
||||
rk_s32 i;
|
||||
|
||||
for (i = 0; i < impl->count; i++) {
|
||||
MppSThdImpl *thd = &impl->thds[i];
|
||||
@@ -582,7 +708,7 @@ void mpp_sthd_grp_start(MppSThdGrp grp)
|
||||
status = impl->status;
|
||||
switch (status) {
|
||||
case MPP_STHD_READY : {
|
||||
RK_S32 i;
|
||||
rk_s32 i;
|
||||
|
||||
for (i = 0; i < impl->count; i++)
|
||||
mpp_sthd_start(&impl->thds[i]);
|
||||
@@ -609,7 +735,7 @@ void mpp_sthd_grp_stop(MppSThdGrp grp)
|
||||
switch (status) {
|
||||
case MPP_STHD_RUNNING :
|
||||
case MPP_STHD_WAITING : {
|
||||
RK_S32 i;
|
||||
rk_s32 i;
|
||||
|
||||
impl->status = MPP_STHD_STOPPING;
|
||||
|
||||
@@ -642,7 +768,7 @@ void mpp_sthd_grp_stop_sync(MppSThdGrp grp)
|
||||
switch (status) {
|
||||
case MPP_STHD_STOPPING : {
|
||||
void *dummy;
|
||||
RK_S32 i;
|
||||
rk_s32 i;
|
||||
|
||||
status = MPP_STHD_STOPPING;
|
||||
for (i = 0; i < impl->count; i++) {
|
||||
@@ -660,7 +786,7 @@ void mpp_sthd_grp_stop_sync(MppSThdGrp grp)
|
||||
pthread_mutex_unlock(&impl->lock);
|
||||
}
|
||||
|
||||
MppSThd mpp_sthd_grp_get_each(MppSThdGrp grp, RK_S32 idx)
|
||||
MppSThd mpp_sthd_grp_get_each(MppSThdGrp grp, rk_s32 idx)
|
||||
{
|
||||
MppSThdGrpImpl *impl = (MppSThdGrpImpl *)grp;
|
||||
MppSThd ret = NULL;
|
@@ -1,21 +1,11 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright (c) 2015 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "mpp_time"
|
||||
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/timerfd.h>
|
||||
@@ -27,32 +17,18 @@
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_thread.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
RK_S64 mpp_time()
|
||||
{
|
||||
struct timeb tb;
|
||||
ftime(&tb);
|
||||
return ((RK_S64)tb.time * 1000 + (RK_S64)tb.millitm) * 1000;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <time.h>
|
||||
|
||||
RK_S64 mpp_time()
|
||||
rk_s64 mpp_time()
|
||||
{
|
||||
struct timespec time = {0, 0};
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return (RK_S64)time.tv_sec * 1000000 + (RK_S64)time.tv_nsec / 1000;
|
||||
return (rk_s64)time.tv_sec * 1000000 + (rk_s64)time.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, const char *fmt)
|
||||
void mpp_time_diff(rk_s64 start, rk_s64 end, rk_s64 limit, const char *fmt)
|
||||
{
|
||||
RK_S64 diff = end - start;
|
||||
rk_s64 diff = end - start;
|
||||
|
||||
if (diff >= limit)
|
||||
mpp_dbg(MPP_DBG_TIMING, "%s timing %lld us\n", fmt, diff);
|
||||
}
|
||||
@@ -60,11 +36,11 @@ void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, const char *fmt)
|
||||
typedef struct MppClockImpl_t {
|
||||
const char *check;
|
||||
char name[16];
|
||||
RK_U32 enable;
|
||||
RK_S64 base;
|
||||
RK_S64 time;
|
||||
RK_S64 sum;
|
||||
RK_S64 count;
|
||||
rk_u32 enable;
|
||||
rk_s64 base;
|
||||
rk_s64 time;
|
||||
rk_s64 sum;
|
||||
rk_s64 count;
|
||||
} MppClockImpl;
|
||||
|
||||
static const char *clock_name = "mpp_clock";
|
||||
@@ -82,6 +58,7 @@ MPP_RET check_is_mpp_clock(void *clock)
|
||||
MppClock mpp_clock_get(const char *name)
|
||||
{
|
||||
MppClockImpl *impl = mpp_calloc(MppClockImpl, 1);
|
||||
|
||||
if (impl) {
|
||||
impl->check = clock_name;
|
||||
snprintf(impl->name, sizeof(impl->name) - 1, name, NULL);
|
||||
@@ -93,7 +70,7 @@ MppClock mpp_clock_get(const char *name)
|
||||
|
||||
void mpp_clock_put(MppClock clock)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
if (check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
return;
|
||||
}
|
||||
@@ -101,25 +78,26 @@ void mpp_clock_put(MppClock clock)
|
||||
mpp_free(clock);
|
||||
}
|
||||
|
||||
void mpp_clock_enable(MppClock clock, RK_U32 enable)
|
||||
void mpp_clock_enable(MppClock clock, rk_u32 enable)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
if (check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
} else {
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
p->enable = (enable) ? (1) : (0);
|
||||
}
|
||||
}
|
||||
|
||||
RK_S64 mpp_clock_start(MppClock clock)
|
||||
rk_s64 mpp_clock_start(MppClock clock)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
if (check_is_mpp_clock(p)) {
|
||||
mpp_err_f("invalid clock %p\n", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
if (!p->enable)
|
||||
return 0;
|
||||
|
||||
@@ -128,36 +106,39 @@ RK_S64 mpp_clock_start(MppClock clock)
|
||||
return p->base;
|
||||
}
|
||||
|
||||
RK_S64 mpp_clock_pause(MppClock clock)
|
||||
rk_s64 mpp_clock_pause(MppClock clock)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
rk_s64 time;
|
||||
|
||||
if (check_is_mpp_clock(p)) {
|
||||
mpp_err_f("invalid clock %p\n", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
if (!p->enable)
|
||||
return 0;
|
||||
|
||||
RK_S64 time = mpp_time();
|
||||
time = mpp_time();
|
||||
|
||||
if (!p->time) {
|
||||
// first pause after start
|
||||
p->sum += time - p->base;
|
||||
p->count++;
|
||||
}
|
||||
|
||||
p->time = time;
|
||||
|
||||
return p->time - p->base;
|
||||
}
|
||||
|
||||
RK_S64 mpp_clock_reset(MppClock clock)
|
||||
rk_s64 mpp_clock_reset(MppClock clock)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
} else {
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
if (check_is_mpp_clock(p)) {
|
||||
mpp_err_f("invalid clock %p\n", p);
|
||||
} else {
|
||||
p->base = 0;
|
||||
p->time = 0;
|
||||
p->sum = 0;
|
||||
@@ -167,36 +148,39 @@ RK_S64 mpp_clock_reset(MppClock clock)
|
||||
return 0;
|
||||
}
|
||||
|
||||
RK_S64 mpp_clock_get_sum(MppClock clock)
|
||||
rk_s64 mpp_clock_get_sum(MppClock clock)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
if (check_is_mpp_clock(p)) {
|
||||
mpp_err_f("invalid clock %p\n", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
return (p->enable) ? (p->sum) : (0);
|
||||
}
|
||||
|
||||
RK_S64 mpp_clock_get_count(MppClock clock)
|
||||
rk_s64 mpp_clock_get_count(MppClock clock)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
if (check_is_mpp_clock(p)) {
|
||||
mpp_err_f("invalid clock %p\n", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
return (p->enable) ? (p->count) : (0);
|
||||
}
|
||||
|
||||
const char *mpp_clock_get_name(MppClock clock)
|
||||
{
|
||||
if (NULL == clock || check_is_mpp_clock(clock)) {
|
||||
mpp_err_f("invalid clock %p\n", clock);
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
|
||||
if (check_is_mpp_clock(p)) {
|
||||
mpp_err_f("invalid clock %p\n", p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MppClockImpl *p = (MppClockImpl *)clock;
|
||||
return p->name;
|
||||
}
|
||||
|
||||
@@ -204,11 +188,11 @@ typedef struct MppTimerImpl_t {
|
||||
const char *check;
|
||||
char name[16];
|
||||
|
||||
RK_S32 enabled;
|
||||
RK_S32 initial;
|
||||
RK_S32 interval;
|
||||
RK_S32 timer_fd;
|
||||
RK_S32 epoll_fd;
|
||||
rk_s32 enabled;
|
||||
rk_s32 initial;
|
||||
rk_s32 interval;
|
||||
rk_s32 timer_fd;
|
||||
rk_s32 epoll_fd;
|
||||
|
||||
MppThread *thd;
|
||||
MppThreadFunc func;
|
||||
@@ -230,10 +214,10 @@ MPP_RET check_is_mpp_timer(void *timer)
|
||||
static void *mpp_timer_thread(void *ctx)
|
||||
{
|
||||
struct itimerspec ts;
|
||||
RK_S32 ret = 0;
|
||||
MppTimerImpl *impl = (MppTimerImpl *)ctx;
|
||||
MppThread *thd = impl->thd;
|
||||
RK_S32 timer_fd = impl->timer_fd;
|
||||
rk_s32 timer_fd = impl->timer_fd;
|
||||
rk_s32 ret = 0;
|
||||
|
||||
// first expire time
|
||||
ts.it_value.tv_sec = impl->initial / 1000;
|
||||
@@ -250,19 +234,20 @@ static void *mpp_timer_thread(void *ctx)
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (MPP_THREAD_RUNNING != thd->get_status())
|
||||
break;
|
||||
|
||||
struct epoll_event events;
|
||||
rk_s32 fd_cnt;
|
||||
|
||||
if (MPP_THREAD_RUNNING != mpp_thread_get_status(thd, THREAD_WORK))
|
||||
break;
|
||||
|
||||
memset(&events, 0, sizeof(events));
|
||||
|
||||
/* wait epoll event */
|
||||
RK_S32 fd_cnt = epoll_wait(impl->epoll_fd, &events, 1, 500);
|
||||
fd_cnt = epoll_wait(impl->epoll_fd, &events, 1, 500);
|
||||
if (fd_cnt && (events.events & EPOLLIN) && (events.data.fd == timer_fd)) {
|
||||
RK_U64 exp = 0;
|
||||
|
||||
rk_u64 exp = 0;
|
||||
ssize_t cnt = read(timer_fd, &exp, sizeof(exp));
|
||||
|
||||
mpp_assert(cnt == sizeof(exp));
|
||||
impl->func(impl->ctx);
|
||||
}
|
||||
@@ -273,15 +258,15 @@ static void *mpp_timer_thread(void *ctx)
|
||||
|
||||
MppTimer mpp_timer_get(const char *name)
|
||||
{
|
||||
RK_S32 timer_fd = -1;
|
||||
RK_S32 epoll_fd = -1;
|
||||
MppTimerImpl *impl = NULL;
|
||||
rk_s32 timer_fd = -1;
|
||||
rk_s32 epoll_fd = -1;
|
||||
|
||||
do {
|
||||
struct epoll_event event;
|
||||
|
||||
impl = mpp_calloc(MppTimerImpl, 1);
|
||||
if (NULL == impl) {
|
||||
if (!impl) {
|
||||
mpp_err_f("malloc failed\n");
|
||||
break;
|
||||
}
|
||||
@@ -334,60 +319,63 @@ MppTimer mpp_timer_get(const char *name)
|
||||
|
||||
void mpp_timer_set_callback(MppTimer timer, MppThreadFunc func, void *ctx)
|
||||
{
|
||||
if (NULL == timer || check_is_mpp_timer(timer)) {
|
||||
mpp_err_f("invalid timer %p\n", timer);
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
|
||||
if (check_is_mpp_timer(impl)) {
|
||||
mpp_err_f("invalid timer %p\n", impl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NULL == func) {
|
||||
if (!func) {
|
||||
mpp_err_f("invalid NULL callback\n");
|
||||
return;
|
||||
}
|
||||
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
impl->func = func;
|
||||
impl->ctx = ctx;
|
||||
}
|
||||
|
||||
void mpp_timer_set_timing(MppTimer timer, RK_S32 initial, RK_S32 interval)
|
||||
void mpp_timer_set_timing(MppTimer timer, rk_s32 initial, rk_s32 interval)
|
||||
{
|
||||
if (NULL == timer || check_is_mpp_timer(timer)) {
|
||||
mpp_err_f("invalid timer %p\n", timer);
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
|
||||
if (check_is_mpp_timer(impl)) {
|
||||
mpp_err_f("invalid timer %p\n", impl);
|
||||
return;
|
||||
}
|
||||
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
impl->initial = initial;
|
||||
impl->interval = interval;
|
||||
}
|
||||
|
||||
void mpp_timer_set_enable(MppTimer timer, RK_S32 enable)
|
||||
void mpp_timer_set_enable(MppTimer timer, rk_s32 enable)
|
||||
{
|
||||
if (NULL == timer || check_is_mpp_timer(timer)) {
|
||||
mpp_err_f("invalid timer %p\n", timer);
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
|
||||
if (check_is_mpp_timer(impl)) {
|
||||
mpp_err_f("invalid timer %p\n", impl);
|
||||
return;
|
||||
}
|
||||
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
|
||||
if (NULL == impl->func || impl->initial < 0 || impl->interval < 0) {
|
||||
if (!impl->func || impl->initial < 0 || impl->interval < 0) {
|
||||
mpp_err_f("invalid func %p initial %d interval %d\n",
|
||||
impl->func, impl->initial, impl->interval);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
if (!impl->enabled && NULL == impl->thd) {
|
||||
MppThread *thd = new MppThread(mpp_timer_thread, impl, impl->name);
|
||||
if (!impl->enabled && !impl->thd) {
|
||||
MppThread *thd = mpp_thread_create(mpp_timer_thread, impl, impl->name);
|
||||
|
||||
if (thd) {
|
||||
impl->thd = thd;
|
||||
impl->enabled = 1;
|
||||
thd->start();
|
||||
mpp_thread_start(impl->thd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (impl->enabled && impl->thd) {
|
||||
impl->thd->stop();
|
||||
mpp_thread_stop(impl->thd);
|
||||
impl->enabled = 0;
|
||||
}
|
||||
}
|
||||
@@ -395,15 +383,15 @@ void mpp_timer_set_enable(MppTimer timer, RK_S32 enable)
|
||||
|
||||
void mpp_timer_put(MppTimer timer)
|
||||
{
|
||||
if (NULL == timer || check_is_mpp_timer(timer)) {
|
||||
mpp_err_f("invalid timer %p\n", timer);
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
|
||||
if (check_is_mpp_timer(impl)) {
|
||||
mpp_err_f("invalid timer %p\n", impl);
|
||||
return;
|
||||
}
|
||||
|
||||
MppTimerImpl *impl = (MppTimerImpl *)timer;
|
||||
|
||||
if (impl->enabled)
|
||||
mpp_timer_set_enable(timer, 0);
|
||||
mpp_timer_set_enable(impl, 0);
|
||||
|
||||
if (impl->timer_fd >= 0) {
|
||||
close(impl->timer_fd);
|
||||
@@ -416,7 +404,7 @@ void mpp_timer_put(MppTimer timer)
|
||||
}
|
||||
|
||||
if (impl->thd) {
|
||||
delete impl->thd;
|
||||
mpp_thread_destroy(impl->thd);
|
||||
impl->thd = NULL;
|
||||
}
|
||||
|
||||
@@ -426,34 +414,22 @@ void mpp_timer_put(MppTimer timer)
|
||||
}
|
||||
}
|
||||
|
||||
AutoTiming::AutoTiming(const char *name)
|
||||
{
|
||||
mStart = mpp_time();
|
||||
mName = name;
|
||||
}
|
||||
|
||||
AutoTiming::~AutoTiming()
|
||||
{
|
||||
mEnd = mpp_time();
|
||||
mpp_log("%s timing %lld us\n", mName, mEnd - mStart);
|
||||
}
|
||||
|
||||
#define STOPWATCH_TRACE_STR_LEN 64
|
||||
|
||||
typedef struct MppStopwatchNode_t {
|
||||
char event[STOPWATCH_TRACE_STR_LEN];
|
||||
RK_S64 time;
|
||||
rk_s64 time;
|
||||
} MppStopwatchNode;
|
||||
|
||||
typedef struct MppStopwatchImpl_t {
|
||||
const char *check;
|
||||
char name[STOPWATCH_TRACE_STR_LEN];
|
||||
|
||||
RK_S32 max_count;
|
||||
RK_S32 filled_count;
|
||||
RK_S32 show_on_exit;
|
||||
RK_S32 log_len;
|
||||
RK_S64 time_elipsed;
|
||||
rk_s32 max_count;
|
||||
rk_s32 filled_count;
|
||||
rk_s32 show_on_exit;
|
||||
rk_s32 log_len;
|
||||
rk_s64 time_elipsed;
|
||||
|
||||
MppStopwatchNode *nodes;
|
||||
} MppStopwatchImpl;
|
||||
@@ -489,33 +465,36 @@ MppStopwatch mpp_stopwatch_get(const char *name)
|
||||
return impl;
|
||||
}
|
||||
|
||||
void mpp_stopwatch_set_show_on_exit(MppStopwatch stopwatch, RK_S32 show_on_exit)
|
||||
void mpp_stopwatch_set_show_on_exit(MppStopwatch stopwatch, rk_s32 show_on_exit)
|
||||
{
|
||||
if (NULL == stopwatch || check_is_mpp_stopwatch(stopwatch)) {
|
||||
mpp_err_f("invalid stopwatch %p\n", stopwatch);
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
|
||||
if (check_is_mpp_stopwatch(impl)) {
|
||||
mpp_err_f("invalid stopwatch %p\n", impl);
|
||||
return;
|
||||
}
|
||||
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
impl->show_on_exit = show_on_exit;
|
||||
}
|
||||
|
||||
void mpp_stopwatch_record(MppStopwatch stopwatch, const char *event)
|
||||
{
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
|
||||
/* do not print noisy log */
|
||||
if (NULL == stopwatch)
|
||||
if (!impl)
|
||||
return;
|
||||
|
||||
if (check_is_mpp_stopwatch(stopwatch)) {
|
||||
mpp_err_f("invalid stopwatch %p on %s\n", stopwatch, event);
|
||||
if (check_is_mpp_stopwatch(impl)) {
|
||||
mpp_err_f("invalid stopwatch %p on %s\n", impl, event);
|
||||
return;
|
||||
}
|
||||
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
if (impl->filled_count >= impl->max_count) {
|
||||
RK_S32 max_count = impl->max_count * 2;
|
||||
rk_s32 max_count = impl->max_count * 2;
|
||||
MppStopwatchNode *nodes = mpp_realloc(impl->nodes, MppStopwatchNode,
|
||||
max_count);
|
||||
|
||||
if (nodes) {
|
||||
impl->nodes = nodes;
|
||||
impl->max_count = max_count;
|
||||
@@ -527,8 +506,8 @@ void mpp_stopwatch_record(MppStopwatch stopwatch, const char *event)
|
||||
|
||||
node->time = mpp_time();
|
||||
if (event) {
|
||||
RK_S32 len = snprintf(node->event, sizeof(node->event) - 1,
|
||||
"%s", event);
|
||||
rk_s32 len = snprintf(node->event, sizeof(node->event) - 1, "%s", event);
|
||||
|
||||
if (len > impl->log_len)
|
||||
impl->log_len = len;
|
||||
}
|
||||
@@ -538,16 +517,17 @@ void mpp_stopwatch_record(MppStopwatch stopwatch, const char *event)
|
||||
|
||||
void mpp_stopwatch_put(MppStopwatch stopwatch)
|
||||
{
|
||||
if (NULL == stopwatch || check_is_mpp_stopwatch(stopwatch)) {
|
||||
mpp_err_f("invalid stopwatch %p\n", stopwatch);
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
|
||||
if (check_is_mpp_stopwatch(impl)) {
|
||||
mpp_err_f("invalid stopwatch %p\n", impl);
|
||||
return;
|
||||
}
|
||||
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
if (impl->show_on_exit && impl->nodes && impl->filled_count) {
|
||||
MppStopwatchNode *node = impl->nodes;
|
||||
RK_S64 last_time = node->time;
|
||||
RK_S32 i;
|
||||
rk_s64 last_time = node->time;
|
||||
rk_s32 i;
|
||||
char fmt[32];
|
||||
|
||||
snprintf(fmt, sizeof(fmt) - 1, "%%s %%-%ds: %%6.2f\n", impl->log_len);
|
||||
@@ -564,19 +544,20 @@ void mpp_stopwatch_put(MppStopwatch stopwatch)
|
||||
MPP_FREE(impl);
|
||||
}
|
||||
|
||||
RK_S64 mpp_stopwatch_elapsed_time(MppStopwatch stopwatch)
|
||||
rk_s64 mpp_stopwatch_elapsed_time(MppStopwatch stopwatch)
|
||||
{
|
||||
if (NULL == stopwatch || check_is_mpp_stopwatch(stopwatch)) {
|
||||
mpp_err_f("invalid stopwatch %p\n", stopwatch);
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
|
||||
if (check_is_mpp_stopwatch(impl)) {
|
||||
mpp_err_f("invalid stopwatch %p\n", impl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch;
|
||||
if (impl->filled_count < 2)
|
||||
return 0;
|
||||
|
||||
RK_S64 base_time = impl->nodes[0].time;
|
||||
RK_S64 curr_time = impl->nodes[impl->filled_count - 1].time;
|
||||
RK_S64 elapsed_time = curr_time - base_time;
|
||||
rk_s64 base_time = impl->nodes[0].time;
|
||||
rk_s64 curr_time = impl->nodes[impl->filled_count - 1].time;
|
||||
rk_s64 elapsed_time = curr_time - base_time;
|
||||
return elapsed_time;
|
||||
}
|
@@ -1,17 +1,6 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright (c) 2015 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "mpp_time_test"
|
||||
@@ -103,6 +92,7 @@ int main()
|
||||
mpp_log("mpp_time pause 0 at %.3f ms pause 1 at %.3f ms\n",
|
||||
time_0 / 1000.0, time_1 / 1000.0);
|
||||
|
||||
mpp_clock_put(clock);
|
||||
|
||||
mpp_log("mpp time test done\n");
|
||||
|
||||
|
@@ -69,7 +69,7 @@ typedef struct {
|
||||
MppEncROICfg roi_cfg;
|
||||
|
||||
// input / output
|
||||
mpp_list *list_buf;
|
||||
MppList *list_buf;
|
||||
MppBufferGroup buf_grp;
|
||||
MppBuffer frm_buf[BUF_COUNT];
|
||||
MppBuffer pkt_buf[BUF_COUNT];
|
||||
@@ -531,7 +531,7 @@ MPP_RET mt_test_res_init(MpiEncMtCtxInfo *info)
|
||||
|
||||
mpp_log_q(quiet, "%s start\n", info->name);
|
||||
|
||||
p->list_buf = new mpp_list(NULL);
|
||||
p->list_buf = mpp_list_create(NULL);
|
||||
if (NULL == p->list_buf) {
|
||||
mpp_err_f("failed to get mpp buffer list\n");
|
||||
return MPP_ERR_MALLOC;
|
||||
@@ -556,7 +556,7 @@ MPP_RET mt_test_res_init(MpiEncMtCtxInfo *info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
p->list_buf->add_at_tail(&p->frm_buf[i], sizeof(p->frm_buf[i]));
|
||||
mpp_list_add_at_tail(p->list_buf, &p->frm_buf[i], sizeof(p->frm_buf[i]));
|
||||
}
|
||||
|
||||
// encoder demo
|
||||
@@ -654,7 +654,7 @@ MPP_RET mt_test_res_deinit(MpiEncMtCtxInfo *info)
|
||||
}
|
||||
|
||||
if (p->list_buf) {
|
||||
delete p->list_buf;
|
||||
mpp_list_destroy(p->list_buf);
|
||||
p->list_buf = NULL;
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@ void *enc_test_input(void *arg)
|
||||
RK_S32 chn = info->chn;
|
||||
MppApi *mpi = p->mpi;
|
||||
MppCtx ctx = p->ctx;
|
||||
mpp_list *list_buf = p->list_buf;
|
||||
MppList *list_buf = p->list_buf;
|
||||
RK_U32 cap_num = 0;
|
||||
RK_U32 quiet = cmd->quiet;
|
||||
MPP_RET ret = MPP_OK;
|
||||
@@ -689,18 +689,19 @@ void *enc_test_input(void *arg)
|
||||
RK_S32 cam_frm_idx = -1;
|
||||
MppBuffer cam_buf = NULL;
|
||||
|
||||
{
|
||||
AutoMutex autolock(list_buf->mutex());
|
||||
if (!list_buf->list_size())
|
||||
list_buf->wait();
|
||||
mpp_mutex_cond_lock(&list_buf->cond_lock);
|
||||
if (!mpp_list_size(list_buf))
|
||||
mpp_list_wait(list_buf);
|
||||
|
||||
buffer = NULL;
|
||||
list_buf->del_at_head(&buffer, sizeof(buffer));
|
||||
if (NULL == buffer)
|
||||
mpp_list_del_at_head(list_buf, &buffer, sizeof(buffer));
|
||||
if (NULL == buffer) {
|
||||
mpp_mutex_cond_unlock(&list_buf->cond_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
buf = mpp_buffer_get_ptr(buffer);
|
||||
}
|
||||
mpp_mutex_cond_unlock(&list_buf->cond_lock);
|
||||
|
||||
if (p->fp_input) {
|
||||
ret = read_image((RK_U8 *)buf, p->fp_input, p->width, p->height,
|
||||
@@ -714,8 +715,9 @@ void *enc_test_input(void *arg)
|
||||
p->frm_eos = 0;
|
||||
mpp_log_q(quiet, "chn %d loop times %d\n", chn, ++p->loop_times);
|
||||
if (buffer) {
|
||||
AutoMutex autolock(list_buf->mutex());
|
||||
list_buf->add_at_tail(&buffer, sizeof(buffer));
|
||||
mpp_mutex_cond_lock(&list_buf->cond_lock);
|
||||
mpp_list_add_at_tail(list_buf, &buffer, sizeof(buffer));
|
||||
mpp_mutex_cond_unlock(&list_buf->cond_lock);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -889,7 +891,7 @@ void *enc_test_output(void *arg)
|
||||
MpiEncTestArgs *cmd = info->cmd;
|
||||
MpiEncMtTestData *p = &info->ctx;
|
||||
MpiEncMtCtxRet *enc_ret = &info->ret;
|
||||
mpp_list *list_buf = p->list_buf;
|
||||
MppList *list_buf = p->list_buf;
|
||||
RK_S32 chn = info->chn;
|
||||
MppApi *mpi = p->mpi;
|
||||
MppCtx ctx = p->ctx;
|
||||
@@ -968,9 +970,10 @@ void *enc_test_output(void *arg)
|
||||
frm_buf = mpp_frame_get_buffer(frm);
|
||||
|
||||
if (frm_buf) {
|
||||
AutoMutex autolock(list_buf->mutex());
|
||||
list_buf->add_at_tail(&frm_buf, sizeof(frm_buf));
|
||||
list_buf->signal();
|
||||
mpp_mutex_cond_lock(&list_buf->cond_lock);
|
||||
mpp_list_add_at_tail(list_buf, &frm_buf, sizeof(frm_buf));
|
||||
mpp_list_signal(list_buf);
|
||||
mpp_mutex_cond_unlock(&list_buf->cond_lock);
|
||||
}
|
||||
|
||||
mpp_frame_deinit(&frm);
|
||||
|
Reference in New Issue
Block a user