From 4dd7d79b5257730c91968bdadf90b1e6e927451a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 12 Dec 2014 23:06:07 +0000 Subject: [PATCH] udpsink: allocate scratch space for render functions on the heap and not the stack. Our allocations could get a bit too large to be sure it's not going to cause trouble using the stack. --- gst/udp/gstmultiudpsink.c | 49 ++++++++++++++++++++++++++++----------- gst/udp/gstmultiudpsink.h | 8 +++++-- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/gst/udp/gstmultiudpsink.c b/gst/udp/gstmultiudpsink.c index 310566eeed..87178036f9 100644 --- a/gst/udp/gstmultiudpsink.c +++ b/gst/udp/gstmultiudpsink.c @@ -374,7 +374,6 @@ gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass) GST_DEBUG_CATEGORY_INIT (multiudpsink_debug, "multiudpsink", 0, "UDP sink"); } - static void gst_multiudpsink_init (GstMultiUDPSink * sink) { @@ -404,13 +403,18 @@ gst_multiudpsink_init (GstMultiUDPSink * sink) sink->cancellable = g_cancellable_new (); - /* allocate OutputVector and MapInfo for use in the render function, buffers can - * hold up to a maximum amount of memory so we can create a maximally sized - * array for them. */ + /* pre-allocate OutputVector, MapInfo and OutputMessage arrays + * for use in the render and render_list functions */ max_mem = gst_buffer_get_max_memory (); - sink->vec = g_new (GOutputVector, max_mem); - sink->map = g_new (GstMapInfo, max_mem); + sink->n_vecs = max_mem; + sink->vecs = g_new (GOutputVector, sink->n_vecs); + + sink->n_maps = max_mem; + sink->maps = g_new (GstMapInfo, sink->n_maps); + + sink->n_messages = 1; + sink->messages = g_new (GstOutputMessage, sink->n_messages); /* we assume that the number of memories per buffer can fit into a guint8 */ g_warn_if_fail (max_mem <= G_MAXUINT8); @@ -526,10 +530,12 @@ gst_multiudpsink_finalize (GObject * object) g_free (sink->multi_iface); sink->multi_iface = NULL; - g_free (sink->vec); - sink->vec = NULL; - g_free (sink->map); - sink->map = NULL; + g_free (sink->vecs); + sink->vecs = NULL; + g_free (sink->maps); + sink->maps = NULL; + g_free (sink->messages); + sink->messages = NULL; g_free (sink->bind_address); sink->bind_address = NULL; @@ -767,11 +773,28 @@ gst_multiudpsink_render_buffers (GstMultiUDPSink * sink, GstBuffer ** buffers, GST_LOG_OBJECT (sink, "%u buffers, %u memories -> to be sent to %u clients", num_buffers, total_mem_num, num_addr); - vecs = g_newa (GOutputVector, total_mem_num); - map_infos = g_newa (GstMapInfo, total_mem_num); + /* ensure our pre-allocated scratch space arrays are large enough */ + if (sink->n_vecs < total_mem_num) { + sink->n_vecs = GST_ROUND_UP_16 (total_mem_num); + g_free (sink->vecs); + sink->vecs = g_new (GOutputVector, sink->n_vecs); + } + vecs = sink->vecs; + + if (sink->n_maps < total_mem_num) { + sink->n_maps = GST_ROUND_UP_16 (total_mem_num); + g_free (sink->maps); + sink->maps = g_new (GstMapInfo, sink->n_maps); + } + map_infos = sink->maps; num_msgs = num_addr * num_buffers; - msgs = g_newa (GstOutputMessage, num_msgs); + if (sink->n_messages < num_msgs) { + sink->n_messages = GST_ROUND_UP_16 (num_msgs); + g_free (sink->messages); + sink->messages = g_new (GstOutputMessage, sink->n_messages); + } + msgs = sink->messages; /* populate first num_buffers messages with output vectors for the buffers */ for (i = 0, mem = 0; i < num_buffers; ++i) { diff --git a/gst/udp/gstmultiudpsink.h b/gst/udp/gstmultiudpsink.h index 19d27285d5..ba6f12c534 100644 --- a/gst/udp/gstmultiudpsink.h +++ b/gst/udp/gstmultiudpsink.h @@ -93,8 +93,12 @@ struct _GstMultiUDPSink { GList *clients_to_be_removed; /* pre-allocated scrap space for render function */ - GOutputVector *vec; - GstMapInfo *map; + GOutputVector *vecs; + guint n_vecs; + GstMapInfo *maps; + guint n_maps; + GstOutputMessage *messages; + guint n_messages; /* properties */ guint64 bytes_to_serve;