hlsdemux2: Parse EXT-X-SKIP tag

Parse the attributes from the EXT-X-SKIP tag

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
Jan Schmidt 2022-11-18 03:24:38 +11:00 committed by GStreamer Marge Bot
parent 8a0190b521
commit 7496d2750e
3 changed files with 96 additions and 0 deletions

View file

@ -66,6 +66,9 @@ gst_hls_media_playlist_unref (GstHLSMediaPlaylist * self)
if (self->preload_hints != NULL)
g_ptr_array_free (self->preload_hints, TRUE);
if (self->removed_date_ranges != NULL)
g_strfreev (self->removed_date_ranges);
g_free (self->last_data);
g_mutex_clear (&self->lock);
g_free (self);
@ -479,6 +482,17 @@ gst_hls_media_playlist_dump (GstHLSMediaPlaylist * self)
GST_DEBUG ("can block reloads: %s", self->can_block_reload ? "YES" : "NO");
GST_DEBUG ("skipped segments: %d", self->skipped_segments);
if (self->num_removed_date_ranges && self->removed_date_ranges) {
GST_DEBUG ("Removed date ranges: %u", self->num_removed_date_ranges);
gchar **cur = self->removed_date_ranges;
while (*cur != NULL) {
GST_DEBUG (" ID: %s", *cur);
cur++;
}
}
GST_DEBUG ("Segments : %d", self->segments->len);
for (idx = 0; idx < self->segments->len; idx++) {
GstM3U8MediaSegment *segment = g_ptr_array_index (self->segments, idx);
@ -762,6 +776,37 @@ malformed_line:
}
}
/* Parse EXT-X-SKIP */
static void
parse_skip_tag (GstHLSMediaPlaylist * self, gchar * data)
{
gchar *v, *a;
while (data != NULL && parse_attributes (&data, &a, &v)) {
if (strcmp (a, "SKIPPED-SEGMENTS") == 0) {
if (!int_from_string (v, NULL, &self->skipped_segments)
|| self->skipped_segments < 0) {
GST_WARNING ("Can't read skipped segments from EXT-X-SKIP value");
self->skipped_segments = 0;
goto malformed_line;
}
} else if (strcmp (a, "RECENTLY-REMOVED-DATERANGES") == 0) {
gchar **removed_date_ranges = g_strsplit (v, "\t", -1);
g_strfreev (self->removed_date_ranges);
self->removed_date_ranges = removed_date_ranges;
self->num_removed_date_ranges = g_strv_length (removed_date_ranges);
}
}
return;
malformed_line:
{
GST_WARNING ("Invalid EXT-X-SKIP entry in playlist");
return;
}
}
/* Parse and create a new GstHLSMediaPlaylist */
GstHLSMediaPlaylist *
gst_hls_media_playlist_parse (gchar * data,
@ -1106,6 +1151,9 @@ gst_hls_media_playlist_parse (gchar * data,
(GDestroyNotify) gst_m3u8_preload_hint_unref);
}
g_ptr_array_add (self->preload_hints, hint);
} else if (g_str_has_prefix (data_ext_x, "SKIP:")) {
data += strlen ("#EXT-X-SKIP:");
parse_skip_tag (self, data);
} else {
GST_LOG ("Ignored line: %s", data);
}

View file

@ -142,6 +142,11 @@ struct _GstHLSMediaPlaylist
GstClockTime part_hold_back; /* Part-Hold-Back value, if provided (or CLOCK_TIME_NONE */
gboolean can_block_reload; /* TRUE if CAN-BLOCK-RELOAD was YES */
/* Delta playlist info from EXT-X-SKIP tag */
gint skipped_segments;
gint num_removed_date_ranges;
gchar **removed_date_ranges;
/*< private > */
GMutex lock;

View file

@ -259,6 +259,30 @@ midRoll273.mp4\n\
#EXT-X-PRELOAD-HINT:TYPE=PART,URI=\"midRoll274.1.mp4\"\n\
#EXT-X-RENDITION-REPORT:URI=\"/1M/LL-HLS.m3u8\",LAST-MSN=274,LAST-PART=1";
static const gchar *SKIP_PLAYLIST = "#EXTM3U\n\
#EXT-X-VERSION:7\n\
#EXT-X-TARGETDURATION:4\n\
#EXT-X-PART-INF:PART-TARGET=2\n\
#EXT-X-SKIP:SKIPPED-SEGMENTS=2,RECENTLY-REMOVED-DATERANGES=\"splice-6FFFFFF0\tsplice-6FFFFFF1\"\n\
#EXTINF:4.00008,\n\
fileSequence270.mp4\n\
#EXT-X-PART:DURATION=2.00004,INDEPENDENT=YES,URI=\"filePart271.0.mp4\"\n\
#EXT-X-PART:DURATION=2.00004,URI=\"filePart271.1.mp4\"\n\
#EXTINF:4.00008,\n\
fileSequence271.mp4\n\
#EXT-X-PART:DURATION=2.00004,INDEPENDENT=YES,URI=\"filePart272.0.mp4\"\n\
#EXT-X-PART:DURATION=0.50001,URI=\"filePart272.1.mp4\"\n\
#EXTINF:2.50005,\n\
fileSequence272.mp4\n\
#EXT-X-DISCONTINUITY\n\
#EXT-X-PART:DURATION=2.00004,INDEPENDENT=YES,URI=\"midRoll273.0.mp4\"\n\
#EXT-X-PART:DURATION=2.00004,URI=\"midRoll273.1.mp4\"\n\
#EXTINF:4.00008,\n\
midRoll273.mp4\n\
#EXT-X-PART:DURATION=2.00004,INDEPENDENT=YES,URI=\"midRoll274.0.mp4\"\n\
#EXT-X-PRELOAD-HINT:TYPE=PART,URI=\"midRoll274.1.mp4\"\n\
#EXT-X-RENDITION-REPORT:URI=\"/1M/LL-HLS.m3u8\",LAST-MSN=274,LAST-PART=1";
static GstHLSMediaPlaylist *
load_m3u8 (const gchar * data)
{
@ -920,6 +944,24 @@ GST_START_TEST (test_low_latency_playlist)
}
GST_END_TEST;
GST_START_TEST (test_playlist_skip)
{
GstHLSMediaPlaylist *pl;
pl = load_m3u8 (SKIP_PLAYLIST);
fail_unless (pl != NULL);
assert_equals_int (pl->skipped_segments, 2);
assert_equals_int (pl->num_removed_date_ranges, 2);
fail_unless (g_strcmp0 (pl->removed_date_ranges[0], "splice-6FFFFFF0") == 0);
fail_unless (g_strcmp0 (pl->removed_date_ranges[1], "splice-6FFFFFF1") == 0);
gst_hls_media_playlist_unref (pl);
}
GST_END_TEST;
static Suite *
hlsdemux_suite (void)
{
@ -955,6 +997,7 @@ hlsdemux_suite (void)
tcase_add_test (tc_m3u8, test_stream_inf_tag);
tcase_add_test (tc_m3u8, test_map_tag);
tcase_add_test (tc_m3u8, test_low_latency_playlist);
tcase_add_test (tc_m3u8, test_playlist_skip);
return s;
}