diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c b/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c index b9d091cdd..c036138d2 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c @@ -536,21 +536,10 @@ GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, mtl_st20p_tx, GST_PACKAGE_ORIGIN) static int gst_mtl_st20p_tx_frame_done(void* priv, struct st_frame* frame) { - /* In case of format conversion (transmit vs input), MTL may call - * gst_mtl_st20p_tx_frame_done twice. - * To avoid double free, we set (frame->opaque = NULL) in first call so that the second - * call can exit gracefully. - */ - if (frame == NULL || frame->opaque == NULL) { - return 0; - } - GstSt20pTxExternalDataChild* child = frame->opaque; GstSt20pTxExternalDataParent* parent = child->parent; gst_memory_unmap(child->gst_buffer_memory, &child->map_info); - - frame->opaque = NULL; free(child); pthread_mutex_lock(&parent->parent_mutex); diff --git a/lib/src/st2110/pipeline/st20_pipeline_tx.c b/lib/src/st2110/pipeline/st20_pipeline_tx.c index 18c880e16..4ecf6a5e4 100644 --- a/lib/src/st2110/pipeline/st20_pipeline_tx.c +++ b/lib/src/st2110/pipeline/st20_pipeline_tx.c @@ -130,8 +130,10 @@ static int tx_st20p_frame_done(void* priv, uint16_t frame_idx, frame->epoch = meta->epoch; frame->rtp_timestamp = meta->rtp_timestamp; - if (ctx->ops.notify_frame_done) { /* notify app which frame done */ + if (ctx->ops.notify_frame_done && + !framebuff->frame_done_cb_called) { /* notify app which frame done */ ctx->ops.notify_frame_done(ctx->ops.priv, frame); + framebuff->frame_done_cb_called = true; } /* notify app can get frame */ @@ -212,6 +214,11 @@ static int tx_st20p_convert_put_frame(void* priv, struct st20_convert_frame_meta framebuff->stat = ST20P_TX_FRAME_CONVERTED; } + if (ctx->ops.notify_frame_done && !framebuff->frame_done_cb_called) { + ctx->ops.notify_frame_done(ctx->ops.priv, &framebuff->src); + framebuff->frame_done_cb_called = true; + } + return 0; } @@ -602,6 +609,7 @@ struct st_frame* st20p_tx_get_frame(st20p_tx_handle handle) { } framebuff->stat = ST20P_TX_FRAME_IN_USER; + framebuff->frame_done_cb_called = false; /* point to next */ ctx->framebuff_producer_idx = tx_st20p_next_idx(ctx, framebuff->idx); mt_pthread_mutex_unlock(&ctx->lock); @@ -748,8 +756,10 @@ int st20p_tx_put_ext_frame(st20p_tx_handle handle, struct st_frame* frame, if (ctx->internal_converter) { /* convert internal */ ctx->internal_converter->convert_func(&framebuff->src, &framebuff->dst); framebuff->stat = ST20P_TX_FRAME_CONVERTED; - if (ctx->ops.notify_frame_done) + if (ctx->ops.notify_frame_done && !framebuff->frame_done_cb_called) { ctx->ops.notify_frame_done(ctx->ops.priv, &framebuff->src); + framebuff->frame_done_cb_called = true; + } } else { framebuff->stat = ST20P_TX_FRAME_READY; st20_convert_notify_frame_ready(ctx->convert_impl); diff --git a/lib/src/st2110/pipeline/st20_pipeline_tx.h b/lib/src/st2110/pipeline/st20_pipeline_tx.h index a55ef8497..228a2b97b 100644 --- a/lib/src/st2110/pipeline/st20_pipeline_tx.h +++ b/lib/src/st2110/pipeline/st20_pipeline_tx.h @@ -27,6 +27,7 @@ struct st20p_tx_frame { void* user_meta; /* the meta data from user */ size_t user_meta_buffer_size; size_t user_meta_data_size; + bool frame_done_cb_called; /* frame done callback called */ }; struct st20p_tx_ctx {