Skip to content

Commit daa2f3a

Browse files
authored
Fix: prevent double notification for frame done in external frame usage (#1180)
Skip notify if ext_frame is used and derive is false (input_fmt != transport_fmt). In this case, the frame done notification is not needed since the notification is already done after convert callback. This is to avoid double notification(and double free) for the same frame. Fixes #1147
1 parent e62c41b commit daa2f3a

File tree

3 files changed

+13
-13
lines changed

3 files changed

+13
-13
lines changed

ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -536,21 +536,10 @@ GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, mtl_st20p_tx,
536536
GST_PACKAGE_ORIGIN)
537537

538538
static int gst_mtl_st20p_tx_frame_done(void* priv, struct st_frame* frame) {
539-
/* In case of format conversion (transmit vs input), MTL may call
540-
* gst_mtl_st20p_tx_frame_done twice.
541-
* To avoid double free, we set (frame->opaque = NULL) in first call so that the second
542-
* call can exit gracefully.
543-
*/
544-
if (frame == NULL || frame->opaque == NULL) {
545-
return 0;
546-
}
547-
548539
GstSt20pTxExternalDataChild* child = frame->opaque;
549540
GstSt20pTxExternalDataParent* parent = child->parent;
550541

551542
gst_memory_unmap(child->gst_buffer_memory, &child->map_info);
552-
553-
frame->opaque = NULL;
554543
free(child);
555544

556545
pthread_mutex_lock(&parent->parent_mutex);

lib/src/st2110/pipeline/st20_pipeline_tx.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,10 @@ static int tx_st20p_frame_done(void* priv, uint16_t frame_idx,
130130
frame->epoch = meta->epoch;
131131
frame->rtp_timestamp = meta->rtp_timestamp;
132132

133-
if (ctx->ops.notify_frame_done) { /* notify app which frame done */
133+
if (ctx->ops.notify_frame_done &&
134+
!framebuff->frame_done_cb_called) { /* notify app which frame done */
134135
ctx->ops.notify_frame_done(ctx->ops.priv, frame);
136+
framebuff->frame_done_cb_called = true;
135137
}
136138

137139
/* notify app can get frame */
@@ -212,6 +214,11 @@ static int tx_st20p_convert_put_frame(void* priv, struct st20_convert_frame_meta
212214
framebuff->stat = ST20P_TX_FRAME_CONVERTED;
213215
}
214216

217+
if (ctx->ops.notify_frame_done && !framebuff->frame_done_cb_called) {
218+
ctx->ops.notify_frame_done(ctx->ops.priv, &framebuff->src);
219+
framebuff->frame_done_cb_called = true;
220+
}
221+
215222
return 0;
216223
}
217224

@@ -602,6 +609,7 @@ struct st_frame* st20p_tx_get_frame(st20p_tx_handle handle) {
602609
}
603610

604611
framebuff->stat = ST20P_TX_FRAME_IN_USER;
612+
framebuff->frame_done_cb_called = false;
605613
/* point to next */
606614
ctx->framebuff_producer_idx = tx_st20p_next_idx(ctx, framebuff->idx);
607615
mt_pthread_mutex_unlock(&ctx->lock);
@@ -748,8 +756,10 @@ int st20p_tx_put_ext_frame(st20p_tx_handle handle, struct st_frame* frame,
748756
if (ctx->internal_converter) { /* convert internal */
749757
ctx->internal_converter->convert_func(&framebuff->src, &framebuff->dst);
750758
framebuff->stat = ST20P_TX_FRAME_CONVERTED;
751-
if (ctx->ops.notify_frame_done)
759+
if (ctx->ops.notify_frame_done && !framebuff->frame_done_cb_called) {
752760
ctx->ops.notify_frame_done(ctx->ops.priv, &framebuff->src);
761+
framebuff->frame_done_cb_called = true;
762+
}
753763
} else {
754764
framebuff->stat = ST20P_TX_FRAME_READY;
755765
st20_convert_notify_frame_ready(ctx->convert_impl);

lib/src/st2110/pipeline/st20_pipeline_tx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct st20p_tx_frame {
2727
void* user_meta; /* the meta data from user */
2828
size_t user_meta_buffer_size;
2929
size_t user_meta_data_size;
30+
bool frame_done_cb_called; /* frame done callback called */
3031
};
3132

3233
struct st20p_tx_ctx {

0 commit comments

Comments
 (0)