mssdemux: use streams bitrate individually
authorThiago Santos <thiago.sousa.santos@collabora.com>
Wed, 6 Feb 2013 11:48:55 +0000 (08:48 -0300)
committerThiago Santos <thiago.sousa.santos@collabora.com>
Wed, 8 May 2013 00:09:48 +0000 (21:09 -0300)
connection setup times seem to matter when measuring the download
rate of different streams. Streams with longer fragments have a
*relatively* lower connection setup time and achieve higher bitrates.

Using the average seems unfair here, so use each stream's measured bitrate
to select its best quality option.

ext/smoothstreaming/gstmssdemux.c
ext/smoothstreaming/gstmssmanifest.c
ext/smoothstreaming/gstmssmanifest.h

index e6166f2..8127a4d 100644 (file)
@@ -954,27 +954,42 @@ gst_mss_demux_reconfigure (GstMssDemux * mssdemux)
   GSList *oldpads = NULL;
   GSList *iter;
   guint64 new_bitrate;
+  gboolean changed = FALSE;
 
   /* TODO lock? */
 
   if (!gst_mss_demux_all_streams_have_data (mssdemux))
     return;
 
-  new_bitrate =
-      mssdemux->bitrate_limit * gst_mss_demux_get_download_bitrate (mssdemux);
-  if (mssdemux->connection_speed) {
-    new_bitrate = MIN (mssdemux->connection_speed, new_bitrate);
-  }
+  gst_mss_demux_stop_tasks (mssdemux, TRUE);
+  for (iter = mssdemux->streams; iter; iter = g_slist_next (iter)) {
+    GstMssDemuxStream *stream;
 
-  GST_DEBUG_OBJECT (mssdemux, "Current suggested bitrate: %llu", new_bitrate);
+    stream = iter->data;
 
-  gst_mss_demux_stop_tasks (mssdemux, TRUE);
-  if (gst_mss_manifest_change_bitrate (mssdemux->manifest, new_bitrate)) {
-    GstClockTime newseg_ts = GST_CLOCK_TIME_NONE;
+    new_bitrate =
+        mssdemux->bitrate_limit *
+        gst_download_rate_get_current_rate (&stream->download_rate);
+    if (mssdemux->connection_speed) {
+      new_bitrate = MIN (mssdemux->connection_speed, new_bitrate);
+    }
 
-    GST_INFO_OBJECT (mssdemux, "Switching to bitrate %llu", new_bitrate);
+    GST_DEBUG_OBJECT (mssdemux, "Current stream %s download bitrate %llu",
+        GST_PAD_NAME (stream->pad), new_bitrate);
 
-    GST_DEBUG_OBJECT (mssdemux, "Creating new pad group");
+    if (gst_mss_stream_select_bitrate (stream->manifest_stream, new_bitrate)) {
+      changed = TRUE;
+      GST_INFO_OBJECT (mssdemux, "Stream %s changed bitrate to %llu",
+          GST_PAD_NAME (stream->pad),
+          gst_mss_stream_get_current_bitrate (stream->manifest_stream));
+    }
+  }
+
+  if (changed) {
+    GstClockTime newseg_ts = GST_CLOCK_TIME_NONE;
+
+    GST_DEBUG_OBJECT (mssdemux,
+        "Bitrates have changed, creating new pad group");
     /* if we changed the bitrate, we need to add new pads */
     for (iter = mssdemux->streams; iter; iter = g_slist_next (iter)) {
       GstMssDemuxStream *stream = iter->data;
index 56d670a..9eaa810 100644 (file)
@@ -992,7 +992,7 @@ gst_mss_manifest_reload_fragments (GstMssManifest * manifest, GstBuffer * data)
   xmlFreeDoc (xml);
 }
 
-static gboolean
+gboolean
 gst_mss_stream_select_bitrate (GstMssStream * stream, guint64 bitrate)
 {
   GList *iter = stream->current_quality;
@@ -1031,6 +1031,17 @@ gst_mss_stream_select_bitrate (GstMssStream * stream, guint64 bitrate)
   return TRUE;
 }
 
+guint64
+gst_mss_stream_get_current_bitrate (GstMssStream * stream)
+{
+  GstMssStreamQuality *q;
+  if (stream->current_quality == NULL)
+    return 0;
+
+  q = stream->current_quality->data;
+  return q->bitrate;
+}
+
 /**
  * gst_mss_manifest_change_bitrate:
  * @manifest: the manifest
index 982f32d..825b082 100644 (file)
@@ -52,6 +52,8 @@ void gst_mss_manifest_reload_fragments (GstMssManifest * manifest, GstBuffer * d
 
 GstMssStreamType gst_mss_stream_get_type (GstMssStream *stream);
 GstCaps * gst_mss_stream_get_caps (GstMssStream * stream);
+gboolean gst_mss_stream_select_bitrate (GstMssStream * stream, guint64 bitrate);
+guint64 gst_mss_stream_get_current_bitrate (GstMssStream * stream);
 void gst_mss_stream_set_active (GstMssStream * stream, gboolean active);
 guint64 gst_mss_stream_get_timescale (GstMssStream * stream);
 GstFlowReturn gst_mss_stream_get_fragment_url (GstMssStream * stream, gchar ** url);