avformat/flvdec: Check need_context_update when audio codec changes

We did check video codecs but not audio
Fixes: Assertion failure (on codec_id) in parser.c
Fixes: 472097507/clusterfuzz-testcase-minimized-ffmpeg_dem_LIVE_FLV_fuzzer-6016386662203392

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2026-01-20 04:14:08 +01:00
parent c6c6874c44
commit 5fa7d588f5

View File

@@ -301,9 +301,13 @@ static int flv_same_audio_codec(AVCodecParameters *apar, int flags, uint32_t cod
}
}
static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
static int flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
AVCodecParameters *apar, int flv_codecid)
{
FFStream *const astreami = ffstream(astream);
AVCodecParameters *par = astream->codecpar;
enum AVCodecID old_codec_id = astream->codecpar->codec_id;
switch (flv_codecid) {
// no distinction between S16 and S8 PCM codec flags
case FLV_CODECID_PCM:
@@ -356,28 +360,34 @@ static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
break;
case MKBETAG('m', 'p', '4', 'a'):
apar->codec_id = AV_CODEC_ID_AAC;
return;
break;
case MKBETAG('O', 'p', 'u', 's'):
apar->codec_id = AV_CODEC_ID_OPUS;
apar->sample_rate = 48000;
return;
break;
case MKBETAG('.', 'm', 'p', '3'):
apar->codec_id = AV_CODEC_ID_MP3;
return;
break;
case MKBETAG('f', 'L', 'a', 'C'):
apar->codec_id = AV_CODEC_ID_FLAC;
return;
break;
case MKBETAG('a', 'c', '-', '3'):
apar->codec_id = AV_CODEC_ID_AC3;
return;
break;
case MKBETAG('e', 'c', '-', '3'):
apar->codec_id = AV_CODEC_ID_EAC3;
return;
break;
default:
avpriv_request_sample(s, "Audio codec (%x)",
flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
apar->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
}
if (!astreami->need_context_update && par->codec_id != old_codec_id) {
avpriv_request_sample(s, "Changing the codec id midstream");
return AVERROR_PATCHWELCOME;
}
return 0;
}
static int flv_same_video_codec(AVCodecParameters *vpar, uint32_t flv_codecid)
@@ -719,7 +729,9 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream,
return ret;
} else if (!strcmp(key, "audiocodecid") && apar) {
int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
flv_set_audio_codec(s, astream, apar, id);
int ret = flv_set_audio_codec(s, astream, apar, id);
if (ret < 0)
return ret;
} else if (!strcmp(key, "audiosamplerate") && apar) {
apar->sample_rate = num_val;
} else if (!strcmp(key, "audiosamplesize") && apar) {
@@ -1641,8 +1653,10 @@ retry_duration:
st->codecpar->bits_per_coded_sample = bits_per_coded_sample;
}
if (!st->codecpar->codec_id) {
flv_set_audio_codec(s, st, st->codecpar,
ret = flv_set_audio_codec(s, st, st->codecpar,
flags & FLV_AUDIO_CODECID_MASK);
if (ret < 0)
goto leave;
flv->last_sample_rate =
sample_rate = st->codecpar->sample_rate;
flv->last_channels =
@@ -1655,14 +1669,19 @@ retry_duration:
}
par->sample_rate = sample_rate;
par->bits_per_coded_sample = bits_per_coded_sample;
flv_set_audio_codec(s, st, par, flags & FLV_AUDIO_CODECID_MASK);
ret = flv_set_audio_codec(s, st, par, flags & FLV_AUDIO_CODECID_MASK);
if (ret < 0)
goto leave;
sample_rate = par->sample_rate;
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_AUDIO) {
if (!st->codecpar->codec_id)
flv_set_audio_codec(s, st, st->codecpar,
if (!st->codecpar->codec_id) {
ret = flv_set_audio_codec(s, st, st->codecpar,
codec_id ? codec_id : (flags & FLV_AUDIO_CODECID_MASK));
if (ret < 0)
goto leave;
}
// These are not signalled in the flags anymore
channels = 0;