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:
Hongjin Li
2025-06-10 08:53:10 +08:00
committed by Herman Chen
parent 1e74410229
commit aa6ae2c5f6
38 changed files with 2074 additions and 2121 deletions

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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"

View File

@@ -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"

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 = {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -21,6 +21,7 @@
#include "mpp_env.h"
#include "mpp_mem.h"
#include "mpp_debug.h"
#include "mpp_common.h"
#include "mpp_rc.h"

View File

@@ -21,6 +21,7 @@
#include "mpp_env.h"
#include "mpp_mem.h"
#include "mpp_debug.h"
#include "mpp_common.h"
#include "rc_base.h"

View File

@@ -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)

View File

@@ -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",

View File

@@ -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

View File

@@ -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;

View File

@@ -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 :

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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);
}

View File

@@ -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
View 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;
}

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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");

View File

@@ -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);