mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:16:13 +00:00
m3u8: Split gst_m3u8_update_check_consistent_media_seqnums
The function was basically one big if-else. Move the branch to the one caller. Currently, it's never called with previous_files == NULL. Assert that this continues. https://bugzilla.gnome.org/show_bug.cgi?id=788417
This commit is contained in:
parent
234a8ecc50
commit
f80ad048e6
1 changed files with 122 additions and 115 deletions
237
ext/hls/m3u8.c
237
ext/hls/m3u8.c
|
@ -306,138 +306,140 @@ gst_hls_variant_stream_compare_by_bitrate (gconstpointer a, gconstpointer b)
|
||||||
return vs_a->bandwidth - vs_b->bandwidth;
|
return vs_a->bandwidth - vs_b->bandwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we have MEDIA-SEQUENCE, ensure that it's consistent. If it is not,
|
||||||
|
* the client SHOULD halt playback (6.3.4), which is what we do then. */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_m3u8_update_check_consistent_media_seqnums (GstM3U8 * self,
|
check_media_seqnums (GstM3U8 * self, GList * previous_files)
|
||||||
gboolean have_mediasequence, GList * previous_files)
|
|
||||||
{
|
{
|
||||||
if (!previous_files)
|
GList *l, *m;
|
||||||
return TRUE;
|
GstM3U8MediaFile *f1 = NULL, *f2 = NULL;
|
||||||
|
|
||||||
/* If we have MEDIA-SEQUENCE, ensure that it's consistent. If it is not,
|
g_return_val_if_fail (previous_files, FALSE);
|
||||||
* the client SHOULD halt playback (6.3.4), which is what we do then.
|
|
||||||
*
|
|
||||||
* If we don't have MEDIA-SEQUENCE, we check URIs in the previous and
|
|
||||||
* current playlist to calculate the/a correct MEDIA-SEQUENCE for the new
|
|
||||||
* playlist in relation to the old. That is, same URIs get the same number
|
|
||||||
* and later URIs get higher numbers */
|
|
||||||
if (have_mediasequence) {
|
|
||||||
GList *l, *m;
|
|
||||||
GstM3U8MediaFile *f1 = NULL, *f2 = NULL;
|
|
||||||
|
|
||||||
/* Find first case of higher/equal sequence number in new playlist or
|
/* Find first case of higher/equal sequence number in new playlist or
|
||||||
* same URI. From there on we can linearly step ahead */
|
* same URI. From there on we can linearly step ahead */
|
||||||
for (l = self->files; l; l = l->next) {
|
for (l = self->files; l; l = l->next) {
|
||||||
gboolean match = FALSE;
|
gboolean match = FALSE;
|
||||||
|
|
||||||
f1 = l->data;
|
f1 = l->data;
|
||||||
for (m = previous_files; m; m = m->next) {
|
for (m = previous_files; m; m = m->next) {
|
||||||
f2 = m->data;
|
f2 = m->data;
|
||||||
|
|
||||||
if (f1->sequence >= f2->sequence || g_str_equal (f1->uri, f2->uri)) {
|
if (f1->sequence >= f2->sequence || g_str_equal (f1->uri, f2->uri)) {
|
||||||
match = TRUE;
|
match = TRUE;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (match)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (match)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!l) {
|
if (!l) {
|
||||||
/* No match, no sequence in the new playlist was higher than
|
/* No match, no sequence in the new playlist was higher than
|
||||||
* any in the old, and no URI was found again. This is bad! */
|
* any in the old, and no URI was found again. This is bad! */
|
||||||
|
GST_ERROR ("Media sequences inconsistent, ignoring");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (f1 != NULL);
|
||||||
|
g_assert (f2 != NULL);
|
||||||
|
|
||||||
|
for (; l && m; l = l->next, m = m->next) {
|
||||||
|
f1 = l->data;
|
||||||
|
f2 = m->data;
|
||||||
|
|
||||||
|
if (f1->sequence == f2->sequence) {
|
||||||
|
if (!g_str_equal (f1->uri, f2->uri)) {
|
||||||
|
/* Same sequence, different URI. This is bad! */
|
||||||
|
GST_ERROR ("Media sequences inconsistent, ignoring");
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
/* Good case, we advance and check the next one */
|
||||||
|
}
|
||||||
|
} else if (g_str_equal (f1->uri, f2->uri)) {
|
||||||
|
/* Same URIs but different sequences, this is bad! */
|
||||||
GST_ERROR ("Media sequences inconsistent, ignoring");
|
GST_ERROR ("Media sequences inconsistent, ignoring");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
} else {
|
||||||
g_assert (f1 != NULL);
|
/* Not same URI, not same sequence but by construction sequence
|
||||||
g_assert (f2 != NULL);
|
* must be higher in the new one. All good in that case, if it
|
||||||
|
* isn't then this means that sequence numbers are decreasing
|
||||||
for (; l && m; l = l->next, m = m->next) {
|
* or files were inserted */
|
||||||
f1 = l->data;
|
if (f1->sequence < f2->sequence) {
|
||||||
f2 = m->data;
|
GST_ERROR ("Media sequences inconsistent, ignoring");
|
||||||
|
return FALSE;
|
||||||
if (f1->sequence == f2->sequence) {
|
|
||||||
if (!g_str_equal (f1->uri, f2->uri)) {
|
|
||||||
/* Same sequence, different URI. This is bad! */
|
|
||||||
GST_ERROR ("Media sequences inconsistent, ignoring");
|
|
||||||
return FALSE;
|
|
||||||
} else {
|
|
||||||
/* Good case, we advance and check the next one */
|
|
||||||
}
|
|
||||||
} else if (g_str_equal (f1->uri, f2->uri)) {
|
|
||||||
/* Same URIs but different sequences, this is bad! */
|
|
||||||
GST_ERROR ("Media sequences inconsistent, ignoring");
|
|
||||||
return FALSE;
|
|
||||||
} else {
|
|
||||||
/* Not same URI, not same sequence but by construction sequence
|
|
||||||
* must be higher in the new one. All good in that case, if it
|
|
||||||
* isn't then this means that sequence numbers are decreasing
|
|
||||||
* or files were inserted */
|
|
||||||
if (f1->sequence < f2->sequence) {
|
|
||||||
GST_ERROR ("Media sequences inconsistent, ignoring");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All good if we're getting here */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GList *l, *m;
|
|
||||||
GstM3U8MediaFile *f1 = NULL, *f2 = NULL;
|
|
||||||
gint64 mediasequence;
|
|
||||||
|
|
||||||
for (l = self->files; l; l = l->next) {
|
|
||||||
gboolean match = FALSE;
|
|
||||||
|
|
||||||
f1 = l->data;
|
|
||||||
for (m = previous_files; m; m = m->next) {
|
|
||||||
f2 = m->data;
|
|
||||||
|
|
||||||
if (g_str_equal (f1->uri, f2->uri)) {
|
|
||||||
match = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!l) {
|
|
||||||
/* No match, this means f2 is the last item in the previous playlist
|
|
||||||
* and we have to start our new playlist at that sequence */
|
|
||||||
mediasequence = f2->sequence + 1;
|
|
||||||
l = self->files;
|
|
||||||
} else {
|
|
||||||
/* Match, check that all following ones are matching too and continue
|
|
||||||
* sequence numbers from there on */
|
|
||||||
|
|
||||||
mediasequence = f2->sequence;
|
|
||||||
|
|
||||||
for (; l && m; l = l->next, m = m->next) {
|
|
||||||
f1 = l->data;
|
|
||||||
f2 = m->data;
|
|
||||||
|
|
||||||
f1->sequence = mediasequence;
|
|
||||||
mediasequence++;
|
|
||||||
|
|
||||||
if (!g_str_equal (f1->uri, f2->uri)) {
|
|
||||||
GST_WARNING ("Inconsistent URIs after playlist update");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; l; l = l->next) {
|
|
||||||
f1 = l->data;
|
|
||||||
|
|
||||||
f1->sequence = mediasequence;
|
|
||||||
mediasequence++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* All good if we're getting here */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we don't have MEDIA-SEQUENCE, we check URIs in the previous and
|
||||||
|
* current playlist to calculate the/a correct MEDIA-SEQUENCE for the new
|
||||||
|
* playlist in relation to the old. That is, same URIs get the same number
|
||||||
|
* and later URIs get higher numbers */
|
||||||
|
static void
|
||||||
|
generate_media_seqnums (GstM3U8 * self, GList * previous_files)
|
||||||
|
{
|
||||||
|
GList *l, *m;
|
||||||
|
GstM3U8MediaFile *f1 = NULL, *f2 = NULL;
|
||||||
|
gint64 mediasequence;
|
||||||
|
|
||||||
|
g_return_if_fail (previous_files);
|
||||||
|
|
||||||
|
/* Find first case of same URI in new playlist.
|
||||||
|
* From there on we can linearly step ahead */
|
||||||
|
for (l = self->files; l; l = l->next) {
|
||||||
|
gboolean match = FALSE;
|
||||||
|
|
||||||
|
f1 = l->data;
|
||||||
|
for (m = previous_files; m; m = m->next) {
|
||||||
|
f2 = m->data;
|
||||||
|
|
||||||
|
if (g_str_equal (f1->uri, f2->uri)) {
|
||||||
|
match = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l) {
|
||||||
|
/* Match, check that all following ones are matching too and continue
|
||||||
|
* sequence numbers from there on */
|
||||||
|
|
||||||
|
mediasequence = f2->sequence;
|
||||||
|
|
||||||
|
for (; l && m; l = l->next, m = m->next) {
|
||||||
|
f1 = l->data;
|
||||||
|
f2 = m->data;
|
||||||
|
|
||||||
|
f1->sequence = mediasequence;
|
||||||
|
mediasequence++;
|
||||||
|
|
||||||
|
if (!g_str_equal (f1->uri, f2->uri)) {
|
||||||
|
GST_WARNING ("Inconsistent URIs after playlist update");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No match, this means f2 is the last item in the previous playlist
|
||||||
|
* and we have to start our new playlist at that sequence */
|
||||||
|
mediasequence = f2->sequence + 1;
|
||||||
|
l = self->files;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; l; l = l->next) {
|
||||||
|
f1 = l->data;
|
||||||
|
|
||||||
|
f1->sequence = mediasequence;
|
||||||
|
mediasequence++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @data: a m3u8 playlist text data, taking ownership
|
* @data: a m3u8 playlist text data, taking ownership
|
||||||
*/
|
*/
|
||||||
|
@ -688,8 +690,13 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
|
||||||
self->files = g_list_reverse (self->files);
|
self->files = g_list_reverse (self->files);
|
||||||
|
|
||||||
if (previous_files) {
|
if (previous_files) {
|
||||||
gboolean consistent = gst_m3u8_update_check_consistent_media_seqnums (self,
|
gboolean consistent = TRUE;
|
||||||
have_mediasequence, previous_files);
|
|
||||||
|
if (have_mediasequence) {
|
||||||
|
consistent = check_media_seqnums (self, previous_files);
|
||||||
|
} else {
|
||||||
|
generate_media_seqnums (self, previous_files);
|
||||||
|
}
|
||||||
|
|
||||||
g_list_foreach (previous_files, (GFunc) gst_m3u8_media_file_unref, NULL);
|
g_list_foreach (previous_files, (GFunc) gst_m3u8_media_file_unref, NULL);
|
||||||
g_list_free (previous_files);
|
g_list_free (previous_files);
|
||||||
|
|
Loading…
Reference in a new issue