mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-08-12 13:23:48 +00:00
avformat/mov: parse cdsc track references
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user