On Sat, 7 Jan 2012, Justin Ruggles wrote:

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  |   38 ++++++++++++++++++++++++++++++++++++--
tests/ref/acodec/g722 |    8 ++++----
2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c
index 470770c..ceb18b4 100644
--- a/libavcodec/g722enc.c
+++ b/libavcodec/g722enc.c
@@ -32,6 +32,10 @@

#define FREEZE_INTERVAL 128

+/* This is an arbitrary value. Allowing insanely large values leads to strange
+   problems, so we limit it to a reasonable value */
+#define MAX_FRAME_SIZE 32768
+
static av_cold int g722_encode_init(AVCodecContext * avctx)
{
    G722Context *c = avctx->priv_data;
@@ -56,6 +60,29 @@ static av_cold int g722_encode_init(AVCodecContext * avctx)
        }
    }

+    if (avctx->frame_size) {
+        /* validate frame size */
+        if (avctx->frame_size & 1 || avctx->frame_size > MAX_FRAME_SIZE) {
+            int new_frame_size;
+
+            if (avctx->frame_size == 1)
+                new_frame_size = 2;
+            else if (avctx->frame_size > MAX_FRAME_SIZE)
+                new_frame_size = MAX_FRAME_SIZE;
+            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 +328,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);
    else
        g722_encode_no_trellis(c, dst, nb_samples, samples);

-    return buf_size;
+    /* 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 (avctx->frame_size + 1) >> 1;
}

AVCodec ff_adpcm_g722_encoder = {
@@ -319,6 +352,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

Looks good to me, as does 3/3, and the earlier 1/3.

// Martin
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to