The fate reference is updated because the previous test skipped a sample in each encode() call due each input frame having an odd number of samples. --- libavcodec/g722enc.c | 39 +++++++++++++++++++++++++++++++++++---- tests/ref/acodec/g722 | 8 ++++---- 2 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c index 470770c..1e6fe87 100644 --- a/libavcodec/g722enc.c +++ b/libavcodec/g722enc.c @@ -56,6 +56,30 @@ static av_cold int g722_encode_init(AVCodecContext * avctx) } } + if (avctx->frame_size) { + /* validate frame size. must be even. and values that are insanely + large lead to strange problems, so we limit the maximum value */ + if (avctx->frame_size & 1 || avctx->frame_size > 32768) { + int new_frame_size; + + if (avctx->frame_size == 1) + new_frame_size = 2; + else if (avctx->frame_size > 32768) + new_frame_size = 32768; + else + new_frame_size = avctx->frame_size - 1; + + av_log(avctx, AV_LOG_WARNING, "Requested frame size is not " + "allowed. Using %d instead of %d\n", new_frame_size, + avctx->frame_size); + avctx->frame_size = new_frame_size; + } + } else { + /* This is arbitrary. We use 320 because it's 20ms @ 16kHz, which is + a common packet size for VoIP applications */ + avctx->frame_size = 320; + } + return 0; } @@ -301,14 +325,20 @@ static int g722_encode_frame(AVCodecContext *avctx, const int16_t *samples = data; int nb_samples; - nb_samples = buf_size * 2; + nb_samples = avctx->frame_size - (avctx->frame_size & 1); if (avctx->trellis) - g722_encode_trellis(c, avctx->trellis, dst, nb_samples, samples); + g722_encode_trellis(c, avctx->trellis, dst, nb_samples, data); else - g722_encode_no_trellis(c, dst, nb_samples, samples); + g722_encode_no_trellis(c, dst, nb_samples, data); + + /* handle last frame with odd frame_size */ + if (nb_samples < avctx->frame_size) { + int16_t last_samples[2] = { samples[nb_samples], samples[nb_samples] }; + encode_byte(c, &dst[nb_samples >> 1], last_samples); + } - return buf_size; + return (avctx->frame_size + 1) >> 1; } AVCodec ff_adpcm_g722_encoder = { @@ -319,6 +349,7 @@ AVCodec ff_adpcm_g722_encoder = { .init = g722_encode_init, .close = g722_encode_close, .encode = g722_encode_frame, + .capabilities = CODEC_CAP_SMALL_LAST_FRAME, .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"), .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, }; diff --git a/tests/ref/acodec/g722 b/tests/ref/acodec/g722 index a1fc72a..6ea492a 100644 --- a/tests/ref/acodec/g722 +++ b/tests/ref/acodec/g722 @@ -1,4 +1,4 @@ -b380355e0360b4e50ee78f33fd60a0f5 *./tests/data/acodec/g722.wav -47991 ./tests/data/acodec/g722.wav -82fdd5bb059336e0550de7ba5947c5bb *./tests/data/g722.acodec.out.wav -stddev: 8860.44 PSNR: 17.38 MAXDIFF:33814 bytes: 191732/ 1058400 +1975cc4a3521e374b33ae042e182f6b6 *./tests/data/acodec/g722.wav +48053 ./tests/data/acodec/g722.wav +ade04cdcf249e6946395f109b077dd62 *./tests/data/g722.acodec.out.wav +stddev: 8841.24 PSNR: 17.40 MAXDIFF:36225 bytes: 191980/ 1058400 -- 1.7.1 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel