Skip to content
Browse files

g722enc: set frame_size, and also handle an odd number of input samples

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.
  • Loading branch information...
1 parent 34093ba commit 77c5b66cbec5a04c846b0dd3997c898146334b60 @justinruggles justinruggles committed Jan 6, 2012
Showing with 40 additions and 6 deletions.
  1. +36 −2 libavcodec/g722enc.c
  2. +4 −4 tests/ref/acodec/g722
View
38 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},
};
View
8 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

0 comments on commit 77c5b66

Please sign in to comment.
Something went wrong with that request. Please try again.