Coverage Report

Created: 2026-03-12 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mpv/demux/demux_timeline.c
Line
Count
Source
1
/*
2
 * This file is part of mpv.
3
 *
4
 * mpv is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * mpv is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
#include <assert.h>
19
#include <limits.h>
20
21
#include "common/common.h"
22
#include "common/msg.h"
23
24
#include "demux.h"
25
#include "timeline.h"
26
#include "stheader.h"
27
#include "stream/stream.h"
28
29
struct segment {
30
    int index; // index into virtual_source.segments[] (and timeline.parts[])
31
    double start, end;
32
    double d_start;
33
    char *url;
34
    bool lazy;
35
    struct demuxer *d;
36
    // stream_map[sh_stream.index] = virtual_stream, where sh_stream is a stream
37
    // from the source d, and virtual_stream is a streamexported by the
38
    // timeline demuxer (virtual_stream.sh). It's used to map the streams of the
39
    // source onto the set of streams of the virtual timeline.
40
    // Uses NULL for streams that do not appear in the virtual timeline.
41
    struct virtual_stream **stream_map;
42
    int num_stream_map;
43
};
44
45
// Information for each stream on the virtual timeline. (Mirrors streams
46
// exposed by demux_timeline.)
47
struct virtual_stream {
48
    struct sh_stream *sh;       // stream exported by demux_timeline
49
    bool selected;              // ==demux_stream_is_selected(sh)
50
    int eos_packets;            // deal with b-frame delay
51
    struct virtual_source *src; // group this stream is part of
52
};
53
54
// This represents a single timeline source. (See timeline.pars[]. For each
55
// timeline_par struct there is a virtual_source.)
56
struct virtual_source {
57
    struct timeline_par *tl;
58
59
    bool dash, no_clip, delay_open;
60
61
    struct segment **segments;
62
    int num_segments;
63
    struct segment *current;
64
65
    struct virtual_stream **streams;
66
    int num_streams;
67
68
    // Total number of packets received past end of segment. Used
69
    // to be clever about determining when to switch segments.
70
    int eos_packets;
71
72
    bool eof_reached;
73
    double dts;                 // highest read DTS (or PTS if no DTS available)
74
    bool any_selected;          // at least one stream is actually selected
75
76
    struct demux_packet *next;
77
};
78
79
struct priv {
80
    struct timeline *tl;
81
    bool owns_tl;
82
83
    double duration;
84
85
    // As the demuxer user sees it.
86
    struct virtual_stream **streams;
87
    int num_streams;
88
89
    struct virtual_source **sources;
90
    int num_sources;
91
};
92
93
static void update_slave_stats(struct demuxer *demuxer, struct demuxer *slave)
94
808k
{
95
808k
    demux_report_unbuffered_read_bytes(demuxer, demux_get_bytes_read_hack(slave));
96
808k
}
97
98
static bool target_stream_used(struct segment *seg, struct virtual_stream *vs)
99
14.9k
{
100
17.7k
    for (int n = 0; n < seg->num_stream_map; n++) {
101
3.07k
        if (seg->stream_map[n] == vs)
102
201
            return true;
103
3.07k
    }
104
14.7k
    return false;
105
14.9k
}
106
107
// Create mapping from segment streams to virtual timeline streams.
108
static void associate_streams(struct demuxer *demuxer,
109
                              struct virtual_source *src,
110
                              struct segment *seg)
111
17.4k
{
112
17.4k
    if (!seg->d || seg->stream_map)
113
3.66k
        return;
114
115
13.8k
    int num_streams = demux_get_num_stream(seg->d);
116
28.4k
    for (int n = 0; n < num_streams; n++) {
117
14.6k
        struct sh_stream *sh = demux_get_stream(seg->d, n);
118
14.6k
        struct virtual_stream *other = NULL;
119
120
35.3k
        for (int i = 0; i < src->num_streams; i++) {
121
20.7k
            struct virtual_stream *vs = src->streams[i];
122
123
            // The stream must always have the same media type. Also, a stream
124
            // can't be assigned multiple times.
125
20.7k
            if (sh->type != vs->sh->type || target_stream_used(seg, vs))
126
6.00k
                continue;
127
128
            // By default pick the first matching stream.
129
14.7k
            if (!other)
130
14.5k
                other = vs;
131
132
            // Matching by demuxer ID is supposedly useful and preferable for
133
            // ordered chapters.
134
14.7k
            if (sh->demuxer_id >= 0 && sh->demuxer_id == vs->sh->demuxer_id)
135
917
                other = vs;
136
14.7k
        }
137
138
14.6k
        if (!other) {
139
169
            MP_WARN(demuxer, "Source stream %d (%s) unused and hidden.\n",
140
169
                    n, stream_type_name(sh->type));
141
169
        }
142
143
14.6k
        MP_TARRAY_APPEND(seg, seg->stream_map, seg->num_stream_map, other);
144
14.6k
    }
145
13.8k
}
146
147
static void reselect_streams(struct demuxer *demuxer)
148
33.4k
{
149
33.4k
    struct priv *p = demuxer->priv;
150
151
73.8k
    for (int n = 0; n < p->num_streams; n++) {
152
40.3k
        struct virtual_stream *vs = p->streams[n];
153
40.3k
        vs->selected = demux_stream_is_selected(vs->sh);
154
40.3k
    }
155
156
67.0k
    for (int x = 0; x < p->num_sources; x++) {
157
33.5k
        struct virtual_source *src = p->sources[x];
158
159
78.2k
        for (int n = 0; n < src->num_segments; n++) {
160
44.6k
            struct segment *seg = src->segments[n];
161
162
44.6k
            if (!seg->d)
163
7.21k
                continue;
164
165
80.8k
            for (int i = 0; i < seg->num_stream_map; i++) {
166
43.3k
                bool selected =
167
43.3k
                    seg->stream_map[i] && seg->stream_map[i]->selected;
168
169
                // This stops demuxer readahead for inactive segments.
170
43.3k
                if (!src->current || seg->d != src->current->d)
171
29.6k
                    selected = false;
172
43.3k
                struct sh_stream *sh = demux_get_stream(seg->d, i);
173
43.3k
                demuxer_select_track(seg->d, sh, MP_NOPTS_VALUE, selected);
174
175
43.3k
                update_slave_stats(demuxer, seg->d);
176
43.3k
            }
177
37.4k
        }
178
179
33.5k
        bool was_selected = src->any_selected;
180
33.5k
        src->any_selected = false;
181
182
73.9k
        for (int n = 0; n < src->num_streams; n++)
183
40.3k
            src->any_selected |= src->streams[n]->selected;
184
185
33.5k
        if (!was_selected && src->any_selected) {
186
9.82k
            src->eof_reached = false;
187
9.82k
            src->dts = MP_NOPTS_VALUE;
188
9.82k
            TA_FREEP(&src->next);
189
9.82k
        }
190
33.5k
    }
191
33.4k
}
192
193
static void close_lazy_segments(struct demuxer *demuxer,
194
                                struct virtual_source *src)
195
12.1k
{
196
    // unload previous segment
197
27.2k
    for (int n = 0; n < src->num_segments; n++) {
198
15.1k
        struct segment *seg = src->segments[n];
199
15.1k
        if (seg != src->current && seg->d && seg->lazy) {
200
1.77k
            TA_FREEP(&src->next); // might depend on one of the sub-demuxers
201
1.77k
            demux_free(seg->d);
202
1.77k
            seg->d = NULL;
203
1.77k
        }
204
15.1k
    }
205
12.1k
}
206
207
static void reopen_lazy_segments(struct demuxer *demuxer,
208
                                 struct virtual_source *src)
209
11.7k
{
210
11.7k
    if (src->current->d)
211
9.42k
        return;
212
213
    // Note: we must _not_ close segments during demuxing,
214
    // because demuxed packets have demux_packet.codec set to objects owned
215
    // by the segments. Closing them would create dangling pointers.
216
217
2.34k
    struct demuxer_params params = {
218
2.34k
        .init_fragment = src->tl->init_fragment,
219
2.34k
        .skip_lavf_probing = src->tl->dash,
220
2.34k
        .stream_flags = demuxer->stream_origin,
221
2.34k
        .depth = demuxer->depth + 1,
222
2.34k
    };
223
2.34k
    src->current->d = demux_open_url(src->current->url, &params,
224
2.34k
                                     demuxer->cancel, demuxer->global);
225
2.34k
    if (!src->current->d && !demux_cancel_test(demuxer))
226
2.34k
        MP_ERR(demuxer, "failed to load segment\n");
227
2.34k
    if (src->current->d)
228
1.77k
        update_slave_stats(demuxer, src->current->d);
229
2.34k
    associate_streams(demuxer, src, src->current);
230
2.34k
}
231
232
static void switch_segment(struct demuxer *demuxer, struct virtual_source *src,
233
                           struct segment *new, double start_pts, int flags,
234
                           bool init)
235
11.7k
{
236
11.7k
    if (!(flags & SEEK_FORWARD))
237
11.7k
        flags |= SEEK_HR;
238
239
11.7k
    MP_VERBOSE(demuxer, "switch to segment %d\n", new->index);
240
241
11.7k
    if (src->current && src->current->d)
242
2.11k
        update_slave_stats(demuxer, src->current->d);
243
244
11.7k
    src->current = new;
245
11.7k
    reopen_lazy_segments(demuxer, src);
246
11.7k
    if (!new->d)
247
572
        return;
248
11.1k
    reselect_streams(demuxer);
249
11.1k
    if (!src->no_clip)
250
9.42k
        demux_set_ts_offset(new->d, new->start - new->d_start);
251
11.1k
    if (!src->no_clip || !init)
252
9.64k
        demux_seek(new->d, start_pts, flags);
253
254
25.6k
    for (int n = 0; n < src->num_streams; n++) {
255
14.4k
        struct virtual_stream *vs = src->streams[n];
256
14.4k
        vs->eos_packets = 0;
257
14.4k
    }
258
259
11.1k
    src->eof_reached = false;
260
11.1k
    src->eos_packets = 0;
261
11.1k
}
262
263
static void do_read_next_packet(struct demuxer *demuxer,
264
                                struct virtual_source *src)
265
761k
{
266
761k
    if (src->next)
267
0
        return;
268
269
761k
    struct segment *seg = src->current;
270
761k
    if (!seg || !seg->d) {
271
0
        src->eof_reached = true;
272
0
        return;
273
0
    }
274
275
761k
    struct demux_packet *pkt = demux_read_any_packet(seg->d);
276
761k
    if (!pkt || (!src->no_clip && pkt->pts >= seg->end))
277
13.7k
        src->eos_packets += 1;
278
279
761k
    update_slave_stats(demuxer, seg->d);
280
281
    // Test for EOF. Do this here to properly run into EOF even if other
282
    // streams are disabled etc. If it somehow doesn't manage to reach the end
283
    // after demuxing a high (bit arbitrary) number of packets, assume one of
284
    // the streams went EOF early.
285
761k
    bool eos_reached = src->eos_packets > 0;
286
761k
    if (eos_reached && src->eos_packets < 100) {
287
49.1k
        for (int n = 0; n < src->num_streams; n++) {
288
26.8k
            struct virtual_stream *vs = src->streams[n];
289
26.8k
            if (vs->selected) {
290
26.7k
                int max_packets = 0;
291
26.7k
                if (vs->sh->type == STREAM_AUDIO)
292
7.72k
                    max_packets = 1;
293
26.7k
                if (vs->sh->type == STREAM_VIDEO)
294
19.0k
                    max_packets = 16;
295
26.7k
                eos_reached &= vs->eos_packets >= max_packets;
296
26.7k
            }
297
26.8k
        }
298
22.2k
    }
299
300
761k
    src->eof_reached = false;
301
302
761k
    if (eos_reached || !pkt) {
303
11.0k
        talloc_free(pkt);
304
305
11.0k
        struct segment *next = NULL;
306
13.5k
        for (int n = 0; n < src->num_segments - 1; n++) {
307
4.63k
            if (src->segments[n] == seg) {
308
2.11k
                next = src->segments[n + 1];
309
2.11k
                break;
310
2.11k
            }
311
4.63k
        }
312
11.0k
        if (!next) {
313
8.95k
            src->eof_reached = true;
314
8.95k
            return;
315
8.95k
        }
316
2.11k
        switch_segment(demuxer, src, next, next->start, 0, true);
317
2.11k
        return; // reader will retry
318
11.0k
    }
319
320
750k
    if (pkt->stream < 0 || pkt->stream >= seg->num_stream_map)
321
0
        goto drop;
322
323
750k
    if (!src->no_clip || src->delay_open) {
324
738k
        pkt->segmented = true;
325
738k
        if (!pkt->codec)
326
720k
            pkt->codec = demux_get_stream(seg->d, pkt->stream)->codec;
327
738k
    }
328
750k
    if (!src->no_clip) {
329
738k
        if (pkt->start == MP_NOPTS_VALUE || pkt->start < seg->start)
330
720k
            pkt->start = seg->start;
331
738k
        if (pkt->end == MP_NOPTS_VALUE || pkt->end > seg->end)
332
720k
            pkt->end = seg->end;
333
738k
    }
334
335
750k
    struct virtual_stream *vs = seg->stream_map[pkt->stream];
336
750k
    if (!vs)
337
0
        goto drop;
338
339
    // for refresh seeks, demux.c prefers monotonically increasing packet pos
340
    // since the packet pos is meaningless anyway for timeline, use it
341
750k
    if (pkt->pos >= 0)
342
738k
        pkt->pos |= (seg->index & 0x7FFFULL) << 48;
343
344
750k
    if (pkt->pts != MP_NOPTS_VALUE && !src->no_clip && pkt->pts >= seg->end) {
345
        // Trust the keyframe flag. Might not always be a good idea, but will
346
        // be sufficient at least with mkv. The problem is that this flag is
347
        // not well-defined in libavformat and is container-dependent.
348
2.51k
        if (pkt->keyframe || vs->eos_packets == INT_MAX) {
349
1.05k
            vs->eos_packets = INT_MAX;
350
1.05k
            goto drop;
351
1.46k
        } else {
352
1.46k
            vs->eos_packets += 1;
353
1.46k
        }
354
2.51k
    }
355
356
749k
    double dts = pkt->dts != MP_NOPTS_VALUE ? pkt->dts : pkt->pts;
357
749k
    if (src->dts == MP_NOPTS_VALUE || (dts != MP_NOPTS_VALUE && dts > src->dts))
358
645k
        src->dts = dts;
359
360
749k
    pkt->stream = vs->sh->index;
361
749k
    src->next = pkt;
362
749k
    return;
363
364
1.05k
drop:
365
1.05k
    talloc_free(pkt);
366
1.05k
}
367
368
static bool d_read_packet(struct demuxer *demuxer, struct demux_packet **out_pkt)
369
770k
{
370
770k
    struct priv *p = demuxer->priv;
371
770k
    struct virtual_source *src = NULL;
372
373
1.54M
    for (int x = 0; x < p->num_sources; x++) {
374
771k
        struct virtual_source *cur = p->sources[x];
375
376
771k
        if (!cur->any_selected || cur->eof_reached)
377
10.1k
            continue;
378
379
761k
        if (!cur->current)
380
6.63k
            switch_segment(demuxer, cur, cur->segments[0], 0, 0, true);
381
382
761k
        if (!cur->any_selected || !cur->current || !cur->current->d)
383
572
            continue;
384
385
761k
        if (!src || cur->dts == MP_NOPTS_VALUE ||
386
1
            (src->dts != MP_NOPTS_VALUE && cur->dts < src->dts))
387
761k
            src = cur;
388
761k
    }
389
390
770k
    if (!src)
391
9.52k
        return false;
392
393
761k
    do_read_next_packet(demuxer, src);
394
761k
    *out_pkt = src->next;
395
761k
    src->next = NULL;
396
761k
    return true;
397
770k
}
398
399
static void seek_source(struct demuxer *demuxer, struct virtual_source *src,
400
                        double pts, int flags)
401
3.02k
{
402
3.02k
    struct segment *new = src->segments[src->num_segments - 1];
403
3.42k
    for (int n = 0; n < src->num_segments; n++) {
404
3.04k
        if (pts < src->segments[n]->end) {
405
2.64k
            new = src->segments[n];
406
2.64k
            break;
407
2.64k
        }
408
3.04k
    }
409
410
3.02k
    switch_segment(demuxer, src, new, pts, flags, false);
411
412
3.02k
    src->dts = MP_NOPTS_VALUE;
413
3.02k
    TA_FREEP(&src->next);
414
3.02k
}
415
416
static void d_seek(struct demuxer *demuxer, double seek_pts, int flags)
417
3.05k
{
418
3.05k
    struct priv *p = demuxer->priv;
419
420
3.05k
    seek_pts = seek_pts * ((flags & SEEK_FACTOR) ? p->duration : 1);
421
3.05k
    flags &= SEEK_FORWARD | SEEK_HR;
422
423
    // The intention is to seek audio streams to the same target as video
424
    // streams if they are separate streams. Video streams usually have more
425
    // coarse keyframe snapping, which could leave video without audio.
426
3.05k
    struct virtual_source *master = NULL;
427
3.05k
    bool has_slaves = false;
428
6.11k
    for (int x = 0; x < p->num_sources; x++) {
429
3.06k
        struct virtual_source *src = p->sources[x];
430
431
3.06k
        bool any_audio = false, any_video = false;
432
6.17k
        for (int i = 0; i < src->num_streams; i++) {
433
3.10k
            struct virtual_stream *str = src->streams[i];
434
3.10k
            if (str->selected) {
435
3.05k
                if (str->sh->type == STREAM_VIDEO)
436
187
                    any_video = true;
437
3.05k
                if (str->sh->type == STREAM_AUDIO)
438
2.87k
                    any_audio = true;
439
3.05k
            }
440
3.10k
        }
441
442
3.06k
        if (any_video)
443
187
            master = src;
444
        // A true slave stream is audio-only; this also prevents that the master
445
        // stream is considered a slave stream.
446
3.06k
        if (any_audio && !any_video)
447
2.83k
            has_slaves = true;
448
3.06k
    }
449
450
3.05k
    if (!has_slaves)
451
216
        master = NULL;
452
453
3.05k
    if (master) {
454
0
        seek_source(demuxer, master, seek_pts, flags);
455
0
        do_read_next_packet(demuxer, master);
456
0
        if (master->next && master->next->pts != MP_NOPTS_VALUE) {
457
            // Assume we got a seek target. Actually apply the heuristic.
458
0
            MP_VERBOSE(demuxer, "adjust seek target from %f to %f\n", seek_pts,
459
0
                       master->next->pts);
460
0
            seek_pts = master->next->pts;
461
0
            flags &= ~(unsigned)SEEK_FORWARD;
462
0
        }
463
0
    }
464
465
6.11k
    for (int x = 0; x < p->num_sources; x++) {
466
3.06k
        struct virtual_source *src = p->sources[x];
467
3.06k
        if (src != master && src->any_selected)
468
3.02k
            seek_source(demuxer, src, seek_pts, flags);
469
3.06k
    }
470
3.05k
}
471
472
static void print_timeline(struct demuxer *demuxer)
473
12.1k
{
474
12.1k
    struct priv *p = demuxer->priv;
475
476
12.1k
    MP_VERBOSE(demuxer, "Timeline segments:\n");
477
24.2k
    for (int x = 0; x < p->num_sources; x++) {
478
12.1k
        struct virtual_source *src = p->sources[x];
479
480
12.1k
        if (x >= 1)
481
12.1k
            MP_VERBOSE(demuxer, " --- new parallel stream ---\n");
482
483
27.2k
        for (int n = 0; n < src->num_segments; n++) {
484
15.1k
            struct segment *seg = src->segments[n];
485
15.1k
            int src_num = n;
486
18.9k
            for (int i = 0; i < n; i++) {
487
3.80k
                if (seg->d && src->segments[i]->d == seg->d) {
488
15
                    src_num = i;
489
15
                    break;
490
15
                }
491
3.80k
            }
492
15.1k
            MP_VERBOSE(demuxer, " %2d: %12f - %12f [%12f] (",
493
15.1k
                       n, seg->start, seg->end, seg->d_start);
494
27.6k
            for (int i = 0; i < seg->num_stream_map; i++) {
495
12.5k
                struct virtual_stream *vs = seg->stream_map[i];
496
12.5k
                MP_VERBOSE(demuxer, "%s%d", i ? " " : "",
497
12.5k
                           vs ? vs->sh->index : -1);
498
12.5k
            }
499
15.1k
            MP_VERBOSE(demuxer, ")\n  source %d:'%s'\n", src_num, seg->url);
500
15.1k
        }
501
502
12.1k
        if (src->dash)
503
12.1k
            MP_VERBOSE(demuxer, " (Using pseudo-DASH mode.)\n");
504
12.1k
    }
505
12.1k
    MP_VERBOSE(demuxer, "Total duration: %f\n", p->duration);
506
12.1k
}
507
508
// Copy various (not all) metadata fields from src to dst, but try not to
509
// overwrite fields in dst that are unset in src.
510
// May keep data from src by reference.
511
// Imperfect and arbitrary, only suited for EDL stuff.
512
static void apply_meta(struct sh_stream *dst, struct sh_stream *src)
513
13.1k
{
514
13.1k
    if (src->demuxer_id >= 0)
515
910
        dst->demuxer_id = src->demuxer_id;
516
13.1k
    if (src->title)
517
7
        dst->title = src->title;
518
13.1k
    if (src->lang)
519
181
        dst->lang = src->lang;
520
13.1k
    dst->default_track = src->default_track;
521
13.1k
    dst->forced_track = src->forced_track;
522
13.1k
    if (src->hls_bitrate)
523
0
        dst->hls_bitrate = src->hls_bitrate;
524
13.1k
    dst->missing_timestamps = src->missing_timestamps;
525
13.1k
    if (src->attached_picture)
526
0
        dst->attached_picture = src->attached_picture;
527
13.1k
    dst->image = src->image;
528
13.1k
}
529
530
// This is mostly for EDL user-defined metadata.
531
static struct sh_stream *find_matching_meta(struct timeline_par *tl, int index)
532
13.1k
{
533
13.1k
    for (int n = 0; n < tl->num_sh_meta; n++) {
534
5
        struct sh_stream *sh = tl->sh_meta[n];
535
5
        if (sh->index == index || sh->index < 0)
536
5
            return sh;
537
5
    }
538
13.1k
    return NULL;
539
13.1k
}
540
541
static bool add_tl(struct demuxer *demuxer, struct timeline_par *tl)
542
12.1k
{
543
12.1k
    struct priv *p = demuxer->priv;
544
545
12.1k
    struct virtual_source *src = talloc_ptrtype(p, src);
546
12.1k
    *src = (struct virtual_source){
547
12.1k
        .tl = tl,
548
12.1k
        .dash = tl->dash,
549
12.1k
        .delay_open = tl->delay_open,
550
12.1k
        .no_clip = tl->no_clip || tl->dash,
551
12.1k
        .dts = MP_NOPTS_VALUE,
552
12.1k
    };
553
554
12.1k
    if (!tl->num_parts)
555
0
        return false;
556
557
12.1k
    MP_TARRAY_APPEND(p, p->sources, p->num_sources, src);
558
559
12.1k
    p->duration = MPMAX(p->duration, tl->parts[tl->num_parts - 1].end);
560
561
12.1k
    struct demuxer *meta = tl->track_layout;
562
563
    // delay_open streams normally have meta==NULL, and 1 virtual stream
564
12.1k
    int num_streams = 0;
565
12.1k
    if (tl->delay_open) {
566
0
        num_streams = tl->num_sh_meta;
567
12.1k
    } else if (meta) {
568
12.1k
        num_streams = demux_get_num_stream(meta);
569
12.1k
    }
570
25.2k
    for (int n = 0; n < num_streams; n++) {
571
13.1k
        struct sh_stream *new = NULL;
572
573
13.1k
        if (tl->delay_open) {
574
0
            struct sh_stream *tsh = tl->sh_meta[n];
575
0
            new = demux_alloc_sh_stream(tsh->type);
576
0
            new->codec = tsh->codec;
577
0
            apply_meta(new, tsh);
578
0
            demuxer->is_network = true;
579
0
            demuxer->is_streaming = true;
580
13.1k
        } else {
581
13.1k
            struct sh_stream *sh = demux_get_stream(meta, n);
582
13.1k
            new = demux_alloc_sh_stream(sh->type);
583
13.1k
            apply_meta(new, sh);
584
13.1k
            new->codec = sh->codec;
585
13.1k
            struct sh_stream *tsh = find_matching_meta(tl, n);
586
13.1k
            if (tsh)
587
5
                apply_meta(new, tsh);
588
13.1k
        }
589
590
13.1k
        demux_add_sh_stream(demuxer, new);
591
13.1k
        struct virtual_stream *vs = talloc_ptrtype(p, vs);
592
13.1k
        *vs = (struct virtual_stream){
593
13.1k
            .src = src,
594
13.1k
            .sh = new,
595
13.1k
        };
596
13.1k
        MP_TARRAY_APPEND(p, p->streams, p->num_streams, vs);
597
13.1k
        mp_assert(demux_get_stream(demuxer, p->num_streams - 1) == new);
598
13.1k
        MP_TARRAY_APPEND(src, src->streams, src->num_streams, vs);
599
13.1k
    }
600
601
27.2k
    for (int n = 0; n < tl->num_parts; n++) {
602
15.1k
        struct timeline_part *part = &tl->parts[n];
603
604
        // demux_timeline already does caching, doing it for the sub-demuxers
605
        // would be pointless and wasteful.
606
15.1k
        if (part->source) {
607
12.0k
            demuxer->is_network |= part->source->is_network;
608
12.0k
            demuxer->is_streaming |= part->source->is_streaming;
609
12.0k
        }
610
611
15.1k
        if (!part->source)
612
15.1k
            mp_assert(tl->dash || tl->delay_open);
613
614
15.1k
        struct segment *seg = talloc_ptrtype(src, seg);
615
15.1k
        *seg = (struct segment){
616
15.1k
            .d = part->source,
617
15.1k
            .url = part->source ? part->source->filename : part->url,
618
15.1k
            .lazy = !part->source,
619
15.1k
            .d_start = part->source_start,
620
15.1k
            .start = part->start,
621
15.1k
            .end = part->end,
622
15.1k
        };
623
624
15.1k
        associate_streams(demuxer, src, seg);
625
626
15.1k
        seg->index = n;
627
15.1k
        MP_TARRAY_APPEND(src, src->segments, src->num_segments, seg);
628
15.1k
    }
629
630
12.1k
    if (tl->track_layout) {
631
12.1k
        demuxer->is_network |= tl->track_layout->is_network;
632
12.1k
        demuxer->is_streaming |= tl->track_layout->is_streaming;
633
12.1k
    }
634
12.1k
    return true;
635
12.1k
}
636
637
static int d_open(struct demuxer *demuxer, enum demux_check check)
638
12.1k
{
639
12.1k
    struct priv *p = demuxer->priv = talloc_zero(demuxer, struct priv);
640
12.1k
    p->tl = demuxer->params ? demuxer->params->timeline : NULL;
641
12.1k
    if (!p->tl || p->tl->num_pars < 1)
642
0
        return -1;
643
644
12.1k
    demuxer->chapters = p->tl->chapters;
645
12.1k
    demuxer->num_chapters = p->tl->num_chapters;
646
647
12.1k
    struct demuxer *meta = p->tl->meta;
648
12.1k
    if (meta) {
649
12.1k
        demuxer->metadata = meta->metadata;
650
12.1k
        demuxer->attachments = meta->attachments;
651
12.1k
        demuxer->num_attachments = meta->num_attachments;
652
12.1k
        demuxer->editions = meta->editions;
653
12.1k
        demuxer->num_editions = meta->num_editions;
654
12.1k
        demuxer->edition = meta->edition;
655
12.1k
    }
656
657
24.2k
    for (int n = 0; n < p->tl->num_pars; n++) {
658
12.1k
        if (!add_tl(demuxer, p->tl->pars[n]))
659
0
            return -1;
660
12.1k
    }
661
662
12.1k
    if (!p->num_sources)
663
0
        return -1;
664
665
12.1k
    demuxer->is_network |= p->tl->is_network;
666
12.1k
    demuxer->is_streaming |= p->tl->is_streaming;
667
668
12.1k
    demuxer->duration = p->duration;
669
670
12.1k
    print_timeline(demuxer);
671
672
12.1k
    demuxer->seekable = true;
673
12.1k
    demuxer->partially_seekable = false;
674
675
12.1k
    const char *format_name = "unknown";
676
12.1k
    if (meta)
677
12.1k
        format_name = meta->filetype ? meta->filetype : meta->desc->name;
678
12.1k
    demuxer->filetype = talloc_asprintf(p, "%s/%s", p->tl->format, format_name);
679
680
12.1k
    reselect_streams(demuxer);
681
682
12.1k
    p->owns_tl = true;
683
12.1k
    return 0;
684
12.1k
}
685
686
static void d_close(struct demuxer *demuxer)
687
12.1k
{
688
12.1k
    struct priv *p = demuxer->priv;
689
690
24.2k
    for (int x = 0; x < p->num_sources; x++) {
691
12.1k
        struct virtual_source *src = p->sources[x];
692
693
12.1k
        src->current = NULL;
694
12.1k
        TA_FREEP(&src->next);
695
12.1k
        close_lazy_segments(demuxer, src);
696
12.1k
    }
697
698
12.1k
    if (p->owns_tl) {
699
12.1k
        struct demuxer *master = p->tl->demuxer;
700
12.1k
        timeline_destroy(p->tl);
701
12.1k
        demux_free(master);
702
12.1k
    }
703
12.1k
}
704
705
static void d_switched_tracks(struct demuxer *demuxer)
706
10.1k
{
707
10.1k
    reselect_streams(demuxer);
708
10.1k
}
709
710
const demuxer_desc_t demuxer_desc_timeline = {
711
    .name = "timeline",
712
    .desc = "timeline segments",
713
    .read_packet = d_read_packet,
714
    .open = d_open,
715
    .close = d_close,
716
    .seek = d_seek,
717
    .switched_tracks = d_switched_tracks,
718
};