cngdec: Allow flushing the decoder
authorMartin Storsjö <martin@martin.st>
Tue, 30 Oct 2012 10:03:25 +0000 (12:03 +0200)
committerMartin Storsjö <martin@martin.st>
Tue, 30 Oct 2012 14:51:25 +0000 (16:51 +0200)
After a flush, don't average the output envelope and energy with
previous iterations.

Also start directly from the target values for the first iteration
at startup.

Signed-off-by: Martin Storsjö <martin@martin.st>
libavcodec/cngdec.c

index fca4b9e..4fe7839 100644 (file)
@@ -32,6 +32,7 @@ typedef struct CNGContext {
     float *lpc_coef;
     int order;
     int energy, target_energy;
+    int inited;
     float *filter_out;
     float *excitation;
     AVLFG lfg;
@@ -94,6 +95,12 @@ static void make_lpc_coefs(float *lpc, const float *refl, int order)
         memcpy(lpc, cur, sizeof(*lpc) * order);
 }
 
+static void cng_decode_flush(AVCodecContext *avctx)
+{
+    CNGContext *p = avctx->priv_data;
+    p->inited = 0;
+}
+
 static int cng_decode_frame(AVCodecContext *avctx, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
@@ -114,9 +121,15 @@ static int cng_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    p->energy = p->energy / 2 + p->target_energy / 2;
-    for (i = 0; i < p->order; i++)
-        p->refl_coef[i] = 0.6 *p->refl_coef[i] + 0.4 * p->target_refl_coef[i];
+    if (p->inited) {
+        p->energy = p->energy / 2 + p->target_energy / 2;
+        for (i = 0; i < p->order; i++)
+            p->refl_coef[i] = 0.6 *p->refl_coef[i] + 0.4 * p->target_refl_coef[i];
+    } else {
+        p->energy = p->target_energy;
+        memcpy(p->refl_coef, p->target_refl_coef, p->order * sizeof(*p->refl_coef));
+        p->inited = 1;
+    }
     make_lpc_coefs(p->lpc_coef, p->refl_coef, p->order);
 
     for (i = 0; i < p->order; i++)
@@ -154,6 +167,7 @@ AVCodec ff_comfortnoise_decoder = {
     .priv_data_size = sizeof(CNGContext),
     .init           = cng_decode_init,
     .decode         = cng_decode_frame,
+    .flush          = cng_decode_flush,
     .close          = cng_decode_close,
     .long_name      = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,