From cc033c7ca00d3d76305ded716571048b7de842ba Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Wed, 16 Apr 2014 06:12:42 -0300 Subject: [PATCH] hlsdemux: enable download bitrate measure Measure the download bitrate to be able to select the best playlist. As the buffers are directly pushed downstream and it might block. The time is only measured from the download until the pad push and it is started again after the push returns. --- ext/hls/gsthlsdemux.c | 49 ++++++++++++++++++++++--------------------- ext/hls/gsthlsdemux.h | 3 +++ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c index 030d007e8f..ba6bd716ba 100644 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -96,10 +96,7 @@ static void gst_hls_demux_stream_loop (GstHLSDemux * demux); static void gst_hls_demux_updates_loop (GstHLSDemux * demux); static void gst_hls_demux_stop (GstHLSDemux * demux); static void gst_hls_demux_pause_tasks (GstHLSDemux * demux); -#if 0 -static gboolean gst_hls_demux_switch_playlist (GstHLSDemux * demux, - GstFragment * fragment); -#endif +static gboolean gst_hls_demux_switch_playlist (GstHLSDemux * demux); static gboolean gst_hls_demux_get_next_fragment (GstHLSDemux * demux, gboolean * end_of_playlist, GError ** err); static gboolean gst_hls_demux_update_playlist (GstHLSDemux * demux, @@ -853,7 +850,13 @@ _src_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) demux->need_segment = FALSE; } + /* accumulate time and size to get this chunk */ + demux->download_total_time += + g_get_monotonic_time () - demux->download_start_time; + demux->download_total_bytes += gst_buffer_get_size (buffer); + ret = gst_proxy_pad_chain_default (pad, parent, buffer); + demux->download_start_time = g_get_monotonic_time (); if (ret != GST_FLOW_OK) { if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { @@ -902,6 +905,10 @@ _src_event (GstPad * pad, GstObject * parent, GstEvent * event) gst_buffer_resize (demux->pending_buffer, 0, unpadded_size); /* TODO check return */ + demux->download_total_time += + g_get_monotonic_time () - demux->download_start_time; + demux->download_total_bytes += + gst_buffer_get_size (demux->pending_buffer); gst_pad_push (demux->srcpad, demux->pending_buffer); demux->pending_buffer = NULL; } @@ -945,6 +952,9 @@ switch_pads (GstHLSDemux * demux, GstCaps * newcaps) newcaps); target = gst_element_get_static_pad (demux->src, "src"); + if (oldpad) { + gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (oldpad), NULL); + } /* First create and activate new pad */ name = g_strdup_printf ("src_%u", demux->srcpad_counter++); @@ -1150,11 +1160,11 @@ gst_hls_demux_stream_loop (GstHLSDemux * demux) if (demux->stop_updates_task) { goto pause_task; } -#if 0 /* try to switch to another bitrate if needed */ - gst_hls_demux_switch_playlist (demux, fragment); -#endif + gst_hls_demux_switch_playlist (demux); + demux->download_total_bytes = 0; + demux->download_total_time = 0; GST_DEBUG_OBJECT (demux, "Finished pushing fragment"); @@ -1558,28 +1568,21 @@ retry_failover_protection: return TRUE; } -#if 0 static gboolean -gst_hls_demux_switch_playlist (GstHLSDemux * demux, GstFragment * fragment) +gst_hls_demux_switch_playlist (GstHLSDemux * demux) { - GstClockTime diff; - gsize size; gint64 bitrate; - GstBuffer *buffer; - - if (!fragment) - return TRUE; /* compare the time when the fragment was downloaded with the time when it was * scheduled */ - diff = fragment->download_stop_time - fragment->download_start_time; - buffer = gst_fragment_get_buffer (fragment); - size = gst_buffer_get_size (buffer); - bitrate = (size * 8) / ((double) diff / GST_SECOND); + bitrate = + (demux->download_total_bytes * 8) / ((double) demux->download_total_time / + G_GUINT64_CONSTANT (1000000)); GST_DEBUG_OBJECT (demux, - "Downloaded %d bytes in %" GST_TIME_FORMAT ". Bitrate is : %d", - (guint) size, GST_TIME_ARGS (diff), (gint) bitrate); + "Downloaded %u bytes in %" GST_TIME_FORMAT ". Bitrate is : %d", + (guint) demux->download_total_bytes, + GST_TIME_ARGS (demux->download_total_time * GST_USECOND), (gint) bitrate); /* Take old rate into account too */ if (demux->current_download_rate != -1) @@ -1590,8 +1593,6 @@ gst_hls_demux_switch_playlist (GstHLSDemux * demux, GstFragment * fragment) GST_DEBUG_OBJECT (demux, "Using current download rate: %d", (gint) bitrate); - gst_buffer_unref (buffer); - GST_M3U8_CLIENT_LOCK (demux->client); if (!demux->client->main->lists) { GST_M3U8_CLIENT_UNLOCK (demux->client); @@ -1601,7 +1602,6 @@ gst_hls_demux_switch_playlist (GstHLSDemux * demux, GstFragment * fragment) return gst_hls_demux_change_playlist (demux, bitrate * demux->bitrate_limit); } -#endif #ifdef HAVE_NETTLE static gboolean @@ -1759,6 +1759,7 @@ gst_hls_demux_get_next_fragment (GstHLSDemux * demux, (GstSeekFlags) GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, range_start, GST_SEEK_TYPE_SET, range_end)); + demux->download_start_time = g_get_monotonic_time (); gst_element_sync_state_with_parent (demux->src); /* wait for the fragment to be completely downloaded */ diff --git a/ext/hls/gsthlsdemux.h b/ext/hls/gsthlsdemux.h index a8fa3a40b6..f6c425be49 100644 --- a/ext/hls/gsthlsdemux.h +++ b/ext/hls/gsthlsdemux.h @@ -116,6 +116,9 @@ struct _GstHLSDemux GCond fragment_download_cond; GstClockTime current_timestamp; gboolean starting_fragment; + gint64 download_start_time; + gint64 download_total_time; + gint64 download_total_bytes; /* decryption tooling */ #ifdef HAVE_NETTLE