mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
hlsdemux2: Handle async playlist loading failures
Add failed variant playlists to a list and failover to other variants until there is none left Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
parent
454779f094
commit
2b93dae59a
6 changed files with 123 additions and 112 deletions
|
@ -1952,8 +1952,11 @@ gst_hls_demux_stream_select_bitrate (GstAdaptiveDemux2Stream * stream,
|
||||||
/* Handle variant streams */
|
/* Handle variant streams */
|
||||||
GST_DEBUG_OBJECT (hlsdemux,
|
GST_DEBUG_OBJECT (hlsdemux,
|
||||||
"Checking playlist change for main variant stream");
|
"Checking playlist change for main variant stream");
|
||||||
gst_hls_demux_change_variant_playlist (hlsdemux, bitrate / MAX (1.0,
|
if (!gst_hls_demux_change_variant_playlist (hlsdemux,
|
||||||
ABS (play_rate)), &changed);
|
hlsdemux->current_variant->iframe,
|
||||||
|
bitrate / MAX (1.0, ABS (play_rate)), &changed)) {
|
||||||
|
GST_ERROR_OBJECT (hlsdemux, "Failed to choose a new variant to play");
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (hlsdemux, "Returning changed: %d", changed);
|
GST_DEBUG_OBJECT (hlsdemux, "Returning changed: %d", changed);
|
||||||
return changed;
|
return changed;
|
||||||
|
|
|
@ -358,17 +358,16 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
||||||
&& rate < -1.0 && old_rate >= -1.0 && old_rate <= 1.0) {
|
&& rate < -1.0 && old_rate >= -1.0 && old_rate <= 1.0) {
|
||||||
|
|
||||||
/* Switch to I-frame variant */
|
/* Switch to I-frame variant */
|
||||||
gst_hls_demux_set_current_variant (hlsdemux,
|
if (!gst_hls_demux_change_variant_playlist (hlsdemux, TRUE,
|
||||||
hlsdemux->master->iframe_variants->data);
|
bitrate / ABS (rate), NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
} else if (rate > -1.0 && rate <= 1.0 && (old_rate < -1.0 || old_rate > 1.0)) {
|
} else if (rate > -1.0 && rate <= 1.0 && (old_rate < -1.0 || old_rate > 1.0)) {
|
||||||
/* Switch to normal variant */
|
/* Switch to normal variant */
|
||||||
gst_hls_demux_set_current_variant (hlsdemux,
|
if (!gst_hls_demux_change_variant_playlist (hlsdemux, FALSE, bitrate, NULL))
|
||||||
hlsdemux->master->variants->data);
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_hls_demux_change_variant_playlist (hlsdemux, bitrate / ABS (rate), NULL);
|
|
||||||
|
|
||||||
/* Of course the playlist isn't loaded as soon as we ask - we need to wait */
|
/* Of course the playlist isn't loaded as soon as we ask - we need to wait */
|
||||||
GstFlowReturn flow_ret = gst_hls_demux_wait_for_variant_playlist (hlsdemux);
|
GstFlowReturn flow_ret = gst_hls_demux_wait_for_variant_playlist (hlsdemux);
|
||||||
if (flow_ret == GST_FLOW_FLUSHING)
|
if (flow_ret == GST_FLOW_FLUSHING)
|
||||||
|
@ -716,19 +715,25 @@ gst_hls_demux_process_initial_manifest (GstAdaptiveDemux * demux,
|
||||||
} else if (hlsdemux->start_bitrate > 0) {
|
} else if (hlsdemux->start_bitrate > 0) {
|
||||||
variant =
|
variant =
|
||||||
gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
|
gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
|
||||||
NULL, hlsdemux->start_bitrate, demux->min_bitrate);
|
FALSE, hlsdemux->start_bitrate, demux->min_bitrate,
|
||||||
|
hlsdemux->failed_variants);
|
||||||
} else {
|
} else {
|
||||||
variant =
|
variant =
|
||||||
gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
|
gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
|
||||||
NULL, demux->connection_speed, demux->min_bitrate);
|
FALSE, demux->connection_speed, demux->min_bitrate,
|
||||||
|
hlsdemux->failed_variants);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variant) {
|
if (variant == NULL) {
|
||||||
GST_INFO_OBJECT (hlsdemux,
|
GST_ELEMENT_ERROR (demux, STREAM, FAILED,
|
||||||
"Manifest processed, initial variant selected : `%s`", variant->name);
|
(_("Internal data stream error.")),
|
||||||
gst_hls_demux_set_current_variant (hlsdemux, variant);
|
("Could not find an initial variant to play"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (hlsdemux,
|
||||||
|
"Manifest processed, initial variant selected : `%s`", variant->name);
|
||||||
|
gst_hls_demux_set_current_variant (hlsdemux, variant);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (hlsdemux, "Manifest handled, now setting up streams");
|
GST_DEBUG_OBJECT (hlsdemux, "Manifest handled, now setting up streams");
|
||||||
|
|
||||||
ret = gst_hls_demux_setup_streams (demux);
|
ret = gst_hls_demux_setup_streams (demux);
|
||||||
|
@ -1057,12 +1062,34 @@ gst_hls_demux_handle_variant_playlist_update (GstHLSDemux * demux,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (demux->pending_variant) {
|
if (demux->pending_variant) {
|
||||||
|
/* The pending variant must always match the one that just got updated:
|
||||||
|
* The loader should only do a callback for the most recently set URI */
|
||||||
g_assert (g_str_equal (demux->pending_variant->uri, playlist_uri));
|
g_assert (g_str_equal (demux->pending_variant->uri, playlist_uri));
|
||||||
|
|
||||||
|
gboolean changed = (demux->pending_variant != demux->current_variant);
|
||||||
|
|
||||||
gst_hls_variant_stream_unref (demux->current_variant);
|
gst_hls_variant_stream_unref (demux->current_variant);
|
||||||
/* Stealing ref */
|
/* Stealing ref */
|
||||||
demux->current_variant = demux->pending_variant;
|
demux->current_variant = demux->pending_variant;
|
||||||
demux->pending_variant = NULL;
|
demux->pending_variant = NULL;
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
GstAdaptiveDemux *basedemux = GST_ADAPTIVE_DEMUX (demux);
|
||||||
|
const gchar *main_uri =
|
||||||
|
gst_adaptive_demux_get_manifest_ref_uri (basedemux);
|
||||||
|
gchar *uri = demux->current_variant->uri;
|
||||||
|
gint new_bandwidth = demux->current_variant->bandwidth;
|
||||||
|
|
||||||
|
gst_element_post_message (GST_ELEMENT_CAST (demux),
|
||||||
|
gst_message_new_element (GST_OBJECT_CAST (demux),
|
||||||
|
gst_structure_new (GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME,
|
||||||
|
"manifest-uri", G_TYPE_STRING,
|
||||||
|
main_uri, "uri", G_TYPE_STRING,
|
||||||
|
uri, "bitrate", G_TYPE_INT, new_bandwidth, NULL)));
|
||||||
|
|
||||||
|
/* Mark discont on the next packet after switching variant */
|
||||||
|
GST_ADAPTIVE_DEMUX2_STREAM (demux->main_stream)->discont = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update time mappings. We only use the variant stream for collecting
|
/* Update time mappings. We only use the variant stream for collecting
|
||||||
|
@ -1076,7 +1103,22 @@ void
|
||||||
gst_hls_demux_handle_variant_playlist_update_error (GstHLSDemux * demux,
|
gst_hls_demux_handle_variant_playlist_update_error (GstHLSDemux * demux,
|
||||||
const gchar * playlist_uri)
|
const gchar * playlist_uri)
|
||||||
{
|
{
|
||||||
GST_FIXME ("Variant playlist update failed. Switch over to another variant");
|
if (demux->pending_variant) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "Variant playlist update failed. "
|
||||||
|
"Marking variant URL %s as failed and switching over to another variant",
|
||||||
|
playlist_uri);
|
||||||
|
|
||||||
|
/* The pending variant must always match the one that just got updated:
|
||||||
|
* The loader should only do a callback for the most recently set URI */
|
||||||
|
g_assert (g_str_equal (demux->pending_variant->uri, playlist_uri));
|
||||||
|
g_assert (g_list_find (demux->failed_variants,
|
||||||
|
demux->pending_variant) == NULL);
|
||||||
|
|
||||||
|
/* Steal pending_variant ref into the failed variants */
|
||||||
|
demux->failed_variants =
|
||||||
|
g_list_prepend (demux->failed_variants, demux->pending_variant);
|
||||||
|
demux->pending_variant = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset hlsdemux in case of live synchronization loss (i.e. when a media
|
/* Reset hlsdemux in case of live synchronization loss (i.e. when a media
|
||||||
|
@ -1163,6 +1205,11 @@ gst_hls_demux_reset (GstAdaptiveDemux * ademux)
|
||||||
gst_hls_variant_stream_unref (demux->pending_variant);
|
gst_hls_variant_stream_unref (demux->pending_variant);
|
||||||
demux->pending_variant = NULL;
|
demux->pending_variant = NULL;
|
||||||
}
|
}
|
||||||
|
if (demux->failed_variants != NULL) {
|
||||||
|
g_list_free_full (demux->failed_variants,
|
||||||
|
(GDestroyNotify) gst_hls_variant_stream_unref);
|
||||||
|
demux->failed_variants = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_list_free_full (demux->mappings, (GDestroyNotify) gst_hls_time_map_free);
|
g_list_free_full (demux->mappings, (GDestroyNotify) gst_hls_time_map_free);
|
||||||
demux->mappings = NULL;
|
demux->mappings = NULL;
|
||||||
|
@ -1182,101 +1229,47 @@ gst_hls_demux_check_variant_playlist_loaded (GstHLSDemux * demux)
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_hls_demux_change_variant_playlist (GstHLSDemux * demux, guint max_bitrate,
|
gst_hls_demux_change_variant_playlist (GstHLSDemux * demux,
|
||||||
gboolean * changed)
|
gboolean iframe_variant, guint max_bitrate, gboolean * changed)
|
||||||
{
|
{
|
||||||
GstHLSVariantStream *lowest_variant, *lowest_ivariant;
|
|
||||||
GstHLSVariantStream *previous_variant, *new_variant;
|
|
||||||
gint old_bandwidth, new_bandwidth;
|
|
||||||
GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX_CAST (demux);
|
GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX_CAST (demux);
|
||||||
GstAdaptiveDemux2Stream *stream;
|
|
||||||
|
|
||||||
g_return_val_if_fail (demux->main_stream != NULL, FALSE);
|
g_return_val_if_fail (demux->main_stream != NULL, FALSE);
|
||||||
stream = (GstAdaptiveDemux2Stream *) demux->main_stream;
|
|
||||||
|
|
||||||
/* Make sure we keep a reference in case we need to switch back */
|
if (changed)
|
||||||
previous_variant = gst_hls_variant_stream_ref (demux->current_variant);
|
*changed = FALSE;
|
||||||
new_variant =
|
|
||||||
|
/* Make sure we keep a reference for the debug output below */
|
||||||
|
GstHLSVariantStream *new_variant =
|
||||||
gst_hls_master_playlist_get_variant_for_bitrate (demux->master,
|
gst_hls_master_playlist_get_variant_for_bitrate (demux->master,
|
||||||
demux->current_variant, max_bitrate, adaptive_demux->min_bitrate);
|
iframe_variant, max_bitrate, adaptive_demux->min_bitrate,
|
||||||
|
demux->failed_variants);
|
||||||
|
|
||||||
retry_failover_protection:
|
/* We're out of available variants to use */
|
||||||
old_bandwidth = previous_variant->bandwidth;
|
if (new_variant == NULL) {
|
||||||
new_bandwidth = new_variant->bandwidth;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstHLSVariantStream *previous_variant =
|
||||||
|
gst_hls_variant_stream_ref (demux->current_variant);
|
||||||
|
|
||||||
/* Don't do anything else if the playlist is the same */
|
/* Don't do anything else if the playlist is the same */
|
||||||
if (new_bandwidth == old_bandwidth) {
|
if (new_variant == previous_variant) {
|
||||||
gst_hls_variant_stream_unref (previous_variant);
|
gst_hls_variant_stream_unref (previous_variant);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_hls_demux_set_current_variant (demux, new_variant);
|
gst_hls_demux_set_current_variant (demux, new_variant);
|
||||||
|
|
||||||
|
gint new_bandwidth = new_variant->bandwidth;
|
||||||
|
|
||||||
GST_INFO_OBJECT (demux, "Client was on %dbps, max allowed is %dbps, switching"
|
GST_INFO_OBJECT (demux, "Client was on %dbps, max allowed is %dbps, switching"
|
||||||
" to bitrate %dbps", old_bandwidth, max_bitrate, new_bandwidth);
|
" to bitrate %dbps", previous_variant->bandwidth, max_bitrate,
|
||||||
|
new_bandwidth);
|
||||||
GstFlowReturn flow_ret = gst_hls_demux_check_variant_playlist_loaded (demux);
|
|
||||||
|
|
||||||
/* If the stream is still fetching the playlist, stop */
|
|
||||||
if (flow_ret == GST_ADAPTIVE_DEMUX_FLOW_BUSY)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* FIXME: Dead code. We need a different fail and retry mechanism */
|
|
||||||
if (flow_ret == GST_FLOW_OK) {
|
|
||||||
const gchar *main_uri;
|
|
||||||
gchar *uri = new_variant->uri;
|
|
||||||
|
|
||||||
main_uri = gst_adaptive_demux_get_manifest_ref_uri (adaptive_demux);
|
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (demux),
|
|
||||||
gst_message_new_element (GST_OBJECT_CAST (demux),
|
|
||||||
gst_structure_new (GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME,
|
|
||||||
"manifest-uri", G_TYPE_STRING,
|
|
||||||
main_uri, "uri", G_TYPE_STRING,
|
|
||||||
uri, "bitrate", G_TYPE_INT, new_bandwidth, NULL)));
|
|
||||||
if (changed)
|
|
||||||
*changed = TRUE;
|
|
||||||
stream->discont = TRUE;
|
|
||||||
} else if (gst_adaptive_demux2_is_running (GST_ADAPTIVE_DEMUX_CAST (demux))) {
|
|
||||||
GstHLSVariantStream *failover_variant = NULL;
|
|
||||||
GList *failover;
|
|
||||||
|
|
||||||
GST_INFO_OBJECT (demux, "Unable to update playlist. Switching back");
|
|
||||||
|
|
||||||
/* we find variants by bitrate by going from highest to lowest, so it's
|
|
||||||
* possible that there's another variant with the same bitrate before the
|
|
||||||
* one selected which we can use as failover */
|
|
||||||
failover = g_list_find (demux->master->variants, new_variant);
|
|
||||||
if (failover != NULL)
|
|
||||||
failover = failover->prev;
|
|
||||||
if (failover != NULL)
|
|
||||||
failover_variant = failover->data;
|
|
||||||
if (failover_variant && new_bandwidth == failover_variant->bandwidth) {
|
|
||||||
new_variant = failover_variant;
|
|
||||||
goto retry_failover_protection;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_hls_demux_set_current_variant (demux, previous_variant);
|
|
||||||
|
|
||||||
/* Try a lower bitrate (or stop if we just tried the lowest) */
|
|
||||||
if (previous_variant->iframe) {
|
|
||||||
lowest_ivariant = demux->master->iframe_variants->data;
|
|
||||||
if (new_bandwidth == lowest_ivariant->bandwidth) {
|
|
||||||
gst_hls_variant_stream_unref (previous_variant);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lowest_variant = demux->master->variants->data;
|
|
||||||
if (new_bandwidth == lowest_variant->bandwidth) {
|
|
||||||
gst_hls_variant_stream_unref (previous_variant);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gst_hls_variant_stream_unref (previous_variant);
|
|
||||||
return gst_hls_demux_change_variant_playlist (demux, new_bandwidth - 1,
|
|
||||||
changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_hls_variant_stream_unref (previous_variant);
|
gst_hls_variant_stream_unref (previous_variant);
|
||||||
|
if (changed)
|
||||||
|
*changed = TRUE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,14 +88,17 @@ struct _GstHLSDemux2
|
||||||
GHashTable *keys;
|
GHashTable *keys;
|
||||||
GMutex keys_lock;
|
GMutex keys_lock;
|
||||||
|
|
||||||
/* FIXME: check locking, protected automatically by manifest_lock already? */
|
/* The master playlist with the available variant streams,
|
||||||
/* The master playlist with the available variant streams */
|
* created at demuxer start based on the input multivariant playlist */
|
||||||
GstHLSMasterPlaylist *master;
|
GstHLSMasterPlaylist *master;
|
||||||
|
|
||||||
GstHLSVariantStream *current_variant;
|
GstHLSVariantStream *current_variant;
|
||||||
/* The variant to switch to */
|
/* The variant we're switching to (currently being loaded by the playlist loader) */
|
||||||
GstHLSVariantStream *pending_variant;
|
GstHLSVariantStream *pending_variant;
|
||||||
|
|
||||||
|
/* List of failed variants that should be ignored */
|
||||||
|
GList *failed_variants;
|
||||||
|
|
||||||
GstHLSDemuxStream *main_stream;
|
GstHLSDemuxStream *main_stream;
|
||||||
|
|
||||||
/* Time Mappings (GstHLSTimeMap) */
|
/* Time Mappings (GstHLSTimeMap) */
|
||||||
|
@ -122,7 +125,7 @@ void gst_hls_demux_handle_variant_playlist_update (GstHLSDemux * demux,
|
||||||
void gst_hls_demux_handle_variant_playlist_update_error (GstHLSDemux * demux,
|
void gst_hls_demux_handle_variant_playlist_update_error (GstHLSDemux * demux,
|
||||||
const gchar *playlist_uri);
|
const gchar *playlist_uri);
|
||||||
gboolean gst_hls_demux_change_variant_playlist (GstHLSDemux * demux,
|
gboolean gst_hls_demux_change_variant_playlist (GstHLSDemux * demux,
|
||||||
guint max_bitrate, gboolean * changed);
|
gboolean iframe_variant, guint max_bitrate, gboolean * changed);
|
||||||
GstFlowReturn gst_hls_demux_update_variant_playlist (GstHLSDemux * demux,
|
GstFlowReturn gst_hls_demux_update_variant_playlist (GstHLSDemux * demux,
|
||||||
GError ** err);
|
GError ** err);
|
||||||
|
|
||||||
|
|
|
@ -3276,20 +3276,26 @@ hls_master_playlist_new_from_data (gchar * data, const gchar * base_uri)
|
||||||
|
|
||||||
GstHLSVariantStream *
|
GstHLSVariantStream *
|
||||||
hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist *
|
hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist *
|
||||||
playlist, GstHLSVariantStream * current_variant, guint bitrate,
|
playlist, gboolean iframe_variant, guint bitrate,
|
||||||
guint min_bitrate)
|
guint min_bitrate, GList * failed_variants)
|
||||||
{
|
{
|
||||||
GstHLSVariantStream *variant = current_variant;
|
GstHLSVariantStream *variant = NULL;
|
||||||
GstHLSVariantStream *variant_by_min = current_variant;
|
GstHLSVariantStream *variant_by_min = NULL;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
/* variant lists are sorted low to high, so iterate from highest to lowest */
|
/* variant lists are sorted low to high, so iterate from highest to lowest */
|
||||||
if (current_variant == NULL || !current_variant->iframe)
|
if (iframe_variant && playlist->iframe_variants != NULL)
|
||||||
l = g_list_last (playlist->variants);
|
|
||||||
else
|
|
||||||
l = g_list_last (playlist->iframe_variants);
|
l = g_list_last (playlist->iframe_variants);
|
||||||
|
else
|
||||||
|
l = g_list_last (playlist->variants);
|
||||||
|
|
||||||
while (l != NULL) {
|
while (l != NULL) {
|
||||||
|
if (g_list_find (failed_variants, l->data) != NULL) {
|
||||||
|
/* Ignore all variants from the failed list */
|
||||||
|
l = l->prev;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
variant = l->data;
|
variant = l->data;
|
||||||
if (variant->bandwidth >= min_bitrate)
|
if (variant->bandwidth >= min_bitrate)
|
||||||
variant_by_min = variant;
|
variant_by_min = variant;
|
||||||
|
|
|
@ -495,9 +495,10 @@ GstHLSMasterPlaylist * hls_master_playlist_new_from_data (gchar * data,
|
||||||
|
|
||||||
#define gst_hls_master_playlist_get_variant_for_bitrate hls_master_playlist_get_variant_for_bitrate
|
#define gst_hls_master_playlist_get_variant_for_bitrate hls_master_playlist_get_variant_for_bitrate
|
||||||
GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist,
|
GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist,
|
||||||
GstHLSVariantStream * current_variant,
|
gboolean iframe_variant,
|
||||||
guint bitrate,
|
guint bitrate,
|
||||||
guint min_bitrate);
|
guint min_bitrate,
|
||||||
|
GList * failed_variants);
|
||||||
|
|
||||||
#define gst_hls_master_playlist_get_common_caps hls_master_playlist_get_common_caps
|
#define gst_hls_master_playlist_get_common_caps hls_master_playlist_get_common_caps
|
||||||
GstCaps * hls_master_playlist_get_common_caps (GstHLSMasterPlaylist *playlist);
|
GstCaps * hls_master_playlist_get_common_caps (GstHLSMasterPlaylist *playlist);
|
||||||
|
|
|
@ -781,22 +781,27 @@ GST_START_TEST (test_get_stream_for_bitrate)
|
||||||
GstHLSVariantStream *stream;
|
GstHLSVariantStream *stream;
|
||||||
|
|
||||||
master = load_master_playlist (VARIANT_PLAYLIST);
|
master = load_master_playlist (VARIANT_PLAYLIST);
|
||||||
stream = gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 0, 0);
|
stream =
|
||||||
|
gst_hls_master_playlist_get_variant_for_bitrate (master, FALSE, 0, 0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
assert_equals_int (stream->bandwidth, 65000);
|
assert_equals_int (stream->bandwidth, 65000);
|
||||||
|
|
||||||
stream =
|
stream =
|
||||||
gst_hls_master_playlist_get_variant_for_bitrate (master, NULL,
|
gst_hls_master_playlist_get_variant_for_bitrate (master, FALSE,
|
||||||
G_MAXINT32, 0);
|
G_MAXINT32, 0, NULL);
|
||||||
assert_equals_int (stream->bandwidth, 768000);
|
assert_equals_int (stream->bandwidth, 768000);
|
||||||
stream =
|
stream =
|
||||||
gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 300000, 0);
|
gst_hls_master_playlist_get_variant_for_bitrate (master, FALSE, 300000, 0,
|
||||||
|
NULL);
|
||||||
assert_equals_int (stream->bandwidth, 256000);
|
assert_equals_int (stream->bandwidth, 256000);
|
||||||
stream =
|
stream =
|
||||||
gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 500000, 0);
|
gst_hls_master_playlist_get_variant_for_bitrate (master, FALSE, 500000, 0,
|
||||||
|
NULL);
|
||||||
assert_equals_int (stream->bandwidth, 256000);
|
assert_equals_int (stream->bandwidth, 256000);
|
||||||
stream =
|
stream =
|
||||||
gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 255000, 0);
|
gst_hls_master_playlist_get_variant_for_bitrate (master, FALSE, 255000, 0,
|
||||||
|
NULL);
|
||||||
assert_equals_int (stream->bandwidth, 128000);
|
assert_equals_int (stream->bandwidth, 128000);
|
||||||
|
|
||||||
gst_hls_master_playlist_unref (master);
|
gst_hls_master_playlist_unref (master);
|
||||||
|
|
Loading…
Reference in a new issue