mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-08-09 09:32:43 +00:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user