1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

avcodec/dca: remove old decoder

Remove all files and functions which are not going to be reused,
and disable all functions and FATE tests temporarily which will be.
This commit is contained in:
foo86 2016-01-16 11:07:08 +03:00 committed by Hendrik Leppkes
parent b552f3afa2
commit 4608996772
29 changed files with 17 additions and 5064 deletions

1
configure vendored
View File

@ -2271,7 +2271,6 @@ comfortnoise_encoder_select="lpc"
cook_decoder_select="audiodsp mdct sinewin"
cscd_decoder_select="lzo"
cscd_decoder_suggest="zlib"
dca_decoder_select="fmtconvert mdct"
dds_decoder_select="texturedsp"
dirac_decoder_select="dirac_parse dwt golomb videodsp mpegvideoenc"
dnxhd_decoder_select="blockdsp idctdsp"

View File

@ -222,9 +222,6 @@ OBJS-$(CONFIG_COMFORTNOISE_ENCODER) += cngenc.o
OBJS-$(CONFIG_CPIA_DECODER) += cpia.o
OBJS-$(CONFIG_CSCD_DECODER) += cscd.o
OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadsp.o \
dcadata.o dca_exss.o \
dca_xll.o synth_filter.o
OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o
OBJS-$(CONFIG_DDS_DECODER) += dds.o
OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o \

View File

@ -1,5 +1,4 @@
OBJS-$(CONFIG_DCA_DECODER) += aarch64/dcadsp_init.o \
aarch64/synth_filter_init.o
#OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_init.o
OBJS-$(CONFIG_FFT) += aarch64/fft_init_aarch64.o
OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_init.o
OBJS-$(CONFIG_H264CHROMA) += aarch64/h264chroma_init_aarch64.o
@ -18,8 +17,7 @@ OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_init.o
ARMV8-OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp.o
NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/dcadsp_neon.o \
aarch64/synth_filter_neon.o
#NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_neon.o
NEON-OBJS-$(CONFIG_FFT) += aarch64/fft_neon.o
NEON-OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_neon.o
NEON-OBJS-$(CONFIG_H264CHROMA) += aarch64/h264cmc_neon.o

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
*
* 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 "config.h"
#include "libavutil/aarch64/cpu.h"
#include "libavutil/attributes.h"
#include "libavutil/internal.h"
#include "libavcodec/dcadsp.h"
void ff_dca_lfe_fir0_neon(float *out, const float *in, const float *coefs);
void ff_dca_lfe_fir1_neon(float *out, const float *in, const float *coefs);
av_cold void ff_dcadsp_init_aarch64(DCADSPContext *s)
{
int cpu_flags = av_get_cpu_flags();
if (have_neon(cpu_flags)) {
s->lfe_fir[0] = ff_dca_lfe_fir0_neon;
s->lfe_fir[1] = ff_dca_lfe_fir1_neon;
}
}

View File

@ -1,109 +0,0 @@
/*
* Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
* Copyright (c) 2015 Janne Grunau <janne-libav@jannau.net>
*
* 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/aarch64/asm.S"
function ff_dca_lfe_fir0_neon, export=1
mov x3, #32 // decifactor
sub x1, x1, #7*4
add x4, x0, #2*32*4 - 16 // out2
mov x7, #-16
ld1 {v0.4s,v1.4s}, [x1]
// reverse [-num_coeffs + 1, 0]
ext v3.16b, v0.16b, v0.16b, #8
ext v2.16b, v1.16b, v1.16b, #8
rev64 v3.4s, v3.4s
rev64 v2.4s, v2.4s
1:
ld1 {v4.4s,v5.4s}, [x2], #32
ld1 {v6.4s,v7.4s}, [x2], #32
subs x3, x3, #4
fmul v16.4s, v2.4s, v4.4s
fmul v23.4s, v0.4s, v4.4s
fmul v17.4s, v2.4s, v6.4s
fmul v22.4s, v0.4s, v6.4s
fmla v16.4s, v3.4s, v5.4s
fmla v23.4s, v1.4s, v5.4s
ld1 {v4.4s,v5.4s}, [x2], #32
fmla v17.4s, v3.4s, v7.4s
fmla v22.4s, v1.4s, v7.4s
ld1 {v6.4s,v7.4s}, [x2], #32
fmul v18.4s, v2.4s, v4.4s
fmul v21.4s, v0.4s, v4.4s
fmul v19.4s, v2.4s, v6.4s
fmul v20.4s, v0.4s, v6.4s
fmla v18.4s, v3.4s, v5.4s
fmla v21.4s, v1.4s, v5.4s
fmla v19.4s, v3.4s, v7.4s
fmla v20.4s, v1.4s, v7.4s
faddp v16.4s, v16.4s, v17.4s
faddp v18.4s, v18.4s, v19.4s
faddp v20.4s, v20.4s, v21.4s
faddp v22.4s, v22.4s, v23.4s
faddp v16.4s, v16.4s, v18.4s
faddp v20.4s, v20.4s, v22.4s
st1 {v16.4s}, [x0], #16
st1 {v20.4s}, [x4], x7
b.gt 1b
ret
endfunc
function ff_dca_lfe_fir1_neon, export=1
mov x3, #64 // decifactor
sub x1, x1, #3*4
add x4, x0, #2*64*4 - 16 // out2
mov x7, #-16
ld1 {v0.4s}, [x1]
// reverse [-num_coeffs + 1, 0]
ext v1.16b, v0.16b, v0.16b, #8
rev64 v1.4s, v1.4s
1:
ld1 {v4.4s,v5.4s}, [x2], #32
ld1 {v6.4s,v7.4s}, [x2], #32
subs x3, x3, #4
fmul v16.4s, v1.4s, v4.4s
fmul v23.4s, v0.4s, v4.4s
fmul v17.4s, v1.4s, v5.4s
fmul v22.4s, v0.4s, v5.4s
fmul v18.4s, v1.4s, v6.4s
fmul v21.4s, v0.4s, v6.4s
fmul v19.4s, v1.4s, v7.4s
fmul v20.4s, v0.4s, v7.4s
faddp v16.4s, v16.4s, v17.4s
faddp v18.4s, v18.4s, v19.4s
faddp v20.4s, v20.4s, v21.4s
faddp v22.4s, v22.4s, v23.4s
faddp v16.4s, v16.4s, v18.4s
faddp v20.4s, v20.4s, v22.4s
st1 {v16.4s}, [x0], #16
st1 {v20.4s}, [x4], x7
b.gt 1b
ret
endfunc

View File

@ -391,7 +391,7 @@ void avcodec_register_all(void)
REGISTER_DECODER(BINKAUDIO_RDFT, binkaudio_rdft);
REGISTER_DECODER(BMV_AUDIO, bmv_audio);
REGISTER_DECODER(COOK, cook);
REGISTER_ENCDEC (DCA, dca);
REGISTER_ENCODER(DCA, dca);
REGISTER_DECODER(DSD_LSBF, dsd_lsbf);
REGISTER_DECODER(DSD_MSBF, dsd_msbf);
REGISTER_DECODER(DSD_LSBF_PLANAR, dsd_lsbf_planar);

View File

@ -36,8 +36,7 @@ OBJS-$(CONFIG_VP8DSP) += arm/vp8dsp_init_arm.o
# decoders/encoders
OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_init_arm.o \
arm/sbrdsp_init_arm.o
OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o \
arm/synth_filter_init_arm.o
#OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_init_arm.o
OBJS-$(CONFIG_HEVC_DECODER) += arm/hevcdsp_init_arm.o
OBJS-$(CONFIG_MLP_DECODER) += arm/mlpdsp_init_arm.o
OBJS-$(CONFIG_RV40_DECODER) += arm/rv40dsp_init_arm.o
@ -88,8 +87,7 @@ VFP-OBJS-$(CONFIG_FMTCONVERT) += arm/fmtconvert_vfp.o
VFP-OBJS-$(CONFIG_MDCT) += arm/mdct_vfp.o
# decoders/encoders
VFP-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_vfp.o \
arm/synth_filter_vfp.o
#VFP-OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_vfp.o
# NEON optimizations
@ -128,8 +126,7 @@ NEON-OBJS-$(CONFIG_VP8DSP) += arm/vp8dsp_init_neon.o \
NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_neon.o \
arm/sbrdsp_neon.o
NEON-OBJS-$(CONFIG_LLAUDDSP) += arm/lossless_audiodsp_neon.o
NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \
arm/synth_filter_neon.o
#NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_neon.o
NEON-OBJS-$(CONFIG_HEVC_DECODER) += arm/hevcdsp_init_neon.o \
arm/hevcdsp_deblock_neon.o \
arm/hevcdsp_idct_neon.o \

View File

@ -24,7 +24,6 @@
#include <stdint.h>
#include "config.h"
#include "libavcodec/dcadsp.h"
#include "libavcodec/mathops.h"
#if HAVE_ARMV6_INLINE && AV_GCC_VERSION_AT_LEAST(4,4) && !CONFIG_THUMB

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
*
* 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 "config.h"
#include "libavutil/arm/cpu.h"
#include "libavutil/attributes.h"
#include "libavcodec/dcadsp.h"
void ff_dca_lfe_fir0_neon(float *out, const float *in, const float *coefs);
void ff_dca_lfe_fir1_neon(float *out, const float *in, const float *coefs);
void ff_dca_lfe_fir32_vfp(float *out, const float *in, const float *coefs);
void ff_dca_lfe_fir64_vfp(float *out, const float *in, const float *coefs);
void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act,
SynthFilterContext *synth, FFTContext *imdct,
float synth_buf_ptr[512],
int *synth_buf_offset, float synth_buf2[32],
const float window[512], float *samples_out,
float raXin[32], float scale);
av_cold void ff_dcadsp_init_arm(DCADSPContext *s)
{
int cpu_flags = av_get_cpu_flags();
if (have_vfp_vm(cpu_flags)) {
s->lfe_fir[0] = ff_dca_lfe_fir32_vfp;
s->lfe_fir[1] = ff_dca_lfe_fir64_vfp;
s->qmf_32_subbands = ff_dca_qmf_32_subbands_vfp;
}
if (have_neon(cpu_flags)) {
s->lfe_fir[0] = ff_dca_lfe_fir0_neon;
s->lfe_fir[1] = ff_dca_lfe_fir1_neon;
}
}

View File

@ -1,64 +0,0 @@
/*
* Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
*
* 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/arm/asm.S"
function ff_dca_lfe_fir0_neon, export=1
push {r4-r6,lr}
mov r3, #32 @ decifactor
mov r6, #256/32
b dca_lfe_fir
endfunc
function ff_dca_lfe_fir1_neon, export=1
push {r4-r6,lr}
mov r3, #64 @ decifactor
mov r6, #256/64
dca_lfe_fir:
add r4, r0, r3, lsl #2 @ out2
add r5, r2, #256*4-16 @ cf1
sub r1, r1, #12
mov lr, #-16
1:
vmov.f32 q2, #0.0 @ v0
vmov.f32 q3, #0.0 @ v1
mov r12, r6
2:
vld1.32 {q8}, [r2,:128]! @ cf0
vld1.32 {q9}, [r5,:128], lr @ cf1
vld1.32 {q1}, [r1], lr @ in
subs r12, r12, #4
vrev64.32 q10, q8
vmla.f32 q3, q1, q9
vmla.f32 d4, d2, d21
vmla.f32 d5, d3, d20
bne 2b
add r1, r1, r6, lsl #2
subs r3, r3, #1
vadd.f32 d4, d4, d5
vadd.f32 d6, d6, d7
vpadd.f32 d5, d4, d6
vst1.32 {d5[0]}, [r0,:32]!
vst1.32 {d5[1]}, [r4,:32]!
bne 1b
pop {r4-r6,pc}
endfunc

View File

@ -1,476 +0,0 @@
/*
* Copyright (c) 2013 RISC OS Open Ltd
* Author: Ben Avison <bavison@riscosopen.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 Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/arm/asm.S"
POUT .req a1
PIN .req a2
PCOEF .req a3
OLDFPSCR .req a4
COUNTER .req ip
IN0 .req s4
IN1 .req s5
IN2 .req s6
IN3 .req s7
IN4 .req s0
IN5 .req s1
IN6 .req s2
IN7 .req s3
COEF0 .req s8 @ coefficient elements
COEF1 .req s9
COEF2 .req s10
COEF3 .req s11
COEF4 .req s12
COEF5 .req s13
COEF6 .req s14
COEF7 .req s15
ACCUM0 .req s16 @ double-buffered multiply-accumulate results
ACCUM4 .req s20
POST0 .req s24 @ do long-latency post-multiply in this vector in parallel
POST1 .req s25
POST2 .req s26
POST3 .req s27
.macro inner_loop decifactor, dir, tail, head
.ifc "\dir","up"
.set X, 0
.set Y, 4
.else
.set X, 4*JMAX*4 - 4
.set Y, -4
.endif
.ifnc "\head",""
vldr COEF0, [PCOEF, #X + (0*JMAX + 0) * Y]
vldr COEF1, [PCOEF, #X + (1*JMAX + 0) * Y]
vldr COEF2, [PCOEF, #X + (2*JMAX + 0) * Y]
vldr COEF3, [PCOEF, #X + (3*JMAX + 0) * Y]
.endif
.ifnc "\tail",""
vadd.f POST0, ACCUM0, ACCUM4 @ vector operation
.endif
.ifnc "\head",""
vmul.f ACCUM0, COEF0, IN0 @ vector = vector * scalar
vldr COEF4, [PCOEF, #X + (0*JMAX + 1) * Y]
vldr COEF5, [PCOEF, #X + (1*JMAX + 1) * Y]
vldr COEF6, [PCOEF, #X + (2*JMAX + 1) * Y]
.endif
.ifnc "\head",""
vldr COEF7, [PCOEF, #X + (3*JMAX + 1) * Y]
.ifc "\tail",""
vmul.f ACCUM4, COEF4, IN1 @ vector operation
.endif
vldr COEF0, [PCOEF, #X + (0*JMAX + 2) * Y]
vldr COEF1, [PCOEF, #X + (1*JMAX + 2) * Y]
.ifnc "\tail",""
vmul.f ACCUM4, COEF4, IN1 @ vector operation
.endif
vldr COEF2, [PCOEF, #X + (2*JMAX + 2) * Y]
vldr COEF3, [PCOEF, #X + (3*JMAX + 2) * Y]
.endif
.ifnc "\tail",""
vstmia POUT!, {POST0-POST3}
.endif
.ifnc "\head",""
vmla.f ACCUM0, COEF0, IN2 @ vector = vector * scalar
vldr COEF4, [PCOEF, #X + (0*JMAX + 3) * Y]
vldr COEF5, [PCOEF, #X + (1*JMAX + 3) * Y]
vldr COEF6, [PCOEF, #X + (2*JMAX + 3) * Y]
vldr COEF7, [PCOEF, #X + (3*JMAX + 3) * Y]
vmla.f ACCUM4, COEF4, IN3 @ vector = vector * scalar
.if \decifactor == 32
vldr COEF0, [PCOEF, #X + (0*JMAX + 4) * Y]
vldr COEF1, [PCOEF, #X + (1*JMAX + 4) * Y]
vldr COEF2, [PCOEF, #X + (2*JMAX + 4) * Y]
vldr COEF3, [PCOEF, #X + (3*JMAX + 4) * Y]
vmla.f ACCUM0, COEF0, IN4 @ vector = vector * scalar
vldr COEF4, [PCOEF, #X + (0*JMAX + 5) * Y]
vldr COEF5, [PCOEF, #X + (1*JMAX + 5) * Y]
vldr COEF6, [PCOEF, #X + (2*JMAX + 5) * Y]
vldr COEF7, [PCOEF, #X + (3*JMAX + 5) * Y]
vmla.f ACCUM4, COEF4, IN5 @ vector = vector * scalar
vldr COEF0, [PCOEF, #X + (0*JMAX + 6) * Y]
vldr COEF1, [PCOEF, #X + (1*JMAX + 6) * Y]
vldr COEF2, [PCOEF, #X + (2*JMAX + 6) * Y]
vldr COEF3, [PCOEF, #X + (3*JMAX + 6) * Y]
vmla.f ACCUM0, COEF0, IN6 @ vector = vector * scalar
vldr COEF4, [PCOEF, #X + (0*JMAX + 7) * Y]
vldr COEF5, [PCOEF, #X + (1*JMAX + 7) * Y]
vldr COEF6, [PCOEF, #X + (2*JMAX + 7) * Y]
vldr COEF7, [PCOEF, #X + (3*JMAX + 7) * Y]
vmla.f ACCUM4, COEF4, IN7 @ vector = vector * scalar
.endif
.endif
.endm
.macro dca_lfe_fir decifactor
function ff_dca_lfe_fir\decifactor\()_vfp, export=1
fmrx OLDFPSCR, FPSCR
ldr ip, =0x03030000 @ RunFast mode, short vectors of length 4, stride 1
fmxr FPSCR, ip
vldr IN0, [PIN, #-0*4]
vldr IN1, [PIN, #-1*4]
vldr IN2, [PIN, #-2*4]
vldr IN3, [PIN, #-3*4]
.if \decifactor == 32
.set JMAX, 8
vpush {s16-s31}
vldr IN4, [PIN, #-4*4]
vldr IN5, [PIN, #-5*4]
vldr IN6, [PIN, #-6*4]
vldr IN7, [PIN, #-7*4]
.else
.set JMAX, 4
vpush {s16-s27}
.endif
mov COUNTER, #\decifactor/4 - 1
inner_loop \decifactor, up,, head
1: add PCOEF, PCOEF, #4*JMAX*4
subs COUNTER, COUNTER, #1
inner_loop \decifactor, up, tail, head
bne 1b
inner_loop \decifactor, up, tail
mov COUNTER, #\decifactor/4 - 1
inner_loop \decifactor, down,, head
1: sub PCOEF, PCOEF, #4*JMAX*4
subs COUNTER, COUNTER, #1
inner_loop \decifactor, down, tail, head
bne 1b
inner_loop \decifactor, down, tail
.if \decifactor == 32
vpop {s16-s31}
.else
vpop {s16-s27}
.endif
fmxr FPSCR, OLDFPSCR
bx lr
endfunc
.endm
dca_lfe_fir 64
.ltorg
dca_lfe_fir 32
.unreq POUT
.unreq PIN
.unreq PCOEF
.unreq OLDFPSCR
.unreq COUNTER
.unreq IN0
.unreq IN1
.unreq IN2
.unreq IN3
.unreq IN4
.unreq IN5
.unreq IN6
.unreq IN7
.unreq COEF0
.unreq COEF1
.unreq COEF2
.unreq COEF3
.unreq COEF4
.unreq COEF5
.unreq COEF6
.unreq COEF7
.unreq ACCUM0
.unreq ACCUM4
.unreq POST0
.unreq POST1
.unreq POST2
.unreq POST3
IN .req a1
SBACT .req a2
OLDFPSCR .req a3
IMDCT .req a4
WINDOW .req v1
OUT .req v2
BUF .req v3
SCALEINT .req v4 @ only used in softfp case
COUNT .req v5
SCALE .req s0
/* Stack layout differs in softfp and hardfp cases:
*
* hardfp
* fp -> 6 arg words saved by caller
* a3,a4,v1-v3,v5,fp,lr on entry (a3 just to pad to 8 bytes)
* s16-s23 on entry
* align 16
* buf -> 8*32*4 bytes buffer
* s0 on entry
* sp -> 3 arg words for callee
*
* softfp
* fp -> 7 arg words saved by caller
* a4,v1-v5,fp,lr on entry
* s16-s23 on entry
* align 16
* buf -> 8*32*4 bytes buffer
* sp -> 4 arg words for callee
*/
/* void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act,
* SynthFilterContext *synth, FFTContext *imdct,
* float (*synth_buf_ptr)[512],
* int *synth_buf_offset, float (*synth_buf2)[32],
* const float (*window)[512], float *samples_out,
* float (*raXin)[32], float scale);
*/
function ff_dca_qmf_32_subbands_vfp, export=1
VFP push {a3-a4,v1-v3,v5,fp,lr}
NOVFP push {a4,v1-v5,fp,lr}
add fp, sp, #8*4
vpush {s16-s23}
@ The buffer pointed at by raXin isn't big enough for us to do a
@ complete matrix transposition as we want to, so allocate an
@ alternative buffer from the stack. Align to 4 words for speed.
sub BUF, sp, #8*32*4
bic BUF, BUF, #15
mov sp, BUF
ldr lr, =0x03330000 @ RunFast mode, short vectors of length 4, stride 2
fmrx OLDFPSCR, FPSCR
fmxr FPSCR, lr
@ COUNT is used to count down 2 things at once:
@ bits 0-4 are the number of word pairs remaining in the output row
@ bits 5-31 are the number of words to copy (with possible negation)
@ from the source matrix before we start zeroing the remainder
mov COUNT, #(-4 << 5) + 16
adds COUNT, COUNT, SBACT, lsl #5
bmi 2f
1:
vldr s8, [IN, #(0*8+0)*4]
vldr s10, [IN, #(0*8+1)*4]
vldr s12, [IN, #(0*8+2)*4]
vldr s14, [IN, #(0*8+3)*4]
vldr s16, [IN, #(0*8+4)*4]
vldr s18, [IN, #(0*8+5)*4]
vldr s20, [IN, #(0*8+6)*4]
vldr s22, [IN, #(0*8+7)*4]
vneg.f s8, s8
vldr s9, [IN, #(1*8+0)*4]
vldr s11, [IN, #(1*8+1)*4]
vldr s13, [IN, #(1*8+2)*4]
vldr s15, [IN, #(1*8+3)*4]
vneg.f s16, s16
vldr s17, [IN, #(1*8+4)*4]
vldr s19, [IN, #(1*8+5)*4]
vldr s21, [IN, #(1*8+6)*4]
vldr s23, [IN, #(1*8+7)*4]
vstr d4, [BUF, #(0*32+0)*4]
vstr d5, [BUF, #(1*32+0)*4]
vstr d6, [BUF, #(2*32+0)*4]
vstr d7, [BUF, #(3*32+0)*4]
vstr d8, [BUF, #(4*32+0)*4]
vstr d9, [BUF, #(5*32+0)*4]
vstr d10, [BUF, #(6*32+0)*4]
vstr d11, [BUF, #(7*32+0)*4]
vldr s9, [IN, #(3*8+0)*4]
vldr s11, [IN, #(3*8+1)*4]
vldr s13, [IN, #(3*8+2)*4]
vldr s15, [IN, #(3*8+3)*4]
vldr s17, [IN, #(3*8+4)*4]
vldr s19, [IN, #(3*8+5)*4]
vldr s21, [IN, #(3*8+6)*4]
vldr s23, [IN, #(3*8+7)*4]
vneg.f s9, s9
vldr s8, [IN, #(2*8+0)*4]
vldr s10, [IN, #(2*8+1)*4]
vldr s12, [IN, #(2*8+2)*4]
vldr s14, [IN, #(2*8+3)*4]
vneg.f s17, s17
vldr s16, [IN, #(2*8+4)*4]
vldr s18, [IN, #(2*8+5)*4]
vldr s20, [IN, #(2*8+6)*4]
vldr s22, [IN, #(2*8+7)*4]
vstr d4, [BUF, #(0*32+2)*4]
vstr d5, [BUF, #(1*32+2)*4]
vstr d6, [BUF, #(2*32+2)*4]
vstr d7, [BUF, #(3*32+2)*4]
vstr d8, [BUF, #(4*32+2)*4]
vstr d9, [BUF, #(5*32+2)*4]
vstr d10, [BUF, #(6*32+2)*4]
vstr d11, [BUF, #(7*32+2)*4]
add IN, IN, #4*8*4
add BUF, BUF, #4*4
subs COUNT, COUNT, #(4 << 5) + 2
bpl 1b
2: @ Now deal with trailing < 4 samples
adds COUNT, COUNT, #3 << 5
bmi 4f @ sb_act was a multiple of 4
bics lr, COUNT, #0x1F
bne 3f
@ sb_act was n*4+1
vldr s8, [IN, #(0*8+0)*4]
vldr s10, [IN, #(0*8+1)*4]
vldr s12, [IN, #(0*8+2)*4]
vldr s14, [IN, #(0*8+3)*4]
vldr s16, [IN, #(0*8+4)*4]
vldr s18, [IN, #(0*8+5)*4]
vldr s20, [IN, #(0*8+6)*4]
vldr s22, [IN, #(0*8+7)*4]
vneg.f s8, s8
vldr s9, zero
vldr s11, zero
vldr s13, zero
vldr s15, zero
vneg.f s16, s16
vldr s17, zero
vldr s19, zero
vldr s21, zero
vldr s23, zero
vstr d4, [BUF, #(0*32+0)*4]
vstr d5, [BUF, #(1*32+0)*4]
vstr d6, [BUF, #(2*32+0)*4]
vstr d7, [BUF, #(3*32+0)*4]
vstr d8, [BUF, #(4*32+0)*4]
vstr d9, [BUF, #(5*32+0)*4]
vstr d10, [BUF, #(6*32+0)*4]
vstr d11, [BUF, #(7*32+0)*4]
add BUF, BUF, #2*4
sub COUNT, COUNT, #1
b 4f
3: @ sb_act was n*4+2 or n*4+3, so do the first 2
vldr s8, [IN, #(0*8+0)*4]
vldr s10, [IN, #(0*8+1)*4]
vldr s12, [IN, #(0*8+2)*4]
vldr s14, [IN, #(0*8+3)*4]
vldr s16, [IN, #(0*8+4)*4]
vldr s18, [IN, #(0*8+5)*4]
vldr s20, [IN, #(0*8+6)*4]
vldr s22, [IN, #(0*8+7)*4]
vneg.f s8, s8
vldr s9, [IN, #(1*8+0)*4]
vldr s11, [IN, #(1*8+1)*4]
vldr s13, [IN, #(1*8+2)*4]
vldr s15, [IN, #(1*8+3)*4]
vneg.f s16, s16
vldr s17, [IN, #(1*8+4)*4]
vldr s19, [IN, #(1*8+5)*4]
vldr s21, [IN, #(1*8+6)*4]
vldr s23, [IN, #(1*8+7)*4]
vstr d4, [BUF, #(0*32+0)*4]
vstr d5, [BUF, #(1*32+0)*4]
vstr d6, [BUF, #(2*32+0)*4]
vstr d7, [BUF, #(3*32+0)*4]
vstr d8, [BUF, #(4*32+0)*4]
vstr d9, [BUF, #(5*32+0)*4]
vstr d10, [BUF, #(6*32+0)*4]
vstr d11, [BUF, #(7*32+0)*4]
add BUF, BUF, #2*4
sub COUNT, COUNT, #(2 << 5) + 1
bics lr, COUNT, #0x1F
bne 4f
@ sb_act was n*4+3
vldr s8, [IN, #(2*8+0)*4]
vldr s10, [IN, #(2*8+1)*4]
vldr s12, [IN, #(2*8+2)*4]
vldr s14, [IN, #(2*8+3)*4]
vldr s16, [IN, #(2*8+4)*4]
vldr s18, [IN, #(2*8+5)*4]
vldr s20, [IN, #(2*8+6)*4]
vldr s22, [IN, #(2*8+7)*4]
vldr s9, zero
vldr s11, zero
vldr s13, zero
vldr s15, zero
vldr s17, zero
vldr s19, zero
vldr s21, zero
vldr s23, zero
vstr d4, [BUF, #(0*32+0)*4]
vstr d5, [BUF, #(1*32+0)*4]
vstr d6, [BUF, #(2*32+0)*4]
vstr d7, [BUF, #(3*32+0)*4]
vstr d8, [BUF, #(4*32+0)*4]
vstr d9, [BUF, #(5*32+0)*4]
vstr d10, [BUF, #(6*32+0)*4]
vstr d11, [BUF, #(7*32+0)*4]
add BUF, BUF, #2*4
sub COUNT, COUNT, #1
4: @ Now fill the remainder with 0
vldr s8, zero
vldr s9, zero
ands COUNT, COUNT, #0x1F
beq 6f
5: vstr d4, [BUF, #(0*32+0)*4]
vstr d4, [BUF, #(1*32+0)*4]
vstr d4, [BUF, #(2*32+0)*4]
vstr d4, [BUF, #(3*32+0)*4]
vstr d4, [BUF, #(4*32+0)*4]
vstr d4, [BUF, #(5*32+0)*4]
vstr d4, [BUF, #(6*32+0)*4]
vstr d4, [BUF, #(7*32+0)*4]
add BUF, BUF, #2*4
subs COUNT, COUNT, #1
bne 5b
6:
fmxr FPSCR, OLDFPSCR
ldr WINDOW, [fp, #3*4]
ldr OUT, [fp, #4*4]
sub BUF, BUF, #32*4
NOVFP ldr SCALEINT, [fp, #6*4]
mov COUNT, #8
VFP vpush {SCALE}
VFP sub sp, sp, #3*4
NOVFP sub sp, sp, #4*4
7:
VFP ldr a1, [fp, #-7*4] @ imdct
NOVFP ldr a1, [fp, #-8*4]
ldmia fp, {a2-a4}
VFP stmia sp, {WINDOW, OUT, BUF}
NOVFP stmia sp, {WINDOW, OUT, BUF, SCALEINT}
VFP vldr SCALE, [sp, #3*4]
bl X(ff_synth_filter_float_vfp)
add OUT, OUT, #32*4
add BUF, BUF, #32*4
subs COUNT, COUNT, #1
bne 7b
A sub sp, fp, #(8+8)*4
T sub fp, fp, #(8+8)*4
T mov sp, fp
vpop {s16-s23}
VFP pop {a3-a4,v1-v3,v5,fp,pc}
NOVFP pop {a4,v1-v5,fp,pc}
endfunc
.unreq IN
.unreq SBACT
.unreq OLDFPSCR
.unreq IMDCT
.unreq WINDOW
.unreq OUT
.unreq BUF
.unreq SCALEINT
.unreq COUNT
.unreq SCALE
.align 2
zero: .word 0

View File

@ -27,282 +27,8 @@
#include <stdint.h>
#include "libavutil/float_dsp.h"
#include "libavutil/internal.h"
#include "avcodec.h"
#include "dcadsp.h"
#include "fmtconvert.h"
#include "get_bits.h"
#define DCA_PRIM_CHANNELS_MAX (7)
#define DCA_ABITS_MAX (32) /* Should be 28 */
#define DCA_SUBSUBFRAMES_MAX (4)
#define DCA_SUBFRAMES_MAX (16)
#define DCA_BLOCKS_MAX (16)
#define DCA_LFE_MAX (3)
#define DCA_CHSETS_MAX (4)
#define DCA_CHSET_CHANS_MAX (8)
#define DCA_PRIM_CHANNELS_MAX (7)
#define DCA_ABITS_MAX (32) /* Should be 28 */
#define DCA_SUBSUBFRAMES_MAX (4)
#define DCA_SUBFRAMES_MAX (16)
#define DCA_BLOCKS_MAX (16)
#define DCA_LFE_MAX (3)
#define DCA_XLL_FBANDS_MAX (4)
#define DCA_XLL_SEGMENTS_MAX (16)
#define DCA_XLL_CHSETS_MAX (16)
#define DCA_XLL_CHANNELS_MAX (16)
#define DCA_XLL_AORDER_MAX (15)
/* Arbitrary limit; not sure what the maximum really is, but much larger. */
#define DCA_XLL_DMIX_NCOEFFS_MAX (18)
#define DCA_MAX_FRAME_SIZE 16384
#define DCA_MAX_EXSS_HEADER_SIZE 4096
#define DCA_BUFFER_PADDING_SIZE 1024
enum DCAExtensionMask {
DCA_EXT_CORE = 0x001, ///< core in core substream
DCA_EXT_XXCH = 0x002, ///< XXCh channels extension in core substream
DCA_EXT_X96 = 0x004, ///< 96/24 extension in core substream
DCA_EXT_XCH = 0x008, ///< XCh channel extension in core substream
DCA_EXT_EXSS_CORE = 0x010, ///< core in ExSS (extension substream)
DCA_EXT_EXSS_XBR = 0x020, ///< extended bitrate extension in ExSS
DCA_EXT_EXSS_XXCH = 0x040, ///< XXCh channels extension in ExSS
DCA_EXT_EXSS_X96 = 0x080, ///< 96/24 extension in ExSS
DCA_EXT_EXSS_LBR = 0x100, ///< low bitrate component in ExSS
DCA_EXT_EXSS_XLL = 0x200, ///< lossless extension in ExSS
};
typedef struct XllChSetSubHeader {
int channels; ///< number of channels in channel set, at most 16
int residual_encode; ///< residual channel encoding
int bit_resolution; ///< input sample bit-width
int bit_width; ///< original input sample bit-width
int sampling_frequency; ///< sampling frequency
int samp_freq_interp; ///< sampling frequency interpolation multiplier
int replacement_set; ///< replacement channel set group
int active_replace_set; ///< current channel set is active channel set
int primary_ch_set;
int downmix_coeff_code_embedded;
int downmix_embedded;
int downmix_type;
int hier_chset; ///< hierarchical channel set
int downmix_ncoeffs;
int downmix_coeffs[DCA_XLL_DMIX_NCOEFFS_MAX];
int ch_mask_enabled;
int ch_mask;
int mapping_coeffs_present;
int num_freq_bands;
/* m_nOrigChanOrder */
uint8_t orig_chan_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
uint8_t orig_chan_order_inv[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
/* Coefficients for channel pairs (at most 8), m_anPWChPairsCoeffs */
int8_t pw_ch_pairs_coeffs[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX/2];
/* m_nCurrHighestLPCOrder */
uint8_t adapt_order_max[DCA_XLL_FBANDS_MAX];
/* m_pnAdaptPredOrder */
uint8_t adapt_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
/* m_pnFixedPredOrder */
uint8_t fixed_order[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
/* m_pnLPCReflCoeffsQInd, unsigned version */
uint8_t lpc_refl_coeffs_q_ind[DCA_XLL_FBANDS_MAX]
[DCA_XLL_CHANNELS_MAX][DCA_XLL_AORDER_MAX];
int lsb_fsize[DCA_XLL_FBANDS_MAX];
int8_t scalable_lsbs[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
int8_t bit_width_adj_per_ch[DCA_XLL_FBANDS_MAX][DCA_XLL_CHANNELS_MAX];
} XllChSetSubHeader;
typedef struct XllNavi {
GetBitContext gb; // Context for parsing the data segments
unsigned band_size[DCA_XLL_FBANDS_MAX];
unsigned segment_size[DCA_XLL_FBANDS_MAX][DCA_XLL_SEGMENTS_MAX];
unsigned chset_size[DCA_XLL_FBANDS_MAX][DCA_XLL_SEGMENTS_MAX][DCA_XLL_CHSETS_MAX];
} XllNavi;
typedef struct QMF64_table {
float dct4_coeff[32][32];
float dct2_coeff[32][32];
float rcos[32];
float rsin[32];
} QMF64_table;
/* Primary audio coding header */
typedef struct DCAAudioHeader {
int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count
int vq_start_subband[DCA_PRIM_CHANNELS_MAX]; ///< high frequency vq start subband
int joint_intensity[DCA_PRIM_CHANNELS_MAX]; ///< joint intensity coding index
int transient_huffman[DCA_PRIM_CHANNELS_MAX]; ///< transient mode code book
int scalefactor_huffman[DCA_PRIM_CHANNELS_MAX]; ///< scale factor code book
int bitalloc_huffman[DCA_PRIM_CHANNELS_MAX]; ///< bit allocation quantizer select
int quant_index_huffman[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< quantization index codebook select
uint32_t scalefactor_adj[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< scale factor adjustment
int subframes; ///< number of subframes
int total_channels; ///< number of channels including extensions
int prim_channels; ///< number of primary audio channels
} DCAAudioHeader;
typedef struct DCAChan {
DECLARE_ALIGNED(32, int32_t, subband_samples)[DCA_BLOCKS_MAX][DCA_SUBBANDS][SAMPLES_PER_SUBBAND];
/* Subband samples history (for ADPCM) */
DECLARE_ALIGNED(32, int32_t, subband_samples_hist)[DCA_SUBBANDS][4];
int hist_index;
/* Half size is sufficient for core decoding, but for 96 kHz data
* we need QMF with 64 subbands and 1024 samples. */
DECLARE_ALIGNED(32, float, subband_fir_hist)[1024];
DECLARE_ALIGNED(32, float, subband_fir_noidea)[64];
/* Primary audio coding side information */
int prediction_mode[DCA_SUBBANDS]; ///< prediction mode (ADPCM used or not)
int prediction_vq[DCA_SUBBANDS]; ///< prediction VQ coefs
int bitalloc[DCA_SUBBANDS]; ///< bit allocation index
int transition_mode[DCA_SUBBANDS]; ///< transition mode (transients)
int32_t scale_factor[DCA_SUBBANDS][2];///< scale factors (2 if transient)
int joint_huff; ///< joint subband scale factors codebook
int joint_scale_factor[DCA_SUBBANDS]; ///< joint subband scale factors
int32_t high_freq_vq[DCA_SUBBANDS]; ///< VQ encoded high frequency subbands
} DCAChan;
typedef struct DCAContext {
const AVClass *class; ///< class for AVOptions
AVCodecContext *avctx;
/* Frame header */
int frame_type; ///< type of the current frame
int samples_deficit; ///< deficit sample count
int crc_present; ///< crc is present in the bitstream
int sample_blocks; ///< number of PCM sample blocks
int frame_size; ///< primary frame byte size
int amode; ///< audio channels arrangement
int sample_rate; ///< audio sampling rate
int bit_rate; ///< transmission bit rate
int bit_rate_index; ///< transmission bit rate index
int dynrange; ///< embedded dynamic range flag
int timestamp; ///< embedded time stamp flag
int aux_data; ///< auxiliary data flag
int hdcd; ///< source material is mastered in HDCD
int ext_descr; ///< extension audio descriptor flag
int ext_coding; ///< extended coding flag
int aspf; ///< audio sync word insertion flag
int lfe; ///< low frequency effects flag
int predictor_history; ///< predictor history flag
int header_crc; ///< header crc check bytes
int multirate_inter; ///< multirate interpolator switch
int version; ///< encoder software revision
int copy_history; ///< copy history
int source_pcm_res; ///< source pcm resolution
int front_sum; ///< front sum/difference flag
int surround_sum; ///< surround sum/difference flag
int dialog_norm; ///< dialog normalisation parameter
/* Primary audio coding header */
DCAAudioHeader audio_header;
/* Primary audio coding side information */
int subsubframes[DCA_SUBFRAMES_MAX]; ///< number of subsubframes
int partial_samples[DCA_SUBFRAMES_MAX]; ///< partial subsubframe samples count
float downmix_coef[DCA_PRIM_CHANNELS_MAX + 1][2]; ///< stereo downmix coefficients
int dynrange_coef; ///< dynamic range coefficient
/* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1)
* Input: primary audio channels (incl. LFE if present)
* Output: downmix audio channels (up to 4, no LFE) */
uint8_t core_downmix; ///< embedded downmix coefficients available
uint8_t core_downmix_amode; ///< audio channel arrangement of embedded downmix
uint16_t core_downmix_codes[DCA_PRIM_CHANNELS_MAX + 1][4]; ///< embedded downmix coefficients (9-bit codes)
float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data
int lfe_scale_factor;
/* Subband samples history (for ADPCM) */
DECLARE_ALIGNED(32, float, raXin)[32];
DCAChan dca_chan[DCA_PRIM_CHANNELS_MAX];
int output; ///< type of output
float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1];
float *extra_channels[DCA_PRIM_CHANNELS_MAX + 1];
uint8_t *extra_channels_buffer;
unsigned int extra_channels_buffer_size;
uint8_t dca_buffer[DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE + DCA_BUFFER_PADDING_SIZE];
int dca_buffer_size; ///< how much data is in the dca_buffer
const int8_t *channel_order_tab; ///< channel reordering table, lfe and non lfe
GetBitContext gb;
/* Current position in DCA frame */
int current_subframe;
int current_subsubframe;
int core_ext_mask; ///< present extensions in the core substream
int exss_ext_mask; ///< Non-core extensions
/* XCh extension information */
int xch_present; ///< XCh extension present and valid
int xch_base_channel; ///< index of first (only) channel containing XCH data
int xch_disable; ///< whether the XCh extension should be decoded or not
/* XXCH extension information */
int xxch_chset;
int xxch_nbits_spk_mask;
uint32_t xxch_core_spkmask;
uint32_t xxch_spk_masks[4]; /* speaker masks, last element is core mask */
int xxch_chset_nch[4];
float xxch_dmix_sf[DCA_CHSETS_MAX];
uint32_t xxch_dmix_embedded; /* lower layer has mix pre-embedded, per chset */
float xxch_dmix_coeff[DCA_PRIM_CHANNELS_MAX][32]; /* worst case sizing */
int8_t xxch_order_tab[32];
int8_t lfe_index;
/* XLL extension information */
int xll_disable;
int xll_nch_sets; ///< number of channel sets per frame
int xll_channels; ///< total number of channels (in all channel sets)
int xll_residual_channels; ///< number of residual channels
int xll_segments; ///< number of segments per frame
int xll_log_smpl_in_seg; ///< supposedly this is "nBits4SamplLoci"
int xll_smpl_in_seg; ///< samples in segment per one frequency band for the first channel set
int xll_bits4seg_size; ///< number of bits used to read segment size
int xll_banddata_crc; ///< presence of CRC16 within each frequency band
int xll_scalable_lsb;
int xll_bits4ch_mask; ///< channel position mask
int xll_fixed_lsb_width;
XllChSetSubHeader xll_chsets[DCA_XLL_CHSETS_MAX];
XllNavi xll_navi;
int *xll_sample_buf;
unsigned int xll_sample_buf_size;
/* ExSS header parser */
int static_fields; ///< static fields present
int mix_metadata; ///< mixing metadata present
int num_mix_configs; ///< number of mix out configurations
int mix_config_num_ch[4]; ///< number of channels in each mix out configuration
int profile;
int one2one_map_chtospkr;
int debug_flag; ///< used for suppressing repeated error messages output
AVFloatDSPContext *fdsp;
FFTContext imdct;
SynthFilterContext synth;
DCADSPContext dcadsp;
QMF64_table *qmf64_table;
FmtConvertContext fmt_conv;
} DCAContext;
#include "libavutil/intreadwrite.h"
extern av_export const uint32_t avpriv_dca_sample_rates[16];
@ -310,15 +36,6 @@ extern av_export const uint32_t avpriv_dca_sample_rates[16];
* Convert bitstream to one representation based on sync marker
*/
int avpriv_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
int max_size);
int ff_dca_xbr_parse_frame(DCAContext *s);
int ff_dca_xxch_decode_frame(DCAContext *s);
void ff_dca_exss_parse_header(DCAContext *s);
int ff_dca_xll_decode_header(DCAContext *s);
int ff_dca_xll_decode_navi(DCAContext *s, int asset_end);
int ff_dca_xll_decode_audio(DCAContext *s, AVFrame *frame);
int max_size);
#endif /* AVCODEC_DCA_H */

View File

@ -1,373 +0,0 @@
/*
* DCA ExSS extension
*
* 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/common.h"
#include "libavutil/log.h"
#include "dca.h"
#include "dca_syncwords.h"
#include "get_bits.h"
/* extensions that reside in core substream */
#define DCA_CORE_EXTS (DCA_EXT_XCH | DCA_EXT_XXCH | DCA_EXT_X96)
/* these are unconfirmed but should be mostly correct */
enum DCAExSSSpeakerMask {
DCA_EXSS_FRONT_CENTER = 0x0001,
DCA_EXSS_FRONT_LEFT_RIGHT = 0x0002,
DCA_EXSS_SIDE_REAR_LEFT_RIGHT = 0x0004,
DCA_EXSS_LFE = 0x0008,
DCA_EXSS_REAR_CENTER = 0x0010,
DCA_EXSS_FRONT_HIGH_LEFT_RIGHT = 0x0020,
DCA_EXSS_REAR_LEFT_RIGHT = 0x0040,
DCA_EXSS_FRONT_HIGH_CENTER = 0x0080,
DCA_EXSS_OVERHEAD = 0x0100,
DCA_EXSS_CENTER_LEFT_RIGHT = 0x0200,
DCA_EXSS_WIDE_LEFT_RIGHT = 0x0400,
DCA_EXSS_SIDE_LEFT_RIGHT = 0x0800,
DCA_EXSS_LFE2 = 0x1000,
DCA_EXSS_SIDE_HIGH_LEFT_RIGHT = 0x2000,
DCA_EXSS_REAR_HIGH_CENTER = 0x4000,
DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000,
};
/**
* Return the number of channels in an ExSS speaker mask (HD)
*/
static int dca_exss_mask2count(int mask)
{
/* count bits that mean speaker pairs twice */
return av_popcount(mask) +
av_popcount(mask & (DCA_EXSS_CENTER_LEFT_RIGHT |
DCA_EXSS_FRONT_LEFT_RIGHT |
DCA_EXSS_FRONT_HIGH_LEFT_RIGHT |
DCA_EXSS_WIDE_LEFT_RIGHT |
DCA_EXSS_SIDE_LEFT_RIGHT |
DCA_EXSS_SIDE_HIGH_LEFT_RIGHT |
DCA_EXSS_SIDE_REAR_LEFT_RIGHT |
DCA_EXSS_REAR_LEFT_RIGHT |
DCA_EXSS_REAR_HIGH_LEFT_RIGHT));
}
/**
* Skip mixing coefficients of a single mix out configuration (HD)
*/
static void dca_exss_skip_mix_coeffs(GetBitContext *gb, int channels, int out_ch)
{
int i;
for (i = 0; i < channels; i++) {
int mix_map_mask = get_bits(gb, out_ch);
int num_coeffs = av_popcount(mix_map_mask);
skip_bits_long(gb, num_coeffs * 6);
}
}
/**
* Parse extension substream asset header (HD)
*/
static int dca_exss_parse_asset_header(DCAContext *s)
{
int header_pos = get_bits_count(&s->gb);
int header_size;
int channels = 0;
int embedded_stereo = 0;
int embedded_6ch = 0;
int drc_code_present;
int extensions_mask = 0;
int i, j;
if (get_bits_left(&s->gb) < 16)
return AVERROR_INVALIDDATA;
/* We will parse just enough to get to the extensions bitmask with which
* we can set the profile value. */
header_size = get_bits(&s->gb, 9) + 1;
skip_bits(&s->gb, 3); // asset index
if (s->static_fields) {
if (get_bits1(&s->gb))
skip_bits(&s->gb, 4); // asset type descriptor
if (get_bits1(&s->gb))
skip_bits_long(&s->gb, 24); // language descriptor
if (get_bits1(&s->gb)) {
/* How can one fit 1024 bytes of text here if the maximum value
* for the asset header size field above was 512 bytes? */
int text_length = get_bits(&s->gb, 10) + 1;
if (get_bits_left(&s->gb) < text_length * 8)
return AVERROR_INVALIDDATA;
skip_bits_long(&s->gb, text_length * 8); // info text
}
skip_bits(&s->gb, 5); // bit resolution - 1
skip_bits(&s->gb, 4); // max sample rate code
channels = get_bits(&s->gb, 8) + 1;
s->one2one_map_chtospkr = get_bits1(&s->gb);
if (s->one2one_map_chtospkr) {
int spkr_remap_sets;
int spkr_mask_size = 16;
int num_spkrs[7];
if (channels > 2)
embedded_stereo = get_bits1(&s->gb);
if (channels > 6)
embedded_6ch = get_bits1(&s->gb);
if (get_bits1(&s->gb)) {
spkr_mask_size = (get_bits(&s->gb, 2) + 1) << 2;
skip_bits(&s->gb, spkr_mask_size); // spkr activity mask
}
spkr_remap_sets = get_bits(&s->gb, 3);
for (i = 0; i < spkr_remap_sets; i++) {
/* std layout mask for each remap set */
num_spkrs[i] = dca_exss_mask2count(get_bits(&s->gb, spkr_mask_size));
}
for (i = 0; i < spkr_remap_sets; i++) {
int num_dec_ch_remaps = get_bits(&s->gb, 5) + 1;
if (get_bits_left(&s->gb) < 0)
return AVERROR_INVALIDDATA;
for (j = 0; j < num_spkrs[i]; j++) {
int remap_dec_ch_mask = get_bits_long(&s->gb, num_dec_ch_remaps);
int num_dec_ch = av_popcount(remap_dec_ch_mask);
skip_bits_long(&s->gb, num_dec_ch * 5); // remap codes
}
}
} else {
skip_bits(&s->gb, 3); // representation type
}
}
drc_code_present = get_bits1(&s->gb);
if (drc_code_present)
get_bits(&s->gb, 8); // drc code
if (get_bits1(&s->gb))
skip_bits(&s->gb, 5); // dialog normalization code
if (drc_code_present && embedded_stereo)
get_bits(&s->gb, 8); // drc stereo code
if (s->mix_metadata && get_bits1(&s->gb)) {
skip_bits(&s->gb, 1); // external mix
skip_bits(&s->gb, 6); // post mix gain code
if (get_bits(&s->gb, 2) != 3) // mixer drc code
skip_bits(&s->gb, 3); // drc limit
else
skip_bits(&s->gb, 8); // custom drc code
if (get_bits1(&s->gb)) // channel specific scaling
for (i = 0; i < s->num_mix_configs; i++)
skip_bits_long(&s->gb, s->mix_config_num_ch[i] * 6); // scale codes
else
skip_bits_long(&s->gb, s->num_mix_configs * 6); // scale codes
for (i = 0; i < s->num_mix_configs; i++) {
if (get_bits_left(&s->gb) < 0)
return AVERROR_INVALIDDATA;
dca_exss_skip_mix_coeffs(&s->gb, channels, s->mix_config_num_ch[i]);
if (embedded_6ch)
dca_exss_skip_mix_coeffs(&s->gb, 6, s->mix_config_num_ch[i]);
if (embedded_stereo)
dca_exss_skip_mix_coeffs(&s->gb, 2, s->mix_config_num_ch[i]);
}
}
switch (get_bits(&s->gb, 2)) {
case 0:
extensions_mask = get_bits(&s->gb, 12);
break;
case 1:
extensions_mask = DCA_EXT_EXSS_XLL;
break;
case 2:
extensions_mask = DCA_EXT_EXSS_LBR;
break;
case 3:
extensions_mask = 0; /* aux coding */
break;
}
/* not parsed further, we were only interested in the extensions mask */
if (get_bits_left(&s->gb) < 0)
return AVERROR_INVALIDDATA;
if (get_bits_count(&s->gb) - header_pos > header_size * 8) {
av_log(s->avctx, AV_LOG_WARNING, "Asset header size mismatch.\n");
return AVERROR_INVALIDDATA;
}
skip_bits_long(&s->gb, header_pos + header_size * 8 - get_bits_count(&s->gb));
if (extensions_mask & DCA_EXT_EXSS_XLL)
s->profile = FF_PROFILE_DTS_HD_MA;
else if (extensions_mask & (DCA_EXT_EXSS_XBR | DCA_EXT_EXSS_X96 |
DCA_EXT_EXSS_XXCH))
s->profile = FF_PROFILE_DTS_HD_HRA;
if (!(extensions_mask & DCA_EXT_CORE))
av_log(s->avctx, AV_LOG_WARNING, "DTS core detection mismatch.\n");
if ((extensions_mask & DCA_CORE_EXTS) != s->core_ext_mask)
av_log(s->avctx, AV_LOG_WARNING,
"DTS extensions detection mismatch (%d, %d)\n",
extensions_mask & DCA_CORE_EXTS, s->core_ext_mask);
return 0;
}
/**
* Parse extension substream header (HD)
*/
void ff_dca_exss_parse_header(DCAContext *s)
{
int asset_size[8];
int ss_index;
int blownup;
int num_audiop = 1;
int num_assets = 1;
int active_ss_mask[8];
int i, j;
int start_pos;
int hdrsize;
uint32_t mkr;
if (get_bits_left(&s->gb) < 52)
return;
start_pos = get_bits_count(&s->gb) - 32;
skip_bits(&s->gb, 8); // user data
ss_index = get_bits(&s->gb, 2);
blownup = get_bits1(&s->gb);
hdrsize = get_bits(&s->gb, 8 + 4 * blownup) + 1; // header_size
skip_bits(&s->gb, 16 + 4 * blownup); // hd_size
s->static_fields = get_bits1(&s->gb);
if (s->static_fields) {
skip_bits(&s->gb, 2); // reference clock code
skip_bits(&s->gb, 3); // frame duration code
if (get_bits1(&s->gb))
skip_bits_long(&s->gb, 36); // timestamp
/* a single stream can contain multiple audio assets that can be
* combined to form multiple audio presentations */
num_audiop = get_bits(&s->gb, 3) + 1;
if (num_audiop > 1) {
avpriv_request_sample(s->avctx,
"Multiple DTS-HD audio presentations");
/* ignore such streams for now */
return;
}
num_assets = get_bits(&s->gb, 3) + 1;
if (num_assets > 1) {
avpriv_request_sample(s->avctx, "Multiple DTS-HD audio assets");
/* ignore such streams for now */
return;
}
for (i = 0; i < num_audiop; i++)
active_ss_mask[i] = get_bits(&s->gb, ss_index + 1);
for (i = 0; i < num_audiop; i++)
for (j = 0; j <= ss_index; j++)
if (active_ss_mask[i] & (1 << j))
skip_bits(&s->gb, 8); // active asset mask
s->mix_metadata = get_bits1(&s->gb);
if (s->mix_metadata) {
int mix_out_mask_size;
skip_bits(&s->gb, 2); // adjustment level
mix_out_mask_size = (get_bits(&s->gb, 2) + 1) << 2;
s->num_mix_configs = get_bits(&s->gb, 2) + 1;
for (i = 0; i < s->num_mix_configs; i++) {
int mix_out_mask = get_bits(&s->gb, mix_out_mask_size);
s->mix_config_num_ch[i] = dca_exss_mask2count(mix_out_mask);
}
}
}
av_assert0(num_assets > 0); // silence a warning
for (i = 0; i < num_assets; i++)
asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup) + 1;
for (i = 0; i < num_assets; i++) {
if (dca_exss_parse_asset_header(s))
return;
}
j = get_bits_count(&s->gb);
if (start_pos + hdrsize * 8 > j)
skip_bits_long(&s->gb, start_pos + hdrsize * 8 - j);
for (i = 0; i < num_assets; i++) {
int end_pos;
start_pos = get_bits_count(&s->gb);
end_pos = start_pos + asset_size[i] * 8;
mkr = get_bits_long(&s->gb, 32);
/* parse extensions that we know about */
switch (mkr) {
case DCA_SYNCWORD_XBR:
ff_dca_xbr_parse_frame(s);
break;
case DCA_SYNCWORD_XXCH:
ff_dca_xxch_decode_frame(s);
s->core_ext_mask |= DCA_EXT_XXCH; /* xxx use for chan reordering */
break;
case DCA_SYNCWORD_XLL:
if (s->xll_disable) {
av_log(s->avctx, AV_LOG_DEBUG,
"DTS-XLL: ignoring XLL extension\n");
break;
}
av_log(s->avctx, AV_LOG_DEBUG,
"DTS-XLL: decoding XLL extension\n");
if (ff_dca_xll_decode_header(s) == 0 &&
ff_dca_xll_decode_navi(s, end_pos) == 0)
s->exss_ext_mask |= DCA_EXT_EXSS_XLL;
break;
default:
av_log(s->avctx, AV_LOG_DEBUG,
"DTS-ExSS: unknown marker = 0x%08x\n", mkr);
}
/* skip to end of block */
j = get_bits_count(&s->gb);
if (j > end_pos)
av_log(s->avctx, AV_LOG_ERROR,
"DTS-ExSS: Processed asset too long.\n");
if (j < end_pos)
skip_bits_long(&s->gb, end_pos - j);
}
}

View File

@ -1,747 +0,0 @@
/*
* DCA XLL extension
*
* Copyright (C) 2012 Paul B Mahol
* Copyright (C) 2014 Niels Möller
*
* 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 "libavutil/common.h"
#include "libavutil/internal.h"
#include "avcodec.h"
#include "dca.h"
#include "dcadata.h"
#include "get_bits.h"
#include "unary.h"
/* Sign as bit 0 */
static inline int get_bits_sm(GetBitContext *s, unsigned n)
{
int x = get_bits(s, n);
if (x & 1)
return -(x >> 1) - 1;
else
return x >> 1;
}
/* Return -1 on error. */
static int32_t get_dmix_coeff(DCAContext *s, int inverse)
{
unsigned code = get_bits(&s->gb, 9);
int32_t sign = (int32_t) (code >> 8) - 1;
unsigned idx = code & 0xff;
int inv_offset = FF_DCA_DMIXTABLE_SIZE -FF_DCA_INV_DMIXTABLE_SIZE;
if (idx >= FF_DCA_DMIXTABLE_SIZE) {
av_log(s->avctx, AV_LOG_ERROR,
"XLL: Invalid channel set downmix code %x\n", code);
return -1;
} else if (!inverse) {
return (ff_dca_dmixtable[idx] ^ sign) - sign;
} else if (idx < inv_offset) {
av_log(s->avctx, AV_LOG_ERROR,
"XLL: Invalid channel set inverse downmix code %x\n", code);
return -1;
} else {
return (ff_dca_inv_dmixtable[idx - inv_offset] ^ sign) - sign;
}
}
static int32_t dca_get_dmix_coeff(DCAContext *s)
{
return get_dmix_coeff(s, 0);
}
static int32_t dca_get_inv_dmix_coeff(DCAContext *s)
{
return get_dmix_coeff(s, 1);
}
/* parse XLL header */
int ff_dca_xll_decode_header(DCAContext *s)
{
int hdr_pos, hdr_size;
av_unused int version, frame_size;
int i, chset_index;
/* get bit position of sync header */
hdr_pos = get_bits_count(&s->gb) - 32;
version = get_bits(&s->gb, 4) + 1;
hdr_size = get_bits(&s->gb, 8) + 1;
frame_size = get_bits_long(&s->gb, get_bits(&s->gb, 5) + 1) + 1;
s->xll_channels =
s->xll_residual_channels = 0;
s->xll_nch_sets = get_bits(&s->gb, 4) + 1;
s->xll_segments = 1 << get_bits(&s->gb, 4);
s->xll_log_smpl_in_seg = get_bits(&s->gb, 4);
s->xll_smpl_in_seg = 1 << s->xll_log_smpl_in_seg;
s->xll_bits4seg_size = get_bits(&s->gb, 5) + 1;
s->xll_banddata_crc = get_bits(&s->gb, 2);
s->xll_scalable_lsb = get_bits1(&s->gb);
s->xll_bits4ch_mask = get_bits(&s->gb, 5) + 1;
if (s->xll_scalable_lsb) {
s->xll_fixed_lsb_width = get_bits(&s->gb, 4);
if (s->xll_fixed_lsb_width)
av_log(s->avctx, AV_LOG_WARNING,
"XLL: fixed lsb width = %d, non-zero not supported.\n",
s->xll_fixed_lsb_width);
}
/* skip to the end of the common header */
i = get_bits_count(&s->gb);
if (hdr_pos + hdr_size * 8 > i)
skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i);
for (chset_index = 0; chset_index < s->xll_nch_sets; chset_index++) {
XllChSetSubHeader *chset = &s->xll_chsets[chset_index];
hdr_pos = get_bits_count(&s->gb);
hdr_size = get_bits(&s->gb, 10) + 1;
chset->channels = get_bits(&s->gb, 4) + 1;
chset->residual_encode = get_bits(&s->gb, chset->channels);
chset->bit_resolution = get_bits(&s->gb, 5) + 1;
chset->bit_width = get_bits(&s->gb, 5) + 1;
chset->sampling_frequency = ff_dca_sampling_freqs[get_bits(&s->gb, 4)];
chset->samp_freq_interp = get_bits(&s->gb, 2);
chset->replacement_set = get_bits(&s->gb, 2);
if (chset->replacement_set)
chset->active_replace_set = get_bits(&s->gb, 1);
if (s->one2one_map_chtospkr) {
chset->primary_ch_set = get_bits(&s->gb, 1);
chset->downmix_coeff_code_embedded = get_bits(&s->gb, 1);
if (chset->downmix_coeff_code_embedded) {
chset->downmix_embedded = get_bits(&s->gb, 1);
if (chset->primary_ch_set) {
chset->downmix_type = get_bits(&s->gb, 3);
if (chset->downmix_type > 6) {
av_log(s->avctx, AV_LOG_ERROR,
"XLL: Invalid channel set downmix type\n");
return AVERROR_INVALIDDATA;
}
}
}
chset->hier_chset = get_bits(&s->gb, 1);
if (chset->downmix_coeff_code_embedded) {
/* nDownmixCoeffs is specified as N * M. For a primary
* channel set, it appears that N = number of
* channels, and M is the number of downmix channels.
*
* For a non-primary channel set, N is specified as
* number of channels + 1, and M is derived from the
* channel set hierarchy, and at least in simple cases
* M is the number of channels in preceding channel
* sets. */
if (chset->primary_ch_set) {
static const char dmix_table[7] = { 1, 2, 2, 3, 3, 4, 4 };
chset->downmix_ncoeffs = chset->channels * dmix_table[chset->downmix_type];
} else
chset->downmix_ncoeffs = (chset->channels + 1) * s->xll_channels;
if (chset->downmix_ncoeffs > DCA_XLL_DMIX_NCOEFFS_MAX) {
avpriv_request_sample(s->avctx,
"XLL: More than %d downmix coefficients",
DCA_XLL_DMIX_NCOEFFS_MAX);
return AVERROR_PATCHWELCOME;
} else if (chset->primary_ch_set) {
for (i = 0; i < chset->downmix_ncoeffs; i++)
if ((chset->downmix_coeffs[i] = dca_get_dmix_coeff(s)) == -1)
return AVERROR_INVALIDDATA;
} else {
unsigned c, r;
for (c = 0, i = 0; c < s->xll_channels; c++, i += chset->channels + 1) {
if ((chset->downmix_coeffs[i] = dca_get_inv_dmix_coeff(s)) == -1)
return AVERROR_INVALIDDATA;
for (r = 1; r <= chset->channels; r++) {
int32_t coeff = dca_get_dmix_coeff(s);
if (coeff == -1)
return AVERROR_INVALIDDATA;
chset->downmix_coeffs[i + r] =
(chset->downmix_coeffs[i] * (int64_t) coeff + (1 << 15)) >> 16;
}
}
}
}
chset->ch_mask_enabled = get_bits(&s->gb, 1);
if (chset->ch_mask_enabled)
chset->ch_mask = get_bits(&s->gb, s->xll_bits4ch_mask);
else
/* Skip speaker configuration bits */
skip_bits_long(&s->gb, 25 * chset->channels);
} else {
chset->primary_ch_set = 1;
chset->downmix_coeff_code_embedded = 0;
/* Spec: NumChHierChSet = 0, NumDwnMixCodeCoeffs = 0, whatever that means. */
chset->mapping_coeffs_present = get_bits(&s->gb, 1);
if (chset->mapping_coeffs_present) {
avpriv_report_missing_feature(s->avctx, "XLL: mapping coefficients");
return AVERROR_PATCHWELCOME;
}
}
if (chset->sampling_frequency > 96000)
chset->num_freq_bands = 2 * (1 + get_bits(&s->gb, 1));
else
chset->num_freq_bands = 1;
if (chset->num_freq_bands > 1) {
avpriv_report_missing_feature(s->avctx, "XLL: num_freq_bands > 1");
return AVERROR_PATCHWELCOME;
}
if (get_bits(&s->gb, 1)) { /* pw_ch_decor_enabled */
int bits = av_ceil_log2(chset->channels);
for (i = 0; i < chset->channels; i++) {
unsigned j = get_bits(&s->gb, bits);
if (j >= chset->channels) {
av_log(s->avctx, AV_LOG_ERROR,
"Original channel order value %u too large, only %d channels.\n",
j, chset->channels);
return AVERROR_INVALIDDATA;
}
chset->orig_chan_order[0][i] = j;
chset->orig_chan_order_inv[0][j] = i;
}
for (i = 0; i < chset->channels / 2; i++) {
if (get_bits(&s->gb, 1)) /* bChPFlag */
chset->pw_ch_pairs_coeffs[0][i] = get_bits_sm(&s->gb, 7);
else
chset->pw_ch_pairs_coeffs[0][i] = 0;
}
} else {
for (i = 0; i < chset->channels; i++)
chset->orig_chan_order[0][i] =
chset->orig_chan_order_inv[0][i] = i;
for (i = 0; i < chset->channels / 2; i++)
chset->pw_ch_pairs_coeffs[0][i] = 0;
}
/* Adaptive prediction order */
chset->adapt_order_max[0] = 0;
for (i = 0; i < chset->channels; i++) {
chset->adapt_order[0][i] = get_bits(&s->gb, 4);
if (chset->adapt_order_max[0] < chset->adapt_order[0][i])
chset->adapt_order_max[0] = chset->adapt_order[0][i];
}
/* Fixed prediction order, used in case the adaptive order
* above is zero */
for (i = 0; i < chset->channels; i++)
chset->fixed_order[0][i] =
chset->adapt_order[0][i] ? 0 : get_bits(&s->gb, 2);
for (i = 0; i < chset->channels; i++) {
unsigned j;
for (j = 0; j < chset->adapt_order[0][i]; j++)
chset->lpc_refl_coeffs_q_ind[0][i][j] = get_bits(&s->gb, 8);
}
if (s->xll_scalable_lsb) {
chset->lsb_fsize[0] = get_bits(&s->gb, s->xll_bits4seg_size);
for (i = 0; i < chset->channels; i++)
chset->scalable_lsbs[0][i] = get_bits(&s->gb, 4);
for (i = 0; i < chset->channels; i++)
chset->bit_width_adj_per_ch[0][i] = get_bits(&s->gb, 4);
} else {
memset(chset->scalable_lsbs[0], 0,
chset->channels * sizeof(chset->scalable_lsbs[0][0]));
memset(chset->bit_width_adj_per_ch[0], 0,
chset->channels * sizeof(chset->bit_width_adj_per_ch[0][0]));
}
s->xll_channels += chset->channels;
s->xll_residual_channels += chset->channels -
av_popcount(chset->residual_encode);
/* FIXME: Parse header data for extra frequency bands. */
/* Skip to end of channel set sub header. */
i = get_bits_count(&s->gb);
if (hdr_pos + 8 * hdr_size < i) {
av_log(s->avctx, AV_LOG_ERROR,
"chset header too large, %d bits, should be <= %d bits\n",
i - hdr_pos, 8 * hdr_size);
return AVERROR_INVALIDDATA;
}
if (hdr_pos + 8 * hdr_size > i)
skip_bits_long(&s->gb, hdr_pos + 8 * hdr_size - i);
}
return 0;
}
/* parse XLL navigation table */
int ff_dca_xll_decode_navi(DCAContext *s, int asset_end)
{
int nbands, band, chset, seg, data_start;
/* FIXME: Supports only a single frequency band */
nbands = 1;
for (band = 0; band < nbands; band++) {
s->xll_navi.band_size[band] = 0;
for (seg = 0; seg < s->xll_segments; seg++) {
/* Note: The spec, ETSI TS 102 114 V1.4.1 (2012-09), says
* we should read a base value for segment_size from the
* stream, before reading the sizes of the channel sets.
* But that's apparently incorrect. */
s->xll_navi.segment_size[band][seg] = 0;
for (chset = 0; chset < s->xll_nch_sets; chset++)
if (band < s->xll_chsets[chset].num_freq_bands) {
s->xll_navi.chset_size[band][seg][chset] =
get_bits(&s->gb, s->xll_bits4seg_size) + 1;
s->xll_navi.segment_size[band][seg] +=
s->xll_navi.chset_size[band][seg][chset];
}
s->xll_navi.band_size[band] += s->xll_navi.segment_size[band][seg];
}
}
/* Align to 8 bits and skip 16-bit CRC. */
skip_bits_long(&s->gb, 16 + ((-get_bits_count(&s->gb)) & 7));
data_start = get_bits_count(&s->gb);
if (data_start + 8 * s->xll_navi.band_size[0] > asset_end) {
av_log(s->avctx, AV_LOG_ERROR,
"XLL: Data in NAVI table exceeds containing asset\n"
"start: %d (bit), size %u (bytes), end %d (bit), error %u\n",
data_start, s->xll_navi.band_size[0], asset_end,
data_start + 8 * s->xll_navi.band_size[0] - asset_end);
return AVERROR_INVALIDDATA;
}
init_get_bits(&s->xll_navi.gb, s->gb.buffer + data_start / 8,
8 * s->xll_navi.band_size[0]);
return 0;
}
static void dca_xll_inv_adapt_pred(int *samples, int nsamples, unsigned order,
const int *prev, const uint8_t *q_ind)
{
static const uint16_t table[0x81] = {
0, 3070, 5110, 7140, 9156, 11154, 13132, 15085,
17010, 18904, 20764, 22588, 24373, 26117, 27818, 29474,
31085, 32648, 34164, 35631, 37049, 38418, 39738, 41008,
42230, 43404, 44530, 45609, 46642, 47630, 48575, 49477,
50337, 51157, 51937, 52681, 53387, 54059, 54697, 55302,
55876, 56421, 56937, 57426, 57888, 58326, 58741, 59132,
59502, 59852, 60182, 60494, 60789, 61066, 61328, 61576,
61809, 62029, 62236, 62431, 62615, 62788, 62951, 63105,
63250, 63386, 63514, 63635, 63749, 63855, 63956, 64051,
64140, 64224, 64302, 64376, 64446, 64512, 64573, 64631,
64686, 64737, 64785, 64830, 64873, 64913, 64950, 64986,
65019, 65050, 65079, 65107, 65133, 65157, 65180, 65202,
65222, 65241, 65259, 65275, 65291, 65306, 65320, 65333,
65345, 65357, 65368, 65378, 65387, 65396, 65405, 65413,
65420, 65427, 65434, 65440, 65446, 65451, 65456, 65461,
65466, 65470, 65474, 65478, 65481, 65485, 65488, 65491,
65535, /* Final value is for the -128 corner case, see below. */
};
int c[DCA_XLL_AORDER_MAX];
int64_t s;
unsigned i, j;
for (i = 0; i < order; i++) {
if (q_ind[i] & 1)
/* The index value 0xff corresponds to a lookup of entry 0x80 in
* the table, and no value is provided in the specification. */
c[i] = -table[(q_ind[i] >> 1) + 1];
else
c[i] = table[q_ind[i] >> 1];
}
/* The description in the spec is a bit convoluted. We can convert
* the reflected values to direct values in place, using a
* sequence of reflections operating on two values. */
for (i = 1; i < order; i++) {
/* i = 1: scale c[0]
* i = 2: reflect c[0] <-> c[1]
* i = 3: scale c[1], reflect c[0] <-> c[2]
* i = 4: reflect c[0] <-> c[3] reflect c[1] <-> c[2]
* ... */
if (i & 1)
c[i / 2] += ((int64_t) c[i] * c[i / 2] + 0x8000) >> 16;
for (j = 0; j < i / 2; j++) {
int r0 = c[j];
int r1 = c[i - j - 1];
c[j] += ((int64_t) c[i] * r1 + 0x8000) >> 16;
c[i - j - 1] += ((int64_t) c[i] * r0 + 0x8000) >> 16;
}
}
/* Apply predictor. */
/* NOTE: Processing samples in this order means that the
* predictor is applied to the newly reconstructed samples. */
if (prev) {
for (i = 0; i < order; i++) {
for (j = s = 0; j < i; j++)
s += (int64_t) c[j] * samples[i - 1 - j];
for (; j < order; j++)
s += (int64_t) c[j] * prev[DCA_XLL_AORDER_MAX + i - 1 - j];
samples[i] -= av_clip_intp2((s + 0x8000) >> 16, 24);
}
}
for (i = order; i < nsamples; i++) {
for (j = s = 0; j < order; j++)
s += (int64_t) c[j] * samples[i - 1 - j];
/* NOTE: Equations seem to imply addition, while the
* pseudocode seems to use subtraction.*/
samples[i] -= av_clip_intp2((s + 0x8000) >> 16, 24);
}
}
int ff_dca_xll_decode_audio(DCAContext *s, AVFrame *frame)
{
/* FIXME: Decodes only the first frequency band. */
int seg, chset_i;
/* Coding parameters for each channel set. */
struct coding_params {
int seg_type;
int rice_code_flag[16];
int pancAuxABIT[16];
int pancABIT0[16]; /* Not sure what this is */
int pancABIT[16]; /* Not sure what this is */
int nSamplPart0[16];
} param_state[16];
GetBitContext *gb = &s->xll_navi.gb;
int *history;
/* Layout: First the sample buffer for one segment per channel,
* followed by history buffers of DCA_XLL_AORDER_MAX samples for
* each channel. */
av_fast_malloc(&s->xll_sample_buf, &s->xll_sample_buf_size,
(s->xll_smpl_in_seg + DCA_XLL_AORDER_MAX) *
s->xll_channels * sizeof(*s->xll_sample_buf));
if (!s->xll_sample_buf)
return AVERROR(ENOMEM);
history = s->xll_sample_buf + s->xll_smpl_in_seg * s->xll_channels;
for (seg = 0; seg < s->xll_segments; seg++) {
unsigned in_channel;
for (chset_i = in_channel = 0; chset_i < s->xll_nch_sets; chset_i++) {
/* The spec isn't very explicit, but I think the NAVI sizes are in bytes. */
int end_pos = get_bits_count(gb) +
8 * s->xll_navi.chset_size[0][seg][chset_i];
int i, j;
struct coding_params *params = &param_state[chset_i];
/* I think this flag means that we should keep seg_type and
* other parameters from the previous segment. */
int use_seg_state_code_param;
XllChSetSubHeader *chset = &s->xll_chsets[chset_i];
if (in_channel >= s->avctx->channels)
/* FIXME: Could go directly to next segment */
goto next_chset;
if (s->avctx->sample_rate != chset->sampling_frequency) {
av_log(s->avctx, AV_LOG_WARNING,
"XLL: unexpected chset sample rate %d, expected %d\n",
chset->sampling_frequency, s->avctx->sample_rate);
goto next_chset;
}
if (seg != 0)
use_seg_state_code_param = get_bits(gb, 1);
else
use_seg_state_code_param = 0;
if (!use_seg_state_code_param) {
int num_param_sets, i;
unsigned bits4ABIT;
params->seg_type = get_bits(gb, 1);
num_param_sets = params->seg_type ? 1 : chset->channels;
if (chset->bit_width > 16) {
bits4ABIT = 5;
} else {
if (chset->bit_width > 8)
bits4ABIT = 4;
else
bits4ABIT = 3;
if (s->xll_nch_sets > 1)
bits4ABIT++;
}
for (i = 0; i < num_param_sets; i++) {
params->rice_code_flag[i] = get_bits(gb, 1);
if (!params->seg_type && params->rice_code_flag[i] && get_bits(gb, 1))
params->pancAuxABIT[i] = get_bits(gb, bits4ABIT) + 1;
else
params->pancAuxABIT[i] = 0;
}
for (i = 0; i < num_param_sets; i++) {
if (!seg) {
/* Parameters for part 1 */
params->pancABIT0[i] = get_bits(gb, bits4ABIT);
if (params->rice_code_flag[i] == 0 && params->pancABIT0[i] > 0)
/* For linear code */
params->pancABIT0[i]++;
/* NOTE: In the spec, not indexed by band??? */
if (params->seg_type == 0)
params->nSamplPart0[i] = chset->adapt_order[0][i];
else
params->nSamplPart0[i] = chset->adapt_order_max[0];
} else
params->nSamplPart0[i] = 0;
/* Parameters for part 2 */
params->pancABIT[i] = get_bits(gb, bits4ABIT);
if (params->rice_code_flag[i] == 0 && params->pancABIT[i] > 0)
/* For linear code */
params->pancABIT[i]++;
}
}
for (i = 0; i < chset->channels; i++) {
int param_index = params->seg_type ? 0 : i;
int part0 = params->nSamplPart0[param_index];
int bits = part0 ? params->pancABIT0[param_index] : 0;
int *sample_buf = s->xll_sample_buf +
(in_channel + i) * s->xll_smpl_in_seg;
if (!params->rice_code_flag[param_index]) {
/* Linear code */
if (bits)
for (j = 0; j < part0; j++)
sample_buf[j] = get_bits_sm(gb, bits);
else
memset(sample_buf, 0, part0 * sizeof(sample_buf[0]));
/* Second part */
bits = params->pancABIT[param_index];
if (bits)
for (j = part0; j < s->xll_smpl_in_seg; j++)
sample_buf[j] = get_bits_sm(gb, bits);
else
memset(sample_buf + part0, 0,
(s->xll_smpl_in_seg - part0) * sizeof(sample_buf[0]));
} else {
int aux_bits = params->pancAuxABIT[param_index];
for (j = 0; j < part0; j++) {
/* FIXME: Is this identical to Golomb code? */
int t = get_unary(gb, 1, 33) << bits;
/* FIXME: Could move this test outside of the loop, for efficiency. */
if (bits)
t |= get_bits(gb, bits);
sample_buf[j] = (t & 1) ? -(t >> 1) - 1 : (t >> 1);
}
/* Second part */
bits = params->pancABIT[param_index];
/* Follow the spec's suggestion of using the
* buffer also to store the hybrid-rice flags. */
memset(sample_buf + part0, 0,
(s->xll_smpl_in_seg - part0) * sizeof(sample_buf[0]));
if (aux_bits > 0) {
/* For hybrid rice encoding, some samples are linearly
* coded. According to the spec, "nBits4SamplLoci" bits
* are used for each index, but this value is not
* defined. I guess we should use log2(xll_smpl_in_seg)
* bits. */
int count = get_bits(gb, s->xll_log_smpl_in_seg);
av_log(s->avctx, AV_LOG_DEBUG, "aux count %d (bits %d)\n",
count, s->xll_log_smpl_in_seg);
for (j = 0; j < count; j++)
sample_buf[get_bits(gb, s->xll_log_smpl_in_seg)] = 1;
}
for (j = part0; j < s->xll_smpl_in_seg; j++) {
if (!sample_buf[j]) {
int t = get_unary(gb, 1, 33);
if (bits)
t = (t << bits) | get_bits(gb, bits);
sample_buf[j] = (t & 1) ? -(t >> 1) - 1 : (t >> 1);
} else
sample_buf[j] = get_bits_sm(gb, aux_bits);
}
}
}
for (i = 0; i < chset->channels; i++) {
unsigned adapt_order = chset->adapt_order[0][i];
int *sample_buf = s->xll_sample_buf +
(in_channel + i) * s->xll_smpl_in_seg;
int *prev = history + (in_channel + i) * DCA_XLL_AORDER_MAX;
if (!adapt_order) {
unsigned order;
for (order = chset->fixed_order[0][i]; order > 0; order--) {
unsigned j;
for (j = 1; j < s->xll_smpl_in_seg; j++)
sample_buf[j] += sample_buf[j - 1];
}
} else
/* Inverse adaptive prediction, in place. */
dca_xll_inv_adapt_pred(sample_buf, s->xll_smpl_in_seg,
adapt_order, seg ? prev : NULL,
chset->lpc_refl_coeffs_q_ind[0][i]);
memcpy(prev, sample_buf + s->xll_smpl_in_seg - DCA_XLL_AORDER_MAX,
DCA_XLL_AORDER_MAX * sizeof(*prev));
}
for (i = 1; i < chset->channels; i += 2) {
int coeff = chset->pw_ch_pairs_coeffs[0][i / 2];
if (coeff != 0) {
int *sample_buf = s->xll_sample_buf +
(in_channel + i) * s->xll_smpl_in_seg;
int *prev = sample_buf - s->xll_smpl_in_seg;
unsigned j;
for (j = 0; j < s->xll_smpl_in_seg; j++)
/* Shift is unspecified, but should apparently be 3. */
sample_buf[j] += ((int64_t) coeff * prev[j] + 4) >> 3;
}
}
if (s->xll_scalable_lsb) {
int lsb_start = end_pos - 8 * chset->lsb_fsize[0] -
8 * (s->xll_banddata_crc & 2);
int done;
i = get_bits_count(gb);
if (i > lsb_start) {
av_log(s->avctx, AV_LOG_ERROR,
"chset data lsb exceeds NAVI size, end_pos %d, lsb_start %d, pos %d\n",
end_pos, lsb_start, i);
return AVERROR_INVALIDDATA;
}
if (i < lsb_start)
skip_bits_long(gb, lsb_start - i);
for (i = done = 0; i < chset->channels; i++) {
int bits = chset->scalable_lsbs[0][i];
if (bits > 0) {
/* The channel reordering is conceptually done
* before adding the lsb:s, so we need to do
* the inverse permutation here. */
unsigned pi = chset->orig_chan_order_inv[0][i];
int *sample_buf = s->xll_sample_buf +
(in_channel + pi) * s->xll_smpl_in_seg;
int adj = chset->bit_width_adj_per_ch[0][i];
int msb_shift = bits;
unsigned j;
if (adj > 0)
msb_shift += adj - 1;
for (j = 0; j < s->xll_smpl_in_seg; j++)
sample_buf[j] = (sample_buf[j] << msb_shift) +
(get_bits(gb, bits) << adj);
done += bits * s->xll_smpl_in_seg;
}
}
if (done > 8 * chset->lsb_fsize[0]) {
av_log(s->avctx, AV_LOG_ERROR,
"chset lsb exceeds lsb_size\n");
return AVERROR_INVALIDDATA;
}
}
/* Store output. */
for (i = 0; i < chset->channels; i++) {
int *sample_buf = s->xll_sample_buf +
(in_channel + i) * s->xll_smpl_in_seg;
int shift = 1 - chset->bit_resolution;
int out_channel = chset->orig_chan_order[0][i];
float *out;
/* XLL uses the channel order C, L, R, and we want L,
* R, C. FIXME: Generalize. */
if (chset->ch_mask_enabled &&
(chset->ch_mask & 7) == 7 && out_channel < 3)
out_channel = out_channel ? out_channel - 1 : 2;
out_channel += in_channel;
if (out_channel >= s->avctx->channels)
continue;
out = (float *) frame->extended_data[out_channel];
out += seg * s->xll_smpl_in_seg;
/* NOTE: A one bit means residual encoding is *not* used. */
if ((chset->residual_encode >> i) & 1) {
/* Replace channel samples.
* FIXME: Most likely not the right thing to do. */
for (j = 0; j < s->xll_smpl_in_seg; j++)
out[j] = ldexpf(sample_buf[j], shift);
} else {
/* Add residual signal to core channel */
for (j = 0; j < s->xll_smpl_in_seg; j++)
out[j] += ldexpf(sample_buf[j], shift);
}
}
if (chset->downmix_coeff_code_embedded &&
!chset->primary_ch_set && chset->hier_chset) {
/* Undo hierarchical downmix of earlier channels. */
unsigned mix_channel;
for (mix_channel = 0; mix_channel < in_channel; mix_channel++) {
float *mix_buf;
const int *col;
float coeff;
unsigned row;
/* Similar channel reorder C, L, R vs L, R, C reorder. */
if (chset->ch_mask_enabled &&
(chset->ch_mask & 7) == 7 && mix_channel < 3)
mix_buf = (float *) frame->extended_data[mix_channel ? mix_channel - 1 : 2];
else
mix_buf = (float *) frame->extended_data[mix_channel];
mix_buf += seg * s->xll_smpl_in_seg;
col = &chset->downmix_coeffs[mix_channel * (chset->channels + 1)];
/* Scale */
coeff = ldexpf(col[0], -16);
for (j = 0; j < s->xll_smpl_in_seg; j++)
mix_buf[j] *= coeff;
for (row = 0;
row < chset->channels && in_channel + row < s->avctx->channels;
row++)
if (col[row + 1]) {
const float *new_channel =
(const float *) frame->extended_data[in_channel + row];
new_channel += seg * s->xll_smpl_in_seg;
coeff = ldexpf(col[row + 1], -15);
for (j = 0; j < s->xll_smpl_in_seg; j++)
mix_buf[j] -= coeff * new_channel[j];
}
}
}
next_chset:
in_channel += chset->channels;
/* Skip to next channel set using the NAVI info. */
i = get_bits_count(gb);
if (i > end_pos) {
av_log(s->avctx, AV_LOG_ERROR,
"chset data exceeds NAVI size\n");
return AVERROR_INVALIDDATA;
}
if (i < end_pos)
skip_bits_long(gb, end_pos - i);
}
}
return 0;
}

View File

@ -22,7 +22,6 @@
#include <stdint.h>
#include "libavutil/channel_layout.h"
#include "libavutil/mem.h"
#include "dca.h"
@ -7509,76 +7508,6 @@ DECLARE_ALIGNED(16, const float, ff_dca_lfe_fir_128)[256] = {
};
#undef SCALE
#define SCALE(c) ((float)(c) / (256.0f * 32768.0f * 8388608.0f))
DECLARE_ALIGNED(16, const float, ff_dca_lfe_xll_fir_64)[256] = {
SCALE( 6103), SCALE( 52170), SCALE(-558064), SCALE(1592440),
SCALE(6290049), SCALE(1502534), SCALE(-546669), SCALE( 53047),
SCALE( 1930), SCALE( 51089), SCALE(-568920), SCALE(1683709),
SCALE(6286575), SCALE(1414057), SCALE(-534782), SCALE( 53729),
SCALE( 2228), SCALE( 49794), SCALE(-579194), SCALE(1776276),
SCALE(6279634), SCALE(1327070), SCALE(-522445), SCALE( 54228),
SCALE( 2552), SCALE( 48275), SCALE(-588839), SCALE(1870070),
SCALE(6269231), SCALE(1241632), SCALE(-509702), SCALE( 54550),
SCALE( 2904), SCALE( 46523), SCALE(-597808), SCALE(1965017),
SCALE(6255380), SCALE(1157798), SCALE(-496595), SCALE( 54708),
SCALE( 3287), SCALE( 44529), SCALE(-606054), SCALE(2061044),
SCALE(6238099), SCALE(1075621), SCALE(-483164), SCALE( 54710),
SCALE( 3704), SCALE( 42282), SCALE(-613529), SCALE(2158071),
SCALE(6217408), SCALE( 995149), SCALE(-469451), SCALE( 54566),
SCALE( 4152), SCALE( 39774), SCALE(-620186), SCALE(2256019),
SCALE(6193332), SCALE( 916430), SCALE(-455494), SCALE( 54285),
SCALE( 4631), SCALE( 36995), SCALE(-625976), SCALE(2354805),
SCALE(6165900), SCALE( 839507), SCALE(-441330), SCALE( 53876),
SCALE( 5139), SCALE( 33937), SCALE(-630850), SCALE(2454343),
SCALE(6135146), SCALE( 764419), SCALE(-426998), SCALE( 53348),
SCALE( 5682), SCALE( 30591), SCALE(-634759), SCALE(2554547),
SCALE(6101107), SCALE( 691203), SCALE(-412531), SCALE( 52711),
SCALE( 6264), SCALE( 26948), SCALE(-637655), SCALE(2655326),
SCALE(6063824), SCALE( 619894), SCALE(-397966), SCALE( 51972),
SCALE( 6886), SCALE( 23001), SCALE(-639488), SCALE(2756591),
SCALE(6023343), SCALE( 550521), SCALE(-383335), SCALE( 51140),
SCALE( 7531), SCALE( 18741), SCALE(-640210), SCALE(2858248),
SCALE(5979711), SCALE( 483113), SCALE(-368671), SCALE( 50224),
SCALE( 8230), SCALE( 14162), SCALE(-639772), SCALE(2960201),
SCALE(5932981), SCALE( 417692), SCALE(-354003), SCALE( 49231),
SCALE( 8959), SCALE( 9257), SCALE(-638125), SCALE(3062355),
SCALE(5883210), SCALE( 354281), SCALE(-339362), SCALE( 48168),
SCALE( 9727), SCALE( 4018), SCALE(-635222), SCALE(3164612),
SCALE(5830457), SCALE( 292897), SCALE(-324777), SCALE( 47044),
SCALE( 10535), SCALE( -1558), SCALE(-631014), SCALE(3266872),
SCALE(5774785), SCALE( 233555), SCALE(-310273), SCALE( 45866),
SCALE( 11381), SCALE( -7480), SCALE(-625455), SCALE(3369035),
SCALE(5716260), SCALE( 176267), SCALE(-295877), SCALE( 44640),
SCALE( 12267), SCALE( -13750), SCALE(-618499), SCALE(3471000),
SCALE(5654952), SCALE( 121042), SCALE(-281613), SCALE( 43373),
SCALE( 13190), SCALE( -20372), SCALE(-610098), SCALE(3572664),
SCALE(5590933), SCALE( 67886), SCALE(-267505), SCALE( 42072),
SCALE( 14152), SCALE( -27352), SCALE(-600209), SCALE(3673924),
SCALE(5524280), SCALE( 16800), SCALE(-253574), SCALE( 40743),
SCALE( 15153), SCALE( -34691), SCALE(-588788), SCALE(3774676),
SCALE(5455069), SCALE( -32214), SCALE(-239840), SCALE( 39391),
SCALE( 16192), SCALE( -42390), SCALE(-575791), SCALE(3874816),
SCALE(5383383), SCALE( -79159), SCALE(-226323), SCALE( 38022),
SCALE( 17267), SCALE( -50453), SCALE(-561178), SCALE(3974239),
SCALE(5309305), SCALE(-124041), SCALE(-213041), SCALE( 36642),
SCALE( 18377), SCALE( -58879), SCALE(-544906), SCALE(4072841),
SCALE(5232922), SCALE(-166869), SCALE(-200010), SCALE( 35256),
SCALE( 19525), SCALE( -67667), SCALE(-526937), SCALE(4170517),
SCALE(5154321), SCALE(-207653), SCALE(-187246), SCALE( 33866),
SCALE( 20704), SCALE( -76817), SCALE(-507233), SCALE(4267162),
SCALE(5073593), SCALE(-246406), SCALE(-174764), SCALE( 32480),
SCALE( 21915), SCALE( -86327), SCALE(-485757), SCALE(4362672),
SCALE(4990831), SCALE(-283146), SCALE(-162575), SCALE( 31101),
SCALE( 23157), SCALE( -96193), SCALE(-462476), SCALE(4456942),
SCALE(4906129), SCALE(-317890), SCALE(-150692), SCALE( 29732),
SCALE( 24426), SCALE(-106412), SCALE(-437356), SCALE(4549871),
SCALE(4819584), SCALE(-350658), SCALE(-139125), SCALE( 28376),
SCALE( 25721), SCALE(-116977), SCALE(-410365), SCALE(4641355),
SCALE(4731293), SCALE(-381475), SCALE(-127884), SCALE( 27038),
};
#undef SCALE
DECLARE_ALIGNED(16, const float, ff_dca_fir_64bands)[1024] = {
/* Bank 0 */
-7.1279389866041690e-8, -7.0950903150874990e-8,
@ -8178,220 +8107,11 @@ const uint32_t ff_dca_inv_dmixtable[FF_DCA_INV_DMIXTABLE_SIZE] = {
65536,
};
const float ff_dca_default_coeffs[10][6][2] = {
{ { 0.707107, 0.707107 }, { 0.000000, 0.000000 }, }, // A [LFE]
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // A + B (dual mono) [LFE]
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // L + R (stereo) [LFE]
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // (L+R) + (L-R) (sum-difference) [LFE]
{ { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // LT + RT (left and right total) [LFE]
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.000000, 0.000000 }, }, // C + L + R [LFE]
{ { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + S [LFE]
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + S [LFE]
{ { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + SL + SR [LFE]
{ { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + SL + SR [LFE]
};
const int32_t ff_dca_sampling_freqs[16] = {
8000, 16000, 32000, 64000, 128000, 22050, 44100, 88200,
176400, 352800, 12000, 24000, 48000, 96000, 192000, 384000,
};
/* downmix coeffs
*
* TABLE 9
* ______________________________________
* Down-mix coefficients for 8-channel source
* audio (5 + 3 format)
* lt
* cen- rt lt ctr rt
* lt ter ctr center
* rt srd srd srd
* ______________________________________
* 1 0.71 0.74 1.0 0.71 0.71 0.58 0.58 0.58
* 2 left 1.0 0.89 0.71 0.46 0.71 0.50
* rt 0.45 0.71 0.89 1.0 0.50 0.71
* 3 lt 1.0 0.89 0.71 0.45
* rt 0.45 0.71 0.89 1.0
* srd 0.71 0.71 0.71
* 4 lt 1.0 0.89 0.71 0.45
* rt 0.45 0.71 0.89 1.0
* lt srd 1.0 0.71
* rt srd 0.71 0.71
* 4 lt 1.0 0.5
* ctr 0.87 1.0 0.87
* rt 0.5 1.0
* srd 0.71 0.71 0.71
* 5 lt 1.0 0.5
* ctr 0.87 1.0 0.87
* rt 0.5 1.0
* lt srd 1.0 0.71
* rt srd 0.71 1.0
* 6 lt 1.0 0.5
* lt ctr 0.87 0.71
* rt ctr 0.71 0.87
* rt 0.5 1.0
* lt srd 1.0 0.71
* rt srd 0.71 1.0
* 6 lt 1.0 0.5
* ctr 0.86 1.0 0.86
* rt 0.5 1.0
* lt srd 1.0
* ctr srd 1.0
* rt srd 1.0
* 7 lt 1.0
* lt ctr 1.0
* ctr 1.0
* rt ctr 1.0
* rt 1.0
* lt srd 1.0 0.71
* rt srd 0.71 1.0
* 7 lt 1.0 0.5
* lt ctr 0.87 0.71
* rt ctr 0.71 0.87
* rt 0.5 1.0
* lt srd 1.0
* ctr srd 1.0
* rt srd 1.0
* 8 lt 1.0 0.5
* lt ctr 0.87 0.71
* rt ctr 0.71 0.87
* rt 0.5 1.0
* lt 1 srd 0.87 0.35
* lt 2 srd 0.5 0.61
* rt 2 srd 0.61 0.50
* rt 2 srd 0.35 0.87
*
* Generation of Lt Rt
*
* In the case when the playback system has analog or digital surround
* multi-channel capability, a down matrix from 5, 4, or 3 channel to
* Lt Rt may be desirable. In the case when the number of decoded audio
* channels exceeds 5, 4 or 3 respectively a first stage down mix to 5,
* 4 or 3 chs should be used as described above.
*
* The down matrixing equations for 5-channel source audio to a
* two-channel Lt Rt playback system are given by:
*
* Left = left + 0.7 * center - 0.7 * (lt surround + rt surround)
*
* Right = right + 0.7 * center + 0.7 * (lt surround + rt surround)
*
* Embedded mixing to 2-channel
*
* One concern arising from the proliferation of multi-channel audio
* systems is that most home systems presently have only two channel
* playback capability. To accommodate this a fixed 2-channel down
* matrix processes is commonly used following the multi-channel
* decoding stage. However, for music only applications the image
* quality etc. of the down matrixed signal may not match that of an
* equivalent stereo recording found on CD.
*
* The concept of embedded mixing is to allow the producer to
* dynamically specify the matrixing coefficients within the audio
* frame itself. In this way the stereo down mix at the decoder may be
* better matched to a 2-channel playback environment.
*
* CHS*2, 7-bit down mix indexes (MCOEFFS) are transmitted along with
* the multi-channel audio once in every frame. The indexes are
* converted to attenuation factors using a 7 bit LUT. The 2-ch down
* mix equations are as follows,
*
* Left Ch = sum (MCOEFF[n] * Ch[n]) for n=1, CHS
*
* Right Ch = sum (MCOEFF[n + CHS] * Ch[n]) for n=1, CHS
*
* where Ch(n) represents the subband samples in the (n)th audio channel.
*/
const uint32_t ff_dca_map_xxch_to_native[28] = {
AV_CH_FRONT_CENTER,
AV_CH_FRONT_LEFT,
AV_CH_FRONT_RIGHT,
AV_CH_SIDE_LEFT,
AV_CH_SIDE_RIGHT,
AV_CH_LOW_FREQUENCY,
AV_CH_BACK_CENTER,
AV_CH_BACK_LEFT,
AV_CH_BACK_RIGHT,
AV_CH_SIDE_LEFT, /* side surround left -- dup sur side L */
AV_CH_SIDE_RIGHT, /* side surround right -- dup sur side R */
AV_CH_FRONT_LEFT_OF_CENTER,
AV_CH_FRONT_RIGHT_OF_CENTER,
AV_CH_TOP_FRONT_LEFT,
AV_CH_TOP_FRONT_CENTER,
AV_CH_TOP_FRONT_RIGHT,
AV_CH_LOW_FREQUENCY, /* lfe2 -- duplicate lfe1 position */
AV_CH_FRONT_LEFT_OF_CENTER, /* side front left -- dup front cntr L */
AV_CH_FRONT_RIGHT_OF_CENTER,/* side front right -- dup front cntr R */
AV_CH_TOP_CENTER, /* overhead */
AV_CH_TOP_FRONT_LEFT, /* side high left -- dup */
AV_CH_TOP_FRONT_RIGHT, /* side high right -- dup */
AV_CH_TOP_BACK_CENTER,
AV_CH_TOP_BACK_LEFT,
AV_CH_TOP_BACK_RIGHT,
AV_CH_BACK_CENTER, /* rear low center -- dup */
AV_CH_BACK_LEFT, /* rear low left -- dup */
AV_CH_BACK_RIGHT /* read low right -- dup */
};
/* -1 are reserved or unknown */
const int ff_dca_ext_audio_descr_mask[8] = {
DCA_EXT_XCH,
-1,
DCA_EXT_X96,
DCA_EXT_XCH | DCA_EXT_X96,
-1,
-1,
DCA_EXT_XXCH,
-1,
};
/* Tables for mapping dts channel configurations to libavcodec multichannel api.
* Some compromises have been made for special configurations. Most configurations
* are never used so complete accuracy is not needed.
*
* L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead.
* S -> side, when both rear and back are configured move one of them to the side channel
* OV -> center back
* All 2 channel configurations -> AV_CH_LAYOUT_STEREO
*/
const uint64_t ff_dca_core_channel_layout[16] = {
AV_CH_FRONT_CENTER, ///< 1, A
AV_CH_LAYOUT_STEREO, ///< 2, A + B (dual mono)
AV_CH_LAYOUT_STEREO, ///< 2, L + R (stereo)
AV_CH_LAYOUT_STEREO, ///< 2, (L + R) + (L - R) (sum-difference)
AV_CH_LAYOUT_STEREO, ///< 2, LT + RT (left and right total)
AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER, ///< 3, C + L + R
AV_CH_LAYOUT_STEREO | AV_CH_BACK_CENTER, ///< 3, L + R + S
AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER, ///< 4, C + L + R + S
AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 4, L + R + SL + SR
AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_SIDE_LEFT |
AV_CH_SIDE_RIGHT, ///< 5, C + L + R + SL + SR
AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT |
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER, ///< 6, CL + CR + L + R + SL + SR
AV_CH_LAYOUT_STEREO | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT |
AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER, ///< 6, C + L + R + LR + RR + OV
AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER |
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_BACK_CENTER |
AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT, ///< 6, CF + CR + LF + RF + LR + RR
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER |
AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO |
AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 7, CL + C + CR + L + R + SL + SR
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER |
AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT |
AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT, ///< 8, CL + CR + L + R + SL1 + SL2 + SR1 + SR2
AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER |
AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO |
AV_CH_SIDE_LEFT | AV_CH_BACK_CENTER | AV_CH_SIDE_RIGHT, ///< 8, CL + C + CR + L + R + SL + S + SR
};
const int8_t ff_dca_lfe_index[16] = {
1, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 1, 3, 2, 3
};
@ -8415,25 +8135,6 @@ const int8_t ff_dca_channel_reorder_lfe[16][9] = {
{ 4, 2, 5, 0, 1, 6, 8, 7, -1 },
};
const int8_t ff_dca_channel_reorder_lfe_xch[16][9] = {
{ 0, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 3, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 3, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 3, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 3, -1, -1, -1, -1, -1, -1 },
{ 2, 0, 1, 4, -1, -1, -1, -1, -1 },
{ 0, 1, 3, 4, -1, -1, -1, -1, -1 },
{ 2, 0, 1, 4, 5, -1, -1, -1, -1 },
{ 0, 1, 4, 5, 3, -1, -1, -1, -1 },
{ 2, 0, 1, 5, 6, 4, -1, -1, -1 },
{ 3, 4, 0, 1, 6, 7, 5, -1, -1 },
{ 2, 0, 1, 4, 5, 6, 7, -1, -1 },
{ 0, 6, 4, 5, 2, 3, 7, -1, -1 },
{ 4, 2, 5, 0, 1, 7, 8, 6, -1 },
{ 5, 6, 0, 1, 8, 3, 9, 4, 7 },
{ 4, 2, 5, 0, 1, 6, 9, 8, 7 },
};
const int8_t ff_dca_channel_reorder_nolfe[16][9] = {
{ 0, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, -1, -1, -1, -1, -1, -1, -1 },
@ -8453,25 +8154,6 @@ const int8_t ff_dca_channel_reorder_nolfe[16][9] = {
{ 3, 2, 4, 0, 1, 5, 7, 6, -1 },
};
const int8_t ff_dca_channel_reorder_nolfe_xch[16][9] = {
{ 0, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 2, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 2, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 2, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 2, -1, -1, -1, -1, -1, -1 },
{ 2, 0, 1, 3, -1, -1, -1, -1, -1 },
{ 0, 1, 2, 3, -1, -1, -1, -1, -1 },
{ 2, 0, 1, 3, 4, -1, -1, -1, -1 },
{ 0, 1, 3, 4, 2, -1, -1, -1, -1 },
{ 2, 0, 1, 4, 5, 3, -1, -1, -1 },
{ 2, 3, 0, 1, 5, 6, 4, -1, -1 },
{ 2, 0, 1, 3, 4, 5, 6, -1, -1 },
{ 0, 5, 3, 4, 1, 2, 6, -1, -1 },
{ 3, 2, 4, 0, 1, 6, 7, 5, -1 },
{ 4, 5, 0, 1, 7, 2, 8, 3, 6 },
{ 3, 2, 4, 0, 1, 5, 8, 7, 6 },
};
const uint16_t ff_dca_vlc_offs[63] = {
0, 512, 640, 768, 1282, 1794, 2436, 3080, 3770, 4454, 5364,
5372, 5380, 5388, 5392, 5396, 5412, 5420, 5428, 5460, 5492, 5508,

View File

@ -45,7 +45,6 @@ extern const float ff_dca_fir_32bands_nonperfect[512];
extern const float ff_dca_lfe_fir_64[256];
extern const float ff_dca_lfe_fir_128[256];
extern const float ff_dca_lfe_xll_fir_64[256];
extern const float ff_dca_fir_64bands[1024];
#define FF_DCA_DMIXTABLE_SIZE 242
@ -54,21 +53,12 @@ extern const float ff_dca_fir_64bands[1024];
extern const uint16_t ff_dca_dmixtable[FF_DCA_DMIXTABLE_SIZE];
extern const uint32_t ff_dca_inv_dmixtable[FF_DCA_INV_DMIXTABLE_SIZE];
extern const float ff_dca_default_coeffs[10][6][2];
extern const uint32_t ff_dca_map_xxch_to_native[28];
extern const int ff_dca_ext_audio_descr_mask[8];
extern const uint64_t ff_dca_core_channel_layout[16];
extern const int32_t ff_dca_sampling_freqs[16];
extern const int8_t ff_dca_lfe_index[16];
extern const int8_t ff_dca_channel_reorder_lfe[16][9];
extern const int8_t ff_dca_channel_reorder_lfe_xch[16][9];
extern const int8_t ff_dca_channel_reorder_nolfe[16][9];
extern const int8_t ff_dca_channel_reorder_nolfe_xch[16][9];
extern const uint16_t ff_dca_vlc_offs[63];

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +0,0 @@
/*
* Copyright (c) 2004 Gildas Bazin
* Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
*
* 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 "config.h"
#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
#include "dcadsp.h"
#include "dcamath.h"
static void decode_hf_c(int32_t dst[DCA_SUBBANDS][SAMPLES_PER_SUBBAND],
const int32_t vq_num[DCA_SUBBANDS],
const int8_t hf_vq[1024][32], intptr_t vq_offset,
int32_t scale[DCA_SUBBANDS][2],
intptr_t start, intptr_t end)
{
int i, j;
for (j = start; j < end; j++) {
const int8_t *ptr = &hf_vq[vq_num[j]][vq_offset];
for (i = 0; i < 8; i++)
dst[j][i] = ptr[i] * scale[j][0] + 8 >> 4;
}
}
static inline void dca_lfe_fir(float *out, const float *in, const float *coefs,
int decifactor)
{
float *out2 = out + 2 * decifactor - 1;
int num_coeffs = 256 / decifactor;
int j, k;
/* One decimated sample generates 2*decifactor interpolated ones */
for (k = 0; k < decifactor; k++) {
float v0 = 0.0;
float v1 = 0.0;
for (j = 0; j < num_coeffs; j++, coefs++) {
v0 += in[-j] * *coefs;
v1 += in[j + 1 - num_coeffs] * *coefs;
}
*out++ = v0;
*out2-- = v1;
}
}
static void dca_qmf_32_subbands(float samples_in[DCA_SUBBANDS][SAMPLES_PER_SUBBAND], int sb_act,
SynthFilterContext *synth, FFTContext *imdct,
float synth_buf_ptr[512],
int *synth_buf_offset, float synth_buf2[32],
const float window[512], float *samples_out,
float raXin[32], float scale)
{
int i;
int subindex;
for (i = sb_act; i < 32; i++)
raXin[i] = 0.0;
/* Reconstructed channel sample index */
for (subindex = 0; subindex < 8; subindex++) {
/* Load in one sample from each subband and clear inactive subbands */
for (i = 0; i < sb_act; i++) {
unsigned sign = (i - 1) & 2;
uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
AV_WN32A(&raXin[i], v);
}
synth->synth_filter_float(imdct, synth_buf_ptr, synth_buf_offset,
synth_buf2, window, samples_out, raXin,
scale);
samples_out += 32;
}
}
static void dequantize_c(int32_t *samples, uint32_t step_size, uint32_t scale)
{
int64_t step = (int64_t)step_size * scale;
int shift, i;
int32_t step_scale;
if (step > (1 << 23))
shift = av_log2(step >> 23) + 1;
else
shift = 0;
step_scale = (int32_t)(step >> shift);
for (i = 0; i < SAMPLES_PER_SUBBAND; i++)
samples[i] = dca_clip23(dca_norm((int64_t)samples[i] * step_scale, 22 - shift));
}
static void dca_lfe_fir0_c(float *out, const float *in, const float *coefs)
{
dca_lfe_fir(out, in, coefs, 32);
}
static void dca_lfe_fir1_c(float *out, const float *in, const float *coefs)
{
dca_lfe_fir(out, in, coefs, 64);
}
av_cold void ff_dcadsp_init(DCADSPContext *s)
{
s->lfe_fir[0] = dca_lfe_fir0_c;
s->lfe_fir[1] = dca_lfe_fir1_c;
s->qmf_32_subbands = dca_qmf_32_subbands;
s->decode_hf = decode_hf_c;
s->dequantize = dequantize_c;
if (ARCH_AARCH64)
ff_dcadsp_init_aarch64(s);
if (ARCH_ARM)
ff_dcadsp_init_arm(s);
if (ARCH_X86)
ff_dcadsp_init_x86(s);
}

View File

@ -1,51 +0,0 @@
/*
* 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_DCADSP_H
#define AVCODEC_DCADSP_H
#include "avfft.h"
#include "synth_filter.h"
#define DCA_SUBBANDS_X96K 64
#define DCA_SUBBANDS 64
#define SAMPLES_PER_SUBBAND 8 // number of samples per subband per subsubframe
typedef struct DCADSPContext {
void (*lfe_fir[2])(float *out, const float *in, const float *coefs);
void (*qmf_32_subbands)(float samples_in[DCA_SUBBANDS][SAMPLES_PER_SUBBAND], int sb_act,
SynthFilterContext *synth, FFTContext *imdct,
float synth_buf_ptr[512],
int *synth_buf_offset, float synth_buf2[32],
const float window[512], float *samples_out,
float raXin[32], float scale);
void (*decode_hf)(int32_t dst[DCA_SUBBANDS][SAMPLES_PER_SUBBAND],
const int32_t vq_num[DCA_SUBBANDS],
const int8_t hf_vq[1024][32], intptr_t vq_offset,
int32_t scale[DCA_SUBBANDS][2],
intptr_t start, intptr_t end);
void (*dequantize)(int32_t *samples, uint32_t step_size, uint32_t scale);
} DCADSPContext;
void ff_dcadsp_init(DCADSPContext *s);
void ff_dcadsp_init_aarch64(DCADSPContext *s);
void ff_dcadsp_init_arm(DCADSPContext *s);
void ff_dcadsp_init_x86(DCADSPContext *s);
#endif /* AVCODEC_DCADSP_H */

View File

@ -1,47 +0,0 @@
/*
* 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_DCAMATH_H
#define AVCODEC_DCAMATH_H
#include "libavutil/common.h"
// clip a signed integer into the (-2^23), (2^23-1) range
static inline int dca_clip23(int a)
{
return av_clip_intp2(a, 23);
}
static inline int32_t dca_norm(int64_t a, int bits)
{
if (bits > 0)
return (int32_t)((a + (INT64_C(1) << (bits - 1))) >> bits);
else
return (int32_t)a;
}
static inline int64_t dca_round(int64_t a, int bits)
{
if (bits > 0)
return (a + (INT64_C(1) << (bits - 1))) & ~((INT64_C(1) << bits) - 1);
else
return a;
}
#endif /* AVCODEC_DCAMATH_H */

View File

@ -44,8 +44,7 @@ OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp_init.o
OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp_init.o
OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o
OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o
OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp_init.o \
x86/synth_filter_init.o
#OBJS-$(CONFIG_DCA_DECODER) += x86/synth_filter_init.o
OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o
OBJS-$(CONFIG_HEVC_DECODER) += x86/hevcdsp_init.o
OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp_init.o
@ -133,8 +132,7 @@ YASM-OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp.o
YASM-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp.o
YASM-OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp.o
YASM-OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp.o
YASM-OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp.o \
x86/synth_filter.o
#YASM-OBJS-$(CONFIG_DCA_DECODER) += x86/synth_filter.o
YASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp_mmx.o x86/diracdsp_yasm.o \
x86/dwt_yasm.o
YASM-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc.o

View File

@ -1,123 +0,0 @@
;******************************************************************************
;* SSE-optimized functions for the DCA decoder
;* Copyright (C) 2012-2014 Christophe Gisquet <christophe.gisquet@gmail.com>
;*
;* 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/x86/x86util.asm"
SECTION_RODATA
pf_inv16: times 4 dd 0x3D800000 ; 1/16
SECTION .text
; %1=v0/v1 %2=in1 %3=in2
%macro FIR_LOOP 2-3
.loop%1:
%define va m1
%define vb m2
%if %1
%define OFFSET 0
%else
%define OFFSET NUM_COEF*count
%endif
; for v0, incrementing and for v1, decrementing
mova va, [cf0q + OFFSET]
mova vb, [cf0q + OFFSET + 4*NUM_COEF]
%if %0 == 3
mova m4, [cf0q + OFFSET + mmsize]
mova m0, [cf0q + OFFSET + 4*NUM_COEF + mmsize]
%endif
mulps va, %2
mulps vb, %2
%if %0 == 3
%if cpuflag(fma3)
fmaddps va, m4, %3, va
fmaddps vb, m0, %3, vb
%else
mulps m4, %3
mulps m0, %3
addps va, m4
addps vb, m0
%endif
%endif
; va = va1 va2 va3 va4
; vb = vb1 vb2 vb3 vb4
%if %1
SWAP va, vb
%endif
mova m4, va
unpcklps va, vb ; va3 vb3 va4 vb4
unpckhps m4, vb ; va1 vb1 va2 vb2
addps m4, va ; va1+3 vb1+3 va2+4 vb2+4
movhlps vb, m4 ; va1+3 vb1+3
addps vb, m4 ; va0..4 vb0..4
movlps [outq + count], vb
%if %1
sub cf0q, 8*NUM_COEF
%endif
add count, 8
jl .loop%1
%endmacro
; void dca_lfe_fir(float *out, float *in, float *coefs)
%macro DCA_LFE_FIR 1
cglobal dca_lfe_fir%1, 3,3,6-%1, out, in, cf0
%define IN1 m3
%define IN2 m5
%define count inq
%define NUM_COEF 4*(2-%1)
%define NUM_OUT 32*(%1+1)
movu IN1, [inq + 4 - 1*mmsize]
shufps IN1, IN1, q0123
%if %1 == 0
movu IN2, [inq + 4 - 2*mmsize]
shufps IN2, IN2, q0123
%endif
mov count, -4*NUM_OUT
add cf0q, 4*NUM_COEF*NUM_OUT
add outq, 4*NUM_OUT
; compute v0 first
%if %1 == 0
FIR_LOOP 0, IN1, IN2
%else
FIR_LOOP 0, IN1
%endif
shufps IN1, IN1, q0123
mov count, -4*NUM_OUT
; cf1 already correctly positioned
add outq, 4*NUM_OUT ; outq now at out2
sub cf0q, 8*NUM_COEF
%if %1 == 0
shufps IN2, IN2, q0123
FIR_LOOP 1, IN2, IN1
%else
FIR_LOOP 1, IN1
%endif
RET
%endmacro
INIT_XMM sse
DCA_LFE_FIR 0
DCA_LFE_FIR 1
%if HAVE_FMA3_EXTERNAL
INIT_XMM fma3
DCA_LFE_FIR 0
%endif

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2012-2014 Christophe Gisquet <christophe.gisquet@gmail.com>
*
* 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 "libavutil/cpu.h"
#include "libavutil/x86/cpu.h"
#include "libavcodec/dcadsp.h"
void ff_dca_lfe_fir0_sse(float *out, const float *in, const float *coefs);
void ff_dca_lfe_fir1_sse(float *out, const float *in, const float *coefs);
void ff_dca_lfe_fir0_fma3(float *out, const float *in, const float *coefs);
av_cold void ff_dcadsp_init_x86(DCADSPContext *s)
{
int cpu_flags = av_get_cpu_flags();
if (EXTERNAL_SSE(cpu_flags)) {
s->lfe_fir[0] = ff_dca_lfe_fir0_sse;
s->lfe_fir[1] = ff_dca_lfe_fir1_sse;
}
if (EXTERNAL_FMA3(cpu_flags)) {
s->lfe_fir[0] = ff_dca_lfe_fir0_fma3;
}
}

View File

@ -1,7 +1,7 @@
# libavcodec tests
AVCODECOBJS-$(CONFIG_ALAC_DECODER) += alacdsp.o
AVCODECOBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o
AVCODECOBJS-$(CONFIG_DCA_DECODER) += dcadsp.o synth_filter.o
#AVCODECOBJS-$(CONFIG_DCA_DECODER) += synth_filter.o
AVCODECOBJS-$(CONFIG_FLACDSP) += flacdsp.o
AVCODECOBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o
AVCODECOBJS-$(CONFIG_H264PRED) += h264pred.o

View File

@ -71,10 +71,9 @@ static const struct {
#if CONFIG_BSWAPDSP
{ "bswapdsp", checkasm_check_bswapdsp },
#endif
#if CONFIG_DCA_DECODER
{ "dcadsp", checkasm_check_dcadsp },
/* #if CONFIG_DCA_DECODER
{ "synth_filter", checkasm_check_synth_filter },
#endif
#endif*/
#if CONFIG_FLACDSP
{ "flacdsp", checkasm_check_flacdsp },
#endif

View File

@ -32,7 +32,6 @@
void checkasm_check_alacdsp(void);
void checkasm_check_bswapdsp(void);
void checkasm_check_dcadsp(void);
void checkasm_check_flacdsp(void);
void checkasm_check_fmtconvert(void);
void checkasm_check_h264pred(void);

View File

@ -1,92 +0,0 @@
/*
* Copyright (c) 2015 Janne Grunau
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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 <math.h>
#include <string.h>
#include <stdlib.h>
#include "libavutil/internal.h"
#include "libavutil/intfloat.h"
#include "libavcodec/dca.h"
#include "libavcodec/dcadsp.h"
#include "libavcodec/dcadata.h"
#include "checkasm.h"
#define randomize_lfe_fir(size) \
do { \
int i; \
for (i = 0; i < size; i++) { \
float f = (float)rnd() / (UINT_MAX >> 1) - 1.0f; \
in[i] = f; \
} \
for (i = 0; i < 256; i++) { \
float f = (float)rnd() / (UINT_MAX >> 1) - 1.0f; \
coeffs[i] = f; \
} \
} while (0)
#define check_lfe_fir(decifactor, eps) \
do { \
LOCAL_ALIGNED_16(float, in, [256 / decifactor]); \
LOCAL_ALIGNED_16(float, out0, [decifactor * 2]); \
LOCAL_ALIGNED_16(float, out1, [decifactor * 2]); \
LOCAL_ALIGNED_16(float, coeffs, [256]); \
int i; \
const float * in_ptr = in + (256 / decifactor) - 1; \
declare_func(void, float *out, const float *in, const float *coeffs); \
/* repeat the test several times */ \
for (i = 0; i < 32; i++) { \
int j; \
memset(out0, 0, sizeof(*out0) * 2 * decifactor); \
memset(out1, 0xFF, sizeof(*out1) * 2 * decifactor); \
randomize_lfe_fir(256 / decifactor); \
call_ref(out0, in_ptr, coeffs); \
call_new(out1, in_ptr, coeffs); \
for (j = 0; j < 2 * decifactor; j++) { \
if (!float_near_abs_eps(out0[j], out1[j], eps)) { \
if (0) { \
union av_intfloat32 x, y; x.f = out0[j]; y.f = out1[j]; \
fprintf(stderr, "%3d: %11g (0x%08x); %11g (0x%08x)\n", \
j, x.f, x.i, y.f, y.i); \
} \
fail(); \
break; \
} \
} \
bench_new(out1, in_ptr, coeffs); \
} \
} while (0)
void checkasm_check_dcadsp(void)
{
DCADSPContext c;
ff_dcadsp_init(&c);
/* values are limited to {-8, 8} so absolute epsilon is good enough */
if (check_func(c.lfe_fir[0], "dca_lfe_fir0"))
check_lfe_fir(32, 1.0e-6f);
if (check_func(c.lfe_fir[1], "dca_lfe_fir1"))
check_lfe_fir(64, 1.0e-6f);
report("dcadsp");
}

View File

@ -99,14 +99,14 @@ FATE_ACODEC-$(call ENCDEC, ALAC, MOV) += fate-acodec-alac
fate-acodec-alac: FMT = mov
fate-acodec-alac: CODEC = alac -compression_level 1
FATE_ACODEC-$(call ENCDEC, DCA, DTS) += fate-acodec-dca
#FATE_ACODEC-$(call ENCDEC, DCA, DTS) += fate-acodec-dca
fate-acodec-dca: tests/data/asynth-44100-2.wav
fate-acodec-dca: SRC = tests/data/asynth-44100-2.wav
fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact
fate-acodec-dca: CMP = oneline
fate-acodec-dca: REF = 7ffdefdf47069289990755c79387cc90
FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2
#FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2
fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact
fate-acodec-dca2: REF = $(SRC)
fate-acodec-dca2: CMP = stddev

View File

@ -21,12 +21,7 @@ fate-dca-core: CMD = pcm -i $(TARGET_SAMPLES)/dts/dts.ts
fate-dca-core: CMP = oneoff
fate-dca-core: REF = $(SAMPLES)/dts/dts.pcm
FATE_DCA-$(CONFIG_DTS_DEMUXER) += fate-dca-xll
fate-dca-xll: CMD = pcm -disable_xll 0 -i $(TARGET_SAMPLES)/dts/master_audio_7.1_24bit.dts
fate-dca-xll: CMP = oneoff
fate-dca-xll: REF = $(SAMPLES)/dts/master_audio_7.1_24bit_2.pcm
FATE_SAMPLES_AUDIO-$(CONFIG_DCA_DECODER) += $(FATE_DCA-yes)
#FATE_SAMPLES_AUDIO-$(CONFIG_DCA_DECODER) += $(FATE_DCA-yes)
fate-dca: $(FATE_DCA-yes)
FATE_SAMPLES_AUDIO-$(call DEMDEC, DSICIN, DSICINAUDIO) += fate-delphine-cin-audio
@ -36,7 +31,7 @@ FATE_SAMPLES_AUDIO-$(call DEMDEC, DSS, DSS_SP) += fate-dss-lp fate-dss-sp
fate-dss-lp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/lp.dss -frames 30
fate-dss-sp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/sp.dss -frames 30
FATE_SAMPLES_AUDIO-$(call DEMDEC, DTS, DCA) += fate-dts_es
#FATE_SAMPLES_AUDIO-$(call DEMDEC, DTS, DCA) += fate-dts_es
fate-dts_es: CMD = pcm -i $(TARGET_SAMPLES)/dts/dts_es.dts
fate-dts_es: CMP = oneoff
fate-dts_es: REF = $(SAMPLES)/dts/dts_es_2.pcm