summaryrefslogtreecommitdiffstats
path: root/demux/demux_edl.c
diff options
context:
space:
mode:
Diffstat (limited to 'demux/demux_edl.c')
-rw-r--r--demux/demux_edl.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/demux/demux_edl.c b/demux/demux_edl.c
index c0225737e1..52b36ebfc9 100644
--- a/demux/demux_edl.c
+++ b/demux/demux_edl.c
@@ -49,6 +49,7 @@ struct tl_parts {
char *init_fragment_url;
struct tl_part *parts;
int num_parts;
+ struct tl_parts *next;
};
struct priv {
@@ -79,6 +80,7 @@ static bool parse_time(bstr str, double *out_time)
static struct tl_parts *parse_edl(bstr str)
{
struct tl_parts *tl = talloc_zero(NULL, struct tl_parts);
+ struct tl_parts *root = tl;
while (str.len) {
if (bstr_eatstart0(&str, "#")) {
bstr_split_tok(str, "\n", &(bstr){0}, &str);
@@ -138,13 +140,15 @@ static struct tl_parts *parse_edl(bstr str)
break;
}
if (is_header) {
- if (tl->num_parts)
- goto error; // can't have header once an entry was defined
bstr type = param_vals[0]; // value, because no "="
if (bstr_equals0(type, "mp4_dash")) {
tl->dash = true;
if (nparam > 1 && bstr_equals0(param_names[1], "init"))
tl->init_fragment_url = bstrto0(tl, param_vals[1]);
+ } else if (bstr_equals0(type, "new_stream")) {
+ struct tl_parts *ntl = talloc_zero(tl, struct tl_parts);
+ tl->next = ntl;
+ tl = ntl;
}
continue;
}
@@ -152,11 +156,11 @@ static struct tl_parts *parse_edl(bstr str)
goto error;
MP_TARRAY_APPEND(tl, tl->parts, tl->num_parts, p);
}
- if (!tl->num_parts)
+ if (!root->num_parts)
goto error;
- return tl;
+ return root;
error:
- talloc_free(tl);
+ talloc_free(root);
return NULL;
}
@@ -260,11 +264,12 @@ static void build_timeline(struct timeline *tl, struct tl_parts *parts)
MP_WARN(tl, "Segment %d has unknown duration.\n", n);
if (part->offset_set)
MP_WARN(tl, "Offsets are ignored.\n");
- tl->demuxer->is_network = true;
+ if (tl->demuxer)
+ tl->demuxer->is_network = true;
if (!tl->track_layout) {
- source = open_source(tl, part->filename);
- if (!source)
+ tl->track_layout = open_source(tl, part->filename);
+ if (!tl->track_layout)
goto error;
}
} else {
@@ -320,12 +325,8 @@ static void build_timeline(struct timeline *tl, struct tl_parts *parts)
starttime += part->length;
- if (source) {
- tl->demuxer->is_network |= source->is_network;
-
- if (!tl->track_layout)
- tl->track_layout = source;
- }
+ if (source && !tl->track_layout)
+ tl->track_layout = source;
}
tl->parts[parts->num_parts] = (struct timeline_part) {.start = starttime};
tl->num_parts = parts->num_parts;
@@ -352,16 +353,32 @@ static void build_mpv_edl_timeline(struct timeline *tl)
{
struct priv *p = tl->demuxer->priv;
- struct tl_parts *parts = parse_edl(p->data);
- if (!parts) {
+ struct timeline *root_tl = tl;
+ struct tl_parts *root = parse_edl(p->data);
+ if (!root) {
MP_ERR(tl, "Error in EDL.\n");
return;
}
- MP_TARRAY_APPEND(tl, tl->sources, tl->num_sources, tl->demuxer);
- if (!p->allow_any)
- fix_filenames(parts, tl->demuxer->filename);
- build_timeline(tl, parts);
- talloc_free(parts);
+
+ for (struct tl_parts *parts = root; parts; parts = parts->next) {
+ if (tl->demuxer)
+ MP_TARRAY_APPEND(tl, tl->sources, tl->num_sources, tl->demuxer);
+ if (!p->allow_any)
+ fix_filenames(parts, root_tl->demuxer->filename);
+ build_timeline(tl, parts);
+
+ if (parts->next) {
+ struct timeline *ntl = talloc_zero(tl, struct timeline);
+ *ntl = (struct timeline) {
+ .global = tl->global,
+ .log = tl->log,
+ .cancel = tl->cancel,
+ };
+ tl->next = ntl;
+ tl = ntl;
+ }
+ }
+ talloc_free(root);
}
static int try_open_file(struct demuxer *demuxer, enum demux_check check)