]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/g723_1.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / g723_1.c
index c7f6ac9301e242c731ac486a828990b0c02b25b1..c4016f8112f564cc72e3e6f3c2b405ba43863542 100644 (file)
@@ -35,7 +35,6 @@
 #include "acelp_vectors.h"
 #include "celp_filters.h"
 #include "celp_math.h"
-#include "lsp.h"
 #include "g723_1_data.h"
 
 typedef struct g723_1_context {
@@ -52,7 +51,7 @@ typedef struct g723_1_context {
 
     int16_t prev_lsp[LPC_ORDER];
     int16_t prev_excitation[PITCH_MAX];
-    int16_t excitation[PITCH_MAX + FRAME_LEN];
+    int16_t excitation[PITCH_MAX + FRAME_LEN + 4];
     int16_t synth_mem[LPC_ORDER];
     int16_t fir_mem[LPC_ORDER];
     int     iir_mem[LPC_ORDER];
@@ -65,8 +64,8 @@ typedef struct g723_1_context {
     int reflection_coef;
     int pf_gain;                 ///< formant postfilter
                                  ///< gain scaling unit memory
-
     int postfilter;
+    int16_t audio[FRAME_LEN + LPC_ORDER];
     int16_t prev_data[HALF_FRAME_LEN];
     int16_t prev_weight_sig[PITCH_MAX];
 
@@ -264,11 +263,14 @@ static int scale_vector(int16_t *vector, int length)
     for (i = 0; i < length; i++)
         max = FFMAX(max, FFABS(vector[i]));
 
+    max   = FFMIN(max, 0x7FFF);
     bits  = normalize_bits(max, 15);
     scale = shift_table[bits];
 
-    for (i = 0; i < length; i++)
+    for (i = 0; i < length; i++) {
+        av_assert2(av_clipl_int32(vector[i] * (int64_t)scale << 1) == vector[i] * (int64_t)scale << 1);
         vector[i] = (vector[i] * scale) >> 3;
+    }
 
     return bits - 3;
 }
@@ -592,7 +594,10 @@ static int autocorr_max(G723_1_Context *p, int offset, int *ccr_max,
     int i;
 
     pitch_lag = FFMIN(PITCH_MAX - 3, pitch_lag);
-    limit     = FFMIN(FRAME_LEN + PITCH_MAX - offset - length, pitch_lag + 3);
+    if (dir > 0)
+        limit = FFMIN(FRAME_LEN + PITCH_MAX - offset - length, pitch_lag + 3);
+    else
+        limit = pitch_lag + 3;
 
     for (i = pitch_lag - 3; i <= limit; i++) {
         ccr = ff_dot_product(buf, buf + dir * i, length)<<1;
@@ -908,6 +913,7 @@ static void formant_postfilter(G723_1_Context *p, int16_t *lpc, int16_t *buf)
         }
         iir_filter(filter_coef[0], filter_coef[1], buf + i,
                    filter_signal + i, 1);
+        lpc += LPC_ORDER;
     }
 
     memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(int16_t));
@@ -917,7 +923,7 @@ static void formant_postfilter(G723_1_Context *p, int16_t *lpc, int16_t *buf)
     signal_ptr = filter_signal + LPC_ORDER;
     for (i = 0; i < SUBFRAMES; i++) {
         int16_t temp_vector[SUBFRAME_LEN];
-        int16_t temp;
+        int temp;
         int auto_corr[2];
         int scale, energy;
 
@@ -936,13 +942,12 @@ static void formant_postfilter(G723_1_Context *p, int16_t *lpc, int16_t *buf)
         if (temp) {
             temp = (auto_corr[0] >> 2) / temp;
         }
-        p->reflection_coef = ((p->reflection_coef << 2) - p->reflection_coef +
-                              temp + 2) >> 2;
-        temp = (p->reflection_coef * 0xffffc >> 3) & 0xfffc;
+        p->reflection_coef = (3 * p->reflection_coef + temp + 2) >> 2;
+        temp = -p->reflection_coef >> 1 & ~3;
 
         /* Compensation filter */
         for (j = 0; j < SUBFRAME_LEN; j++) {
-            buf_ptr[j] = av_clipl_int32(signal_ptr[j] +
+            buf_ptr[j] = av_clipl_int32((int64_t)signal_ptr[j] +
                                         ((signal_ptr[j - 1] >> 16) *
                                          temp << 1)) >> 16;
         }
@@ -967,7 +972,6 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
     G723_1_Context *p  = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    int16_t *out;
     int dec_mode       = buf[0] & 3;
 
     PPFParam ppf[SUBFRAMES];
@@ -975,9 +979,14 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
     int16_t lpc[SUBFRAMES * LPC_ORDER];
     int16_t acb_vector[SUBFRAME_LEN];
     int16_t *vector_ptr;
+    int16_t *out;
     int bad_frame = 0, i, j, ret;
 
-    if (!buf_size || buf_size < frame_size[dec_mode]) {
+    if (buf_size < frame_size[dec_mode]) {
+        if (buf_size)
+            av_log(avctx, AV_LOG_WARNING,
+                   "Expected %d bytes, got %d - skipping packet\n",
+                   frame_size[dec_mode], buf_size);
         *got_frame_ptr = 0;
         return buf_size;
     }
@@ -990,13 +999,13 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
             p->cur_frame_type = UNTRANSMITTED_FRAME;
     }
 
-    p->frame.nb_samples = FRAME_LEN + LPC_ORDER;
+    p->frame.nb_samples = FRAME_LEN;
     if ((ret = avctx->get_buffer(avctx, &p->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out= (int16_t*)p->frame.data[0];
 
+    out = (int16_t *)p->frame.data[0];
 
     if (p->cur_frame_type == ACTIVE_FRAME) {
         if (!bad_frame)
@@ -1036,7 +1045,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
             vector_ptr = p->excitation + PITCH_MAX;
 
             /* Save the excitation */
-            memcpy(out, vector_ptr, FRAME_LEN * sizeof(int16_t));
+            memcpy(p->audio + LPC_ORDER, vector_ptr, FRAME_LEN * sizeof(*p->audio));
 
             p->interp_index = comp_interp_index(p, p->pitch_lag[1],
                                                 &p->sid_gain, &p->cur_gain);
@@ -1051,27 +1060,29 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
             /* Restore the original excitation */
             memcpy(p->excitation, p->prev_excitation,
                    PITCH_MAX * sizeof(*p->excitation));
-            memcpy(vector_ptr, out, FRAME_LEN * sizeof(*vector_ptr));
+            memcpy(vector_ptr, p->audio + LPC_ORDER, FRAME_LEN * sizeof(*vector_ptr));
 
             /* Peform pitch postfiltering */
             if (p->postfilter)
                 for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
-                    ff_acelp_weighted_vector_sum(out + LPC_ORDER + i,
+                    ff_acelp_weighted_vector_sum(p->audio + LPC_ORDER + i,
                                                  vector_ptr + i,
                                                  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 (p->erased_frames == 3) {
                 /* Mute output */
                 memset(p->excitation, 0,
                        (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation));
-                memset(out, 0, (FRAME_LEN + LPC_ORDER) * sizeof(int16_t));
+                memset(p->frame.data[0], 0,
+                       (FRAME_LEN + LPC_ORDER) * sizeof(int16_t));
             } else {
                 /* Regenerate frame */
-                residual_interp(p->excitation, out + LPC_ORDER, p->interp_index,
+                residual_interp(p->excitation, p->audio + LPC_ORDER, p->interp_index,
                                 p->interp_gain, &p->random_seed);
             }
         }
@@ -1079,28 +1090,34 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
         memcpy(p->prev_excitation, p->excitation + FRAME_LEN,
                PITCH_MAX * sizeof(*p->excitation));
     } else {
-        memset(out, 0, sizeof(int16_t)*FRAME_LEN);
+        memset(out, 0, FRAME_LEN * 2);
         av_log(avctx, AV_LOG_WARNING,
                "G.723.1: Comfort noise generation not supported yet\n");
+
+        *got_frame_ptr   = 1;
+        *(AVFrame *)data = p->frame;
         return frame_size[dec_mode];
     }
 
     p->past_frame_type = p->cur_frame_type;
 
-    memcpy(out, p->synth_mem, LPC_ORDER * sizeof(int16_t));
+    memcpy(p->audio, p->synth_mem, LPC_ORDER * sizeof(*p->audio));
     for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
-        ff_celp_lp_synthesis_filter(out + i, &lpc[j * LPC_ORDER],
-                                    out + i, SUBFRAME_LEN, LPC_ORDER,
+        ff_celp_lp_synthesis_filter(p->audio + i, &lpc[j * LPC_ORDER],
+                                    p->audio + i, SUBFRAME_LEN, LPC_ORDER,
                                     0, 1, 1 << 12);
-    memcpy(p->synth_mem, out + FRAME_LEN, LPC_ORDER * sizeof(int16_t));
+    memcpy(p->synth_mem, p->audio + FRAME_LEN, LPC_ORDER * sizeof(*p->audio));
 
-    if (p->postfilter)
-        formant_postfilter(p, lpc, out);
+    if (p->postfilter) {
+        formant_postfilter(p, lpc, p->audio);
+        memcpy(p->frame.data[0], p->audio + LPC_ORDER, FRAME_LEN * 2);
+    } else { // if output is not postfiltered it should be scaled by 2
+        for (i = 0; i < FRAME_LEN; i++)
+            out[i] = av_clip_int16(p->audio[LPC_ORDER + i] << 1);
+    }
 
-    memmove(out, out + LPC_ORDER, sizeof(int16_t)*FRAME_LEN);
-    p->frame.nb_samples = FRAME_LEN;
-    *(AVFrame*)data = p->frame;
-    *got_frame_ptr = 1;
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = p->frame;
 
     return frame_size[dec_mode];
 }
@@ -1114,6 +1131,7 @@ static const AVOption options[] = {
     { NULL }
 };
 
+
 static const AVClass g723_1dec_class = {
     .class_name = "G.723.1 decoder",
     .item_name  = av_default_item_name,
@@ -1124,7 +1142,7 @@ static const AVClass g723_1dec_class = {
 AVCodec ff_g723_1_decoder = {
     .name           = "g723_1",
     .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = CODEC_ID_G723_1,
+    .id             = AV_CODEC_ID_G723_1,
     .priv_data_size = sizeof(G723_1_Context),
     .init           = g723_1_decode_init,
     .decode         = g723_1_decode_frame,
@@ -2259,7 +2277,7 @@ static int g723_1_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 AVCodec ff_g723_1_encoder = {
     .name           = "g723_1",
     .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = CODEC_ID_G723_1,
+    .id             = AV_CODEC_ID_G723_1,
     .priv_data_size = sizeof(G723_1_Context),
     .init           = g723_1_encode_init,
     .encode2        = g723_1_encode_frame,