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:
parent
b552f3afa2
commit
4608996772
1
configure
vendored
1
configure
vendored
@ -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"
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
@ -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);
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
287
libavcodec/dca.h
287
libavcodec/dca.h
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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 = ¶m_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;
|
||||
}
|
@ -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,
|
||||
|
@ -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];
|
||||
|
||||
|
2067
libavcodec/dcadec.c
2067
libavcodec/dcadec.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
@ -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 */
|
@ -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 */
|
@ -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
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user