diff --git a/gst/hls/gsthlsdemux.c b/gst/hls/gsthlsdemux.c index ecc6a15cc1..8de5b41791 100644 --- a/gst/hls/gsthlsdemux.c +++ b/gst/hls/gsthlsdemux.c @@ -68,6 +68,7 @@ enum PROP_FRAGMENTS_CACHE, PROP_BITRATE_LIMIT, + PROP_CONNECTION_SPEED, PROP_LAST }; @@ -76,6 +77,7 @@ static const float update_interval_factor[] = { 1, 0.5, 1.5, 3 }; #define DEFAULT_FRAGMENTS_CACHE 3 #define DEFAULT_FAILED_COUNT 3 #define DEFAULT_BITRATE_LIMIT 0.8 +#define DEFAULT_CONNECTION_SPEED 0 /* GObject */ static void gst_hls_demux_set_property (GObject * object, guint prop_id, @@ -181,6 +183,12 @@ gst_hls_demux_class_init (GstHLSDemuxClass * klass) 0, 1, DEFAULT_BITRATE_LIMIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CONNECTION_SPEED, + g_param_spec_uint ("connection-speed", "Connection Speed", + "Network connection speed in kbps (0 = unknown)", + 0, G_MAXUINT / 1000, DEFAULT_CONNECTION_SPEED, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + element_class->change_state = GST_DEBUG_FUNCPTR (gst_hls_demux_change_state); gst_element_class_add_pad_template (element_class, @@ -219,6 +227,7 @@ gst_hls_demux_init (GstHLSDemux * demux) /* Properties */ demux->fragments_cache = DEFAULT_FRAGMENTS_CACHE; demux->bitrate_limit = DEFAULT_BITRATE_LIMIT; + demux->connection_speed = DEFAULT_CONNECTION_SPEED; demux->queue = g_queue_new (); @@ -249,6 +258,9 @@ gst_hls_demux_set_property (GObject * object, guint prop_id, case PROP_BITRATE_LIMIT: demux->bitrate_limit = g_value_get_float (value); break; + case PROP_CONNECTION_SPEED: + demux->connection_speed = g_value_get_uint (value) * 1000; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -268,6 +280,9 @@ gst_hls_demux_get_property (GObject * object, guint prop_id, GValue * value, case PROP_BITRATE_LIMIT: g_value_set_float (value, demux->bitrate_limit); break; + case PROP_CONNECTION_SPEED: + g_value_set_uint (value, demux->connection_speed / 1000); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -854,9 +869,18 @@ gst_hls_demux_cache_fragments (GstHLSDemux * demux) if (gst_m3u8_client_has_variant_playlist (demux->client)) { GstM3U8 *child = NULL; - GST_M3U8_CLIENT_LOCK (demux->client); - child = demux->client->main->current_variant->data; - GST_M3U8_CLIENT_UNLOCK (demux->client); + if (demux->connection_speed == 0) { + + GST_M3U8_CLIENT_LOCK (demux->client); + child = demux->client->main->current_variant->data; + GST_M3U8_CLIENT_UNLOCK (demux->client); + } else { + GList *tmp = gst_m3u8_client_get_playlist_for_bitrate (demux->client, + demux->connection_speed); + + child = GST_M3U8 (tmp->data); + } + gst_m3u8_client_set_current (demux->client, child); if (!gst_hls_demux_update_playlist (demux, FALSE)) { GST_ERROR_OBJECT (demux, "Could not fetch the child playlist %s", @@ -985,6 +1009,11 @@ gst_hls_demux_change_playlist (GstHLSDemux * demux, guint max_bitrate) GList *previous_variant, *current_variant; gint old_bandwidth, new_bandwidth; + /* If user specifies a connection speed never use a playlist with a bandwidth + * superior than it */ + if (demux->connection_speed != 0 && max_bitrate > demux->connection_speed) + max_bitrate = demux->connection_speed; + previous_variant = demux->client->main->current_variant; current_variant = gst_m3u8_client_get_playlist_for_bitrate (demux->client, max_bitrate); diff --git a/gst/hls/gsthlsdemux.h b/gst/hls/gsthlsdemux.h index e7d4123f44..78202f9070 100644 --- a/gst/hls/gsthlsdemux.h +++ b/gst/hls/gsthlsdemux.h @@ -65,11 +65,12 @@ struct _GstHLSDemux GQueue *queue; /* Queue storing the fetched fragments */ gboolean need_cache; /* Wheter we need to cache some fragments before starting to push data */ gboolean end_of_playlist; - gboolean do_typefind; /* Whether we need to typefind the next buffer */ + gboolean do_typefind; /* Whether we need to typefind the next buffer */ /* Properties */ guint fragments_cache; /* number of fragments needed to be cached to start playing */ - gfloat bitrate_limit; /* limit of the available bitrate to use */ + gfloat bitrate_limit; /* limit of the available bitrate to use */ + guint connection_speed; /* Network connection speed in kbps (0 = unknown) */ /* Streaming task */ GstTask *stream_task;