avformat/mov: fix track handling when mixing IAMF and video tracks

Fixes crashes when muxing the two together.

Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 5b87869c09)
release/7.0
James Almer 6 months ago
parent e3a61e9103
commit 714635937a
  1. 37
      libavformat/movenc.c

@ -7155,7 +7155,9 @@ static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
static int mov_init_iamf_track(AVFormatContext *s) static int mov_init_iamf_track(AVFormatContext *s)
{ {
MOVMuxContext *mov = s->priv_data; MOVMuxContext *mov = s->priv_data;
MOVTrack *track = &mov->tracks[0]; // IAMF if present is always the first track MOVTrack *track;
IAMFContext *iamf;
int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
int nb_audio_elements = 0, nb_mix_presentations = 0; int nb_audio_elements = 0, nb_mix_presentations = 0;
int ret; int ret;
@ -7177,24 +7179,24 @@ static int mov_init_iamf_track(AVFormatContext *s)
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
track->iamf = av_mallocz(sizeof(*track->iamf)); iamf = av_mallocz(sizeof(*iamf));
if (!track->iamf) if (!iamf)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
for (int i = 0; i < s->nb_stream_groups; i++) { for (int i = 0; i < s->nb_stream_groups; i++) {
const AVStreamGroup *stg = s->stream_groups[i]; const AVStreamGroup *stg = s->stream_groups[i];
switch(stg->type) { switch(stg->type) {
case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
for (int j = 0; j < stg->nb_streams; j++) { for (int j = 0; j < stg->nb_streams; j++) {
track->first_iamf_idx = FFMIN(stg->streams[j]->index, track->first_iamf_idx); first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
track->last_iamf_idx = FFMAX(stg->streams[j]->index, track->last_iamf_idx); last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
stg->streams[j]->priv_data = track;
} }
ret = ff_iamf_add_audio_element(track->iamf, stg, s); ret = ff_iamf_add_audio_element(iamf, stg, s);
break; break;
case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
ret = ff_iamf_add_mix_presentation(track->iamf, stg, s); ret = ff_iamf_add_mix_presentation(iamf, stg, s);
break; break;
default: default:
av_assert0(0); av_assert0(0);
@ -7203,8 +7205,20 @@ static int mov_init_iamf_track(AVFormatContext *s)
return ret; return ret;
} }
track = &mov->tracks[first_iamf_idx];
track->iamf = iamf;
track->first_iamf_idx = first_iamf_idx;
track->last_iamf_idx = last_iamf_idx;
track->tag = MKTAG('i','a','m','f'); track->tag = MKTAG('i','a','m','f');
for (int i = 0; i < s->nb_stream_groups; i++) {
AVStreamGroup *stg = s->stream_groups[i];
if (stg->type != AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT)
continue;
for (int j = 0; j < stg->nb_streams; j++)
stg->streams[j]->priv_data = track;
}
ret = avio_open_dyn_buf(&track->iamf_buf); ret = avio_open_dyn_buf(&track->iamf_buf);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -7215,6 +7229,7 @@ static int mov_init_iamf_track(AVFormatContext *s)
static int mov_init(AVFormatContext *s) static int mov_init(AVFormatContext *s)
{ {
MOVMuxContext *mov = s->priv_data; MOVMuxContext *mov = s->priv_data;
int has_iamf = 0;
int i, ret; int i, ret;
mov->fc = s; mov->fc = s;
@ -7365,6 +7380,7 @@ static int mov_init(AVFormatContext *s)
} }
st->priv_data = st; st->priv_data = st;
} }
has_iamf = 1;
if (!mov->nb_tracks) // We support one track for the entire IAMF structure if (!mov->nb_tracks) // We support one track for the entire IAMF structure
mov->nb_tracks++; mov->nb_tracks++;
@ -7461,8 +7477,11 @@ static int mov_init(AVFormatContext *s)
for (int j = 0, i = 0; j < s->nb_streams; j++) { for (int j = 0, i = 0; j < s->nb_streams; j++) {
AVStream *st = s->streams[j]; AVStream *st = s->streams[j];
if (st != st->priv_data) if (st != st->priv_data) {
if (has_iamf)
i += has_iamf--;
continue; continue;
}
st->priv_data = &mov->tracks[i++]; st->priv_data = &mov->tracks[i++];
} }

Loading…
Cancel
Save