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 *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;
}

View File

@ -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);

View File

@ -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);
}
}

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++) {
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);
}

View File

@ -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) {

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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),
};

View File

@ -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;

View File

@ -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);