From 0cc9a64b92939adfe4408003ff119607001a88e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 1 Oct 2012 23:38:50 +0300 Subject: [PATCH 01/12] blowfish: Factorize testing into a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavutil/blowfish.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/libavutil/blowfish.c b/libavutil/blowfish.c index 5df3dfcf1e..35c546a898 100644 --- a/libavutil/blowfish.c +++ b/libavutil/blowfish.c @@ -522,6 +522,25 @@ static const uint8_t ciphertext[8] = { 0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03 }; +#undef exit +static void test_blowfish(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, + const uint8_t *ref, int len, uint8_t *iv, int dir, + const char *test) +{ + av_blowfish_crypt(ctx, dst, src, len, iv, dir); + if (memcmp(dst, ref, 8*len)) { + int i; + printf("%s failed\ngot ", test); + for (i = 0; i < 8*len; i++) + printf("%02x ", dst[i]); + printf("\nexpected "); + for (i = 0; i < 8*len; i++) + printf("%02x ", ref[i]); + printf("\n"); + exit(1); + } +} + int main(void) { AVBlowfish ctx; @@ -532,17 +551,8 @@ int main(void) av_blowfish_init(&ctx, "abcdefghijklmnopqrstuvwxyz", 26); - av_blowfish_crypt(&ctx, tmp, plaintext, 1, NULL, 0); - if (memcmp(tmp, ciphertext, 8)) { - printf("Test encryption failed.\n"); - return 1; - } - - av_blowfish_crypt(&ctx, tmp, ciphertext, 1, NULL, 1); - if (memcmp(tmp, plaintext, 8)) { - printf("Test decryption failed.\n"); - return 1; - } + test_blowfish(&ctx, tmp, plaintext, ciphertext, 1, NULL, 0, "encryption"); + test_blowfish(&ctx, tmp, ciphertext, plaintext, 1, NULL, 1, "decryption"); memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS); memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS); From 87f023f2c01e7004618537114e2d53be69b01019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 2 Oct 2012 00:04:38 +0300 Subject: [PATCH 02/12] blowfish: Fix CBC decryption with dst==src MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavutil/blowfish.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavutil/blowfish.c b/libavutil/blowfish.c index 35c546a898..604c0be821 100644 --- a/libavutil/blowfish.c +++ b/libavutil/blowfish.c @@ -388,15 +388,15 @@ void av_blowfish_crypt(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt); - AV_WB32(dst, v0); - AV_WB32(dst + 4, v1); - if (iv) { - for (i = 0; i < 8; i++) - dst[i] = dst[i] ^ iv[i]; + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); memcpy(iv, src, 8); } + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); + src += 8; dst += 8; } From 75366a504dfc30deadeac71c35e3c444275986f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 1 Oct 2012 23:49:17 +0300 Subject: [PATCH 03/12] blowfish: Add more tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test inplace ECB, normal CBC and inplace CBC encryption/decryption. Signed-off-by: Martin Storsjö --- libavutil/blowfish.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/libavutil/blowfish.c b/libavutil/blowfish.c index 604c0be821..e6f07d6ad0 100644 --- a/libavutil/blowfish.c +++ b/libavutil/blowfish.c @@ -517,11 +517,20 @@ static const uint32_t ciphertext_r[NUM_VARIABLE_KEY_TESTS] = { /* plaintext bytes */ static const uint8_t plaintext[8] = "BLOWFISH"; +static const uint8_t plaintext2[16] = "BLOWFISHBLOWFISH"; + /* ciphertext bytes */ static const uint8_t ciphertext[8] = { 0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03 }; +static const uint8_t ciphertext2[16] = { + 0x53, 0x00, 0x40, 0x06, 0x63, 0xf2, 0x1d, 0x99, + 0x3b, 0x9b, 0x27, 0x64, 0x46, 0xfd, 0x20, 0xc1, +}; + +#define IV "blowfish" + #undef exit static void test_blowfish(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, const uint8_t *ref, int len, uint8_t *iv, int dir, @@ -546,13 +555,23 @@ int main(void) AVBlowfish ctx; uint32_t tmptext_l[NUM_VARIABLE_KEY_TESTS]; uint32_t tmptext_r[NUM_VARIABLE_KEY_TESTS]; - uint8_t tmp[8]; + uint8_t tmp[16], iv[8]; int i; av_blowfish_init(&ctx, "abcdefghijklmnopqrstuvwxyz", 26); test_blowfish(&ctx, tmp, plaintext, ciphertext, 1, NULL, 0, "encryption"); test_blowfish(&ctx, tmp, ciphertext, plaintext, 1, NULL, 1, "decryption"); + test_blowfish(&ctx, tmp, tmp, ciphertext, 1, NULL, 0, "Inplace encryption"); + test_blowfish(&ctx, tmp, tmp, plaintext, 1, NULL, 1, "Inplace decryption"); + memcpy(iv, IV, 8); + test_blowfish(&ctx, tmp, plaintext2, ciphertext2, 2, iv, 0, "CBC encryption"); + memcpy(iv, IV, 8); + test_blowfish(&ctx, tmp, ciphertext2, plaintext2, 2, iv, 1, "CBC decryption"); + memcpy(iv, IV, 8); + test_blowfish(&ctx, tmp, tmp, ciphertext2, 2, iv, 0, "Inplace CBC encryption"); + memcpy(iv, IV, 8); + test_blowfish(&ctx, tmp, tmp, plaintext2, 2, iv, 1, "Inplace CBC decryption"); memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS); memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS); From 05e209c04ceda37c9a6921f17955c841b93419a2 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 9 Sep 2012 14:07:20 +0100 Subject: [PATCH 04/12] Allow use of strncpy() There are cases where strncpy() does exactly what is required. A blanket ban forces more convoluted solutions to be used in those cases and has been a cause of bugs. Signed-off-by: Mans Rullgard --- libavutil/internal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavutil/internal.h b/libavutil/internal.h index 6862000722..e61a629f05 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -70,8 +70,6 @@ #define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf #undef strcat #define strcat strcat_is_forbidden_due_to_security_issues_use_av_strlcat -#undef strncpy -#define strncpy strncpy_is_forbidden_due_to_security_issues_use_av_strlcpy #undef exit #define exit exit_is_forbidden #undef printf From 8be5b0d6d52d0308bfa99218e8f4f9436498d92a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 3 Oct 2012 16:20:41 +0200 Subject: [PATCH 05/12] avconv/avprobe: Add missing 'void' to exit_program() definition --- avconv.c | 2 +- avprobe.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/avconv.c b/avconv.c index 2e420651c1..9aaa4a8cc2 100644 --- a/avconv.c +++ b/avconv.c @@ -143,7 +143,7 @@ static int decode_interrupt_cb(void *ctx) const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; -static void exit_program() +static void exit_program(void) { int i, j; diff --git a/avprobe.c b/avprobe.c index 8bc2a21459..c9bcee27e9 100644 --- a/avprobe.c +++ b/avprobe.c @@ -59,7 +59,7 @@ static const char unit_hertz_str[] = "Hz" ; static const char unit_byte_str[] = "byte" ; static const char unit_bit_per_second_str[] = "bit/s"; -static void exit_program() +static void exit_program(void) { av_dict_free(&fmt_entries_to_show); } From fd712a5584f13f8f89b2cd486d5a65a47634ed2a Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 5 Sep 2012 11:35:13 +0200 Subject: [PATCH 06/12] configure: Refactor HAVE_ options available on the command line --- configure | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/configure b/configure index bca93619ee..c74693bb22 100755 --- a/configure +++ b/configure @@ -1107,6 +1107,12 @@ ARCH_EXT_LIST=" vis " +HAVE_LIST_CMDLINE=' + inline_asm + symver + yasm +' + HAVE_LIST_PUB=' bigendian fast_unaligned @@ -1116,6 +1122,7 @@ HAVE_LIST=" $ARCH_EXT_LIST $(add_suffix _external $ARCH_EXT_LIST) $(add_suffix _inline $ARCH_EXT_LIST) + $HAVE_LIST_CMDLINE $HAVE_LIST_PUB $THREADS_LIST aligned_malloc @@ -1164,7 +1171,6 @@ HAVE_LIST=" gnu_as ibm_asm inet_aton - inline_asm io_h isatty isinf @@ -1222,7 +1228,6 @@ HAVE_LIST=" struct_sockaddr_sa_len struct_sockaddr_storage struct_v4l2_frmivalenum_discrete - symver symver_asm_label symver_gnu_asm sysconf @@ -1246,7 +1251,6 @@ HAVE_LIST=" xform_asm xgetbv xmm_clobbers - yasm " # options emitted with CONFIG_ prefix but not available on command line @@ -1278,16 +1282,14 @@ CONFIG_EXTRA=" CMDLINE_SELECT=" $ARCH_EXT_LIST $CONFIG_LIST + $HAVE_LIST_CMDLINE $THREADS_LIST asm cross_compile debug extra_warnings - inline_asm logging optimizations - symver - yasm " PATHS_LIST=' From ca074cc3134cb81c086f54b441f0bbde4d4249e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 3 Oct 2012 19:19:37 +0300 Subject: [PATCH 07/12] xtea: Factorize testing into a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on a patch by Michael Niedermayer. Signed-off-by: Martin Storsjö --- libavutil/xtea.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/libavutil/xtea.c b/libavutil/xtea.c index 7c3a14c2be..11ae2664bb 100644 --- a/libavutil/xtea.c +++ b/libavutil/xtea.c @@ -139,6 +139,25 @@ static const uint8_t xtea_test_ct[XTEA_NUM_TESTS][8] = { { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } }; +#undef exit +static void test_xtea(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + const uint8_t *ref, int len, uint8_t *iv, int dir, + const char *test) +{ + av_xtea_crypt(ctx, dst, src, len, iv, dir); + if (memcmp(dst, ref, 8*len)) { + int i; + printf("%s failed\ngot ", test); + for (i = 0; i < 8*len; i++) + printf("%02x ", dst[i]); + printf("\nexpected "); + for (i = 0; i < 8*len; i++) + printf("%02x ", ref[i]); + printf("\n"); + exit(1); + } +} + int main(void) { AVXTEA ctx; @@ -148,17 +167,8 @@ int main(void) for (i = 0; i < XTEA_NUM_TESTS; i++) { av_xtea_init(&ctx, xtea_test_key[i]); - av_xtea_crypt(&ctx, buf, xtea_test_pt[i], 1, NULL, 0); - if (memcmp(buf, xtea_test_ct[i], 8)) { - printf("Test encryption failed.\n"); - return 1; - } - - av_xtea_crypt(&ctx, buf, xtea_test_ct[i], 1, NULL, 1); - if (memcmp(buf, xtea_test_pt[i], 8)) { - printf("Test decryption failed.\n"); - return 1; - } + test_xtea(&ctx, buf, xtea_test_pt[i], xtea_test_ct[i], 1, NULL, 0, "encryption"); + test_xtea(&ctx, buf, xtea_test_ct[i], xtea_test_pt[i], 1, NULL, 1, "decryption"); } printf("Test encryption/decryption success.\n"); From b4345004319eee35e697520ca305eb95db0669e9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 30 Sep 2012 17:46:37 +0200 Subject: [PATCH 08/12] xtea: Fix CBC decryption when src==dst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavutil/xtea.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libavutil/xtea.c b/libavutil/xtea.c index 11ae2664bb..cf63670dbe 100644 --- a/libavutil/xtea.c +++ b/libavutil/xtea.c @@ -36,7 +36,7 @@ void av_xtea_init(AVXTEA *ctx, const uint8_t key[16]) } static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, - int decrypt) + int decrypt, uint8_t *iv) { uint32_t v0, v1; int i; @@ -52,6 +52,11 @@ static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, sum -= delta; v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); } + if (iv) { + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } } else { uint32_t sum = 0, delta = 0x9E3779B9; @@ -73,13 +78,7 @@ void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, if (decrypt) { while (count--) { - xtea_crypt_ecb(ctx, dst, src, decrypt); - - if (iv) { - for (i = 0; i < 8; i++) - dst[i] = dst[i] ^ iv[i]; - memcpy(iv, src, 8); - } + xtea_crypt_ecb(ctx, dst, src, decrypt, iv); src += 8; dst += 8; @@ -89,10 +88,10 @@ void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, if (iv) { for (i = 0; i < 8; i++) dst[i] = src[i] ^ iv[i]; - xtea_crypt_ecb(ctx, dst, dst, decrypt); + xtea_crypt_ecb(ctx, dst, dst, decrypt, NULL); memcpy(iv, dst, 8); } else { - xtea_crypt_ecb(ctx, dst, src, decrypt); + xtea_crypt_ecb(ctx, dst, src, decrypt, NULL); } src += 8; dst += 8; From f0fce9f33e604544c678b6de4c29301ed4d0751f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 30 Sep 2012 17:36:01 +0200 Subject: [PATCH 09/12] xtea: Test inplace decryption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on test code by: Giorgio Vazzana Signed-off-by: Martin Storsjö --- libavutil/xtea.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libavutil/xtea.c b/libavutil/xtea.c index cf63670dbe..f3357ce544 100644 --- a/libavutil/xtea.c +++ b/libavutil/xtea.c @@ -160,14 +160,28 @@ static void test_xtea(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int main(void) { AVXTEA ctx; - uint8_t buf[8]; + uint8_t buf[8], iv[8]; int i; + const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld"; + uint8_t ct[32]; + uint8_t pl[32]; for (i = 0; i < XTEA_NUM_TESTS; i++) { av_xtea_init(&ctx, xtea_test_key[i]); test_xtea(&ctx, buf, xtea_test_pt[i], xtea_test_ct[i], 1, NULL, 0, "encryption"); test_xtea(&ctx, buf, xtea_test_ct[i], xtea_test_pt[i], 1, NULL, 1, "decryption"); + + /* encrypt */ + memcpy(iv, "HALLO123", 8); + av_xtea_crypt(&ctx, ct, src, 4, iv, 0); + + /* decrypt into pl */ + memcpy(iv, "HALLO123", 8); + test_xtea(&ctx, pl, ct, src, 4, iv, 1, "CBC decryption"); + + memcpy(iv, "HALLO123", 8); + test_xtea(&ctx, ct, ct, src, 4, iv, 1, "CBC inplace decryption"); } printf("Test encryption/decryption success.\n"); From ad11681acd59a9eb00952d07224a78bfc71c48ea Mon Sep 17 00:00:00 2001 From: Dmitry Samonenko Date: Sat, 29 Sep 2012 15:47:28 +0400 Subject: [PATCH 10/12] libspeex: Add a private option for enabling VAD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Speex detects non-speech periods and encodes them with just enough bits to reproduce the background noise, aka ``comfort noise generation''. Signed-off-by: Martin Storsjö --- libavcodec/libspeexenc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c index 38fa4cd5ca..43f84dc5f4 100644 --- a/libavcodec/libspeexenc.c +++ b/libavcodec/libspeexenc.c @@ -84,6 +84,7 @@ typedef struct { float vbr_quality; ///< VBR quality 0.0 to 10.0 int cbr_quality; ///< CBR quality 0 to 10 int abr; ///< flag to enable ABR + int vad; ///< flag to enable VAD int pkt_frame_count; ///< frame count for the current packet AudioFrameQueue afq; ///< frame queue } LibSpeexEncContext; @@ -118,6 +119,7 @@ static av_cold void print_enc_params(AVCodecContext *avctx, s->frames_per_packet); av_log(avctx, AV_LOG_DEBUG, "packet size: %d\n", avctx->frame_size * s->frames_per_packet); + av_log(avctx, AV_LOG_DEBUG, "voice activity detection: %d\n", s->vad); } static av_cold int encode_init(AVCodecContext *avctx) @@ -158,6 +160,7 @@ static av_cold int encode_init(AVCodecContext *avctx) if (avctx->flags & CODEC_FLAG_QSCALE) { /* VBR */ s->header.vbr = 1; + s->vad = 1; /* VAD is always implicitly activated for VBR */ speex_encoder_ctl(s->enc_state, SPEEX_SET_VBR, &s->header.vbr); s->vbr_quality = av_clipf(avctx->global_quality / (float)FF_QP2LAMBDA, 0.0f, 10.0f); @@ -189,6 +192,10 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->bit_rate = s->header.bitrate + (avctx->channels == 2 ? 800 : 0); } + /* VAD is activated with VBR or can be turned on by itself */ + if (s->vad) + speex_encoder_ctl(s->enc_state, SPEEX_SET_VAD, &s->vad); + /* set encoding complexity */ if (avctx->compression_level > FF_COMPRESSION_DEFAULT) { complexity = av_clip(avctx->compression_level, 0, 10); @@ -310,6 +317,7 @@ static const AVOption options[] = { { "abr", "Use average bit rate", OFFSET(abr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE }, { "cbr_quality", "Set quality value (0 to 10) for CBR", OFFSET(cbr_quality), AV_OPT_TYPE_INT, { .i64 = 8 }, 0, 10, AE }, { "frames_per_packet", "Number of frames to encode in each packet", OFFSET(frames_per_packet), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 8, AE }, + { "vad", "Voice Activity Detection", OFFSET(vad), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE }, { NULL }, }; From 3b061c5e10f78caaf3b2a45cf7a92e50d4d20bfb Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 30 Sep 2012 21:45:24 -0400 Subject: [PATCH 11/12] 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. --- libavcodec/libspeexdec.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c index a63d394731..390d4de403 100644 --- a/libavcodec/libspeexdec.c +++ b/libavcodec/libspeexdec.c @@ -39,31 +39,36 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) { LibSpeexContext *s = avctx->priv_data; const SpeexMode *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; + int spx_mode; if (avctx->extradata_size >= 80) s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size); avctx->sample_fmt = AV_SAMPLE_FMT_S16; if (s->header) { - avctx->sample_rate = s->header->rate; avctx->channels = s->header->nb_channels; s->frame_size = s->header->frame_size; - - mode = speex_lib_get_mode(s->header->mode); - if (!mode) { - av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode); - return AVERROR_INVALIDDATA; + 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; } - } else - av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n"); + } + + mode = speex_lib_get_mode(spx_mode); + if (!mode) { + av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", spx_mode); + return AVERROR_INVALIDDATA; + } + avctx->sample_rate = 8000 << spx_mode; if (avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n"); From 29abb04e73b0580ebe38703cadb988d26df6a76a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 30 Sep 2012 21:59:03 -0400 Subject: [PATCH 12/12] libspeexdec: If the channel count is not valid, decode as stereo. When initialized as stereo, libspeex can decode either mono or stereo packets and will output stereo. --- libavcodec/libspeexdec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c index 390d4de403..b9d9149ee2 100644 --- a/libavcodec/libspeexdec.c +++ b/libavcodec/libspeexdec.c @@ -70,9 +70,11 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) } avctx->sample_rate = 8000 << spx_mode; - if (avctx->channels > 2) { - av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n"); - return AVERROR(EINVAL); + if (avctx->channels < 1 || avctx->channels > 2) { + /* libspeex can handle mono or stereo if initialized as stereo */ + av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d.\n" + "Decoding as stereo.\n", avctx->channels); + avctx->channels = 2; } speex_bits_init(&s->bits);