diff --git a/demux/cue.c b/demux/cue.c index 7f2ded28c8..d72e84249b 100644 --- a/demux/cue.c +++ b/demux/cue.c @@ -24,6 +24,7 @@ #include "misc/bstr.h" #include "common/common.h" +#include "common/tags.h" #include "cue.h" @@ -37,6 +38,7 @@ enum cue_command { CUE_TRACK, CUE_INDEX, CUE_TITLE, + CUE_PERFORMER, }; static const struct { @@ -51,7 +53,7 @@ static const struct { { CUE_UNUSED, "CDTEXTFILE" }, { CUE_UNUSED, "FLAGS" }, { CUE_UNUSED, "ISRC" }, - { CUE_UNUSED, "PERFORMER" }, + { CUE_PERFORMER, "PERFORMER" }, { CUE_UNUSED, "POSTGAP" }, { CUE_UNUSED, "PREGAP" }, { CUE_UNUSED, "REM" }, @@ -160,17 +162,19 @@ bool mp_probe_cue(struct bstr data) struct cue_file *mp_parse_cue(struct bstr data) { struct cue_file *f = talloc_zero(NULL, struct cue_file); + f->tags = talloc_zero(f, struct mp_tags); data = skip_utf8_bom(data); char *filename = NULL; // Global metadata, and copied into new tracks. struct cue_track proto_track = {0}; - struct cue_track *cur_track = &proto_track; + struct cue_track *cur_track = NULL; while (data.len) { struct bstr param; - switch (read_cmd(&data, ¶m)) { + int cmd = read_cmd(&data, ¶m); + switch (cmd) { case CUE_ERROR: talloc_free(f); return NULL; @@ -179,19 +183,29 @@ struct cue_file *mp_parse_cue(struct bstr data) f->num_tracks += 1; cur_track = &f->tracks[f->num_tracks - 1]; *cur_track = proto_track; + cur_track->tags = talloc_zero(f, struct mp_tags); break; } case CUE_TITLE: - cur_track->title = read_quoted(f, ¶m); + case CUE_PERFORMER: { + static const char *metanames[] = { + [CUE_TITLE] = "title", + [CUE_PERFORMER] = "performer", + }; + struct mp_tags *tags = cur_track ? cur_track->tags : f->tags; + mp_tags_set_bstr(tags, bstr0(metanames[cmd]), param); break; + } case CUE_INDEX: { int type = read_int_2(¶m); double time = read_time(¶m); - if (type == 1) { - cur_track->start = time; - cur_track->filename = filename; - } else if (type == 0) { - cur_track->pregap_start = time; + if (cur_track) { + if (type == 1) { + cur_track->start = time; + cur_track->filename = filename; + } else if (type == 0) { + cur_track->pregap_start = time; + } } break; } diff --git a/demux/cue.h b/demux/cue.h index 5645dd01ab..cf4b4c1a08 100644 --- a/demux/cue.h +++ b/demux/cue.h @@ -25,6 +25,7 @@ struct cue_file { struct cue_track *tracks; int num_tracks; + struct mp_tags *tags; }; struct cue_track { @@ -32,7 +33,7 @@ struct cue_track { double start; // corresponds to INDEX 01 char *filename; int source; - char *title; + struct mp_tags *tags; }; bool mp_probe_cue(struct bstr data); diff --git a/demux/demux.c b/demux/demux.c index d0e44ab363..5028afa15e 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -924,7 +924,8 @@ static void demux_init_cuesheet(struct demuxer *demuxer) if (f) { for (int n = 0; n < f->num_tracks; n++) { struct cue_track *t = &f->tracks[n]; - demuxer_add_chapter(demuxer, t->title, t->start, -1); + int idx = demuxer_add_chapter(demuxer, "", t->start, -1); + mp_tags_merge(demuxer->chapters[idx].metadata, t->tags); } } talloc_free(f); diff --git a/demux/demux_cue.c b/demux/demux_cue.c index ed3d3d83f3..43420573ec 100644 --- a/demux/demux_cue.c +++ b/demux/demux_cue.c @@ -38,7 +38,7 @@ #define PROBE_SIZE 512 struct priv { - bstr data; + struct cue_file *f; }; static void add_source(struct timeline *tl, struct demuxer *d) @@ -150,15 +150,8 @@ static void build_timeline(struct timeline *tl) add_source(tl, tl->demuxer); - struct cue_file *f = mp_parse_cue(p->data); - if (!f) { - MP_ERR(tl, "CUE: error parsing input file!\n"); - goto out; - } - talloc_steal(ctx, f); - - struct cue_track *tracks = f->tracks; - size_t track_count = f->num_tracks; + struct cue_track *tracks = p->f->tracks; + size_t track_count = p->f->num_tracks; if (track_count == 0) { MP_ERR(tl, "CUE: no tracks found!\n"); @@ -224,10 +217,8 @@ static void build_timeline(struct timeline *tl) }; chapters[i] = (struct demux_chapter) { .pts = timeline[i].start, - .metadata = talloc_zero(tl, struct mp_tags), + .metadata = mp_tags_dup(tl, tracks[i].tags), }; - // might want to include other metadata here - mp_tags_set_str(chapters[i].metadata, "title", tracks[i].title); starttime += duration; } @@ -261,9 +252,18 @@ static int try_open_file(struct demuxer *demuxer, enum demux_check check) struct priv *p = talloc_zero(demuxer, struct priv); demuxer->priv = p; demuxer->fully_read = true; - p->data = stream_read_complete(s, demuxer, 1000000); - if (p->data.start == NULL) + + bstr data = stream_read_complete(s, p, 1000000); + if (data.start == NULL) return -1; + p->f = mp_parse_cue(data); + talloc_steal(p, p->f); + if (!p->f) { + MP_ERR(demuxer, "error parsing input file!\n"); + return -1; + } + + mp_tags_merge(demuxer->metadata, p->f->tags); return 0; }