From 52c97834df6a86f67cb5d7011360d3ba2457d0f8 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Tue, 5 Feb 2013 17:48:42 -0300 Subject: [PATCH] mssdemux: use downloadbitrate utility for measuring bitrate downloadbitrate keeps a short history of bitrates and helps tracking the current average download bitrate for mssdemux --- ext/smoothstreaming/Makefile.am | 6 +- ext/smoothstreaming/gstdownloadrate.c | 109 ++++++++++++++++++++++++++ ext/smoothstreaming/gstdownloadrate.h | 55 +++++++++++++ ext/smoothstreaming/gstmssdemux.c | 11 ++- ext/smoothstreaming/gstmssdemux.h | 3 +- 5 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 ext/smoothstreaming/gstdownloadrate.c create mode 100644 ext/smoothstreaming/gstdownloadrate.h diff --git a/ext/smoothstreaming/Makefile.am b/ext/smoothstreaming/Makefile.am index 534c69b375..314d10c331 100644 --- a/ext/smoothstreaming/Makefile.am +++ b/ext/smoothstreaming/Makefile.am @@ -13,11 +13,13 @@ libgstsmoothstreaming_la_LIBADD = \ libgstsmoothstreaming_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS} libgstsmoothstreaming_la_SOURCES = gstsmoothstreaming-plugin.c \ gstmssdemux.c \ - gstmssmanifest.c + gstmssmanifest.c \ + gstdownloadrate.c libgstsmoothstreaming_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = gstmssdemux.h \ - gstmssmanifest.h + gstmssmanifest.h \ + gstdownloadrate.h Android.mk: Makefile.am $(BUILT_SOURCES) androgenizer \ diff --git a/ext/smoothstreaming/gstdownloadrate.c b/ext/smoothstreaming/gstdownloadrate.c new file mode 100644 index 0000000000..c7c676a99f --- /dev/null +++ b/ext/smoothstreaming/gstdownloadrate.c @@ -0,0 +1,109 @@ +/* GStreamer + * Copyright (C) 2011 Andoni Morales Alastruey + * Copyright (C) 2012 Smart TV Alliance + * Author: Louis-Francis Ratté-Boulianne , 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 +#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); +} + +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/smoothstreaming/gstdownloadrate.h b/ext/smoothstreaming/gstdownloadrate.h new file mode 100644 index 0000000000..87a2fe81e1 --- /dev/null +++ b/ext/smoothstreaming/gstdownloadrate.h @@ -0,0 +1,55 @@ +/* GStreamer + * Copyright (C) 2012 Smart TV Alliance + * Author: Thiago Sousa Santos , 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 +#include + +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__ */ diff --git a/ext/smoothstreaming/gstmssdemux.c b/ext/smoothstreaming/gstmssdemux.c index 0246226451..e6166f23ce 100644 --- a/ext/smoothstreaming/gstmssdemux.c +++ b/ext/smoothstreaming/gstmssdemux.c @@ -83,6 +83,8 @@ GST_DEBUG_CATEGORY (mssdemux_debug); #define DEFAULT_MAX_QUEUE_SIZE_BUFFERS 0 #define DEFAULT_BITRATE_LIMIT 0.8 +#define DOWNLOAD_RATE_MAX_HISTORY_LENGTH 5 + enum { PROP_0, @@ -237,6 +239,9 @@ gst_mss_demux_stream_new (GstMssDemux * mssdemux, stream->pad = srcpad; stream->manifest_stream = manifeststream; stream->parent = mssdemux; + gst_download_rate_init (&stream->download_rate); + gst_download_rate_set_max_length (&stream->download_rate, + DOWNLOAD_RATE_MAX_HISTORY_LENGTH); return stream; } @@ -244,6 +249,7 @@ gst_mss_demux_stream_new (GstMssDemux * mssdemux, static void gst_mss_demux_stream_free (GstMssDemuxStream * stream) { + gst_download_rate_deinit (&stream->download_rate); if (stream->download_task) { if (GST_TASK_STATE (stream->download_task) != GST_TASK_STOPPED) { GST_DEBUG_OBJECT (stream->parent, "Leaving streaming task %s:%s", @@ -920,7 +926,7 @@ gst_mss_demux_get_download_bitrate (GstMssDemux * mssdemux) for (iter = mssdemux->streams; iter; iter = g_slist_next (iter)) { GstMssDemuxStream *stream = iter->data; - total += stream->download_bitrate; + total += gst_download_rate_get_current_rate (&stream->download_rate); count++; } @@ -1146,7 +1152,8 @@ gst_mss_demux_stream_download_fragment (GstMssDemuxStream * stream, GST_DEBUG_OBJECT (mssdemux, "Measured download bitrate: %s %llu bps", GST_PAD_NAME (stream->pad), bitrate); - stream->download_bitrate = bitrate; + gst_download_rate_add_rate (&stream->download_rate, + GST_BUFFER_SIZE (_buffer), 1000 * (after_download - before_download)); GST_DEBUG_OBJECT (mssdemux, "Storing buffer for stream %p - %s. Timestamp: %" GST_TIME_FORMAT diff --git a/ext/smoothstreaming/gstmssdemux.h b/ext/smoothstreaming/gstmssdemux.h index ddd9a3baeb..2c48aac364 100644 --- a/ext/smoothstreaming/gstmssdemux.h +++ b/ext/smoothstreaming/gstmssdemux.h @@ -28,6 +28,7 @@ #include #include "gstmssmanifest.h" #include +#include "gstdownloadrate.h" G_BEGIN_DECLS @@ -72,7 +73,7 @@ struct _GstMssDemuxStream { gboolean eos; gboolean have_data; - guint64 download_bitrate; + GstDownloadRate download_rate; }; struct _GstMssDemux { -- 2.34.1