hlsdemux: Add a connection-speed property
authorThibault Saunier <thibault.saunier@collabora.com>
Thu, 10 May 2012 14:11:18 +0000 (10:11 -0400)
committerThibault Saunier <thibault.saunier@collabora.com>
Thu, 10 May 2012 18:17:57 +0000 (14:17 -0400)
Conflicts:

gst/hls/gsthlsdemux.c

gst/hls/gsthlsdemux.c
gst/hls/gsthlsdemux.h

index ecc6a15..8de5b41 100644 (file)
@@ -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);
index e7d4123..78202f9 100644 (file)
@@ -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;