mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-20 22:40:47 +00:00
libspeexdec: improve setting of Speex mode and sample rate
If there is no extradata and the sample rate given by the user is not valid, decode as ultra-wideband.
This commit is contained in:
parent
ad11681acd
commit
3b061c5e10
@ -39,31 +39,36 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx)
|
|||||||
{
|
{
|
||||||
LibSpeexContext *s = avctx->priv_data;
|
LibSpeexContext *s = avctx->priv_data;
|
||||||
const SpeexMode *mode;
|
const SpeexMode *mode;
|
||||||
|
int spx_mode;
|
||||||
// defaults in the case of a missing header
|
|
||||||
if (avctx->sample_rate <= 8000)
|
|
||||||
mode = &speex_nb_mode;
|
|
||||||
else if (avctx->sample_rate <= 16000)
|
|
||||||
mode = &speex_wb_mode;
|
|
||||||
else
|
|
||||||
mode = &speex_uwb_mode;
|
|
||||||
|
|
||||||
if (avctx->extradata_size >= 80)
|
if (avctx->extradata_size >= 80)
|
||||||
s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size);
|
s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size);
|
||||||
|
|
||||||
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
|
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||||
if (s->header) {
|
if (s->header) {
|
||||||
avctx->sample_rate = s->header->rate;
|
|
||||||
avctx->channels = s->header->nb_channels;
|
avctx->channels = s->header->nb_channels;
|
||||||
s->frame_size = s->header->frame_size;
|
s->frame_size = s->header->frame_size;
|
||||||
|
spx_mode = s->header->mode;
|
||||||
|
} else {
|
||||||
|
switch (avctx->sample_rate) {
|
||||||
|
case 8000: spx_mode = 0; break;
|
||||||
|
case 16000: spx_mode = 1; break;
|
||||||
|
case 32000: spx_mode = 2; break;
|
||||||
|
default:
|
||||||
|
/* libspeex can handle any mode if initialized as ultra-wideband */
|
||||||
|
av_log(avctx, AV_LOG_WARNING, "Invalid sample rate: %d\n"
|
||||||
|
"Decoding as 32kHz ultra-wideband\n",
|
||||||
|
avctx->sample_rate);
|
||||||
|
spx_mode = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mode = speex_lib_get_mode(s->header->mode);
|
mode = speex_lib_get_mode(spx_mode);
|
||||||
if (!mode) {
|
if (!mode) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode);
|
av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", spx_mode);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
} else
|
avctx->sample_rate = 8000 << spx_mode;
|
||||||
av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n");
|
|
||||||
|
|
||||||
if (avctx->channels > 2) {
|
if (avctx->channels > 2) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n");
|
av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user