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

Reply via email to