[FFmpeg-soc] [soc] G.723.1 Decoder 2420742873e9364b717e9cf298a7fb149c512b92

naufal11 at gmail.com naufal11 at gmail.com
Thu Jul 8 17:06:40 CEST 2010



- Log -----------------------------------------------------------------
commit 2420742873e9364b717e9cf298a7fb149c512b92
Author: Naufal <naufal11 at gmail.com>
Date:   Thu Jul 8 20:35:26 2010 +0530

    Add error handling code

diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index df861f4..40836c3 100755
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -15,7 +15,9 @@ typedef struct g723_1_context {
     FrameType past_frame_type;
     Rate cur_rate;
 
+    int16_t random_seed;
     int16_t interp_index;
+    int16_t interp_gain;
     int16_t sid_gain;
     int16_t cur_gain;
 } G723_1_Context;
@@ -153,6 +155,12 @@ static inline int16_t abs_16(int16_t x)
     return (v & INT16_MIN) ? INT16_MAX : v;
 }
 
+static inline int16_t prand(int16_t *rseed)
+{
+    *rseed = *rseed * 521 + 259;
+    return *rseed;
+}
+
 static inline int dot_product(const int16_t *v1, const int16_t *v2, int length)
 {
     int i, sum = 0;
@@ -647,6 +655,34 @@ static int16_t comp_interp_index(int16_t *buf, int16_t pitch_lag,
         return 0;
 }
 
+/*
+ * Peform residual interpolation based on frame classification.
+ *
+ * @param buf   decoded excitation vector
+ * @prarm out   output vector
+ * @param lag   decoded pitch lag
+ * @param gain  interpolated gain
+ * @param rseed seed for random number generator
+ */
+static void residual_interp(int16_t *buf, int16_t *out, int16_t lag,
+                            int16_t gain, int16_t *rseed)
+{
+    int i;
+    if (lag) { // Voiced
+        int16_t *vector_ptr = buf + PITCH_MAX;
+        // Attenuate
+        for (i = 0; i < lag; i++)
+            vector_ptr[i - lag] = vector_ptr[i - lag] * 0x6000 >> 15;
+        for (i = 0; i < FRAME_LEN; i++)
+            vector_ptr[i] = vector_ptr[i - lag];
+        memcpy(out, vector_ptr, FRAME_LEN * sizeof(int16_t));
+    } else {  // Unvoiced
+        for (i = 0; i < FRAME_LEN; i++)
+            out[i] = gain * prand(rseed) >> 15;
+        memset(buf, 0, (FRAME_LEN + PITCH_MAX) * sizeof(int16_t));
+    }
+}
+
 static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
                                int *data_size, AVPacket *avpkt)
 {
@@ -661,7 +697,6 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
     int16_t excitation[FRAME_LEN + PITCH_MAX];
     int16_t acb_vector[SUBFRAME_LEN];
     int16_t *vector_ptr;
-    int16_t interp_gain;
     int bad_frame = 0, erased_frames = 0, i, j;
 
     if (!buf_size || buf_size < frame_size[buf[0] & 3]) {
@@ -689,7 +724,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
         vector_ptr = excitation + PITCH_MAX;
         if (!erased_frames) {
             // Update interpolation gain memory
-            interp_gain = fixed_cb_gain[(p->subframe[2].amp_index +
+            p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index +
                                         p->subframe[3].amp_index) >> 1];
             for (i = 0; i < SUBFRAMES; i++) {
                 gen_fcb_excitation(vector_ptr, p->subframe[i], p->cur_rate,
@@ -726,6 +761,17 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
                                              vector_ptr + i + ppf[j].index,
                                              ppf[j].sc_gain, ppf[j].opt_gain,
                                              1 << 14, 15, SUBFRAME_LEN);
+        } else {
+            p->interp_gain = (p->interp_gain * 3 + 2) >> 2;
+            if (erased_frames == 3) {
+                // Mute output
+                memset(excitation, 0, (FRAME_LEN + PITCH_MAX) * sizeof(int16_t));
+                memset(out, 0, FRAME_LEN * sizeof(int16_t));
+            } else {
+                // Regenerate frame
+                residual_interp(excitation, out, p->interp_index,
+                                p->interp_gain, &p->random_seed);
+            }
         }
     }
 

commit 7662f5e1379373f827dcf623f2d39a1e53d25d99
Author: Naufal <naufal11 at gmail.com>
Date:   Thu Jul 8 15:54:04 2010 +0530

    Compute residual interpolation index

diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index 435d668..df861f4 100755
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -14,6 +14,10 @@ typedef struct g723_1_context {
     FrameType cur_frame_type;
     FrameType past_frame_type;
     Rate cur_rate;
+
+    int16_t interp_index;
+    int16_t sid_gain;
+    int16_t cur_gain;
 } G723_1_Context;
 
 static av_cold int g723_1_decode_init(AVCodecContext *avctx)
@@ -595,6 +599,54 @@ static void comp_ppf_coeff(int16_t *buf, int16_t pitch_lag, PPFParam *ppf,
     }
 }
 
+/*
+ * Classify frames as voiced/unvoiced.
+ *
+ * @param buf     decoded excitation vector
+ * @param exc_eng excitation energy estimation
+ * @param scale   scaling factor of exc_eng
+ *
+ * @return residual interpolation index if voiced, 0 otherwise
+ */
+static int16_t comp_interp_index(int16_t *buf, int16_t pitch_lag,
+                                 int16_t *exc_eng, int16_t *scale)
+{
+    int16_t index;
+    int16_t *vector_ptr;
+    int ccr, tgt_eng, best_eng;
+    int temp;
+
+    *scale     = scale_vector(buf, FRAME_LEN + PITCH_MAX);
+
+    pitch_lag  = FFMIN(PITCH_MAX - 3, pitch_lag);
+    vector_ptr = buf + PITCH_MAX + 2 * SUBFRAME_LEN;
+    index      = pitch_lag;
+
+    // Compute maximum backward cross-correlation
+    ccr   = 0;
+    index = get_ppf_lag(vector_ptr, &ccr, pitch_lag, SUBFRAME_LEN * 2, -1);
+    ccr   = av_clipl_int32((int64_t)ccr + (1 << 15)) >> 16;
+
+    // Compute target energy
+    tgt_eng   = dot_product(vector_ptr, vector_ptr, SUBFRAME_LEN * 2);
+    *exc_eng  = av_clipl_int32(tgt_eng + (1 << 15)) >> 16;
+
+    if (ccr <= 0)
+        return 0;
+
+    // Compute best energy
+    best_eng = dot_product(vector_ptr - index, vector_ptr - index,
+                           SUBFRAME_LEN * 2);
+    best_eng = av_clipl_int32((int64_t)best_eng + (1 << 15)) >> 16;
+
+    temp = best_eng * tgt_eng >> 3;
+
+    if (temp < ccr * ccr)
+        return index;
+    else
+        return 0;
+}
+
 static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
                                int *data_size, AVPacket *avpkt)
 {
@@ -655,6 +707,9 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
             // Save the excitation
             memcpy(out, excitation + PITCH_MAX, FRAME_LEN);
 
+            p->interp_index = comp_interp_index(excitation, p->pitch_lag[1],
+                                                &p->sid_gain, &p->cur_gain);
+
             vector_ptr = excitation + PITCH_MAX;
 
             for (i = 0, j = 0; i < FRAME_LEN; i += SUBFRAME_LEN, j++)

-----------------------------------------------------------------------

Summary of changes:
 libavcodec/g723_1.c |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 103 insertions(+), 2 deletions(-)


-- 
http://github.com/naufal/ffmpeg-soc


More information about the FFmpeg-soc mailing list