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