From 969757baa0af99d905a9b8c99f0c92efa4e0fb33 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 2 Nov 2014 17:20:04 +0100 Subject: player: always use demux_chapter Instead of defining a separate data structure in the core. For some odd reason, demux_chapter exported the chapter time in nano-seconds. Change that to the usual timestamps (rename the field to make any code relying on this to fail compilation), and also remove the unused chapter end time. --- demux/demux.c | 20 +++++++++++++++----- demux/demux.h | 8 +++++--- demux/demux_disc.c | 2 +- demux/demux_lavf.c | 6 +----- demux/demux_mkv.c | 2 +- player/command.c | 7 ++++--- player/core.h | 7 +------ player/loadfile.c | 12 ++---------- player/playloop.c | 4 ++-- player/timeline/tl_cue.c | 8 ++++---- player/timeline/tl_matroska.c | 8 ++++---- player/timeline/tl_mpv_edl.c | 14 +++++++------- 12 files changed, 47 insertions(+), 51 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index 48b1babe35..d4206228d5 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -1076,9 +1076,9 @@ static int chapter_compare(const void *p1, const void *p2) struct demux_chapter *c1 = (void *)p1; struct demux_chapter *c2 = (void *)p2; - if (c1->start > c2->start) + if (c1->pts > c2->pts) return 1; - else if (c1->start < c2->start) + else if (c1->pts < c2->pts) return -1; return c1->original_index > c2->original_index ? 1 :-1; // never equal } @@ -1090,12 +1090,11 @@ static void demuxer_sort_chapters(demuxer_t *demuxer) } int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name, - uint64_t start, uint64_t end, uint64_t demuxer_id) + double pts, uint64_t demuxer_id) { struct demux_chapter new = { .original_index = demuxer->num_chapters, - .start = start, - .end = end, + .pts = pts, .name = name.len ? bstrdup0(demuxer, name) : NULL, .metadata = talloc_zero(demuxer, struct mp_tags), .demuxer_id = demuxer_id, @@ -1309,3 +1308,14 @@ void demux_unpause(demuxer_t *demuxer) pthread_cond_signal(&in->wakeup); pthread_mutex_unlock(&in->lock); } + +struct demux_chapter *demux_copy_chapter_data(struct demux_chapter *c, int num) +{ + struct demux_chapter *new = talloc_array(NULL, struct demux_chapter, num); + for (int n = 0; n < num; n++) { + new[n] = c[n]; + new[n].name = talloc_strdup(new, new[n].name); + new[n].metadata = mp_tags_dup(new, new[n].metadata); + } + return new; +} diff --git a/demux/demux.h b/demux/demux.h index 2d7e95ed5e..7892718027 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -123,7 +123,7 @@ typedef struct demuxer_desc { typedef struct demux_chapter { int original_index; - uint64_t start, end; + double pts; char *name; struct mp_tags *metadata; uint64_t demuxer_id; // for mapping to internal demuxer data structures @@ -268,8 +268,8 @@ void demuxer_help(struct mp_log *log); int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name, struct bstr type, struct bstr data); -int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name, - uint64_t start, uint64_t end, uint64_t demuxer_id); +int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name, + double pts, uint64_t demuxer_id); double demuxer_get_time_length(struct demuxer *demuxer); @@ -284,6 +284,8 @@ void demux_update(demuxer_t *demuxer); struct sh_stream *demuxer_stream_by_demuxer_id(struct demuxer *d, enum stream_type t, int id); +struct demux_chapter *demux_copy_chapter_data(struct demux_chapter *c, int num); + bool demux_matroska_uid_cmp(struct matroska_segment_uid *a, struct matroska_segment_uid *b); diff --git a/demux/demux_disc.c b/demux/demux_disc.c index d0054079c1..e92198f0af 100644 --- a/demux/demux_disc.c +++ b/demux/demux_disc.c @@ -275,7 +275,7 @@ static void add_stream_chapters(struct demuxer *demuxer) double p = n; if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p) < 1) continue; - demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0, 0); + demuxer_add_chapter(demuxer, bstr0(""), p, 0); } } diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index e6b62adb12..8cfcfc449f 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -769,13 +769,9 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) for (i = 0; i < avfc->nb_chapters; i++) { AVChapter *c = avfc->chapters[i]; - uint64_t start = av_rescale_q(c->start, c->time_base, - (AVRational){1, 1000000000}); - uint64_t end = av_rescale_q(c->end, c->time_base, - (AVRational){1, 1000000000}); t = av_dict_get(c->metadata, "title", NULL, 0); int index = demuxer_add_chapter(demuxer, t ? bstr0(t->value) : bstr0(""), - start, end, i); + c->start * av_q2d(c->time_base), i); mp_tags_copy_from_av_dictionary(demuxer->chapters[index].metadata, c->metadata); } diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 97db573e20..72020ce123 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -879,7 +879,7 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer) BSTR_P(name)); if (idx == selected_edition) { - demuxer_add_chapter(demuxer, name, chapter.start, chapter.end, + demuxer_add_chapter(demuxer, name, chapter.start / 1e9, ca->chapter_uid); } if (m_chapters) { diff --git a/player/command.c b/player/command.c index dbe81bff15..2995f094a0 100644 --- a/player/command.c +++ b/player/command.c @@ -1081,12 +1081,13 @@ static int mp_property_chapter_metadata(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - struct demuxer *demuxer = mpctx->master_demuxer; int chapter = get_current_chapter(mpctx); - if (!demuxer || chapter < 0 || chapter >= demuxer->num_chapters) + if (chapter < 0 || chapter >= mpctx->num_chapters) + return M_PROPERTY_UNAVAILABLE; + if (!mpctx->chapters[chapter].metadata) return M_PROPERTY_UNAVAILABLE; - return tag_property(action, arg, demuxer->chapters[chapter].metadata); + return tag_property(action, arg, mpctx->chapters[chapter].metadata); } static int mp_property_vf_metadata(void *ctx, struct m_property *prop, diff --git a/player/core.h b/player/core.h index 445c0c7105..ae0a5c5dbb 100644 --- a/player/core.h +++ b/player/core.h @@ -47,11 +47,6 @@ struct timeline_part { struct demuxer *source; }; -struct chapter { - double start; - char *name; -}; - enum mp_osd_seek_info { OSD_SEEK_INFO_BAR = 1, OSD_SEEK_INFO_TEXT = 2, @@ -195,7 +190,7 @@ typedef struct MPContext { struct timeline_part *timeline; int num_timeline_parts; int timeline_part; - struct chapter *chapters; + struct demux_chapter *chapters; int num_chapters; double video_offset; diff --git a/player/loadfile.c b/player/loadfile.c index a7905a8a36..efca08519c 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -797,16 +797,8 @@ static void load_chapters(struct MPContext *mpctx) } if (src && !mpctx->chapters) { talloc_free(mpctx->chapters); - int count = src->num_chapters; - mpctx->chapters = talloc_array(NULL, struct chapter, count); - mpctx->num_chapters = count; - for (int n = 0; n < count; n++) { - struct demux_chapter *dchapter = &src->chapters[n]; - mpctx->chapters[n] = (struct chapter){ - .start = dchapter->start / 1e9, - .name = talloc_strdup(mpctx->chapters, dchapter->name), - }; - } + mpctx->num_chapters = src->num_chapters; + mpctx->chapters = demux_copy_chapter_data(src->chapters, src->num_chapters); } if (free_src) { struct stream *s = src->stream; diff --git a/player/playloop.c b/player/playloop.c index 8a0aba2ec8..22cc12f70d 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -451,7 +451,7 @@ int get_current_chapter(struct MPContext *mpctx) double current_pts = get_current_time(mpctx); int i; for (i = 0; i < mpctx->num_chapters; i++) - if (current_pts < mpctx->chapters[i].start) + if (current_pts < mpctx->chapters[i].pts) break; return MPMAX(mpctx->last_chapter_seek, i - 1); } @@ -490,7 +490,7 @@ double chapter_start_time(struct MPContext *mpctx, int chapter) if (chapter == -1) return get_start_time(mpctx); if (chapter >= 0 && chapter < mpctx->num_chapters) - return mpctx->chapters[chapter].start; + return mpctx->chapters[chapter].pts; return MP_NOPTS_VALUE; } diff --git a/player/timeline/tl_cue.c b/player/timeline/tl_cue.c index a4f23c45cf..8b8afeae17 100644 --- a/player/timeline/tl_cue.c +++ b/player/timeline/tl_cue.c @@ -361,8 +361,8 @@ void build_cue_timeline(struct MPContext *mpctx) struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline, track_count + 1); - struct chapter *chapters = talloc_array_ptrtype(NULL, chapters, - track_count); + struct demux_chapter *chapters = talloc_array_ptrtype(NULL, chapters, + track_count); double starttime = 0; for (int i = 0; i < track_count; i++) { struct demuxer *source = mpctx->sources[1 + tracks[i].source]; @@ -387,8 +387,8 @@ void build_cue_timeline(struct MPContext *mpctx) .source_start = tracks[i].start, .source = source, }; - chapters[i] = (struct chapter) { - .start = timeline[i].start, + chapters[i] = (struct demux_chapter) { + .pts = timeline[i].start, // might want to include other metadata here .name = bstrdup0(chapters, tracks[i].title), }; diff --git a/player/timeline/tl_matroska.c b/player/timeline/tl_matroska.c index 6f64ae8484..e97a8ce594 100644 --- a/player/timeline/tl_matroska.c +++ b/player/timeline/tl_matroska.c @@ -380,7 +380,7 @@ static void build_timeline_loop(struct MPContext *mpctx, uint64_t *missing_time, uint64_t *last_end_time, struct timeline_part **timeline, - struct chapter *chapters, + struct demux_chapter *chapters, int *part_count, uint64_t skip, uint64_t limit) @@ -419,7 +419,7 @@ static void build_timeline_loop(struct MPContext *mpctx, * needed to add chapters for external non-ordered segment loading * as well since that part is not recursive. */ if (!limit) { - chapters[i].start = *starttime / 1e9; + chapters[i].pts = *starttime / 1e9; chapters[i].name = talloc_strdup(chapters, c->name); } @@ -560,8 +560,8 @@ void build_ordered_chapter_timeline(struct MPContext *mpctx) talloc_free(uids); struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline, 0); - struct chapter *chapters = - talloc_zero_array(NULL, struct chapter, m->num_ordered_chapters); + struct demux_chapter *chapters = + talloc_zero_array(NULL, struct demux_chapter, m->num_ordered_chapters); uint64_t starttime = 0; uint64_t missing_time = 0; uint64_t last_end_time = 0; diff --git a/player/timeline/tl_mpv_edl.c b/player/timeline/tl_mpv_edl.c index e11b483935..4cd62fc497 100644 --- a/player/timeline/tl_mpv_edl.c +++ b/player/timeline/tl_mpv_edl.c @@ -158,20 +158,20 @@ static double demuxer_chapter_time(struct demuxer *demuxer, int n) { if (n < 0 || n >= demuxer->num_chapters) return -1; - return demuxer->chapters[n].start / 1e9; + return demuxer->chapters[n].pts; } // Append all chapters from src to the chapters array. // Ignore chapters outside of the given time range. -static void copy_chapters(struct chapter **chapters, int *num_chapters, +static void copy_chapters(struct demux_chapter **chapters, int *num_chapters, struct demuxer *src, double start, double len, double dest_offset) { for (int n = 0; n < src->num_chapters; n++) { double time = demuxer_chapter_time(src, n); if (time >= start && time <= start + len) { - struct chapter ch = { - .start = dest_offset + time - start, + struct demux_chapter ch = { + .pts = dest_offset + time - start, .name = talloc_strdup(*chapters, src->chapters[n].name), }; MP_TARRAY_APPEND(NULL, *chapters, *num_chapters, ch); @@ -208,7 +208,7 @@ static void resolve_timestamps(struct tl_part *part, struct demuxer *demuxer) static void build_timeline(struct MPContext *mpctx, struct tl_parts *parts) { - struct chapter *chapters = talloc_new(NULL); + struct demux_chapter *chapters = talloc_new(NULL); int num_chapters = 0; struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline, parts->num_parts + 1); @@ -244,8 +244,8 @@ static void build_timeline(struct MPContext *mpctx, struct tl_parts *parts) } // Add a chapter between each file. - struct chapter ch = { - .start = starttime, + struct demux_chapter ch = { + .pts = starttime, .name = talloc_strdup(chapters, part->filename), }; MP_TARRAY_APPEND(NULL, chapters, num_chapters, ch); -- cgit v1.2.3