mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
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
This commit is contained in:
parent
b45dd51fb1
commit
f9dc67c372
2 changed files with 91 additions and 0 deletions
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri,
|
static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri,
|
||||||
gchar * title, GstClockTime duration, guint sequence);
|
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);
|
static gchar *uri_join (const gchar * uri, const gchar * path);
|
||||||
|
|
||||||
GstM3U8 *
|
GstM3U8 *
|
||||||
|
@ -144,6 +145,8 @@ gst_m3u8_media_file_unref (GstM3U8MediaFile * self)
|
||||||
g_return_if_fail (self != NULL && self->ref_count > 0);
|
g_return_if_fail (self != NULL && self->ref_count > 0);
|
||||||
|
|
||||||
if (g_atomic_int_dec_and_test (&self->ref_count)) {
|
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->title);
|
||||||
g_free (self->uri);
|
g_free (self->uri);
|
||||||
g_free (self->key);
|
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
|
static gboolean
|
||||||
int_from_string (gchar * ptr, gchar ** endptr, gint * val)
|
int_from_string (gchar * ptr, gchar ** endptr, gint * val)
|
||||||
{
|
{
|
||||||
|
@ -458,6 +493,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
|
||||||
gint64 mediasequence;
|
gint64 mediasequence;
|
||||||
GList *previous_files = NULL;
|
GList *previous_files = NULL;
|
||||||
gboolean have_mediasequence = FALSE;
|
gboolean have_mediasequence = FALSE;
|
||||||
|
GstM3U8InitFile *last_init_file = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (self != NULL, FALSE);
|
g_return_val_if_fail (self != NULL, FALSE);
|
||||||
g_return_val_if_fail (data != NULL, FALSE);
|
g_return_val_if_fail (data != NULL, FALSE);
|
||||||
|
@ -555,6 +591,8 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
|
||||||
}
|
}
|
||||||
|
|
||||||
file->discont = discontinuity;
|
file->discont = discontinuity;
|
||||||
|
if (last_init_file)
|
||||||
|
file->init_file = gst_m3u8_init_file_ref (last_init_file);
|
||||||
|
|
||||||
duration = 0;
|
duration = 0;
|
||||||
title = NULL;
|
title = NULL;
|
||||||
|
@ -672,6 +710,47 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
|
||||||
} else {
|
} else {
|
||||||
goto next_line;
|
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 {
|
} else {
|
||||||
GST_LOG ("Ignored line: %s", data);
|
GST_LOG ("Ignored line: %s", data);
|
||||||
}
|
}
|
||||||
|
@ -690,6 +769,9 @@ gst_m3u8_update (GstM3U8 * self, gchar * data)
|
||||||
|
|
||||||
self->files = g_list_reverse (self->files);
|
self->files = g_list_reverse (self->files);
|
||||||
|
|
||||||
|
if (last_init_file)
|
||||||
|
gst_m3u8_init_file_unref (last_init_file);
|
||||||
|
|
||||||
if (previous_files) {
|
if (previous_files) {
|
||||||
gboolean consistent = TRUE;
|
gboolean consistent = TRUE;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstM3U8 GstM3U8;
|
typedef struct _GstM3U8 GstM3U8;
|
||||||
typedef struct _GstM3U8MediaFile GstM3U8MediaFile;
|
typedef struct _GstM3U8MediaFile GstM3U8MediaFile;
|
||||||
|
typedef struct _GstM3U8InitFile GstM3U8InitFile;
|
||||||
typedef struct _GstHLSMedia GstHLSMedia;
|
typedef struct _GstHLSMedia GstHLSMedia;
|
||||||
typedef struct _GstM3U8Client GstM3U8Client;
|
typedef struct _GstM3U8Client GstM3U8Client;
|
||||||
typedef struct _GstHLSVariantStream GstHLSVariantStream;
|
typedef struct _GstHLSVariantStream GstHLSVariantStream;
|
||||||
|
@ -99,6 +100,14 @@ struct _GstM3U8MediaFile
|
||||||
guint8 iv[16];
|
guint8 iv[16];
|
||||||
gint64 offset, size;
|
gint64 offset, size;
|
||||||
gint ref_count; /* ATOMIC */
|
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);
|
GstM3U8MediaFile * gst_m3u8_media_file_ref (GstM3U8MediaFile * mfile);
|
||||||
|
|
Loading…
Reference in a new issue