[FFmpeg-devel] [PATCH] 1D DCT for dsputil

Daniel Verkamp daniel
Mon Dec 21 20:02:00 CET 2009


Hi,

In an effort to get at least some parts of the Bink patch committed, I
am splitting it into separable pieces.

This is a one-dimensional floating-point DCT used by Bink audio.  The
actual code was written by Peter Ross.

The comments I myself have about this code:
- Should it be using math.h cos()/sin() or some lookup table approach?
- Can there be a test written? (I don't know enough about the math
involved to write a sane test...)

Thanks,
-- Daniel Verkamp
-------------- next part --------------
>From 8444704a0d1903aa641a7e4d6afd6d06ddf8e67c Mon Sep 17 00:00:00 2001
From: Daniel Verkamp <daniel at drv.nu>
Date: Mon, 21 Dec 2009 13:40:08 -0500
Subject: [PATCH] Add DCT to dsputil

Written by Peter Ross (pross xvid org)
---
 configure            |    2 +
 libavcodec/Makefile  |    1 +
 libavcodec/dct.c     |   95 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/dsputil.h |   18 +++++++++
 4 files changed, 116 insertions(+), 0 deletions(-)
 create mode 100644 libavcodec/dct.c

diff --git a/configure b/configure
index 7b85fa8..623c10a 100755
--- a/configure
+++ b/configure
@@ -99,6 +99,7 @@ Configuration options:
   --disable-fastdiv        disable table-based division
   --enable-small           optimize for size instead of speed
   --disable-aandct         disable AAN DCT code
+  --disable-dct            disable DCT code
   --disable-fft            disable FFT code
   --disable-golomb         disable Golomb code
   --disable-lpc            disable LPC code
@@ -826,6 +827,7 @@ CONFIG_LIST="
     avisynth
     beos_netserver
     bzlib
+    dct
     doc
     fastdiv
     ffmpeg
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f865d53..d00502d 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -27,6 +27,7 @@ OBJS = allcodecs.o                                                      \
 # parts needed for many different codecs
 OBJS-$(CONFIG_AANDCT)                  += aandcttab.o
 OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
+OBJS-$(CONFIG_DCT)                     += dct.o
 FFT-OBJS-$(CONFIG_HARDCODED_TABLES)    += cos_tables.o
 OBJS-$(CONFIG_FFT)                     += fft.o $(FFT-OBJS-yes)
 OBJS-$(CONFIG_GOLOMB)                  += golomb.o
diff --git a/libavcodec/dct.c b/libavcodec/dct.c
new file mode 100644
index 0000000..806b4ea
--- /dev/null
+++ b/libavcodec/dct.c
@@ -0,0 +1,95 @@
+/*
+ * (I)DCT Transforms
+ * Copyright (c) 2009 Peter Ross (pross at xvid.org)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/**
+ * @file libavcodec/dct.c
+ * (Inverse) Discrete Cosine Transforms
+ */
+
+#include <math.h>
+#include "dsputil.h"
+
+av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse)
+{
+    int n = 1 << nbits;
+
+    s->nbits    = nbits;
+    s->inverse  = inverse;
+
+    s->data = av_malloc(sizeof(FFTComplex) * 2 * n);
+    if (!s->data)
+        return -1;
+
+    if (ff_fft_init(&s->fft, nbits+1, inverse) < 0)
+        return -1;
+
+    return 0;
+}
+
+static void ff_dct_calc_c(DCTContext *s, FFTSample *data)
+{
+    int n = 1<<s->nbits;
+    int i;
+
+#define ROTATE(i,n) (-M_PI*((n)-0.5f)*(i)/(n))
+    if (s->inverse) {
+        for(i=0; i < n; i++) {
+            s->data[i].re = 2 * data[i] * cos(ROTATE(i,n));
+            s->data[i].im = 2 * data[i] * sin(ROTATE(i,n));
+        }
+        s->data[n].re = 0;
+        s->data[n].im = 0;
+        for(i=0; i<n-1; i++) {
+            s->data[n+i+1].re = -2 * data[n - (i+1)] * cos(ROTATE(n+i+1,n));
+            s->data[n+i+1].im = -2 * data[n - (i+1)] * sin(ROTATE(n+i+1,n));
+        }
+    }else{
+        for(i=0; i < n; i++) {
+            s->data[i].re = data[n - (i+1)];
+            s->data[i].im = 0;
+            s->data[n+i].re = data[i];
+            s->data[n+i].im = 0;
+        }
+    }
+
+    ff_fft_permute(&s->fft, s->data);
+    ff_fft_calc(&s->fft, s->data);
+
+    if (s->inverse) {
+        for(i=0; i < n; i++)
+            data[i] = s->data[n-(i+1)].re / (2 * n);
+    }else {
+        for(i=0; i < n; i++)
+            data[i] = s->data[i].re / (2 * cos(ROTATE(i,n)));
+    }
+#undef ROTATE
+}
+
+void ff_dct_calc(DCTContext *s, FFTSample *data)
+{
+    ff_dct_calc_c(s, data);
+}
+
+av_cold void ff_dct_end(DCTContext *s)
+{
+    ff_fft_end(&s->fft);
+    av_free(s->data);
+}
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index e483276..83359b5 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -891,6 +891,24 @@ int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans);
 void ff_rdft_calc(RDFTContext *s, FFTSample *data);
 void ff_rdft_end(RDFTContext *s);
 
+/* Discrete Cosine Transform */
+
+typedef struct {
+    int nbits;
+    int inverse;
+    FFTComplex *data;
+    FFTContext fft;
+} DCTContext;
+
+/**
+ * Sets up (Inverse)DCT.
+ * @param nbits           log2 of the length of the input array
+ * @param inverse         >0 forward transform, <0 inverse transform
+ */
+int ff_dct_init(DCTContext *s, int nbits, int inverse);
+void ff_dct_calc(DCTContext *s, FFTSample *data);
+void ff_dct_end(DCTContext *s);
+
 #define WRAPPER8_16(name8, name16)\
 static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
     return name8(s, dst           , src           , stride, h)\
-- 
1.6.6.rc3



More information about the ffmpeg-devel mailing list