Commit 9a9e2f1c authored by Diego Biurrun's avatar Diego Biurrun
Browse files

dsputil: Split audio operations off into a separate context

parent ca1e36a8
......@@ -1529,6 +1529,7 @@ CONFIG_EXTRA="
aandcttables
ac3dsp
audio_frame_queue
audiodsp
blockdsp
cabac
dsputil
......@@ -1713,8 +1714,8 @@ aac_decoder_select="mdct sinewin"
aac_encoder_select="audio_frame_queue mdct sinewin"
aac_latm_decoder_select="aac_decoder aac_latm_parser"
ac3_decoder_select="mdct ac3dsp ac3_parser dsputil"
ac3_encoder_select="mdct ac3dsp dsputil"
ac3_fixed_encoder_select="mdct ac3dsp dsputil"
ac3_encoder_select="ac3dsp audiodsp dsputil mdct"
ac3_fixed_encoder_select="ac3dsp audiodsp dsputil mdct"
aic_decoder_select="dsputil golomb"
alac_encoder_select="lpc"
als_decoder_select="dsputil"
......@@ -1735,7 +1736,7 @@ binkaudio_rdft_decoder_select="mdct rdft sinewin"
cavs_decoder_select="blockdsp dsputil golomb h264chroma qpeldsp videodsp"
cllc_decoder_select="dsputil"
comfortnoise_encoder_select="lpc"
cook_decoder_select="dsputil mdct sinewin"
cook_decoder_select="audiodsp mdct sinewin"
cscd_decoder_select="lzo"
cscd_decoder_suggest="zlib"
dca_decoder_select="mdct"
......@@ -1849,7 +1850,7 @@ svq1_decoder_select="hpeldsp"
svq1_encoder_select="aandcttables dsputil hpeldsp mpegvideoenc"
svq3_decoder_select="h264_decoder hpeldsp tpeldsp"
svq3_decoder_suggest="zlib"
tak_decoder_select="dsputil"
tak_decoder_select="audiodsp"
theora_decoder_select="vp3_decoder"
thp_decoder_select="mjpeg_decoder"
tiff_decoder_suggest="zlib"
......
......@@ -28,6 +28,7 @@ OBJS = allcodecs.o \
OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o
OBJS-$(CONFIG_AC3DSP) += ac3dsp.o
OBJS-$(CONFIG_AUDIO_FRAME_QUEUE) += audio_frame_queue.o
OBJS-$(CONFIG_AUDIODSP) += audiodsp.o
OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o
OBJS-$(CONFIG_CABAC) += cabac.o
OBJS-$(CONFIG_DCT) += dct.o dct32_fixed.o dct32_float.o
......
......@@ -37,6 +37,7 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "put_bits.h"
#include "audiodsp.h"
#include "ac3dsp.h"
#include "ac3.h"
#include "fft.h"
......@@ -2480,6 +2481,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
if (ret)
goto init_fail;
ff_audiodsp_init(&s->adsp);
ff_dsputil_init(&s->dsp, avctx);
ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
......
......@@ -39,6 +39,7 @@
#include "fft.h"
#include "mathops.h"
#include "put_bits.h"
#include "audiodsp.h"
#ifndef CONFIG_AC3ENC_FLOAT
#define CONFIG_AC3ENC_FLOAT 0
......@@ -162,6 +163,7 @@ typedef struct AC3EncodeContext {
AVCodecContext *avctx; ///< parent AVCodecContext
PutBitContext pb; ///< bitstream writer context
DSPContext dsp;
AudioDSPContext adsp;
AVFloatDSPContext fdsp;
AC3DSPContext ac3dsp; ///< AC-3 optimized functions
FFTContext mdct; ///< FFT context for MDCT calculation
......
......@@ -29,6 +29,7 @@
#define FFT_FLOAT 0
#undef CONFIG_AC3ENC_FLOAT
#include "internal.h"
#include "audiodsp.h"
#include "ac3enc.h"
#include "eac3enc.h"
......@@ -100,9 +101,10 @@ static void scale_coefficients(AC3EncodeContext *s)
/*
* Clip MDCT coefficients to allowable range.
*/
static void clip_coefficients(DSPContext *dsp, int32_t *coef, unsigned int len)
static void clip_coefficients(AudioDSPContext *adsp, int32_t *coef,
unsigned int len)
{
dsp->vector_clip_int32(coef, coef, COEF_MIN, COEF_MAX, len);
adsp->vector_clip_int32(coef, coef, COEF_MIN, COEF_MAX, len);
}
......
......@@ -28,6 +28,7 @@
#define CONFIG_AC3ENC_FLOAT 1
#include "internal.h"
#include "audiodsp.h"
#include "ac3enc.h"
#include "eac3enc.h"
#include "kbdwin.h"
......@@ -107,9 +108,10 @@ static void scale_coefficients(AC3EncodeContext *s)
/*
* Clip MDCT coefficients to allowable range.
*/
static void clip_coefficients(DSPContext *dsp, float *coef, unsigned int len)
static void clip_coefficients(AudioDSPContext *adsp, float *coef,
unsigned int len)
{
dsp->vector_clipf(coef, coef, COEF_MIN, COEF_MAX, len);
adsp->vector_clipf(coef, coef, COEF_MIN, COEF_MAX, len);
}
......
......@@ -30,6 +30,8 @@
#include "libavutil/attributes.h"
#include "libavutil/internal.h"
#include "audiodsp.h"
#include "internal.h"
#include "ac3enc.h"
#include "eac3enc.h"
......@@ -40,7 +42,8 @@ static void scale_coefficients(AC3EncodeContext *s);
static int normalize_samples(AC3EncodeContext *s);
static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len);
static void clip_coefficients(AudioDSPContext *adsp, CoefType *coef,
unsigned int len);
static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl);
......@@ -161,7 +164,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
}
/* coefficients must be clipped in order to be encoded */
clip_coefficients(&s->dsp, cpl_coef, num_cpl_coefs);
clip_coefficients(&s->adsp, cpl_coef, num_cpl_coefs);
}
/* calculate energy in each band in coupling channel and each fbw channel */
......@@ -412,7 +415,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt,
if (s->fixed_point)
scale_coefficients(s);
clip_coefficients(&s->dsp, s->blocks[0].mdct_coef[1],
clip_coefficients(&s->adsp, s->blocks[0].mdct_coef[1],
AC3_MAX_COEFS * s->num_blocks * s->channels);
s->cpl_on = s->cpl_enabled;
......
......@@ -26,6 +26,7 @@
#include "avcodec.h"
#include "acelp_pitch_delay.h"
#include "celp_math.h"
#include "audiodsp.h"
int ff_acelp_decode_8bit_to_1st_delay3(int ac_index)
{
......@@ -90,7 +91,7 @@ void ff_acelp_update_past_gain(
}
int16_t ff_acelp_decode_gain_code(
DSPContext *dsp,
AudioDSPContext *adsp,
int gain_corr_factor,
const int16_t* fc_v,
int mr_energy,
......@@ -107,7 +108,7 @@ int16_t ff_acelp_decode_gain_code(
mr_energy += quant_energy[i] * ma_prediction_coeff[i];
mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) /
sqrt(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size));
sqrt(adsp->scalarproduct_int16(fc_v, fc_v, subframe_size));
return mr_energy >> 12;
}
......
......@@ -24,7 +24,8 @@
#define AVCODEC_ACELP_PITCH_DELAY_H
#include <stdint.h>
#include "dsputil.h"
#include "audiodsp.h"
#define PITCH_DELAY_MIN 20
#define PITCH_DELAY_MAX 143
......@@ -139,7 +140,7 @@ void ff_acelp_update_past_gain(
/**
* @brief Decode the adaptive codebook gain and add
* correction (4.1.5 and 3.9.1 of G.729).
* @param dsp initialized dsputil context
* @param adsp initialized audio DSP context
* @param gain_corr_factor gain correction factor (2.13)
* @param fc_v fixed-codebook vector (2.13)
* @param mr_energy mean innovation energy and fixed-point correction (7.13)
......@@ -208,7 +209,7 @@ void ff_acelp_update_past_gain(
* @remark The routine is used in G.729 and AMR (all modes).
*/
int16_t ff_acelp_decode_gain_code(
DSPContext *dsp,
AudioDSPContext *adsp,
int gain_corr_factor,
const int16_t* fc_v,
int mr_energy,
......
......@@ -4,6 +4,7 @@ OBJS += arm/fmtconvert_init_arm.o
OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o \
arm/ac3dsp_arm.o
OBJS-$(CONFIG_AUDIODSP) += arm/audiodsp_init_arm.o
OBJS-$(CONFIG_BLOCKDSP) += arm/blockdsp_init_arm.o
OBJS-$(CONFIG_DSPUTIL) += arm/dsputil_init_arm.o \
arm/dsputil_arm.o \
......@@ -77,11 +78,13 @@ VFP-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_vfp.o \
NEON-OBJS += arm/fmtconvert_neon.o
NEON-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_neon.o
NEON-OBJS-$(CONFIG_AUDIODSP) += arm/audiodsp_init_neon.o \
arm/audiodsp_neon.o \
arm/int_neon.o
NEON-OBJS-$(CONFIG_BLOCKDSP) += arm/blockdsp_init_neon.o \
arm/blockdsp_neon.o
NEON-OBJS-$(CONFIG_DSPUTIL) += arm/dsputil_init_neon.o \
arm/dsputil_neon.o \
arm/int_neon.o \
arm/simple_idct_neon.o
NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o \
arm/fft_fixed_neon.o
......
/*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_ARM_AUDIODSP_ARM_H
#define AVCODEC_ARM_AUDIODSP_ARM_H
#include "libavcodec/audiodsp.h"
void ff_audiodsp_init_neon(AudioDSPContext *c);
#endif /* AVCODEC_ARM_AUDIODSP_ARM_H */
/*
* ARM optimized audio functions
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "libavutil/arm/cpu.h"
#include "libavcodec/audiodsp.h"
#include "audiodsp_arm.h"
av_cold void ff_audiodsp_init_arm(AudioDSPContext *c)
{
int cpu_flags = av_get_cpu_flags();
if (have_neon(cpu_flags))
ff_audiodsp_init_neon(c);
}
/*
* ARM NEON optimised audio functions
* Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "libavutil/attributes.h"
#include "libavcodec/audiodsp.h"
#include "audiodsp_arm.h"
void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,
int len);
void ff_vector_clip_int32_neon(int32_t *dst, const int32_t *src, int32_t min,
int32_t max, unsigned int len);
int32_t ff_scalarproduct_int16_neon(const int16_t *v1, const int16_t *v2, int len);
av_cold void ff_audiodsp_init_neon(AudioDSPContext *c)
{
c->vector_clip_int32 = ff_vector_clip_int32_neon;
c->vector_clipf = ff_vector_clipf_neon;
c->scalarproduct_int16 = ff_scalarproduct_int16_neon;
}
/*
* ARM NEON optimised audio functions
* Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/arm/asm.S"
function ff_vector_clipf_neon, export=1
VFP vdup.32 q1, d0[1]
VFP vdup.32 q0, d0[0]
NOVFP vdup.32 q0, r2
NOVFP vdup.32 q1, r3
NOVFP ldr r2, [sp]
vld1.f32 {q2},[r1,:128]!
vmin.f32 q10, q2, q1
vld1.f32 {q3},[r1,:128]!
vmin.f32 q11, q3, q1
1: vmax.f32 q8, q10, q0
vmax.f32 q9, q11, q0
subs r2, r2, #8
beq 2f
vld1.f32 {q2},[r1,:128]!
vmin.f32 q10, q2, q1
vld1.f32 {q3},[r1,:128]!
vmin.f32 q11, q3, q1
vst1.f32 {q8},[r0,:128]!
vst1.f32 {q9},[r0,:128]!
b 1b
2: vst1.f32 {q8},[r0,:128]!
vst1.f32 {q9},[r0,:128]!
bx lr
endfunc
function ff_vector_clip_int32_neon, export=1
vdup.32 q0, r2
vdup.32 q1, r3
ldr r2, [sp]
1:
vld1.32 {q2-q3}, [r1,:128]!
vmin.s32 q2, q2, q1
vmin.s32 q3, q3, q1
vmax.s32 q2, q2, q0
vmax.s32 q3, q3, q0
vst1.32 {q2-q3}, [r0,:128]!
subs r2, r2, #8
bgt 1b
bx lr
endfunc
......@@ -34,13 +34,6 @@ void ff_add_pixels_clamped_neon(const int16_t *, uint8_t *, int);
void ff_put_pixels_clamped_neon(const int16_t *, uint8_t *, int);
void ff_put_signed_pixels_clamped_neon(const int16_t *, uint8_t *, int);
void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,
int len);
void ff_vector_clip_int32_neon(int32_t *dst, const int32_t *src, int32_t min,
int32_t max, unsigned int len);
int32_t ff_scalarproduct_int16_neon(const int16_t *v1, const int16_t *v2, int len);
av_cold void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
......@@ -57,9 +50,4 @@ av_cold void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx,
c->add_pixels_clamped = ff_add_pixels_clamped_neon;
c->put_pixels_clamped = ff_put_pixels_clamped_neon;
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon;
c->vector_clipf = ff_vector_clipf_neon;
c->vector_clip_int32 = ff_vector_clip_int32_neon;
c->scalarproduct_int16 = ff_scalarproduct_int16_neon;
}
......@@ -126,45 +126,3 @@ function ff_add_pixels_clamped_neon, export=1
vst1.8 {d6}, [r3,:64], r2
bx lr
endfunc
function ff_vector_clipf_neon, export=1
VFP vdup.32 q1, d0[1]
VFP vdup.32 q0, d0[0]
NOVFP vdup.32 q0, r2
NOVFP vdup.32 q1, r3
NOVFP ldr r2, [sp]
vld1.f32 {q2},[r1,:128]!
vmin.f32 q10, q2, q1
vld1.f32 {q3},[r1,:128]!
vmin.f32 q11, q3, q1
1: vmax.f32 q8, q10, q0
vmax.f32 q9, q11, q0
subs r2, r2, #8
beq 2f
vld1.f32 {q2},[r1,:128]!
vmin.f32 q10, q2, q1
vld1.f32 {q3},[r1,:128]!
vmin.f32 q11, q3, q1
vst1.f32 {q8},[r0,:128]!
vst1.f32 {q9},[r0,:128]!
b 1b
2: vst1.f32 {q8},[r0,:128]!
vst1.f32 {q9},[r0,:128]!
bx lr
endfunc
function ff_vector_clip_int32_neon, export=1
vdup.32 q0, r2
vdup.32 q1, r3
ldr r2, [sp]
1:
vld1.32 {q2-q3}, [r1,:128]!
vmin.s32 q2, q2, q1
vmin.s32 q3, q3, q1
vmax.s32 q2, q2, q0
vmax.s32 q3, q3, q0
vst1.32 {q2-q3}, [r0,:128]!
subs r2, r2, #8
bgt 1b
bx lr
endfunc
/*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "libavutil/attributes.h"
#include "libavutil/common.h"
#include "audiodsp.h"
static inline uint32_t clipf_c_one(uint32_t a, uint32_t mini,
uint32_t maxi, uint32_t maxisign)
{
if (a > mini)
return mini;
else if ((a ^ (1U << 31)) > maxisign)
return maxi;
else
return a;
}
static void vector_clipf_c_opposite_sign(float *dst, const float *src,
float *min, float *max, int len)
{
int i;
uint32_t mini = *(uint32_t *) min;
uint32_t maxi = *(uint32_t *) max;
uint32_t maxisign = maxi ^ (1U << 31);
uint32_t *dsti = (uint32_t *) dst;
const uint32_t *srci = (const uint32_t *) src;
for (i = 0; i < len; i += 8) {
dsti[i + 0] = clipf_c_one(srci[i + 0], mini, maxi, maxisign);
dsti[i + 1] = clipf_c_one(srci[i + 1], mini, maxi, maxisign);
dsti[i + 2] = clipf_c_one(srci[i + 2], mini, maxi, maxisign);
dsti[i + 3] = clipf_c_one(srci[i + 3], mini, maxi, maxisign);
dsti[i + 4] = clipf_c_one(srci[i + 4], mini, maxi, maxisign);
dsti[i + 5] = clipf_c_one(srci[i + 5], mini, maxi, maxisign);
dsti[i + 6] = clipf_c_one(srci[i + 6], mini, maxi, maxisign);
dsti[i + 7] = clipf_c_one(srci[i + 7], mini, maxi, maxisign);
}
}
static void vector_clipf_c(float *dst, const float *src,
float min, float max, int len)
{
int i;
if (min < 0 && max > 0) {
vector_clipf_c_opposite_sign(dst, src, &min, &max, len);
} else {
for (i = 0; i < len; i += 8) {
dst[i] = av_clipf(src[i], min, max);
dst[i + 1] = av_clipf(src[i + 1], min, max);
dst[i + 2] = av_clipf(src[i + 2], min, max);
dst[i + 3] = av_clipf(src[i + 3], min, max);
dst[i + 4] = av_clipf(src[i + 4], min, max);
dst[i + 5] = av_clipf(src[i + 5], min, max);
dst[i + 6] = av_clipf(src[i + 6], min, max);
dst[i + 7] = av_clipf(src[i + 7], min, max);
}
}
}
static int32_t scalarproduct_int16_c(const int16_t *v1, const int16_t *v2,
int order)
{
int res = 0;
while (order--)
res += *v1++ **v2++;
return res;
}
static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min,
int32_t max, unsigned int len)
{
do {
*dst++ = av_clip(*src++, min, max);
*dst++ = av_clip(*src++, min, max);
*dst++ = av_clip(*src++, min, max);
*dst++ = av_clip(*src++, min, max);
*dst++ = av_clip(*src++, min, max);
*dst++ = av_clip(*src++, min, max);
*dst++ = av_clip(*src++, min, max);
*dst++ = av_clip(*src++, min, max);
len -= 8;
} while (len > 0);
}
av_cold void ff_audiodsp_init(AudioDSPContext *c)
{
c->scalarproduct_int16 = scalarproduct_int16_c;
c->vector_clip_int32 = vector_clip_int32_c;
c->vector_clipf = vector_clipf_c;
if (ARCH_ARM)
ff_audiodsp_init_arm(c);
if (ARCH_PPC)
ff_audiodsp_init_ppc(c);
if (ARCH_X86)
ff_audiodsp_init_x86(c);
}
/*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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