From 2f6a54598de28eedf196ddcb69d9cd571a9f4ae6 Mon Sep 17 00:00:00 2001 From: Alexander Slobodeniuk Date: Wed, 30 Oct 2024 21:26:20 +0100 Subject: [PATCH 1/3] webcanvassink: fix memory leak of a GstWebVideoFrame Issue: RDI_2126 --- .../subprojects/gst-plugins-web/gst/web/gstwebcanvassink.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gst.wasm/subprojects/gst-plugins-web/gst/web/gstwebcanvassink.cpp b/gst.wasm/subprojects/gst-plugins-web/gst/web/gstwebcanvassink.cpp index 10c5360..2b6b5f7 100644 --- a/gst.wasm/subprojects/gst-plugins-web/gst/web/gstwebcanvassink.cpp +++ b/gst.wasm/subprojects/gst-plugins-web/gst/web/gstwebcanvassink.cpp @@ -132,6 +132,7 @@ gst_web_canvas_sink_draw_video_frame (gpointer data) self->val_context.call ("drawImage", video_frame, 0, 0, video_frame["displayWidth"], video_frame["displayHeight"], 0, 0, self->val_canvas["width"], self->val_canvas["height"]); + gst_memory_unref (GST_MEMORY_CAST (vf)); } static void From e2bc4e8bf281608d5f935f37cbce3953b072a119 Mon Sep 17 00:00:00 2001 From: Alexander Slobodeniuk Date: Wed, 30 Oct 2024 21:54:46 +0100 Subject: [PATCH 2/3] webcodecs: fix enquing limit mechanism It didn't cause any visible bug except the fact that there were thoughsands of frames pending to be dequeued detected at some point. Issue: RDI_2126 --- .../web/codecs/gstwebcodecsvideodecoder.cpp | 22 +++++++------------ .../gst/web/codecs/gstwebcodecsvideodecoder.h | 5 +---- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.cpp b/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.cpp index 71ead18..289582c 100644 --- a/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.cpp +++ b/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.cpp @@ -51,6 +51,8 @@ using namespace emscripten; +#define GST_WEB_CODECS_VIDEO_DECODER_MAX_DEQUEUE 32 + #define GST_WEB_CODECS_VIDEO_DECODER_FROM_JS \ reinterpret_cast ( \ val::module_property ("self").as ()) @@ -164,10 +166,6 @@ gst_web_codecs_video_decoder_on_output (val video_frame) val vf_timestamp; GST_INFO_OBJECT (self, "VideoFrame Received"); - g_mutex_lock (&self->dequeue_lock); - self->has_video_frame = TRUE; - g_cond_signal (&self->dequeue_cond); - g_mutex_unlock (&self->dequeue_lock); GST_VIDEO_DECODER_STREAM_LOCK (self); frame = gst_video_decoder_get_oldest_frame (GST_VIDEO_DECODER (self)); @@ -226,11 +224,6 @@ gst_web_codecs_video_decoder_on_output (val video_frame) if (frame) gst_video_codec_frame_unref (frame); - g_mutex_lock (&self->dequeue_lock); - self->has_video_frame = FALSE; - g_cond_signal (&self->dequeue_cond); - g_mutex_unlock (&self->dequeue_lock); - GST_VIDEO_DECODER_STREAM_UNLOCK (self); } @@ -409,15 +402,16 @@ gst_web_codecs_video_decoder_handle_frame ( GST_DEBUG_OBJECT (decoder, "Handling frame"); /* Wait until there is nothing pending to be to dequeued or there is a buffer */ + GST_VIDEO_DECODER_STREAM_UNLOCK (self); g_mutex_lock (&self->dequeue_lock); - while (self->dequeue_size && !self->has_video_frame) { - GST_INFO_OBJECT (self, - "Waiting until everything is dequeued, pending: %d, has_video_frame: " - "%d", - self->dequeue_size, self->has_video_frame); + while (self->dequeue_size >= GST_WEB_CODECS_VIDEO_DECODER_MAX_DEQUEUE) { + GST_DEBUG_OBJECT (self, "Reached queue limit [%d/%d], waiting for dequeue", + self->dequeue_size, GST_WEB_CODECS_VIDEO_DECODER_MAX_DEQUEUE); g_cond_wait (&self->dequeue_cond, &self->dequeue_lock); } + self->dequeue_size++; g_mutex_unlock (&self->dequeue_lock); + GST_VIDEO_DECODER_STREAM_LOCK (self); /* We are ready to process data */ GST_DEBUG_OBJECT (self, "Ready to process more data"); diff --git a/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.h b/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.h index 2b54879..0a7df82 100644 --- a/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.h +++ b/gst.wasm/subprojects/gst-plugins-web/gst/web/codecs/gstwebcodecsvideodecoder.h @@ -71,11 +71,8 @@ struct _GstWebCodecsVideoDecoder gboolean need_negotiation; emscripten::val decoder; - /* The size of the output frames pending to be dequeued */ + /* Amount of the output frames pending to be dequeued */ gint dequeue_size; - /* In case we receive a VideoFrame, in order to allow the - * blocked stream lock to continue despite the dequeue size */ - gboolean has_video_frame; GMutex dequeue_lock; GCond dequeue_cond; }; From 8e79c2bd450233a94862429ca326b0d15b61c6c2 Mon Sep 17 00:00:00 2001 From: Alexander Slobodeniuk Date: Wed, 30 Oct 2024 22:12:44 +0100 Subject: [PATCH 3/3] webvideoframe: fix leak of the private data Issue: RDI_2126 --- .../gst-plugins-web/gst-libs/gst/web/gstwebvideoframe.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst.wasm/subprojects/gst-plugins-web/gst-libs/gst/web/gstwebvideoframe.cpp b/gst.wasm/subprojects/gst-plugins-web/gst-libs/gst/web/gstwebvideoframe.cpp index 560d893..30abdfb 100644 --- a/gst.wasm/subprojects/gst-plugins-web/gst-libs/gst/web/gstwebvideoframe.cpp +++ b/gst.wasm/subprojects/gst-plugins-web/gst-libs/gst/web/gstwebvideoframe.cpp @@ -179,6 +179,10 @@ gst_web_video_frame_allocator_free (GstAllocator *allocator, GstMemory *memory) /* FIXME can be async */ gst_web_runner_send_message ( self->priv->runner, gst_web_video_frame_close, &close_data); + + gst_object_unref (self->priv->runner); + self->priv->video_frame = val::undefined (); + g_free (self->priv); } static void