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.
This commit is contained in:
wm4 2014-11-02 17:20:04 +01:00
parent 1cebd16350
commit 969757baa0
12 changed files with 47 additions and 51 deletions

View File

@ -1076,9 +1076,9 @@ static int chapter_compare(const void *p1, const void *p2)
struct demux_chapter *c1 = (void *)p1; struct demux_chapter *c1 = (void *)p1;
struct demux_chapter *c2 = (void *)p2; struct demux_chapter *c2 = (void *)p2;
if (c1->start > c2->start) if (c1->pts > c2->pts)
return 1; return 1;
else if (c1->start < c2->start) else if (c1->pts < c2->pts)
return -1; return -1;
return c1->original_index > c2->original_index ? 1 :-1; // never equal 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, 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 = { struct demux_chapter new = {
.original_index = demuxer->num_chapters, .original_index = demuxer->num_chapters,
.start = start, .pts = pts,
.end = end,
.name = name.len ? bstrdup0(demuxer, name) : NULL, .name = name.len ? bstrdup0(demuxer, name) : NULL,
.metadata = talloc_zero(demuxer, struct mp_tags), .metadata = talloc_zero(demuxer, struct mp_tags),
.demuxer_id = demuxer_id, .demuxer_id = demuxer_id,
@ -1309,3 +1308,14 @@ void demux_unpause(demuxer_t *demuxer)
pthread_cond_signal(&in->wakeup); pthread_cond_signal(&in->wakeup);
pthread_mutex_unlock(&in->lock); 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;
}

View File

@ -123,7 +123,7 @@ typedef struct demuxer_desc {
typedef struct demux_chapter typedef struct demux_chapter
{ {
int original_index; int original_index;
uint64_t start, end; double pts;
char *name; char *name;
struct mp_tags *metadata; struct mp_tags *metadata;
uint64_t demuxer_id; // for mapping to internal demuxer data structures 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, int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name,
struct bstr type, struct bstr data); struct bstr type, struct bstr data);
int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name, 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);
double demuxer_get_time_length(struct demuxer *demuxer); 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, struct sh_stream *demuxer_stream_by_demuxer_id(struct demuxer *d,
enum stream_type t, int id); 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, bool demux_matroska_uid_cmp(struct matroska_segment_uid *a,
struct matroska_segment_uid *b); struct matroska_segment_uid *b);

View File

@ -275,7 +275,7 @@ static void add_stream_chapters(struct demuxer *demuxer)
double p = n; double p = n;
if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p) < 1) if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p) < 1)
continue; continue;
demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0, 0); demuxer_add_chapter(demuxer, bstr0(""), p, 0);
} }
} }

View File

@ -769,13 +769,9 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
for (i = 0; i < avfc->nb_chapters; i++) { for (i = 0; i < avfc->nb_chapters; i++) {
AVChapter *c = avfc->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); t = av_dict_get(c->metadata, "title", NULL, 0);
int index = demuxer_add_chapter(demuxer, t ? bstr0(t->value) : bstr0(""), 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); mp_tags_copy_from_av_dictionary(demuxer->chapters[index].metadata, c->metadata);
} }

View File

@ -879,7 +879,7 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
BSTR_P(name)); BSTR_P(name));
if (idx == selected_edition) { if (idx == selected_edition) {
demuxer_add_chapter(demuxer, name, chapter.start, chapter.end, demuxer_add_chapter(demuxer, name, chapter.start / 1e9,
ca->chapter_uid); ca->chapter_uid);
} }
if (m_chapters) { if (m_chapters) {

View File

@ -1081,12 +1081,13 @@ static int mp_property_chapter_metadata(void *ctx, struct m_property *prop,
int action, void *arg) int action, void *arg)
{ {
MPContext *mpctx = ctx; MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
int chapter = get_current_chapter(mpctx); 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 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, static int mp_property_vf_metadata(void *ctx, struct m_property *prop,

View File

@ -47,11 +47,6 @@ struct timeline_part {
struct demuxer *source; struct demuxer *source;
}; };
struct chapter {
double start;
char *name;
};
enum mp_osd_seek_info { enum mp_osd_seek_info {
OSD_SEEK_INFO_BAR = 1, OSD_SEEK_INFO_BAR = 1,
OSD_SEEK_INFO_TEXT = 2, OSD_SEEK_INFO_TEXT = 2,
@ -195,7 +190,7 @@ typedef struct MPContext {
struct timeline_part *timeline; struct timeline_part *timeline;
int num_timeline_parts; int num_timeline_parts;
int timeline_part; int timeline_part;
struct chapter *chapters; struct demux_chapter *chapters;
int num_chapters; int num_chapters;
double video_offset; double video_offset;

View File

@ -797,16 +797,8 @@ static void load_chapters(struct MPContext *mpctx)
} }
if (src && !mpctx->chapters) { if (src && !mpctx->chapters) {
talloc_free(mpctx->chapters); talloc_free(mpctx->chapters);
int count = src->num_chapters; mpctx->num_chapters = src->num_chapters;
mpctx->chapters = talloc_array(NULL, struct chapter, count); mpctx->chapters = demux_copy_chapter_data(src->chapters, src->num_chapters);
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),
};
}
} }
if (free_src) { if (free_src) {
struct stream *s = src->stream; struct stream *s = src->stream;

View File

@ -451,7 +451,7 @@ int get_current_chapter(struct MPContext *mpctx)
double current_pts = get_current_time(mpctx); double current_pts = get_current_time(mpctx);
int i; int i;
for (i = 0; i < mpctx->num_chapters; i++) for (i = 0; i < mpctx->num_chapters; i++)
if (current_pts < mpctx->chapters[i].start) if (current_pts < mpctx->chapters[i].pts)
break; break;
return MPMAX(mpctx->last_chapter_seek, i - 1); return MPMAX(mpctx->last_chapter_seek, i - 1);
} }
@ -490,7 +490,7 @@ double chapter_start_time(struct MPContext *mpctx, int chapter)
if (chapter == -1) if (chapter == -1)
return get_start_time(mpctx); return get_start_time(mpctx);
if (chapter >= 0 && chapter < mpctx->num_chapters) if (chapter >= 0 && chapter < mpctx->num_chapters)
return mpctx->chapters[chapter].start; return mpctx->chapters[chapter].pts;
return MP_NOPTS_VALUE; return MP_NOPTS_VALUE;
} }

View File

@ -361,8 +361,8 @@ void build_cue_timeline(struct MPContext *mpctx)
struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline, struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline,
track_count + 1); track_count + 1);
struct chapter *chapters = talloc_array_ptrtype(NULL, chapters, struct demux_chapter *chapters = talloc_array_ptrtype(NULL, chapters,
track_count); track_count);
double starttime = 0; double starttime = 0;
for (int i = 0; i < track_count; i++) { for (int i = 0; i < track_count; i++) {
struct demuxer *source = mpctx->sources[1 + tracks[i].source]; 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_start = tracks[i].start,
.source = source, .source = source,
}; };
chapters[i] = (struct chapter) { chapters[i] = (struct demux_chapter) {
.start = timeline[i].start, .pts = timeline[i].start,
// might want to include other metadata here // might want to include other metadata here
.name = bstrdup0(chapters, tracks[i].title), .name = bstrdup0(chapters, tracks[i].title),
}; };

View File

@ -380,7 +380,7 @@ static void build_timeline_loop(struct MPContext *mpctx,
uint64_t *missing_time, uint64_t *missing_time,
uint64_t *last_end_time, uint64_t *last_end_time,
struct timeline_part **timeline, struct timeline_part **timeline,
struct chapter *chapters, struct demux_chapter *chapters,
int *part_count, int *part_count,
uint64_t skip, uint64_t skip,
uint64_t limit) 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 * needed to add chapters for external non-ordered segment loading
* as well since that part is not recursive. */ * as well since that part is not recursive. */
if (!limit) { if (!limit) {
chapters[i].start = *starttime / 1e9; chapters[i].pts = *starttime / 1e9;
chapters[i].name = talloc_strdup(chapters, c->name); chapters[i].name = talloc_strdup(chapters, c->name);
} }
@ -560,8 +560,8 @@ void build_ordered_chapter_timeline(struct MPContext *mpctx)
talloc_free(uids); talloc_free(uids);
struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline, 0); struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline, 0);
struct chapter *chapters = struct demux_chapter *chapters =
talloc_zero_array(NULL, struct chapter, m->num_ordered_chapters); talloc_zero_array(NULL, struct demux_chapter, m->num_ordered_chapters);
uint64_t starttime = 0; uint64_t starttime = 0;
uint64_t missing_time = 0; uint64_t missing_time = 0;
uint64_t last_end_time = 0; uint64_t last_end_time = 0;

View File

@ -158,20 +158,20 @@ static double demuxer_chapter_time(struct demuxer *demuxer, int n)
{ {
if (n < 0 || n >= demuxer->num_chapters) if (n < 0 || n >= demuxer->num_chapters)
return -1; return -1;
return demuxer->chapters[n].start / 1e9; return demuxer->chapters[n].pts;
} }
// Append all chapters from src to the chapters array. // Append all chapters from src to the chapters array.
// Ignore chapters outside of the given time range. // 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, struct demuxer *src, double start, double len,
double dest_offset) double dest_offset)
{ {
for (int n = 0; n < src->num_chapters; n++) { for (int n = 0; n < src->num_chapters; n++) {
double time = demuxer_chapter_time(src, n); double time = demuxer_chapter_time(src, n);
if (time >= start && time <= start + len) { if (time >= start && time <= start + len) {
struct chapter ch = { struct demux_chapter ch = {
.start = dest_offset + time - start, .pts = dest_offset + time - start,
.name = talloc_strdup(*chapters, src->chapters[n].name), .name = talloc_strdup(*chapters, src->chapters[n].name),
}; };
MP_TARRAY_APPEND(NULL, *chapters, *num_chapters, ch); 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) 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; int num_chapters = 0;
struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline, struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline,
parts->num_parts + 1); 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. // Add a chapter between each file.
struct chapter ch = { struct demux_chapter ch = {
.start = starttime, .pts = starttime,
.name = talloc_strdup(chapters, part->filename), .name = talloc_strdup(chapters, part->filename),
}; };
MP_TARRAY_APPEND(NULL, chapters, num_chapters, ch); MP_TARRAY_APPEND(NULL, chapters, num_chapters, ch);