summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/Makefile2
-rw-r--r--libavcodec/alac.c61
-rw-r--r--libavcodec/alacdsp.c60
-rw-r--r--libavcodec/alacdsp.h33
4 files changed, 115 insertions, 41 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index b15e431d32..153c3f854e 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -143,7 +143,7 @@ OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \
ac3.o kbdwin.o
OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
OBJS-$(CONFIG_AIC_DECODER) += aic.o
-OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o
+OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o alacdsp.o
OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o alac_data.o
OBJS-$(CONFIG_ALIAS_PIX_DECODER) += aliaspixdec.o
OBJS-$(CONFIG_ALIAS_PIX_ENCODER) += aliaspixenc.o
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 1842e7b3bb..146668ec26 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -57,6 +57,7 @@
#include "unary.h"
#include "mathops.h"
#include "alac_data.h"
+#include "alacdsp.h"
#define ALAC_EXTRADATA_SIZE 36
@@ -81,6 +82,8 @@ typedef struct ALACContext {
int direct_output;
int extra_bit_bug;
+
+ ALACDSPContext dsp;
} ALACContext;
static inline unsigned int decode_scalar(GetBitContext *gb, int k, int bps)
@@ -230,35 +233,6 @@ static void lpc_prediction(int32_t *error_buffer, int32_t *buffer_out,
}
}
-static void decorrelate_stereo(int32_t *buffer[2], int nb_samples,
- int decorr_shift, int decorr_left_weight)
-{
- int i;
-
- for (i = 0; i < nb_samples; i++) {
- int32_t a, b;
-
- a = buffer[0][i];
- b = buffer[1][i];
-
- a -= (b * decorr_left_weight) >> decorr_shift;
- b += a;
-
- buffer[0][i] = b;
- buffer[1][i] = a;
- }
-}
-
-static void append_extra_bits(int32_t *buffer[2], int32_t *extra_bits_buffer[2],
- int extra_bits, int channels, int nb_samples)
-{
- int i, ch;
-
- for (ch = 0; ch < channels; ch++)
- for (i = 0; i < nb_samples; i++)
- buffer[ch][i] = (buffer[ch][i] << extra_bits) | extra_bits_buffer[ch][i];
-}
-
static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
int channels)
{
@@ -389,19 +363,24 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
decorr_left_weight = 0;
}
- if (alac->extra_bits && alac->extra_bit_bug) {
- append_extra_bits(alac->output_samples_buffer, alac->extra_bits_buffer,
- alac->extra_bits, channels, alac->nb_samples);
- }
+ if (channels == 2) {
+ if (alac->extra_bits && alac->extra_bit_bug) {
+ alac->dsp.append_extra_bits[1](alac->output_samples_buffer, alac->extra_bits_buffer,
+ alac->extra_bits, channels, alac->nb_samples);
+ }
- if (channels == 2 && decorr_left_weight) {
- decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
- decorr_shift, decorr_left_weight);
- }
+ if (decorr_left_weight) {
+ alac->dsp.decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
+ decorr_shift, decorr_left_weight);
+ }
- if (alac->extra_bits && !alac->extra_bit_bug) {
- append_extra_bits(alac->output_samples_buffer, alac->extra_bits_buffer,
- alac->extra_bits, channels, alac->nb_samples);
+ if (alac->extra_bits && !alac->extra_bit_bug) {
+ alac->dsp.append_extra_bits[1](alac->output_samples_buffer, alac->extra_bits_buffer,
+ alac->extra_bits, channels, alac->nb_samples);
+ }
+ } else if (alac->extra_bits) {
+ alac->dsp.append_extra_bits[0](alac->output_samples_buffer, alac->extra_bits_buffer,
+ alac->extra_bits, channels, alac->nb_samples);
}
switch(alac->sample_size) {
@@ -606,6 +585,8 @@ static av_cold int alac_decode_init(AVCodecContext * avctx)
return ret;
}
+ ff_alacdsp_init(&alac->dsp);
+
return 0;
}
diff --git a/libavcodec/alacdsp.c b/libavcodec/alacdsp.c
new file mode 100644
index 0000000000..608c0d8915
--- /dev/null
+++ b/libavcodec/alacdsp.c
@@ -0,0 +1,60 @@
+/*
+ * ALAC (Apple Lossless Audio Codec) decoder
+ * Copyright (c) 2005 David Hammerton
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "alacdsp.h"
+#include "config.h"
+
+static void decorrelate_stereo(int32_t *buffer[2], int nb_samples,
+ int decorr_shift, int decorr_left_weight)
+{
+ int i;
+
+ for (i = 0; i < nb_samples; i++) {
+ int32_t a, b;
+
+ a = buffer[0][i];
+ b = buffer[1][i];
+
+ a -= (b * decorr_left_weight) >> decorr_shift;
+ b += a;
+
+ buffer[0][i] = b;
+ buffer[1][i] = a;
+ }
+}
+
+static void append_extra_bits(int32_t *buffer[2], int32_t *extra_bits_buffer[2],
+ int extra_bits, int channels, int nb_samples)
+{
+ int i, ch;
+
+ for (ch = 0; ch < channels; ch++)
+ for (i = 0; i < nb_samples; i++)
+ buffer[ch][i] = (buffer[ch][i] << extra_bits) | extra_bits_buffer[ch][i];
+}
+
+av_cold void ff_alacdsp_init(ALACDSPContext *c)
+{
+ c->decorrelate_stereo = decorrelate_stereo;
+ c->append_extra_bits[0] =
+ c->append_extra_bits[1] = append_extra_bits;
+}
diff --git a/libavcodec/alacdsp.h b/libavcodec/alacdsp.h
new file mode 100644
index 0000000000..a7acdbb56a
--- /dev/null
+++ b/libavcodec/alacdsp.h
@@ -0,0 +1,33 @@
+/*
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_ALACDSP_H
+#define AVCODEC_ALACDSP_H
+
+#include <stdint.h>
+
+typedef struct ALACDSPContext {
+ void (*decorrelate_stereo)(int32_t *buffer[2], int nb_samples,
+ int decorr_shift, int decorr_left_weight);
+ void (*append_extra_bits[2])(int32_t *buffer[2], int32_t *extra_bits_buffer[2],
+ int extra_bits, int channels, int nb_samples);
+} ALACDSPContext;
+
+void ff_alacdsp_init(ALACDSPContext *c);
+
+#endif /* AVCODEC_ALACDSP_H */