summaryrefslogtreecommitdiff
path: root/ext/hls
diff options
context:
space:
mode:
authorSeungha Yang <seungha.yang@navercorp.com>2017-11-04 20:15:33 +0900
committerSebastian Dröge <slomo@coaxion.net>2019-06-18 07:14:28 +0000
commitf9dc67c37279110ae67c9210a1720bb707cee003 (patch)
tree922190b03f0d0cb8a9b61068673ba7b24da2358d /ext/hls
parentb45dd51fb16d036d75d030b3d1c6d94cbfd6b157 (diff)
downloadgstreamer-plugins-bad-f9dc67c37279110ae67c9210a1720bb707cee003.tar.gz
hls: m3u8: Parsing EXT-X-MAP tag to store initialization data
EXT-X-MAP tag informs media initialization data, such as moov box in ISOBMFF case and PAT/PMT for MPEG TS stream. https://bugzilla.gnome.org/show_bug.cgi?id=776928
Diffstat (limited to 'ext/hls')
-rw-r--r--ext/hls/m3u8.c82
-rw-r--r--ext/hls/m3u8.h9
2 files changed, 91 insertions, 0 deletions
diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c
index 594a963eb..679e28876 100644
--- a/ext/hls/m3u8.c
+++ b/ext/hls/m3u8.c
@@ -33,6 +33,7 @@
static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri,
gchar * title, GstClockTime duration, guint sequence);
+static void gst_m3u8_init_file_unref (GstM3U8InitFile * self);
static gchar *uri_join (const gchar * uri, const gchar * path);
GstM3U8 *
@@ -144,6 +145,8 @@ gst_m3u8_media_file_unref (GstM3U8MediaFile * self)
g_return_if_fail (self != NULL && self->ref_count > 0);
if (g_atomic_int_dec_and_test (&self->ref_count)) {
+ if (self->init_file)
+ gst_m3u8_init_file_unref (self->init_file);
g_free (self->title);
g_free (self->uri);
g_free (self->key);
@@ -151,6 +154,38 @@ gst_m3u8_media_file_unref (GstM3U8MediaFile * self)
}
}
+static GstM3U8InitFile *
+gst_m3u8_init_file_new (gchar * uri)
+{
+ GstM3U8InitFile *file;
+
+ file = g_new0 (GstM3U8InitFile, 1);
+ file->uri = uri;
+ file->ref_count = 1;
+
+ return file;
+}
+
+static GstM3U8InitFile *
+gst_m3u8_init_file_ref (GstM3U8InitFile * ifile)
+{
+ g_assert (ifile != NULL && ifile->ref_count > 0);
+
+ g_atomic_int_add (&ifile->ref_count, 1);
+ return ifile;
+}
+
+static void
+gst_m3u8_init_file_unref (GstM3U8InitFile * self)
+{
+ g_return_if_fail (self != NULL && self->ref_count > 0);
+
+ if (g_atomic_int_dec_and_test (&self->ref_count)) {
+ g_free (self->uri);
+ g_free (self);
+ }
+}
+
static gboolean
int_from_string (gchar * ptr, gchar ** endptr, gint * val)
{
@@ -458,6 +493,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
gint64 mediasequence;
GList *previous_files = NULL;
gboolean have_mediasequence = FALSE;
+ GstM3U8InitFile *last_init_file = NULL;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (data != NULL, FALSE);
@@ -555,6 +591,8 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
}
file->discont = discontinuity;
+ if (last_init_file)
+ file->init_file = gst_m3u8_init_file_ref (last_init_file);
duration = 0;
title = NULL;
@@ -672,6 +710,47 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
} else {
goto next_line;
}
+ } else if (g_str_has_prefix (data_ext_x, "MAP:")) {
+ gchar *v, *a, *header_uri = NULL;
+
+ data = data + 11;
+
+ while (data != NULL && parse_attributes (&data, &a, &v)) {
+ if (strcmp (a, "URI") == 0) {
+ header_uri =
+ uri_join (self->base_uri ? self->base_uri : self->uri, v);
+ } else if (strcmp (a, "BYTERANGE") == 0) {
+ if (int64_from_string (v, &v, &size)) {
+ if (*v == '@' && !int64_from_string (v + 1, &v, &offset)) {
+ g_free (header_uri);
+ goto next_line;
+ }
+ } else {
+ g_free (header_uri);
+ goto next_line;
+ }
+ }
+ }
+
+ if (header_uri) {
+ GstM3U8InitFile *init_file;
+ init_file = gst_m3u8_init_file_new (header_uri);
+
+ if (size != -1) {
+ init_file->size = size;
+ if (offset != -1)
+ init_file->offset = offset;
+ else
+ init_file->offset = 0;
+ } else {
+ init_file->size = -1;
+ init_file->offset = 0;
+ }
+ if (last_init_file)
+ gst_m3u8_init_file_unref (last_init_file);
+
+ last_init_file = init_file;
+ }
} else {
GST_LOG ("Ignored line: %s", data);
}
@@ -690,6 +769,9 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
self->files = g_list_reverse (self->files);
+ if (last_init_file)
+ gst_m3u8_init_file_unref (last_init_file);
+
if (previous_files) {
gboolean consistent = TRUE;
diff --git a/ext/hls/m3u8.h b/ext/hls/m3u8.h
index 195ec2ab8..a7af61f1f 100644
--- a/ext/hls/m3u8.h
+++ b/ext/hls/m3u8.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
typedef struct _GstM3U8 GstM3U8;
typedef struct _GstM3U8MediaFile GstM3U8MediaFile;
+typedef struct _GstM3U8InitFile GstM3U8InitFile;
typedef struct _GstHLSMedia GstHLSMedia;
typedef struct _GstM3U8Client GstM3U8Client;
typedef struct _GstHLSVariantStream GstHLSVariantStream;
@@ -99,6 +100,14 @@ struct _GstM3U8MediaFile
guint8 iv[16];
gint64 offset, size;
gint ref_count; /* ATOMIC */
+ GstM3U8InitFile *init_file; /* Media Initialization (hold ref) */
+};
+
+struct _GstM3U8InitFile
+{
+ gchar *uri;
+ gint64 offset, size;
+ guint ref_count; /* ATOMIC */
};
GstM3U8MediaFile * gst_m3u8_media_file_ref (GstM3U8MediaFile * mfile);