mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
souphttpsrc: dynamically adjust blocksize
Update the blocksize depending on how much is obtained from a read of the input stream. This avoids doing too many reads in small chunks when larger amounts of data are available and also prevents using a very large memory area to read a small chunk of data. https://bugzilla.gnome.org/show_bug.cgi?id=767833
This commit is contained in:
parent
75963b47f4
commit
11c61f14bf
2 changed files with 57 additions and 0 deletions
|
@ -134,6 +134,13 @@ enum
|
||||||
#define DEFAULT_RETRIES 3
|
#define DEFAULT_RETRIES 3
|
||||||
#define DEFAULT_SOUP_METHOD NULL
|
#define DEFAULT_SOUP_METHOD NULL
|
||||||
|
|
||||||
|
#define GROW_BLOCKSIZE_LIMIT 1
|
||||||
|
#define GROW_BLOCKSIZE_COUNT 1
|
||||||
|
#define GROW_BLOCKSIZE_FACTOR 2
|
||||||
|
#define REDUCE_BLOCKSIZE_LIMIT 0.20
|
||||||
|
#define REDUCE_BLOCKSIZE_COUNT 2
|
||||||
|
#define REDUCE_BLOCKSIZE_FACTOR 0.5
|
||||||
|
|
||||||
static void gst_soup_http_src_uri_handler_init (gpointer g_iface,
|
static void gst_soup_http_src_uri_handler_init (gpointer g_iface,
|
||||||
gpointer iface_data);
|
gpointer iface_data);
|
||||||
static void gst_soup_http_src_finalize (GObject * gobject);
|
static void gst_soup_http_src_finalize (GObject * gobject);
|
||||||
|
@ -439,6 +446,9 @@ gst_soup_http_src_reset (GstSoupHTTPSrc * src)
|
||||||
src->content_size = 0;
|
src->content_size = 0;
|
||||||
src->have_body = FALSE;
|
src->have_body = FALSE;
|
||||||
|
|
||||||
|
src->reduce_blocksize_count = 0;
|
||||||
|
src->increase_blocksize_count = 0;
|
||||||
|
|
||||||
src->ret = GST_FLOW_OK;
|
src->ret = GST_FLOW_OK;
|
||||||
g_cancellable_reset (src->cancellable);
|
g_cancellable_reset (src->cancellable);
|
||||||
gst_soup_http_src_destroy_input_stream (src);
|
gst_soup_http_src_destroy_input_stream (src);
|
||||||
|
@ -481,6 +491,7 @@ gst_soup_http_src_init (GstSoupHTTPSrc * src)
|
||||||
src->tls_interaction = DEFAULT_TLS_INTERACTION;
|
src->tls_interaction = DEFAULT_TLS_INTERACTION;
|
||||||
src->max_retries = DEFAULT_RETRIES;
|
src->max_retries = DEFAULT_RETRIES;
|
||||||
src->method = DEFAULT_SOUP_METHOD;
|
src->method = DEFAULT_SOUP_METHOD;
|
||||||
|
src->minimum_blocksize = gst_base_src_get_blocksize (GST_BASE_SRC_CAST (src));
|
||||||
proxy = g_getenv ("http_proxy");
|
proxy = g_getenv ("http_proxy");
|
||||||
if (!gst_soup_http_src_set_proxy (src, proxy)) {
|
if (!gst_soup_http_src_set_proxy (src, proxy)) {
|
||||||
GST_WARNING_OBJECT (src,
|
GST_WARNING_OBJECT (src,
|
||||||
|
@ -1457,6 +1468,46 @@ done:
|
||||||
return src->ret;
|
return src->ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the bytes_read is above a certain threshold of the blocksize, if
|
||||||
|
* that happens a few times in a row, increase the blocksize; Do the same in
|
||||||
|
* the opposite direction to reduce the blocksize.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gst_soup_http_src_check_update_blocksize (GstSoupHTTPSrc * src,
|
||||||
|
gint64 bytes_read)
|
||||||
|
{
|
||||||
|
guint blocksize = gst_base_src_get_blocksize (GST_BASE_SRC_CAST (src));
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (src, "Checking to update blocksize. Read:%" G_GINT64_FORMAT
|
||||||
|
" blocksize:%u", bytes_read, blocksize);
|
||||||
|
|
||||||
|
if (bytes_read >= blocksize * GROW_BLOCKSIZE_LIMIT) {
|
||||||
|
src->reduce_blocksize_count = 0;
|
||||||
|
src->increase_blocksize_count++;
|
||||||
|
|
||||||
|
if (src->increase_blocksize_count >= GROW_BLOCKSIZE_COUNT) {
|
||||||
|
blocksize *= GROW_BLOCKSIZE_FACTOR;
|
||||||
|
GST_DEBUG_OBJECT (src, "Increased blocksize to %u", blocksize);
|
||||||
|
gst_base_src_set_blocksize (GST_BASE_SRC_CAST (src), blocksize);
|
||||||
|
src->increase_blocksize_count = 0;
|
||||||
|
}
|
||||||
|
} else if (bytes_read < blocksize * REDUCE_BLOCKSIZE_LIMIT) {
|
||||||
|
src->reduce_blocksize_count++;
|
||||||
|
src->increase_blocksize_count = 0;
|
||||||
|
|
||||||
|
if (src->reduce_blocksize_count >= REDUCE_BLOCKSIZE_COUNT) {
|
||||||
|
blocksize *= REDUCE_BLOCKSIZE_FACTOR;
|
||||||
|
blocksize = MAX (blocksize, src->minimum_blocksize);
|
||||||
|
GST_DEBUG_OBJECT (src, "Decreased blocksize to %u", blocksize);
|
||||||
|
gst_base_src_set_blocksize (GST_BASE_SRC_CAST (src), blocksize);
|
||||||
|
src->reduce_blocksize_count = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
src->reduce_blocksize_count = src->increase_blocksize_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_soup_http_src_update_position (GstSoupHTTPSrc * src, gint64 bytes_read)
|
gst_soup_http_src_update_position (GstSoupHTTPSrc * src, gint64 bytes_read)
|
||||||
{
|
{
|
||||||
|
@ -1586,6 +1637,8 @@ gst_soup_http_src_read_buffer (GstSoupHTTPSrc * src, GstBuffer ** outbuf)
|
||||||
|
|
||||||
/* Got some data, reset retry counter */
|
/* Got some data, reset retry counter */
|
||||||
src->retry_count = 0;
|
src->retry_count = 0;
|
||||||
|
|
||||||
|
gst_soup_http_src_check_update_blocksize (src, read_bytes);
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_unref (*outbuf);
|
gst_buffer_unref (*outbuf);
|
||||||
if (read_bytes < 0) {
|
if (read_bytes < 0) {
|
||||||
|
|
|
@ -94,6 +94,10 @@ struct _GstSoupHTTPSrc {
|
||||||
GMainContext *poll_context;
|
GMainContext *poll_context;
|
||||||
GSource *poll_source;
|
GSource *poll_source;
|
||||||
|
|
||||||
|
gint reduce_blocksize_count;
|
||||||
|
gint increase_blocksize_count;
|
||||||
|
guint minimum_blocksize;
|
||||||
|
|
||||||
/* Shoutcast/icecast metadata extraction handling. */
|
/* Shoutcast/icecast metadata extraction handling. */
|
||||||
gboolean iradio_mode;
|
gboolean iradio_mode;
|
||||||
GstCaps *src_caps;
|
GstCaps *src_caps;
|
||||||
|
|
Loading…
Reference in a new issue