diff options
-rw-r--r-- | demux/demux.h | 3 | ||||
-rw-r--r-- | demux/timeline.c | 42 | ||||
-rw-r--r-- | demux/timeline.h | 37 | ||||
-rw-r--r-- | old-makefile | 1 | ||||
-rw-r--r-- | player/core.h | 8 | ||||
-rw-r--r-- | player/loadfile.c | 60 | ||||
-rw-r--r-- | wscript_build.py | 1 |
7 files changed, 130 insertions, 22 deletions
diff --git a/demux/demux.h b/demux/demux.h index acab2db2ba..8098c16e29 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -104,6 +104,7 @@ enum demux_event { #define MAX_SH_STREAMS 256 struct demuxer; +struct timeline; /** * Demuxer description structure @@ -121,6 +122,8 @@ typedef struct demuxer_desc { void (*close)(struct demuxer *demuxer); void (*seek)(struct demuxer *demuxer, double rel_seek_secs, int flags); int (*control)(struct demuxer *demuxer, int cmd, void *arg); + // See timeline.c + void (*load_timeline)(struct timeline *tl); } demuxer_desc_t; typedef struct demux_chapter diff --git a/demux/timeline.c b/demux/timeline.c new file mode 100644 index 0000000000..6274c25fa3 --- /dev/null +++ b/demux/timeline.c @@ -0,0 +1,42 @@ +#include "common/common.h" +#include "stream/stream.h" +#include "demux.h" + +#include "timeline.h" + +struct timeline *timeline_load(struct mpv_global *global, struct mp_log *log, + struct demuxer *demuxer) +{ + if (!demuxer->desc->load_timeline) + return NULL; + + struct timeline *tl = talloc_ptrtype(NULL, tl); + *tl = (struct timeline){ + .global = global, + .log = log, + .demuxer = demuxer, + .track_layout = demuxer, + }; + + demuxer->desc->load_timeline(tl); + + if (tl->num_parts) + return tl; + timeline_destroy(tl); + return NULL; +} + +void timeline_destroy(struct timeline *tl) +{ + if (!tl) + return; + for (int n = 0; n < tl->num_sources; n++) { + struct demuxer *d = tl->sources[n]; + if (d != tl->demuxer) { + struct stream *s = d->stream; + free_demuxer(d); + free_stream(s); + } + } + talloc_free(tl); +} diff --git a/demux/timeline.h b/demux/timeline.h new file mode 100644 index 0000000000..e4d6f67953 --- /dev/null +++ b/demux/timeline.h @@ -0,0 +1,37 @@ +#ifndef MP_TIMELINE_H_ +#define MP_TIMELINE_H_ + +struct timeline_part { + double start; + double source_start; + struct demuxer *source; +}; + +struct timeline { + struct mpv_global *global; + struct mp_log *log; + + // main source + struct demuxer *demuxer; + + // All referenced files. The source file must be at sources[0]. + struct demuxer **sources; + int num_sources; + + // Segments to play, ordered by time. parts[num_parts] must be valid; its + // start field sets the duration, and source must be NULL. + struct timeline_part *parts; + int num_parts; + + struct demux_chapter *chapters; + int num_chapters; + + // Which source defines the overall track list (over the full timeline). + struct demuxer *track_layout; +}; + +struct timeline *timeline_load(struct mpv_global *global, struct mp_log *log, + struct demuxer *demuxer); +void timeline_destroy(struct timeline *tl); + +#endif diff --git a/old-makefile b/old-makefile index c9eb218fca..443798f632 100644 --- a/old-makefile +++ b/old-makefile @@ -177,6 +177,7 @@ SOURCES = audio/audio.c \ demux/demux_subreader.c \ demux/ebml.c \ demux/packet.c \ + demux/timeline.c \ input/cmd_list.c \ input/cmd_parse.c \ input/event.c \ diff --git a/player/core.h b/player/core.h index 5b69541d24..1ac5ac7817 100644 --- a/player/core.h +++ b/player/core.h @@ -26,6 +26,7 @@ #include "common/common.h" #include "options/options.h" #include "sub/osd.h" +#include "demux/timeline.h" // definitions used internally by the core player code @@ -41,12 +42,6 @@ enum stop_play_reason { PT_ERROR, // play next playlist entry (due to an error) }; -struct timeline_part { - double start; - double source_start; - struct demuxer *source; -}; - enum mp_osd_seek_info { OSD_SEEK_INFO_BAR = 1, OSD_SEEK_INFO_TEXT = 2, @@ -188,6 +183,7 @@ typedef struct MPContext { struct demuxer **sources; int num_sources; + struct timeline *tl; struct timeline_part *timeline; int num_timeline_parts; int timeline_part; diff --git a/player/loadfile.c b/player/loadfile.c index 72e0d14590..c6b2133e51 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -100,12 +100,19 @@ static void uninit_demuxer(struct MPContext *mpctx) mpctx->track_layout = NULL; mpctx->master_demuxer = NULL; mpctx->demuxer = NULL; - talloc_free(mpctx->timeline); - mpctx->timeline = NULL; - mpctx->num_timeline_parts = 0; + if (!mpctx->tl) + mpctx->num_timeline_parts = 0; for (int i = 0; i < mpctx->num_sources; i++) uninit_stream_sub_decoders(mpctx->sources[i]); close_unused_demuxers(mpctx); + if (mpctx->tl) { + timeline_destroy(mpctx->tl); + } else { + talloc_free(mpctx->timeline); + } + mpctx->timeline = NULL; + mpctx->num_timeline_parts = 0; + mpctx->tl = NULL; if (mpctx->num_sources > 0) free_demuxer(mpctx->sources[0]); talloc_free(mpctx->sources); @@ -975,6 +982,39 @@ static struct demuxer *open_demux_async(struct MPContext *mpctx, return args.demux; } +static void load_timeline(struct MPContext *mpctx) +{ + mpctx->track_layout = mpctx->demuxer; + + MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, mpctx->demuxer); + + if (mpctx->demuxer->matroska_data.ordered_chapters) + build_ordered_chapter_timeline(mpctx); + + if (mpctx->demuxer->type == DEMUXER_TYPE_EDL) + build_mpv_edl_timeline(mpctx); + + if (mpctx->demuxer->type == DEMUXER_TYPE_CUE) + build_cue_timeline(mpctx); + + mpctx->tl = timeline_load(mpctx->global, mpctx->log, mpctx->demuxer); + if (mpctx->tl) { + mpctx->timeline = mpctx->tl->parts; + mpctx->num_timeline_parts = mpctx->tl->num_parts; + mpctx->num_chapters = mpctx->tl->num_chapters; + mpctx->chapters = demux_copy_chapter_data(mpctx->tl->chapters, + mpctx->tl->num_chapters); + mpctx->track_layout = mpctx->tl->track_layout; + mpctx->num_sources = 0; + for (int n = 0; n < mpctx->tl->num_sources; n++) { + MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, + mpctx->tl->sources[n]); + } + } + + print_timeline(mpctx); +} + // Start playing the current playlist entry. // Handle initialization and deinitialization. static void play_current_file(struct MPContext *mpctx) @@ -1088,7 +1128,7 @@ goto_reopen_demuxer: ; } mpctx->master_demuxer = mpctx->demuxer; - MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, mpctx->demuxer); + load_timeline(mpctx); if (mpctx->demuxer->playlist) { int entry_stream_flags = @@ -1103,18 +1143,6 @@ goto_reopen_demuxer: ; goto terminate_playback; } - mpctx->track_layout = mpctx->demuxer; - - if (mpctx->demuxer->matroska_data.ordered_chapters) - build_ordered_chapter_timeline(mpctx); - - if (mpctx->demuxer->type == DEMUXER_TYPE_EDL) - build_mpv_edl_timeline(mpctx); - - if (mpctx->demuxer->type == DEMUXER_TYPE_CUE) - build_cue_timeline(mpctx); - - print_timeline(mpctx); load_chapters(mpctx); add_demuxer_tracks(mpctx, mpctx->track_layout); diff --git a/wscript_build.py b/wscript_build.py index ebcab9d618..0539e9e0a8 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -179,6 +179,7 @@ def build(ctx): ( "demux/demux_tv.c", "tv" ), ( "demux/ebml.c" ), ( "demux/packet.c" ), + ( "demux/timeline.c" ), ## Input ( "input/cmd_list.c" ), |