[FFmpeg-cvslog] Gain pitch and gain code for G729D

Vladimir Voroshilov git at videolan.org
Sat Sep 24 21:17:03 CEST 2011


ffmpeg | branch: master | Vladimir Voroshilov <voroshil at gmail.com> | Sat Jun 13 00:32:54 2009 +0700| [0b42463aecff38fda35982141ccd095c9445f78f] | committer: Michael Niedermayer

Gain pitch and gain code for G729D

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=0b42463aecff38fda35982141ccd095c9445f78f
---

 libavcodec/g729data.h |   30 ++++++++++++++++++++++++++++++
 libavcodec/g729dec.c  |   30 ++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/libavcodec/g729data.h b/libavcodec/g729data.h
index d3a0c4e..c36be40 100644
--- a/libavcodec/g729data.h
+++ b/libavcodec/g729data.h
@@ -246,6 +246,36 @@ static const int16_t cb_gain_2nd_8k[1<<GC_2ND_IDX_BITS_8K][2] = { /*(1.14) (1.13
 };
 
 /**
+ * gain codebook (first stage), 6.4k mode (D.3.9.2 of G.729)
+ */
+static const int16_t cb_gain_1st_6k4[1<<GC_1ST_IDX_BITS_6K4][2] =
+{ /*(0.14) (1.14)*/
+ { 5849,     0 },
+ { 3171,  9280 },
+ { 3617,  6747 },
+ { 4987, 22294 },
+ { 2929,  1078 },
+ { 6068,  6093 },
+ { 9425,  2731 },
+ { 3915, 12872 },
+};
+
+/**
+ * gain codebook (second stage), 6.4k mode (D.3.9.2 of G.729)
+ */
+static const int16_t cb_gain_2nd_6k4[1<<GC_2ND_IDX_BITS_6K4][2] =
+{ /*(1.14) (1.14)*/
+ {    0,  4175 },
+ {10828, 27602 },
+ {16423, 15724 },
+ { 4478,  7324 },
+ { 3988,     0 },
+ {10291, 11385 },
+ {11956, 10735 },
+ { 7876,  7821 },
+};
+
+/**
  * 4th order Moving Average (MA) Predictor codebook (3.2.4 of G.729)
  *
  * float cb_ma_predictor_float[2][MA_NP][10] = {
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
index cc1948b..c5deab9 100644
--- a/libavcodec/g729dec.c
+++ b/libavcodec/g729dec.c
@@ -419,10 +419,25 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 
             gain_corr_factor = 0;
         } else {
+            if (packet_type == FORMAT_G729D_6K4) {
+                ctx->past_gain_pitch[0]  = cb_gain_1st_6k4[gc_1st_index][0] +
+                                           cb_gain_2nd_6k4[gc_2nd_index][0];
+                gain_corr_factor = cb_gain_1st_6k4[gc_1st_index][1] +
+                                   cb_gain_2nd_6k4[gc_2nd_index][1];
+
+                /* Without check below overflow can occure in ff_acelp_update_past_gain.
+                   It is not issue for G.729, because gain_corr_factor in it's case is always
+                   greater than 1024, while in G.729D it can be even zero. */
+                gain_corr_factor = FFMAX(gain_corr_factor, 1024);
+#ifndef G729_BITEXACT
+                gain_corr_factor >>= 1;
+#endif
+            } else {
             ctx->past_gain_pitch[0]  = cb_gain_1st_8k[gc_1st_index][0] +
                                        cb_gain_2nd_8k[gc_2nd_index][0];
             gain_corr_factor = cb_gain_1st_8k[gc_1st_index][1] +
                                cb_gain_2nd_8k[gc_2nd_index][1];
+            }
 
             /* Decode the fixed-codebook gain. */
             ctx->past_gain_code[0] = ff_acelp_decode_gain_code(&ctx->dsp, gain_corr_factor,
@@ -430,6 +445,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                                                                ctx->quant_energy,
                                                                ma_prediction_coeff,
                                                                SUBFRAME_SIZE, 4);
+#ifdef G729_BITEXACT
+            /*
+              This correction required to get bit-exact result with
+              reference code, because gain_corr_factor in G.729D is
+              two times larger than in original G.729.
+
+              If bit-exact result is not issue then gain_corr_factor
+              can be simpler devided by 2 before call to g729_get_gain_code
+              instead of using correction below.
+            */
+            if (packet_type == FORMAT_G729D_6K4) {
+                gain_corr_factor >>= 1;
+                ctx->past_gain_code[0] >>= 1;
+            }
+#endif
         }
         ff_acelp_update_past_gain(ctx->quant_energy, gain_corr_factor, 2, frame_erasure);
 



More information about the ffmpeg-cvslog mailing list