urisourcebin: limit the byte size of the queue based on the buffer-size
Use the bitrate advertised by queue2 to determine the limits to set across possibly multiple queue2/downloadbuffer elements. e.g. with two queue2's and a max-bytes based on the ratio of the bitrate/cumulative_bitrate multiplied by the buffer_size set on urisourcebin. This allows finer grained control over the buffer used by all the queue elements inside urisourcebin. Instead of a maximum of n_streams*buffer_size being used, only buffer_size will be used however we will fallback to n_streams*buffer_size if one of the queue2's does not have bitrate information. https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/60
This commit is contained in:
parent
a8e2f76731
commit
8b69b689c0
@ -111,6 +111,8 @@ struct _OutputSlotInfo
|
|||||||
GstPad *sinkpad; /* Sink pad of the queue eleemnt */
|
GstPad *sinkpad; /* Sink pad of the queue eleemnt */
|
||||||
GstPad *srcpad; /* Output ghost pad */
|
GstPad *srcpad; /* Output ghost pad */
|
||||||
gboolean is_eos; /* Did EOS get fed into the buffering element */
|
gboolean is_eos; /* Did EOS get fed into the buffering element */
|
||||||
|
|
||||||
|
gulong bitrate_changed_id; /* queue bitrate changed notification */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -839,6 +841,80 @@ pre_queue_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_byte_limits (GstElement * elem, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (elem);
|
||||||
|
guint64 cumulative_bitrate = 0;
|
||||||
|
GSList *cur;
|
||||||
|
|
||||||
|
GST_URI_SOURCE_BIN_LOCK (urisrc);
|
||||||
|
if (urisrc->buffer_size == -1) {
|
||||||
|
GST_TRACE_OBJECT (urisrc, "Buffer size not set, not recalculating queue "
|
||||||
|
"limits");
|
||||||
|
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cur = urisrc->out_slots; cur != NULL; cur = g_slist_next (cur)) {
|
||||||
|
OutputSlotInfo *slot = (OutputSlotInfo *) (cur->data);
|
||||||
|
guint64 bitrate = 0;
|
||||||
|
|
||||||
|
if (g_object_class_find_property (G_OBJECT_GET_CLASS (slot->queue),
|
||||||
|
"bitrate")) {
|
||||||
|
g_object_get (G_OBJECT (slot->queue), "bitrate", &bitrate, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitrate > 0)
|
||||||
|
cumulative_bitrate += bitrate;
|
||||||
|
else {
|
||||||
|
GST_TRACE_OBJECT (urisrc, "Unknown bitrate detected from %" GST_PTR_FORMAT
|
||||||
|
", resetting all bitrates", slot->queue);
|
||||||
|
cumulative_bitrate = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (urisrc, "recalculating queue limits with cumulative "
|
||||||
|
"bitrate %" G_GUINT64_FORMAT " and buffer size %u", cumulative_bitrate,
|
||||||
|
urisrc->buffer_size);
|
||||||
|
|
||||||
|
for (cur = urisrc->out_slots; cur != NULL; cur = g_slist_next (cur)) {
|
||||||
|
OutputSlotInfo *slot = (OutputSlotInfo *) (cur->data);
|
||||||
|
guint64 bitrate;
|
||||||
|
guint byte_limit;
|
||||||
|
|
||||||
|
if (cumulative_bitrate > 0) {
|
||||||
|
if (g_object_class_find_property (G_OBJECT_GET_CLASS (slot->queue),
|
||||||
|
"bitrate")) {
|
||||||
|
g_object_get (G_OBJECT (slot->queue), "bitrate", &bitrate, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_limit =
|
||||||
|
gst_util_uint64_scale (urisrc->buffer_size, bitrate,
|
||||||
|
cumulative_bitrate);
|
||||||
|
} else {
|
||||||
|
byte_limit = urisrc->buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (urisrc,
|
||||||
|
"calculated new byte limit for queue2 %" GST_PTR_FORMAT ", %u",
|
||||||
|
slot->queue, byte_limit);
|
||||||
|
g_object_set (G_OBJECT (slot->queue), "max-size-bytes", byte_limit, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_queue_bitrate_changed (GstElement * queue, GParamSpec * pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (user_data);
|
||||||
|
|
||||||
|
gst_element_call_async (GST_ELEMENT (urisrc), update_byte_limits, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Called with lock held */
|
/* Called with lock held */
|
||||||
static OutputSlotInfo *
|
static OutputSlotInfo *
|
||||||
get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
|
get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
|
||||||
@ -886,6 +962,10 @@ get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
|
|||||||
/* Set the slot onto the queue (needed in buffering msg handling) */
|
/* Set the slot onto the queue (needed in buffering msg handling) */
|
||||||
g_object_set_data (G_OBJECT (queue), "urisourcebin.slotinfo", slot);
|
g_object_set_data (G_OBJECT (queue), "urisourcebin.slotinfo", slot);
|
||||||
|
|
||||||
|
slot->bitrate_changed_id =
|
||||||
|
g_signal_connect (G_OBJECT (queue), "notify::bitrate",
|
||||||
|
(GCallback) on_queue_bitrate_changed, urisrc);
|
||||||
|
|
||||||
if (do_download) {
|
if (do_download) {
|
||||||
gchar *temp_template, *filename;
|
gchar *temp_template, *filename;
|
||||||
const gchar *tmp_dir, *prgname;
|
const gchar *tmp_dir, *prgname;
|
||||||
@ -1794,6 +1874,10 @@ free_output_slot (OutputSlotInfo * slot, GstURISourceBin * urisrc)
|
|||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (urisrc, "removing old queue element and freeing slot %p",
|
GST_DEBUG_OBJECT (urisrc, "removing old queue element and freeing slot %p",
|
||||||
slot);
|
slot);
|
||||||
|
if (slot->bitrate_changed_id > 0)
|
||||||
|
g_signal_handler_disconnect (slot->queue, slot->bitrate_changed_id);
|
||||||
|
slot->bitrate_changed_id = 0;
|
||||||
|
|
||||||
gst_element_set_locked_state (slot->queue, TRUE);
|
gst_element_set_locked_state (slot->queue, TRUE);
|
||||||
gst_element_set_state (slot->queue, GST_STATE_NULL);
|
gst_element_set_state (slot->queue, GST_STATE_NULL);
|
||||||
gst_bin_remove (GST_BIN_CAST (urisrc), slot->queue);
|
gst_bin_remove (GST_BIN_CAST (urisrc), slot->queue);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user