avcodec/idctdsp: Transmit studio_profile to init instead of using AVCodecContext...
[ffmpeg.git] / libavcodec / evrcdec.c
index 12af5a0..8728c02 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
@@ -66,7 +67,10 @@ typedef struct EVRCAFrame {
 } EVRCAFrame;
 
 typedef struct EVRCContext {
-    AVFrame          avframe;
+    AVClass *class;
+
+    int              postfilter;
+
     GetBitContext    gb;
     evrc_packet_rate bitrate;
     evrc_packet_rate last_valid_bitrate;
@@ -230,9 +234,6 @@ static av_cold int evrc_decode_init(AVCodecContext *avctx)
     int i, n, idx = 0;
     float denom = 2.0 / (2.0 * 8.0 + 1.0);
 
-    avcodec_get_frame_defaults(&e->avframe);
-    avctx->coded_frame = &e->avframe;
-
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;
@@ -280,7 +281,7 @@ static av_cold int evrc_decode_init(AVCodecContext *avctx)
  */
 static int decode_lspf(EVRCContext *e)
 {
-    const float **codebooks = evrc_lspq_codebooks[e->bitrate];
+    const float * const *codebooks = evrc_lspq_codebooks[e->bitrate];
     int i, j, k = 0;
 
     for (i = 0; i < evrc_lspq_nb_codebooks[e->bitrate]; i++) {
@@ -378,7 +379,7 @@ static void bl_intrp(EVRCContext *e, float *ex, float delay)
     int offset, i, coef_idx;
     int16_t t;
 
-    offset = lrintf(fabs(delay));
+    offset = lrintf(delay);
 
     t = (offset - delay + 0.5) * 8.0 + 0.5;
     if (t == 8) {
@@ -644,7 +645,7 @@ static void postfilter(EVRCContext *e, float *in, const float *coeff,
     /* Short term postfilter */
     synthesis_filter(temp, wcoef2, e->postfilter_iir, length, out);
 
-    memcpy(e->postfilter_residual,
+    memmove(e->postfilter_residual,
            e->postfilter_residual + length, ACB_SIZE * sizeof(float));
 }
 
@@ -718,7 +719,7 @@ static void frame_erasure(EVRCContext *e, float *samples)
                 e->pitch[ACB_SIZE + j] = e->energy_vector[i];
         }
 
-        memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
+        memmove(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
 
         if (e->bitrate != RATE_QUANT && e->avg_acb_gain < 0.4) {
             f = 0.1 * e->avg_fcb_gain;
@@ -742,16 +743,17 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
+    AVFrame *frame     = data;
     EVRCContext *e     = avctx->priv_data;
     int buf_size       = avpkt->size;
     float ilspf[FILTER_ORDER], ilpc[FILTER_ORDER], idelay[NB_SUBFRAMES];
     float *samples;
     int   i, j, ret, error_flag = 0;
 
-    e->avframe.nb_samples = 160;
-    if ((ret = ff_get_buffer(avctx, &e->avframe)) < 0)
+    frame->nb_samples = 160;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
-    samples = (float *)e->avframe.data[0];
+    samples = (float *)frame->data[0];
 
     if ((e->bitrate = determine_bitrate(avctx, &buf_size, &buf)) == RATE_ERRS) {
         warn_insufficient_frame_quality(avctx, "bitrate cannot be determined.");
@@ -763,7 +765,8 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data,
                                  && !e->prev_error_flag)
         goto erasure;
 
-    init_get_bits(&e->gb, buf, 8 * buf_size);
+    if ((ret = init_get_bits8(&e->gb, buf, buf_size)) < 0)
+        return ret;
     memset(&e->frame, 0, sizeof(EVRCAFrame));
 
     unpack_frame(e);
@@ -776,7 +779,8 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data,
         }
         if (i == sizeof(EVRCAFrame))
             goto erasure;
-    } else if (e->frame.lsp[0] == e->frame.lsp[1] == 0xf &&
+    } else if (e->frame.lsp[0] == 0xf &&
+               e->frame.lsp[1] == 0xf &&
                e->frame.energy_gain == 0xff) {
         goto erasure;
     }
@@ -816,7 +820,7 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data,
 
                 interpolate_delay(idelay, delay, e->prev_pitch_delay, i);
                 acb_excitation(e, e->pitch + ACB_SIZE, e->avg_acb_gain, idelay, subframe_size);
-                memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
+                memmove(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
             }
         }
 
@@ -874,12 +878,14 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data,
                 e->pitch[ACB_SIZE + j] = e->energy_vector[i];
         }
 
-        memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
+        memmove(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float));
 
         synthesis_filter(e->pitch + ACB_SIZE, ilpc,
-                         e->synthesis, subframe_size, tmp);
-        postfilter(e, tmp, ilpc, samples, pitch_lag,
-                   &postfilter_coeffs[e->bitrate], subframe_size);
+                         e->synthesis, subframe_size,
+                         e->postfilter ? tmp : samples);
+        if (e->postfilter)
+            postfilter(e, tmp, ilpc, samples, pitch_lag,
+                       &postfilter_coeffs[e->bitrate], subframe_size);
 
         samples += subframe_size;
     }
@@ -898,23 +904,38 @@ erasure:
     if (e->bitrate != RATE_QUANT)
         e->prev_pitch_delay = e->pitch_delay;
 
-    samples = (float *)e->avframe.data[0];
+    samples = (float *)frame->data[0];
     for (i = 0; i < 160; i++)
         samples[i] /= 32768;
 
     *got_frame_ptr   = 1;
-    *(AVFrame *)data = e->avframe;
 
     return avpkt->size;
 }
 
+#define OFFSET(x) offsetof(EVRCContext, x)
+#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+    { "postfilter", "enable postfilter", OFFSET(postfilter), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AD },
+    { NULL }
+};
+
+static const AVClass evrcdec_class = {
+    .class_name = "evrc",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_evrc_decoder = {
     .name           = "evrc",
+    .long_name      = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_EVRC,
     .init           = evrc_decode_init,
     .decode         = evrc_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = AV_CODEC_CAP_DR1,
     .priv_data_size = sizeof(EVRCContext),
-    .long_name      = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"),
+    .priv_class     = &evrcdec_class,
 };