diff --git a/mpp/base/mpp_buf_slot.cpp b/mpp/base/mpp_buf_slot.cpp index 7a0d17a2..5520fe3b 100644 --- a/mpp/base/mpp_buf_slot.cpp +++ b/mpp/base/mpp_buf_slot.cpp @@ -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); - slot_assert(impl, (index >= 0) && (index < impl->buf_count)); - MppBufSlotEntry *slot = &impl->slots[index]; - slot_ops_with_log(impl, slot, clr_flag_op[type], NULL); + mpp_mutex_lock(&impl->lock); - if (type == SLOT_HAL_OUTPUT) - impl->decode_count++; + slot_assert(impl, (index >= 0) && (index < impl->buf_count)); + slot = &impl->slots[index]; + slot_ops_with_log(impl, slot, clr_flag_op[type], NULL); - unused = check_entry_unused(impl, slot); - } + 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; } diff --git a/mpp/base/mpp_buffer_impl.cpp b/mpp/base/mpp_buffer_impl.cpp index b5c301de..34578036 100644 --- a/mpp/base/mpp_buffer_impl.cpp +++ b/mpp/base/mpp_buffer_impl.cpp @@ -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) diff --git a/mpp/base/mpp_cluster.cpp b/mpp/base/mpp_cluster.cpp index 121de536..47ec8633 100644 --- a/mpp/base/mpp_cluster.cpp +++ b/mpp/base/mpp_cluster.cpp @@ -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; } diff --git a/mpp/base/mpp_enc_cfg.cpp b/mpp/base/mpp_enc_cfg.cpp index 549f58d5..91a9c083 100644 --- a/mpp/base/mpp_enc_cfg.cpp +++ b/mpp/base/mpp_enc_cfg.cpp @@ -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) diff --git a/mpp/base/mpp_frame.cpp b/mpp/base/mpp_frame.cpp index a03b4036..78a10d6c 100644 --- a/mpp/base/mpp_frame.cpp +++ b/mpp/base/mpp_frame.cpp @@ -18,8 +18,8 @@ #include -#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" diff --git a/mpp/base/mpp_meta.cpp b/mpp/base/mpp_meta.cpp index 2e92d21c..3e90281d 100644 --- a/mpp/base/mpp_meta.cpp +++ b/mpp/base/mpp_meta.cpp @@ -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" diff --git a/mpp/base/mpp_task_impl.cpp b/mpp/base/mpp_task_impl.cpp index 613c3c27..36b7b90a 100644 --- a/mpp/base/mpp_task_impl.cpp +++ b/mpp/base/mpp_task_impl.cpp @@ -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; } diff --git a/mpp/codec/inc/mpp_dec_impl.h b/mpp/codec/inc/mpp_dec_impl.h index 6436a79f..fa07e90d 100644 --- a/mpp/codec/inc/mpp_dec_impl.h +++ b/mpp/codec/inc/mpp_dec_impl.h @@ -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; diff --git a/mpp/codec/inc/mpp_enc_impl.h b/mpp/codec/inc/mpp_enc_impl.h index cbbcab20..632eccae 100644 --- a/mpp/codec/inc/mpp_enc_impl.h +++ b/mpp/codec/inc/mpp_enc_impl.h @@ -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; diff --git a/mpp/codec/inc/rc_data_impl.h b/mpp/codec/inc/rc_data_impl.h index cfcd5e5f..330b1325 100644 --- a/mpp/codec/inc/rc_data_impl.h +++ b/mpp/codec/inc/rc_data_impl.h @@ -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; diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 46d5399f..7dc9aee0 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -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; } diff --git a/mpp/codec/mpp_dec_no_thread.cpp b/mpp/codec/mpp_dec_no_thread.cpp index 46435625..a9c57884 100644 --- a/mpp/codec/mpp_dec_no_thread.cpp +++ b/mpp/codec/mpp_dec_no_thread.cpp @@ -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,8 +47,10 @@ 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) @@ -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 = { diff --git a/mpp/codec/mpp_dec_normal.cpp b/mpp/codec/mpp_dec_normal.cpp index 7a8d742b..af772416 100644 --- a/mpp/codec/mpp_dec_normal.cpp +++ b/mpp/codec/mpp_dec_normal.cpp @@ -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,25 +708,26 @@ 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()) - break; - - /* - * parser thread need to wait at cases below: - * 1. no task slot for output - * 2. no packet for parsing - * 3. info change on progress - * 3. no buffer on analyzing output task - */ - if (check_task_wait(dec, &task)) { - mpp_clock_start(dec->clocks[DEC_PRS_WAIT]); - parser->wait(); - mpp_clock_pause(dec->clocks[DEC_PRS_WAIT]); - } + 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: + * 1. no task slot for output + * 2. no packet for parsing + * 3. info change on progress + * 3. no buffer on analyzing output task + */ + if (check_task_wait(dec, &task)) { + mpp_clock_start(dec->clocks[DEC_PRS_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) { dec_dbg_detail("ctrl proc %d cmd %08x\n", dec->cmd_recv, dec->cmd); @@ -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,29 +792,32 @@ 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()) - break; + 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 - if (dec->hal_reset_post != dec->hal_reset_done) { - dec_dbg_reset("reset: hal reset start\n"); - reset_hal_thread(mpp); - dec_dbg_reset("reset: hal reset done\n"); - dec->hal_reset_done++; - sem_post(&dec->hal_reset); - continue; - } - - mpp_dec_notify(dec, MPP_DEC_NOTIFY_TASK_ALL_DONE); - mpp_clock_start(dec->clocks[DEC_HAL_WAIT]); - hal->wait(); - mpp_clock_pause(dec->clocks[DEC_HAL_WAIT]); + if (hal_task_get_hnd(tasks, TASK_PROCESSING, &task)) { + // process all task then do reset process + if (dec->hal_reset_post != dec->hal_reset_done) { + dec_dbg_reset("reset: hal reset start\n"); + reset_hal_thread(mpp); + 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]); + 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,15 +935,16 @@ 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()) - break; - - if (check_task_wait(dec, &task)) - thd_dec->wait(); + 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)) + mpp_thread_wait(thd_dec, THREAD_WORK); + mpp_thread_unlock(thd_dec, THREAD_WORK); + // process user control if (dec->cmd_send != dec->cmd_recv) { dec_dbg_detail("ctrl proc %d cmd %08x\n", dec->cmd_recv, dec->cmd); @@ -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->mpp, "mpp_dec_parser"); - dec->thread_parser->start(); - dec->thread_hal = new MppThread(mpp_dec_hal_thread, - dec->mpp, "mpp_dec_hal"); + dec->thread_parser = mpp_thread_create(mpp_dec_parser_thread, + dec->mpp, "mpp_dec_parser"); + 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->mpp, "mpp_dec_parser"); - dec->thread_parser->start(); + dec->thread_parser = mpp_thread_create(mpp_dec_advanced_thread, + dec->mpp, "mpp_dec_parser"); + 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; } diff --git a/mpp/codec/mpp_enc_impl.cpp b/mpp/codec/mpp_enc_impl.cpp index a712838e..f8d79310 100644 --- a/mpp/codec/mpp_enc_impl.cpp +++ b/mpp/codec/mpp_enc_impl.cpp @@ -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,15 +2633,18 @@ 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()) - break; + mpp_thread_lock(thd_enc, THREAD_WORK); - if (check_enc_task_wait(enc, &wait)) - thd_enc->wait(); + 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)) + 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) { // 1. process user control @@ -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()); - enc->status_flag = 0; - } + + 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()) - break; - - if (check_enc_async_wait(enc, &wait)) { - enc_dbg_detail("wait start\n"); - thd_enc->wait(); - enc_dbg_detail("wait done\n"); - } + 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"); + 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; } diff --git a/mpp/codec/mpp_enc_v2.cpp b/mpp/codec/mpp_enc_v2.cpp index eb6e9437..14f3deea 100644 --- a/mpp/codec/mpp_enc_v2.cpp +++ b/mpp/codec/mpp_enc_v2.cpp @@ -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; } diff --git a/mpp/codec/mpp_rc.cpp b/mpp/codec/mpp_rc.cpp index 4305e228..d4e3e70f 100644 --- a/mpp/codec/mpp_rc.cpp +++ b/mpp/codec/mpp_rc.cpp @@ -21,6 +21,7 @@ #include "mpp_env.h" #include "mpp_mem.h" +#include "mpp_debug.h" #include "mpp_common.h" #include "mpp_rc.h" diff --git a/mpp/codec/rc/rc_base.cpp b/mpp/codec/rc/rc_base.cpp index 49b871ab..56edb1d6 100644 --- a/mpp/codec/rc/rc_base.cpp +++ b/mpp/codec/rc/rc_base.cpp @@ -21,6 +21,7 @@ #include "mpp_env.h" #include "mpp_mem.h" +#include "mpp_debug.h" #include "mpp_common.h" #include "rc_base.h" diff --git a/mpp/codec/rc/rc_data_impl.cpp b/mpp/codec/rc/rc_data_impl.cpp index 90b8600d..f2df77ba 100644 --- a/mpp/codec/rc/rc_data_impl.cpp +++ b/mpp/codec/rc/rc_data_impl.cpp @@ -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) diff --git a/mpp/codec/rc/rc_impl.cpp b/mpp/codec/rc/rc_impl.cpp index f55dc596..c20acd77 100644 --- a/mpp/codec/rc/rc_impl.cpp +++ b/mpp/codec/rc/rc_impl.cpp @@ -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", diff --git a/mpp/codec/rc/rc_impl.h b/mpp/codec/rc/rc_impl.h index 1199ab3c..3675895e 100644 --- a/mpp/codec/rc/rc_impl.h +++ b/mpp/codec/rc/rc_impl.h @@ -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 diff --git a/mpp/inc/mpp.h b/mpp/inc/mpp.h index 37ab55d0..6a35004f 100644 --- a/mpp/inc/mpp.h +++ b/mpp/inc/mpp.h @@ -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; diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index 6ef98431..45a2e41a 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -185,8 +185,8 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding) switch (mType) { case MPP_CTX_DEC : { - mPktIn = new mpp_list(list_wraper_packet); - mFrmOut = new mpp_list(list_wraper_frame); + mPktIn = mpp_list_create(list_wraper_packet); + mFrmOut = mpp_list_create(list_wraper_frame); if (mInputTimeout == MPP_POLL_BUTT) mInputTimeout = MPP_POLL_NON_BLOCK; @@ -227,8 +227,8 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding) mInitDone = 1; } break; case MPP_CTX_ENC : { - mPktOut = new mpp_list(list_wraper_packet); - mFrmIn = new mpp_list(list_wraper_frame); + mPktOut = mpp_list_create(list_wraper_packet); + mFrmIn = mpp_list_create(list_wraper_frame); if (mInputTimeout == MPP_POLL_BUTT) mInputTimeout = MPP_POLL_BLOCK; @@ -337,19 +337,19 @@ void Mpp::clear() } if (mPktIn) { - delete mPktIn; + mpp_list_destroy(mPktIn); mPktIn = NULL; } if (mPktOut) { - delete mPktOut; + mpp_list_destroy(mPktOut); mPktOut = NULL; } if (mFrmIn) { - delete mFrmIn; + mpp_list_destroy(mFrmIn); mFrmIn = NULL; } if (mFrmOut) { - delete mFrmOut; + mpp_list_destroy(mFrmOut); mFrmOut = NULL; } @@ -519,33 +519,37 @@ RET: MPP_RET Mpp::get_frame(MppFrame *frame) { + MppFrame frm = NULL; + if (!mInitDone) return MPP_ERR_INIT; - AutoMutex autoFrameLock(mFrmOut->mutex()); - MppFrame frm = NULL; + mpp_mutex_cond_lock(&mFrmOut->cond_lock); - if (0 == mFrmOut->list_size()) { + if (0 == mpp_list_size(mFrmOut)) { if (mOutputTimeout) { if (mOutputTimeout < 0) { /* block wait */ - mFrmOut->wait(); + mpp_list_wait(mFrmOut); } else { - RK_S32 ret = mFrmOut->wait(mOutputTimeout); + RK_S32 ret = mpp_list_wait_timed(mFrmOut, mOutputTimeout); if (ret) { - if (ret == ETIMEDOUT) + if (ret == ETIMEDOUT) { + mpp_mutex_cond_unlock(&mFrmOut->cond_lock); return MPP_ERR_TIMEOUT; - else + } else { + mpp_mutex_cond_unlock(&mFrmOut->cond_lock); return MPP_NOK; + } } } } } - if (mFrmOut->list_size()) { + if (mpp_list_size(mFrmOut)) { MppBuffer buffer; - mFrmOut->del_at_head(&frm, sizeof(frame)); + mpp_list_del_at_head(mFrmOut, &frm, sizeof(frame)); mFrameGetCount++; notify(MPP_OUTPUT_DEQUEUE); @@ -559,15 +563,17 @@ MPP_RET Mpp::get_frame(MppFrame *frame) // There is no way to wake up parser thread to continue decoding. // The put_packet only signal sem on may be it better to use sem on info // change too. - AutoMutex autoPacketLock(mPktIn->mutex()); - if (mPktIn->list_size()) + mpp_mutex_cond_lock(&mPktIn->cond_lock); + if (mpp_list_size(mPktIn)) notify(MPP_INPUT_ENQUEUE); + mpp_mutex_cond_unlock(&mPktIn->cond_lock); } *frame = frm; // dump output mpp_ops_dec_get_frm(mDump, frm); + mpp_mutex_cond_unlock(&mFrmOut->cond_lock); return MPP_OK; } @@ -579,13 +585,13 @@ MPP_RET Mpp::get_frame_noblock(MppFrame *frame) if (!mInitDone) return MPP_ERR_INIT; - mFrmOut->lock(); - if (mFrmOut->list_size()) { - mFrmOut->del_at_head(&first, sizeof(frame)); + mpp_mutex_cond_lock(&mFrmOut->cond_lock); + if (mpp_list_size(mFrmOut)) { + mpp_list_del_at_head(mFrmOut, &first, sizeof(frame)); mpp_buffer_sync_ro_begin(mpp_frame_get_buffer(first)); mFrameGetCount++; } - mFrmOut->unlock(); + mpp_mutex_cond_unlock(&mFrmOut->cond_lock); *frame = first; return MPP_OK; @@ -608,18 +614,19 @@ MPP_RET Mpp::decode(MppPacket packet, MppFrame *frame) * But if the output mode is block then we need to send packet first */ if (!mOutputTimeout) { - AutoMutex autoFrameLock(mFrmOut->mutex()); - - if (mFrmOut->list_size()) { + mpp_mutex_cond_lock(&mFrmOut->cond_lock); + if (mpp_list_size(mFrmOut)) { MppBuffer buffer; - mFrmOut->del_at_head(frame, sizeof(*frame)); + mpp_list_del_at_head(mFrmOut, frame, sizeof(*frame)); buffer = mpp_frame_get_buffer(*frame); if (buffer) mpp_buffer_sync_ro_begin(buffer); mFrameGetCount++; + mpp_mutex_cond_unlock(&mFrmOut->cond_lock); return MPP_OK; } + mpp_mutex_cond_unlock(&mFrmOut->cond_lock); } do { @@ -631,20 +638,18 @@ MPP_RET Mpp::decode(MppPacket packet, MppFrame *frame) pkt_done = 1; /* always try getting frame */ - { - AutoMutex autoFrameLock(mFrmOut->mutex()); + mpp_mutex_cond_lock(&mFrmOut->cond_lock); + if (mpp_list_size(mFrmOut)) { + MppBuffer buffer; - if (mFrmOut->list_size()) { - MppBuffer buffer; - - mFrmOut->del_at_head(frame, sizeof(*frame)); - buffer = mpp_frame_get_buffer(*frame); - if (buffer) - mpp_buffer_sync_ro_begin(buffer); - mFrameGetCount++; - frm_rdy = 1; - } + 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,41 +864,44 @@ 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 { @@ -902,12 +910,12 @@ MPP_RET Mpp::get_packet_async(MppPacket *packet) } } - 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 : diff --git a/mpp/mpp_impl.cpp b/mpp/mpp_impl.cpp index e4b17c55..c0c4c1e2 100644 --- a/mpp/mpp_impl.cpp +++ b/mpp/mpp_impl.cpp @@ -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; } diff --git a/mpp/vproc/mpp_dec_vproc.cpp b/mpp/vproc/mpp_dec_vproc.cpp index 246879ea..39d256b2 100644 --- a/mpp/vproc/mpp_dec_vproc.cpp +++ b/mpp/vproc/mpp_dec_vproc.cpp @@ -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,18 +844,18 @@ 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()) - break; - - if (ctx->task_wait.val && !ctx->reset) { - vproc_dbg_status("vproc thread wait %d", ctx->task_wait.val); - thd->wait(); - } + 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); + 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)) { if (ctx->reset) { @@ -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); diff --git a/osal/CMakeLists.txt b/osal/CMakeLists.txt index df6400bc..f7131b50 100644 --- a/osal/CMakeLists.txt +++ b/osal/CMakeLists.txt @@ -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 diff --git a/osal/driver/mpp_server.cpp b/osal/driver/mpp_server.cpp index 7a2809ea..6095f211 100644 --- a/osal/driver/mpp_server.cpp +++ b/osal/driver/mpp_server.cpp @@ -31,6 +31,7 @@ #include "mpp_device_debug.h" #include "mpp_service_impl.h" #include "mpp_server.h" +#include "mpp_thread.h" #define MAX_BATCH_TASK 8 #define MAX_SESSION_TASK 4 @@ -88,7 +89,7 @@ struct MppDevTask_t { }; struct MppDevBatTask_t { - MppMutexCond *cond; + MppMutexCond cond; /* link to server */ struct list_head link_server; @@ -113,7 +114,7 @@ struct MppDevBatTask_t { }; struct MppDevSession_t { - MppMutexCond *cond; + MppMutexCond cond_lock; /* hash table to server */ struct list_head list_server; @@ -134,7 +135,7 @@ struct MppDevSession_t { }; struct MppDevBatServ_t { - Mutex *lock; + MppMutex lock; RK_S32 server_fd; RK_U32 batch_id; @@ -239,7 +240,7 @@ void batch_send(MppDevBatServ *server, MppDevBatTask *batch) void process_task(void *p) { MppDevBatServ *server = (MppDevBatServ *)p; - Mutex *lock = server->lock; + MppMutex *lock = &server->lock; RK_S32 ret = MPP_OK; MppDevTask *task; MppDevBatTask *batch; @@ -284,10 +285,10 @@ void process_task(void *p) mpp_serv_dbg_flow("batch %d:%d session %d ready and remove\n", batch->batch_id, task->batch_slot_id, session->client); - session->cond->lock(); + mpp_mutex_cond_lock(&session->cond_lock); session->task_done++; - session->cond->signal(); - session->cond->unlock(); + mpp_mutex_cond_signal(&session->cond_lock); + mpp_mutex_cond_unlock(&session->cond_lock); if (session->ctx && session->ctx->dev_cb) mpp_callback(session->ctx->dev_cb, NULL); @@ -320,13 +321,13 @@ void process_task(void *p) } while (1); /* 2. get prending task to fill */ - lock->lock(); + mpp_mutex_lock(lock); pending = server->pending_count; if (!pending && !server->batch_run && !server->session_count) { mpp_timer_set_enable(server->timer, 0); mpp_serv_dbg_flow("stop timer\n"); } - lock->unlock(); + mpp_mutex_unlock(lock); mpp_serv_dbg_flow("pending %d running %d free %d max %d process start\n", pending, server->batch_run, server->batch_free, server->batch_max_count); @@ -379,11 +380,11 @@ try_proc_pending_task: mpp_assert(pending); task = NULL; - lock->lock(); + mpp_mutex_lock(lock); task = list_first_entry_or_null(&server->pending_task, MppDevTask, link_server); list_del_init(&task->link_server); server->pending_count--; - lock->unlock(); + mpp_mutex_unlock(lock); pending--; /* first task and setup new batch id */ @@ -473,7 +474,7 @@ MPP_RET send_task(MppDevMppService *ctx) MppDevBatServ *server = session->server; /* get free task from session and add to run list */ - session->cond->lock(); + mpp_mutex_cond_lock(&session->cond_lock); /* get a free task and setup */ task = list_first_entry_or_null(&session->list_done, MppDevTask, link_session); mpp_assert(task); @@ -485,9 +486,9 @@ MPP_RET send_task(MppDevMppService *ctx) list_add_tail(&task->link_session, &session->list_wait); session->task_wait++; - session->cond->unlock(); + mpp_mutex_cond_unlock(&session->cond_lock); - server->lock->lock(); + mpp_mutex_lock(&server->lock); task->task_id = server->task_id++; list_del_init(&task->link_server); list_add_tail(&task->link_server, &server->pending_task); @@ -496,7 +497,7 @@ MPP_RET send_task(MppDevMppService *ctx) session->client, task->slot_idx, server->pending_count); mpp_timer_set_enable(server->timer, 1); - server->lock->unlock(); + mpp_mutex_unlock(&server->lock); return MPP_OK; } @@ -516,15 +517,15 @@ MPP_RET wait_task(MppDevMppService *ctx, RK_S64 timeout) task = list_first_entry_or_null(&session->list_wait, MppDevTask, link_session); mpp_assert(task); - session->cond->lock(); + mpp_mutex_cond_lock(&session->cond_lock); if (session->task_wait != session->task_done) { mpp_serv_dbg_flow("session %d wait %d start %d:%d\n", session->client, task->task_id, session->task_wait, session->task_done); - session->cond->wait(); + mpp_mutex_cond_wait(&session->cond_lock); } mpp_serv_dbg_flow("session %d wait %d done %d:%d\n", session->client, task->task_id, session->task_wait, session->task_done); - session->cond->unlock(); + mpp_mutex_cond_unlock(&session->cond_lock); list_del_init(&task->link_session); list_add_tail(&task->link_session, &session->list_done); @@ -534,7 +535,7 @@ MPP_RET wait_task(MppDevMppService *ctx, RK_S64 timeout) return (MPP_RET)ret; } -class MppDevServer : Mutex +class MppDevServer { private: // avoid any unwanted function @@ -565,6 +566,7 @@ public: return &inst; } + MppMutex lock; MppDevBatServ *bat_server_get(MppClientType client_type); MPP_RET bat_server_put(MppClientType client_type); @@ -628,6 +630,7 @@ MppDevServer::MppDevServer() : clear(); return; } + mpp_mutex_init(&lock); memset(mBatServer, 0, sizeof(mBatServer)); } @@ -639,6 +642,8 @@ MppDevServer::~MppDevServer() for (i = 0; i < VPU_CLIENT_BUTT; i++) bat_server_put((MppClientType)i); + mpp_mutex_destroy(&lock); + clear(); } @@ -661,15 +666,18 @@ MppDevBatServ *MppDevServer::bat_server_get(MppClientType client_type) { MppDevBatServ *server = NULL; - AutoMutex auto_lock(this); + mpp_mutex_lock(&lock); server = mBatServer[client_type]; - if (server) + if (server) { + mpp_mutex_unlock(&lock); return server; + } server = mpp_calloc(MppDevBatServ, 1); if (NULL == server) { mpp_err("mpp server failed to get bat server\n"); + mpp_mutex_unlock(&lock); return NULL; } @@ -690,11 +698,7 @@ MppDevBatServ *MppDevServer::bat_server_get(MppClientType client_type) goto failed; } - server->lock = new Mutex(); - if (NULL == server->lock) { - mpp_err("mpp server get bat server failed to create mutex\n"); - goto failed; - } + mpp_mutex_init(&server->lock); mpp_timer_set_callback(server->timer, mpp_server_thread, server); /* 10ms */ @@ -709,6 +713,7 @@ MppDevBatServ *MppDevServer::bat_server_get(MppClientType client_type) server->max_task_in_batch = mMaxTaskInBatch; mBatServer[client_type] = server; + mpp_mutex_unlock(&lock); return server; failed: @@ -722,12 +727,10 @@ failed: close(server->server_fd); server->server_fd = -1; } - if (server->lock) { - delete server->lock; - server->lock = NULL; - } + mpp_mutex_destroy(&server->lock); } MPP_FREE(server); + mpp_mutex_unlock(&lock); return server; } @@ -735,10 +738,13 @@ MPP_RET MppDevServer::bat_server_put(MppClientType client_type) { MppDevBatTask *batch, *n; MppDevBatServ *server = NULL; - AutoMutex auto_lock(this); - if (NULL == mBatServer[client_type]) + mpp_mutex_lock(&lock); + + if (NULL == mBatServer[client_type]) { + mpp_mutex_unlock(&lock); return MPP_OK; + } server = mBatServer[client_type]; mBatServer[client_type] = NULL; @@ -765,11 +771,10 @@ MPP_RET MppDevServer::bat_server_put(MppClientType client_type) close(server->server_fd); server->server_fd = -1; } - if (server->lock) { - delete server->lock; - server->lock = NULL; - } + mpp_mutex_destroy(&server->lock); MPP_FREE(server); + mpp_mutex_unlock(&lock); + return MPP_OK; } @@ -796,9 +801,11 @@ MPP_RET MppDevServer::attach(MppDevMppService *ctx) return MPP_NOK; } - AutoMutex auto_lock(server->lock); - if (ctx->serv_ctx) + mpp_mutex_lock(&lock); + if (ctx->serv_ctx) { + mpp_mutex_unlock(&lock); return MPP_OK; + } MppDevSession *session = (MppDevSession *)mpp_mem_pool_get(mSessionPool); INIT_LIST_HEAD(&session->list_server); @@ -808,7 +815,7 @@ MPP_RET MppDevServer::attach(MppDevMppService *ctx) session->ctx = ctx; session->server = server; session->client = ctx->client; - session->cond = new MppMutexCond(); + mpp_mutex_cond_init(&session->cond_lock); session->task_wait = 0; session->task_done = 0; @@ -839,6 +846,7 @@ MPP_RET MppDevServer::attach(MppDevMppService *ctx) server->batch_max_count++; server->session_count++; + mpp_mutex_unlock(&lock); return MPP_OK; } @@ -857,9 +865,11 @@ MPP_RET MppDevServer::detach(MppDevMppService *ctx) mpp_assert(server); - AutoMutex auto_lock(server->lock); - if (NULL == ctx->serv_ctx) + mpp_mutex_lock(&lock); + if (NULL == ctx->serv_ctx) { + mpp_mutex_unlock(&lock); return MPP_OK; + } ctx->server = ctx->client; ctx->serv_ctx = NULL; @@ -873,15 +883,13 @@ MPP_RET MppDevServer::detach(MppDevMppService *ctx) list_del_init(&session->list_server); - if (session->cond) { - delete session->cond; - session->cond = NULL; - } + mpp_mutex_cond_destroy(&session->cond_lock); mpp_mem_pool_put(mSessionPool, session); server->batch_max_count++; server->session_count++; + mpp_mutex_unlock(&lock); return MPP_OK; } diff --git a/osal/inc/mpp_list.h b/osal/inc/mpp_list.h index 204ab92c..2aab8445 100644 --- a/osal/inc/mpp_list.h +++ b/osal/inc/mpp_list.h @@ -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 } diff --git a/osal/inc/mpp_queue.h b/osal/inc/mpp_queue.h index f5edb94c..b5604a48 100644 --- a/osal/inc/mpp_queue.h +++ b/osal/inc/mpp_queue.h @@ -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 diff --git a/osal/inc/mpp_thread.h b/osal/inc/mpp_thread.h index 3c3550ce..bdbceff2 100644 --- a/osal/inc/mpp_thread.h +++ b/osal/inc/mpp_thread.h @@ -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 #include #include #include +#include +#include +#include + +#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 \ No newline at end of file diff --git a/osal/inc/mpp_time.h b/osal/inc/mpp_time.h index 92a3f533..f91c4cfd 100644 --- a/osal/inc/mpp_time.h +++ b/osal/inc/mpp_time.h @@ -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 + #include "mpp_thread.h" -#if defined(_WIN32) && !defined(__MINGW32CE__) -#include -#define msleep Sleep -#define sleep(x) Sleep((x)*1000) -#else -#include #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__*/ diff --git a/osal/mpp_list.c b/osal/mpp_list.c new file mode 100644 index 00000000..afe0780e --- /dev/null +++ b/osal/mpp_list.c @@ -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 +#include +#include +#include + +#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); +} diff --git a/osal/mpp_list.cpp b/osal/mpp_list.cpp deleted file mode 100644 index 7c9ec3d2..00000000 --- a/osal/mpp_list.cpp +++ /dev/null @@ -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 -#include -#include -#include - -#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 -#include -#include - -#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 - diff --git a/osal/mpp_queue.c b/osal/mpp_queue.c new file mode 100644 index 00000000..162a176f --- /dev/null +++ b/osal/mpp_queue.c @@ -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; +} diff --git a/osal/mpp_queue.cpp b/osal/mpp_queue.cpp deleted file mode 100644 index 47a05863..00000000 --- a/osal/mpp_queue.cpp +++ /dev/null @@ -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(); -} diff --git a/osal/mpp_thread.cpp b/osal/mpp_thread.c similarity index 59% rename from osal/mpp_thread.cpp rename to osal/mpp_thread.c index a5fc5074..5449adf5 100644 --- a/osal/mpp_thread.cpp +++ b/osal/mpp_thread.c @@ -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 -#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]); + } + } + + return thread; } -MppThreadStatus MppThread::get_status(MppThreadSignal id) +void mpp_thread_dump_status(MppThread *thread) { - return mStatus[id]; + 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::set_status(MppThreadStatus status, MppThreadSignal id) -{ - mStatus[id] = status; -} - -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); + 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(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n", - mName, mFunction, mContext); - } else - set_status(MPP_THREAD_UNINITED); + 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 -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; diff --git a/osal/mpp_time.cpp b/osal/mpp_time.c similarity index 64% rename from osal/mpp_time.cpp rename to osal/mpp_time.c index 26362023..686d4862 100644 --- a/osal/mpp_time.cpp +++ b/osal/mpp_time.c @@ -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 #include #include #include @@ -27,32 +17,18 @@ #include "mpp_common.h" #include "mpp_thread.h" -#if _WIN32 -#include -#include - -RK_S64 mpp_time() -{ - struct timeb tb; - ftime(&tb); - return ((RK_S64)tb.time * 1000 + (RK_S64)tb.millitm) * 1000; -} - -#else -#include - -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,33 +70,34 @@ 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 ; + return; } 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; + 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); - return ; - } - - if (NULL == func) { - mpp_err_f("invalid NULL callback\n"); - return ; - } - MppTimerImpl *impl = (MppTimerImpl *)timer; + + if (check_is_mpp_timer(impl)) { + mpp_err_f("invalid timer %p\n", impl); + return; + } + + if (!func) { + mpp_err_f("invalid NULL callback\n"); + return; + } + 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); - return ; + 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); - return ; - } - MppTimerImpl *impl = (MppTimerImpl *)timer; - if (NULL == impl->func || impl->initial < 0 || impl->interval < 0) { + if (check_is_mpp_timer(impl)) { + mpp_err_f("invalid timer %p\n", impl); + return; + } + + 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 ; + 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); - return ; - } - MppTimerImpl *impl = (MppTimerImpl *)timer; + if (check_is_mpp_timer(impl)) { + mpp_err_f("invalid timer %p\n", impl); + return; + } + 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); - return ; + 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) { - /* do not print noisy log */ - if (NULL == stopwatch) - return ; + MppStopwatchImpl *impl = (MppStopwatchImpl *)stopwatch; - if (check_is_mpp_stopwatch(stopwatch)) { - mpp_err_f("invalid stopwatch %p on %s\n", stopwatch, event); - return ; + /* do not print noisy log */ + if (!impl) + return; + + 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); - return ; + 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; } diff --git a/osal/test/mpp_time_test.c b/osal/test/mpp_time_test.c index 0bf26ef8..44d5d1d4 100644 --- a/osal/test/mpp_time_test.c +++ b/osal/test/mpp_time_test.c @@ -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"); diff --git a/test/mpi_enc_mt_test.cpp b/test/mpi_enc_mt_test.cpp index 496c5978..47ba9be0 100644 --- a/test/mpi_enc_mt_test.cpp +++ b/test/mpi_enc_mt_test.cpp @@ -69,8 +69,8 @@ typedef struct { MppEncROICfg roi_cfg; // input / output - mpp_list *list_buf; - MppBufferGroup buf_grp; + MppList *list_buf; + MppBufferGroup buf_grp; MppBuffer frm_buf[BUF_COUNT]; MppBuffer pkt_buf[BUF_COUNT]; RK_S32 buf_idx; @@ -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,19 +689,20 @@ 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) - continue; - - buf = mpp_buffer_get_ptr(buffer); + buffer = NULL; + 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, p->hor_stride, p->ver_stride, p->fmt); @@ -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);