avformat/mov: parse cdsc track references

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer
2026-07-14 15:50:30 -03:00
parent a302c9ae44
commit 8a3e9147b6
+84
View File
@@ -2623,6 +2623,37 @@ static MovTref *mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
return tag;
}
static int mov_read_cdsc(MOVContext* c, AVIOContext* pb, MOVAtom atom)
{
AVStream* st;
MOVStreamContext* sc;
if (c->fc->nb_streams < 1)
return 0;
if (atom.size > 4) {
av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc is supported\n");
return AVERROR_PATCHWELCOME;
}
if (atom.size < 4)
return AVERROR_INVALIDDATA;
st = get_curr_st(c);
if (!st)
return AVERROR_INVALIDDATA;
sc = st->priv_data;
MovTref *tag = mov_add_tref_tag(sc, atom.type);
if (!tag)
return AVERROR(ENOMEM);
int ret = mov_add_tref_id(tag, avio_rb32(pb));
if (ret < 0)
return ret;
return 0;
}
static int mov_read_sbas(MOVContext* c, AVIOContext* pb, MOVAtom atom)
{
AVStream* st;
@@ -9776,6 +9807,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('a','v','c','C'), mov_read_glbl },
{ MKTAG('p','a','s','p'), mov_read_pasp },
{ MKTAG('c','l','a','p'), mov_read_clap },
{ MKTAG('c','d','s','c'), mov_read_cdsc },
{ MKTAG('s','b','a','s'), mov_read_sbas },
{ MKTAG('v','d','e','p'), mov_read_vdep },
{ MKTAG('s','i','d','x'), mov_read_sidx },
@@ -11101,6 +11133,53 @@ static AVStream *mov_find_reference_track(AVFormatContext *s, AVStream *st,
return NULL;
}
static int mov_parse_cdsc_streams(AVFormatContext *s)
{
int err;
// Don't try to add a group if there's only one track
if (s->nb_streams <= 1)
return 0;
for (int i = 0; i < s->nb_streams; i++) {
AVStreamGroup *stg;
AVStream *st = s->streams[i];
AVStream *st_ref;
MOVStreamContext *sc = st->priv_data;
MovTref *tag = mov_find_tref_tag(sc, MKTAG('c','d','s','c'));
if (!tag)
continue;
st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
if (!st_ref) {
int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
av_log(s, loglevel, "Failed to referenced stream\n");
if (s->error_recognition & AV_EF_EXPLODE)
return AVERROR_INVALIDDATA;
continue;
}
stg = avformat_stream_group_create(s, AV_STREAM_GROUP_PARAMS_TREF, NULL);
if (!stg)
return AVERROR(ENOMEM);
stg->id = st->id;
err = avformat_stream_group_add_stream(stg, st_ref);
if (err < 0)
return err;
err = avformat_stream_group_add_stream(stg, st);
if (err < 0)
return err;
stg->params.tref->metadata_index = stg->nb_streams - 1;
}
return 0;
}
static int mov_parse_lcevc_streams(AVFormatContext *s)
{
int err;
@@ -11321,6 +11400,11 @@ static int mov_read_header(AVFormatContext *s)
}
}
/* Create metadata stream groups. */
err = mov_parse_cdsc_streams(s);
if (err < 0)
return err;
/* copy timecode metadata from tmcd tracks to the related video streams */
err = mov_parse_tmcd_streams(s);
if (err < 0)