mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-09 05:38:58 +00:00
dashdemux: stop fetching live fragments that don't yet exist
There is an issue for live streams where download_loop will keep downloading segments until it gets a 404 error for a segment that has not yet been published. This is a problem because this request for a segment that doesn't exist will propagate all the way back to the origin server(s). This means that dashdemux causes extra load on the origin server(s) for segments that aren't yet available. This patch uses availabilityStartTime, period and the host's idea of UTC to decide if a fragment is available to be requested from an HTTP server and filter out requests for fragments that are not yet available. https://bugzilla.gnome.org/show_bug.cgi?id=701404
This commit is contained in:
parent
4b5d560092
commit
42fd04ce48
3 changed files with 82 additions and 9 deletions
|
@ -2113,6 +2113,36 @@ gst_dash_demux_get_next_fragment (GstDashDemux * demux,
|
||||||
gst_mpdparser_get_active_stream_by_index (demux->client,
|
gst_mpdparser_get_active_stream_by_index (demux->client,
|
||||||
selected_stream->index);
|
selected_stream->index);
|
||||||
|
|
||||||
|
/* If this is a live stream, check the segment end time to make sure
|
||||||
|
* it is available to download
|
||||||
|
*/
|
||||||
|
if (selected_stream && gst_mpd_client_is_live (demux->client) &&
|
||||||
|
demux->client->mpd_node->minimumUpdatePeriod != -1) {
|
||||||
|
GstDateTime *seg_end_time;
|
||||||
|
GstDateTime *cur_time = gst_date_time_new_now_utc ();
|
||||||
|
|
||||||
|
seg_end_time =
|
||||||
|
gst_mpd_client_get_next_segment_availability_end_time (demux->client,
|
||||||
|
*stream);
|
||||||
|
|
||||||
|
if (seg_end_time) {
|
||||||
|
gint64 diff;
|
||||||
|
|
||||||
|
cur_time = gst_date_time_new_now_utc ();
|
||||||
|
diff = gst_mpd_client_calculate_time_difference (cur_time, seg_end_time)
|
||||||
|
/ GST_MSECOND;
|
||||||
|
gst_date_time_unref (seg_end_time);
|
||||||
|
gst_date_time_unref (cur_time);
|
||||||
|
if (diff > 0) {
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"Selected fragment has end timestamp > now (%" PRIi64
|
||||||
|
"), delaying download", diff);
|
||||||
|
end_of_period = FALSE;
|
||||||
|
gst_dash_demux_download_wait (demux, diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the fragment corresponding to each stream index */
|
/* Get the fragment corresponding to each stream index */
|
||||||
if (selected_stream) {
|
if (selected_stream) {
|
||||||
guint stream_idx = selected_stream->index;
|
guint stream_idx = selected_stream->index;
|
||||||
|
|
|
@ -138,8 +138,6 @@ static GstClockTime gst_mpd_client_get_segment_duration (GstMpdClient * client,
|
||||||
GstActiveStream * stream);
|
GstActiveStream * stream);
|
||||||
static GstDateTime *gst_mpd_client_get_availability_start_time (GstMpdClient *
|
static GstDateTime *gst_mpd_client_get_availability_start_time (GstMpdClient *
|
||||||
client);
|
client);
|
||||||
static gint64 gst_mpd_client_calculate_time_difference (const GstDateTime * t1,
|
|
||||||
const GstDateTime * t2);
|
|
||||||
|
|
||||||
/* Adaptation Set */
|
/* Adaptation Set */
|
||||||
static GstAdaptationSetNode
|
static GstAdaptationSetNode
|
||||||
|
@ -2863,7 +2861,7 @@ gst_mpd_client_get_segment_duration (GstMpdClient * client,
|
||||||
{
|
{
|
||||||
GstStreamPeriod *stream_period;
|
GstStreamPeriod *stream_period;
|
||||||
GstMultSegmentBaseType *base = NULL;
|
GstMultSegmentBaseType *base = NULL;
|
||||||
GstClockTime duration;
|
GstClockTime duration = 0;
|
||||||
guint timescale;
|
guint timescale;
|
||||||
|
|
||||||
g_return_val_if_fail (stream != NULL, GST_CLOCK_TIME_NONE);
|
g_return_val_if_fail (stream != NULL, GST_CLOCK_TIME_NONE);
|
||||||
|
@ -3564,7 +3562,7 @@ gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint64
|
gint64
|
||||||
gst_mpd_client_calculate_time_difference (const GstDateTime * t1,
|
gst_mpd_client_calculate_time_difference (const GstDateTime * t1,
|
||||||
const GstDateTime * t2)
|
const GstDateTime * t2)
|
||||||
{
|
{
|
||||||
|
@ -3633,17 +3631,19 @@ gst_mpd_client_get_segment_index_at_time (GstMpdClient * client,
|
||||||
return diff / seg_duration;
|
return diff / seg_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstDateTime *
|
static GstDateTime *
|
||||||
gst_mpd_client_get_availability_start_time (GstMpdClient * client)
|
gst_mpd_client_get_availability_start_time (GstMpdClient * client)
|
||||||
{
|
{
|
||||||
GstDateTime *t;
|
GstDateTime *start_time;
|
||||||
|
|
||||||
g_return_val_if_fail (client != NULL, NULL);
|
if (client == NULL)
|
||||||
|
return (GstDateTime *) NULL;
|
||||||
|
|
||||||
GST_MPD_CLIENT_LOCK (client);
|
GST_MPD_CLIENT_LOCK (client);
|
||||||
t = client->mpd_node->availabilityStartTime;
|
start_time = client->mpd_node->availabilityStartTime;
|
||||||
|
gst_date_time_ref (start_time);
|
||||||
GST_MPD_CLIENT_UNLOCK (client);
|
GST_MPD_CLIENT_UNLOCK (client);
|
||||||
return t;
|
return start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -4283,6 +4283,45 @@ gst_mpdparser_get_list_and_nb_of_audio_language (GstMpdClient * client,
|
||||||
return nb_adapatation_set;
|
return nb_adapatation_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GstDateTime *
|
||||||
|
gst_mpd_client_get_next_segment_availability_end_time (GstMpdClient * client,
|
||||||
|
GstActiveStream * stream)
|
||||||
|
{
|
||||||
|
GstDateTime *availability_start_time, *rv;
|
||||||
|
guint seg_idx;
|
||||||
|
GstClockTime seg_duration;
|
||||||
|
gint64 offset;
|
||||||
|
GstStreamPeriod *stream_period;
|
||||||
|
|
||||||
|
g_return_val_if_fail (client != NULL, NULL);
|
||||||
|
g_return_val_if_fail (stream != NULL, NULL);
|
||||||
|
|
||||||
|
stream_period = gst_mpdparser_get_stream_period (client);
|
||||||
|
|
||||||
|
seg_idx = gst_mpd_client_get_segment_index (stream);
|
||||||
|
seg_duration = gst_mpd_client_get_segment_duration (client, stream);
|
||||||
|
if (seg_duration == 0)
|
||||||
|
return NULL;
|
||||||
|
availability_start_time = gst_mpd_client_get_availability_start_time (client);
|
||||||
|
if (availability_start_time == NULL)
|
||||||
|
return (GstDateTime *) NULL;
|
||||||
|
|
||||||
|
if (stream_period && stream_period->period) {
|
||||||
|
GstDateTime *t =
|
||||||
|
gst_mpd_client_add_time_difference (availability_start_time,
|
||||||
|
stream_period->period->start * 1000);
|
||||||
|
gst_date_time_unref (availability_start_time);
|
||||||
|
availability_start_time = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = (1 + seg_idx) * seg_duration;
|
||||||
|
rv = gst_mpd_client_add_time_difference (availability_start_time,
|
||||||
|
offset / GST_USECOND);
|
||||||
|
gst_date_time_unref (availability_start_time);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
gint
|
gint
|
||||||
gst_mpd_client_check_time_position (GstMpdClient * client,
|
gst_mpd_client_check_time_position (GstMpdClient * client,
|
||||||
GstActiveStream * stream, GstClockTime ts, gint64 * diff)
|
GstActiveStream * stream, GstClockTime ts, gint64 * diff)
|
||||||
|
|
|
@ -504,6 +504,7 @@ gboolean gst_mpd_client_set_period_id (GstMpdClient *client, const gchar * perio
|
||||||
guint gst_mpd_client_get_period_index (GstMpdClient *client);
|
guint gst_mpd_client_get_period_index (GstMpdClient *client);
|
||||||
const gchar *gst_mpd_client_get_period_id (GstMpdClient *client);
|
const gchar *gst_mpd_client_get_period_id (GstMpdClient *client);
|
||||||
gboolean gst_mpd_client_has_next_period (GstMpdClient *client);
|
gboolean gst_mpd_client_has_next_period (GstMpdClient *client);
|
||||||
|
GstDateTime *gst_mpd_client_get_next_segment_availability_end_time (GstMpdClient * client, GstActiveStream * stream);
|
||||||
|
|
||||||
/* Representation selection */
|
/* Representation selection */
|
||||||
gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, gint max_bandwidth);
|
gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, gint max_bandwidth);
|
||||||
|
@ -535,6 +536,9 @@ guint gst_mpd_client_get_audio_stream_num_channels (GstActiveStream * stream);
|
||||||
|
|
||||||
/* Support multi language */
|
/* Support multi language */
|
||||||
guint gst_mpdparser_get_list_and_nb_of_audio_language (GstMpdClient *client, GList **lang);
|
guint gst_mpdparser_get_list_and_nb_of_audio_language (GstMpdClient *client, GList **lang);
|
||||||
|
|
||||||
|
gint64 gst_mpd_client_calculate_time_difference (const GstDateTime * t1, const GstDateTime * t2);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_MPDPARSER_H__ */
|
#endif /* __GST_MPDPARSER_H__ */
|
||||||
|
|
Loading…
Reference in a new issue