dashdemux: add a downloadrate utility
authorThiago Santos <thiago.sousa.santos@collabora.com>
Tue, 5 Feb 2013 20:38:06 +0000 (17:38 -0300)
committerThiago Santos <thiago.sousa.santos@collabora.com>
Wed, 8 May 2013 21:14:39 +0000 (18:14 -0300)
A small struct that keeps a short history of fragment download bitrates
to have an average measure of N last fragments instead of using only
the last downloaded bitrate

ext/dash/Makefile.am
ext/dash/gstdashdemux.c
ext/dash/gstdashdemux.h
ext/dash/gstdownloadrate.c [new file with mode: 0644]
ext/dash/gstdownloadrate.h [new file with mode: 0644]

index d91f0f0..84a20c8 100644 (file)
@@ -4,12 +4,14 @@ plugin_LTLIBRARIES = libgstdashdemux.la
 libgstdashdemux_la_SOURCES =                   \
        gstmpdparser.c                          \
        gstdashdemux.c                          \
-       gstplugin.c
+       gstplugin.c                             \
+       gstdownloadrate.c
 
 # headers we need but don't want installed
 noinst_HEADERS =        \
         gstmpdparser.h \
-       gstdashdemux.h
+       gstdashdemux.h  \
+       gstdownloadrate.h
 
 # compiler and linker flags used to compile this plugin, set in configure.ac
 libgstdashdemux_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_CFLAGS)
index 27b96f6..152e59c 100644 (file)
@@ -184,6 +184,7 @@ enum
 #define DEFAULT_MAX_BITRATE        24000000     /* in bit/s  */
 
 #define DEFAULT_FAILED_COUNT 3
+#define DOWNLOAD_RATE_HISTORY_MAX 3
 
 /* Custom internal event to signal end of period */
 #define GST_EVENT_DASH_EOP GST_EVENT_MAKE_TYPE(81, GST_EVENT_TYPE_DOWNSTREAM | GST_EVENT_TYPE_SERIALIZED)
@@ -711,6 +712,9 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
 
     stream->index = i;
     stream->input_caps = caps;
+    gst_download_rate_init (&stream->dnl_rate);
+    gst_download_rate_set_max_length (&stream->dnl_rate,
+        DOWNLOAD_RATE_HISTORY_MAX);
 
     GST_LOG_OBJECT (demux, "Creating stream %d %" GST_PTR_FORMAT, i, caps);
     demux->streams = g_slist_prepend (demux->streams, stream);
@@ -1207,6 +1211,7 @@ error_pushing:
 static void
 gst_dash_demux_stream_free (GstDashDemuxStream * stream)
 {
+  gst_download_rate_deinit (&stream->dnl_rate);
   if (stream->input_caps) {
     gst_caps_unref (stream->input_caps);
     stream->input_caps = NULL;
@@ -1577,7 +1582,9 @@ gst_dash_demux_select_representations (GstDashDemux * demux)
     if (!rep_list)
       return FALSE;
 
-    bitrate = stream->dnl_rate * demux->bandwidth_usage;
+    bitrate =
+        gst_download_rate_get_current_rate (&stream->dnl_rate) *
+        demux->bandwidth_usage;
     GST_DEBUG_OBJECT (demux, "Trying to change to bitrate: %llu", bitrate);
 
     /* get representation index with current max_bandwidth */
@@ -1859,14 +1866,16 @@ gst_dash_demux_get_next_fragment (GstDashDemux * demux)
   /* Wake the download task up */
   GST_TASK_SIGNAL (demux->download_task);
   if (selected_stream) {
+    guint64 brate;
+
     diff = (GST_TIMEVAL_TO_TIME (now) - GST_TIMEVAL_TO_TIME (start));
-    selected_stream->dnl_rate =
-        (size_buffer * 8) / ((double) diff / GST_SECOND);
+    gst_download_rate_add_rate (&selected_stream->dnl_rate, size_buffer, diff);
+
+    brate = (size_buffer * 8) / ((double) diff / GST_SECOND);
     GST_INFO_OBJECT (demux,
         "Stream: %d Download rate = %" PRIu64 " Kbits/s (%" PRIu64
         " Ko in %.2f s)", selected_stream->index,
-        selected_stream->dnl_rate / 1000, size_buffer / 1024,
-        ((double) diff / GST_SECOND));
+        brate / 1000, size_buffer / 1024, ((double) diff / GST_SECOND));
   }
   return TRUE;
 }
index 481fa54..e7629f9 100644 (file)
@@ -34,6 +34,7 @@
 #include <gst/base/gstadapter.h>
 #include <gst/base/gstdataqueue.h>
 #include "gstmpdparser.h"
+#include "gstdownloadrate.h"
 #include <gst/uridownloader/gsturidownloader.h>
 
 G_BEGIN_DECLS
@@ -93,8 +94,7 @@ struct _GstDashDemuxStream
 
   GstDataQueue *queue;
 
-  /* Download rate */
-  guint64 dnl_rate;
+  GstDownloadRate dnl_rate;
 };
 
 /**
diff --git a/ext/dash/gstdownloadrate.c b/ext/dash/gstdownloadrate.c
new file mode 100644 (file)
index 0000000..a56c78e
--- /dev/null
@@ -0,0 +1,110 @@
+/* GStreamer
+ * Copyright (C) 2011 Andoni Morales Alastruey <ylatuya@gmail.com>
+ * Copyright (C) 2012 Smart TV Alliance
+ *  Author: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>, Collabora Ltd.
+ *
+ * gstfragment.c:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include "gstdownloadrate.h"
+
+static void
+_gst_download_rate_check_remove_rates (GstDownloadRate * rate)
+{
+  if (rate->max_length == 0)
+    return;
+
+  while (g_queue_get_length (&rate->queue) > rate->max_length) {
+    guint bitrate = GPOINTER_TO_UINT (g_queue_pop_head (&rate->queue));
+
+    rate->total -= bitrate;
+  }
+}
+
+void
+gst_download_rate_init (GstDownloadRate * rate)
+{
+  g_queue_init (&rate->queue);
+  g_static_mutex_init (&rate->mutex);
+  rate->total = 0;
+  rate->max_length = 0;
+}
+
+void
+gst_download_rate_deinit (GstDownloadRate * rate)
+{
+  gst_download_rate_clear (rate);
+  g_static_mutex_free (&rate->mutex);
+}
+
+void
+gst_download_rate_set_max_length (GstDownloadRate * rate, gint max_length)
+{
+  g_static_mutex_lock (&rate->mutex);
+  rate->max_length = max_length;
+  _gst_download_rate_check_remove_rates (rate);
+  g_static_mutex_unlock (&rate->mutex);
+}
+
+gint
+gst_download_rate_get_max_length (GstDownloadRate * rate)
+{
+  guint ret;
+  g_static_mutex_lock (&rate->mutex);
+  ret = rate->max_length;
+  g_static_mutex_unlock (&rate->mutex);
+
+  return ret;
+}
+
+void
+gst_download_rate_clear (GstDownloadRate * rate)
+{
+  g_static_mutex_lock (&rate->mutex);
+  g_queue_clear (&rate->queue);
+  rate->total = 0;
+  g_static_mutex_unlock (&rate->mutex);
+}
+
+void
+gst_download_rate_add_rate (GstDownloadRate * rate, guint bytes, guint64 time)
+{
+  guint64 bitrate;
+  g_static_mutex_lock (&rate->mutex);
+
+  /* convert from bytes / nanoseconds to bits per second */
+  bitrate = G_GUINT64_CONSTANT (8000000000) * bytes / time;
+
+  g_queue_push_tail (&rate->queue, GUINT_TO_POINTER ((guint) bitrate));
+  rate->total += bitrate;
+
+  _gst_download_rate_check_remove_rates (rate);
+  g_static_mutex_unlock (&rate->mutex);
+}
+
+guint
+gst_download_rate_get_current_rate (GstDownloadRate * rate)
+{
+  guint ret;
+  g_static_mutex_lock (&rate->mutex);
+  ret = rate->total / g_queue_get_length (&rate->queue);
+  g_static_mutex_unlock (&rate->mutex);
+
+  return ret;
+}
diff --git a/ext/dash/gstdownloadrate.h b/ext/dash/gstdownloadrate.h
new file mode 100644 (file)
index 0000000..87a2fe8
--- /dev/null
@@ -0,0 +1,55 @@
+/* GStreamer
+ * Copyright (C) 2012 Smart TV Alliance
+ *  Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>, Collabora Ltd.
+ *
+ * gstdownloadrate.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_DOWNLOAD_RATE_H__
+#define __GST_DOWNLOAD_RATE_H__
+
+#include <glib-object.h>
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstDownloadRate GstDownloadRate;
+
+struct _GstDownloadRate
+{
+  GQueue queue;
+  GStaticMutex mutex;
+
+  gint max_length;
+
+  guint64 total;
+};
+
+void gst_download_rate_init (GstDownloadRate * rate);
+void gst_download_rate_deinit (GstDownloadRate * rate);
+
+void gst_download_rate_set_max_length (GstDownloadRate * rate, gint max_length);
+gint gst_download_rate_get_max_length (GstDownloadRate * rate);
+
+void gst_download_rate_clear (GstDownloadRate * rate);
+void gst_download_rate_add_rate (GstDownloadRate * rate, guint bytes, guint64 time);
+
+guint gst_download_rate_get_current_rate (GstDownloadRate * rate);
+
+G_END_DECLS
+#endif /* __GST_DOWNLOAD_RATE_H__ */