diff --git a/ext/dash/Makefile.am b/ext/dash/Makefile.am index b6e544677e..97d8623ecd 100644 --- a/ext/dash/Makefile.am +++ b/ext/dash/Makefile.am @@ -4,14 +4,12 @@ plugin_LTLIBRARIES = libgstdashdemux.la libgstdashdemux_la_SOURCES = \ gstmpdparser.c \ gstdashdemux.c \ - gstplugin.c \ - gstdownloadrate.c + gstplugin.c # headers we need but don't want installed noinst_HEADERS = \ gstmpdparser.h \ gstdashdemux.h \ - gstdownloadrate.h \ gstdash_debug.h # compiler and linker flags used to compile this plugin, set in configure.ac diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c index 58eed49787..9981644cfc 100644 --- a/ext/dash/gstdashdemux.c +++ b/ext/dash/gstdashdemux.c @@ -180,7 +180,6 @@ enum #define DEFAULT_MAX_BITRATE 24000000 /* in bit/s */ #define DEFAULT_FAILED_COUNT 3 -#define DOWNLOAD_RATE_HISTORY_MAX 3 #define GST_DASH_DEMUX_CLIENT_LOCK(d) g_mutex_lock (&d->client_lock) #define GST_DASH_DEMUX_CLIENT_UNLOCK(d) g_mutex_unlock (&d->client_lock) @@ -656,13 +655,12 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux) g_cond_init (&stream->download_cond); g_mutex_init (&stream->download_mutex); stream->downloader = gst_uri_downloader_new (); + stream->download_total_time = 0; + stream->download_total_bytes = 0; stream->index = i; stream->input_caps = caps; stream->need_header = TRUE; - 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); streams = g_slist_prepend (streams, stream); @@ -1096,7 +1094,6 @@ gst_dash_demux_advance_period (GstDashDemux * demux) 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; @@ -1593,7 +1590,7 @@ gst_dash_demux_stream_select_representation_unlocked (GstDashDemuxStream * GList *rep_list = NULL; gint new_index; GstDashDemux *demux = stream->demux; - guint64 bitrate; + guint64 bitrate = 0; active_stream = stream->active_stream; if (active_stream == NULL) @@ -1605,11 +1602,29 @@ gst_dash_demux_stream_select_representation_unlocked (GstDashDemuxStream * if (!rep_list) return FALSE; - bitrate = - gst_download_rate_get_current_rate (&stream->dnl_rate) * - demux->bandwidth_usage; - GST_DEBUG_OBJECT (demux, "Trying to change to bitrate: %" G_GUINT64_FORMAT, - bitrate); + /* compare the time when the fragment was downloaded with the time when it was + * scheduled */ + if (stream->download_total_time) + bitrate = + (stream->download_total_bytes * 8) / + ((double) stream->download_total_time / G_GUINT64_CONSTANT (1000000)); + + GST_DEBUG_OBJECT (stream->pad, + "Downloaded %u bytes in %" GST_TIME_FORMAT ". Bitrate is : %d", + (guint) stream->download_total_bytes, + GST_TIME_ARGS (stream->download_total_time * GST_USECOND), + (gint) bitrate); + + /* Take old rate into account too */ + if (stream->current_download_rate != -1) + bitrate = (stream->current_download_rate + bitrate * 3) / 4; + if (bitrate > G_MAXINT) + bitrate = G_MAXINT; + stream->current_download_rate = bitrate; + bitrate *= demux->bandwidth_usage; + + GST_DEBUG_OBJECT (stream->pad, + "Trying to change to bitrate: %" G_GUINT64_FORMAT, bitrate); /* get representation index with current max_bandwidth */ new_index = gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list, bitrate); @@ -2266,23 +2281,6 @@ gst_dash_demux_stream_get_next_fragment (GstDashDemuxStream * stream, GST_WARNING_OBJECT (stream->pad, "Failed to download fragment"); return GST_FLOW_ERROR; } -#if 0 - if (buffer_size > 0 && diff > 0) { -#ifndef GST_DISABLE_GST_DEBUG - guint64 brate; -#endif - - gst_download_rate_add_rate (&stream->dnl_rate, buffer_size, diff); - -#ifndef GST_DISABLE_GST_DEBUG - brate = (buffer_size * 8) / ((double) diff / GST_SECOND); -#endif - GST_INFO_OBJECT (demux, - "Stream: %d Download rate = %" G_GUINT64_FORMAT " Kbits/s (%" - G_GUINT64_FORMAT " Ko in %.2f s)", stream->index, brate / 1000, - buffer_size / 1024, ((double) diff / GST_SECOND)); - } -#endif return ret; } diff --git a/ext/dash/gstdashdemux.h b/ext/dash/gstdashdemux.h index 6d6eeedf18..feb017200b 100644 --- a/ext/dash/gstdashdemux.h +++ b/ext/dash/gstdashdemux.h @@ -34,7 +34,6 @@ #include #include #include "gstmpdparser.h" -#include "gstdownloadrate.h" #include G_BEGIN_DECLS @@ -80,8 +79,6 @@ struct _GstDashDemuxStream GRecMutex download_task_lock; GstUriDownloader *downloader; - GstDownloadRate dnl_rate; - /* download tooling */ GstElement *src; GstPad *src_srcpad; @@ -92,6 +89,7 @@ struct _GstDashDemuxStream gint64 download_start_time; gint64 download_total_time; gint64 download_total_bytes; + gint current_download_rate; }; /** diff --git a/ext/dash/gstdownloadrate.c b/ext/dash/gstdownloadrate.c deleted file mode 100644 index ce25b18b21..0000000000 --- a/ext/dash/gstdownloadrate.c +++ /dev/null @@ -1,113 +0,0 @@ -/* 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_mutex_init (&rate->mutex); - rate->total = 0; - rate->max_length = 0; -} - -void -gst_download_rate_deinit (GstDownloadRate * rate) -{ - gst_download_rate_clear (rate); - g_mutex_clear (&rate->mutex); -} - -void -gst_download_rate_set_max_length (GstDownloadRate * rate, gint max_length) -{ - g_mutex_lock (&rate->mutex); - rate->max_length = max_length; - _gst_download_rate_check_remove_rates (rate); - g_mutex_unlock (&rate->mutex); -} - -gint -gst_download_rate_get_max_length (GstDownloadRate * rate) -{ - guint ret; - g_mutex_lock (&rate->mutex); - ret = rate->max_length; - g_mutex_unlock (&rate->mutex); - - return ret; -} - -void -gst_download_rate_clear (GstDownloadRate * rate) -{ - g_mutex_lock (&rate->mutex); - g_queue_clear (&rate->queue); - rate->total = 0; - g_mutex_unlock (&rate->mutex); -} - -void -gst_download_rate_add_rate (GstDownloadRate * rate, guint bytes, guint64 time) -{ - guint64 bitrate; - g_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_mutex_unlock (&rate->mutex); -} - -guint -gst_download_rate_get_current_rate (GstDownloadRate * rate) -{ - guint ret; - g_mutex_lock (&rate->mutex); - if (g_queue_get_length (&rate->queue)) - ret = rate->total / g_queue_get_length (&rate->queue); - else - ret = G_MAXUINT; - g_mutex_unlock (&rate->mutex); - - return ret; -} diff --git a/ext/dash/gstdownloadrate.h b/ext/dash/gstdownloadrate.h deleted file mode 100644 index 2ea704b28f..0000000000 --- a/ext/dash/gstdownloadrate.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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; - GMutex 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__ */