Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 4348 → Rev 4349

/contrib/sdk/sources/ffmpeg/libswresample/Makefile
0,0 → 1,18
include $(SUBDIR)../config.mak
 
NAME = swresample
FFLIBS = avutil
 
HEADERS = swresample.h \
version.h \
 
OBJS = audioconvert.o \
dither.o \
rematrix.o \
resample.o \
swresample.o \
 
OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o
OBJS-$(CONFIG_SHARED) += log2_tab.o
 
TESTPROGS = swresample
/contrib/sdk/sources/ffmpeg/libswresample/arm/Makefile
0,0 → 1,2
OBJS += arm/audio_convert_init.o
NEON-OBJS += arm/audio_convert_neon.o
/contrib/sdk/sources/ffmpeg/libswresample/arm/audio_convert_init.c
0,0 → 1,67
/*
* This file is part of libswresample.
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#include <stdint.h>
 
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "libavutil/arm/cpu.h"
#include "libavutil/samplefmt.h"
#include "libswresample/swresample_internal.h"
#include "libswresample/audioconvert.h"
 
void swri_oldapi_conv_flt_to_s16_neon(int16_t *dst, const float *src, int len);
void swri_oldapi_conv_fltp_to_s16_2ch_neon(int16_t *dst, float *const *src, int len, int channels);
void swri_oldapi_conv_fltp_to_s16_nch_neon(int16_t *dst, float *const *src, int len, int channels);
 
static void conv_flt_to_s16_neon(uint8_t **dst, const uint8_t **src, int len){
swri_oldapi_conv_flt_to_s16_neon((int16_t*)*dst, (const float*)*src, len);
}
 
static void conv_fltp_to_s16_2ch_neon(uint8_t **dst, const uint8_t **src, int len){
swri_oldapi_conv_fltp_to_s16_2ch_neon((int16_t*)*dst, (float *const*)src, len, 2);
}
 
static void conv_fltp_to_s16_nch_neon(uint8_t **dst, const uint8_t **src, int len){
int channels;
for(channels=3; channels<SWR_CH_MAX && src[channels]; channels++)
;
swri_oldapi_conv_fltp_to_s16_nch_neon((int16_t*)*dst, (float *const*)src, len, channels);
}
 
av_cold void swri_audio_convert_init_arm(struct AudioConvert *ac,
enum AVSampleFormat out_fmt,
enum AVSampleFormat in_fmt,
int channels)
{
int cpu_flags = av_get_cpu_flags();
 
ac->simd_f= NULL;
 
if (have_neon(cpu_flags)) {
if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP)
ac->simd_f = conv_flt_to_s16_neon;
if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels == 2)
ac->simd_f = conv_fltp_to_s16_2ch_neon;
if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels > 2)
ac->simd_f = conv_fltp_to_s16_nch_neon;
if(ac->simd_f)
ac->in_simd_align_mask = ac->out_simd_align_mask = 15;
}
}
/contrib/sdk/sources/ffmpeg/libswresample/arm/audio_convert_neon.S
0,0 → 1,363
/*
* Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
*
* This file is part of libswresample.
*
* libswresample 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.
*
* libswresample 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 libswresample; 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/asm.S"
 
function swri_oldapi_conv_flt_to_s16_neon, export=1
subs r2, r2, #8
vld1.32 {q0}, [r1,:128]!
vcvt.s32.f32 q8, q0, #31
vld1.32 {q1}, [r1,:128]!
vcvt.s32.f32 q9, q1, #31
beq 3f
bics r12, r2, #15
beq 2f
1: subs r12, r12, #16
vqrshrn.s32 d4, q8, #16
vld1.32 {q0}, [r1,:128]!
vcvt.s32.f32 q0, q0, #31
vqrshrn.s32 d5, q9, #16
vld1.32 {q1}, [r1,:128]!
vcvt.s32.f32 q1, q1, #31
vqrshrn.s32 d6, q0, #16
vst1.16 {q2}, [r0,:128]!
vqrshrn.s32 d7, q1, #16
vld1.32 {q8}, [r1,:128]!
vcvt.s32.f32 q8, q8, #31
vld1.32 {q9}, [r1,:128]!
vcvt.s32.f32 q9, q9, #31
vst1.16 {q3}, [r0,:128]!
bne 1b
ands r2, r2, #15
beq 3f
2: vld1.32 {q0}, [r1,:128]!
vqrshrn.s32 d4, q8, #16
vcvt.s32.f32 q0, q0, #31
vld1.32 {q1}, [r1,:128]!
vqrshrn.s32 d5, q9, #16
vcvt.s32.f32 q1, q1, #31
vqrshrn.s32 d6, q0, #16
vst1.16 {q2}, [r0,:128]!
vqrshrn.s32 d7, q1, #16
vst1.16 {q3}, [r0,:128]!
bx lr
3: vqrshrn.s32 d4, q8, #16
vqrshrn.s32 d5, q9, #16
vst1.16 {q2}, [r0,:128]!
bx lr
endfunc
 
function swri_oldapi_conv_fltp_to_s16_2ch_neon, export=1
ldm r1, {r1, r3}
subs r2, r2, #8
vld1.32 {q0}, [r1,:128]!
vcvt.s32.f32 q8, q0, #31
vld1.32 {q1}, [r1,:128]!
vcvt.s32.f32 q9, q1, #31
vld1.32 {q10}, [r3,:128]!
vcvt.s32.f32 q10, q10, #31
vld1.32 {q11}, [r3,:128]!
vcvt.s32.f32 q11, q11, #31
beq 3f
bics r12, r2, #15
beq 2f
1: subs r12, r12, #16
vld1.32 {q0}, [r1,:128]!
vcvt.s32.f32 q0, q0, #31
vsri.32 q10, q8, #16
vld1.32 {q1}, [r1,:128]!
vcvt.s32.f32 q1, q1, #31
vld1.32 {q12}, [r3,:128]!
vcvt.s32.f32 q12, q12, #31
vld1.32 {q13}, [r3,:128]!
vsri.32 q11, q9, #16
vst1.16 {q10}, [r0,:128]!
vcvt.s32.f32 q13, q13, #31
vst1.16 {q11}, [r0,:128]!
vsri.32 q12, q0, #16
vld1.32 {q8}, [r1,:128]!
vsri.32 q13, q1, #16
vst1.16 {q12}, [r0,:128]!
vcvt.s32.f32 q8, q8, #31
vld1.32 {q9}, [r1,:128]!
vcvt.s32.f32 q9, q9, #31
vld1.32 {q10}, [r3,:128]!
vcvt.s32.f32 q10, q10, #31
vld1.32 {q11}, [r3,:128]!
vcvt.s32.f32 q11, q11, #31
vst1.16 {q13}, [r0,:128]!
bne 1b
ands r2, r2, #15
beq 3f
2: vsri.32 q10, q8, #16
vld1.32 {q0}, [r1,:128]!
vcvt.s32.f32 q0, q0, #31
vld1.32 {q1}, [r1,:128]!
vcvt.s32.f32 q1, q1, #31
vld1.32 {q12}, [r3,:128]!
vcvt.s32.f32 q12, q12, #31
vsri.32 q11, q9, #16
vld1.32 {q13}, [r3,:128]!
vcvt.s32.f32 q13, q13, #31
vst1.16 {q10}, [r0,:128]!
vsri.32 q12, q0, #16
vst1.16 {q11}, [r0,:128]!
vsri.32 q13, q1, #16
vst1.16 {q12-q13},[r0,:128]!
bx lr
3: vsri.32 q10, q8, #16
vsri.32 q11, q9, #16
vst1.16 {q10-q11},[r0,:128]!
bx lr
endfunc
 
function swri_oldapi_conv_fltp_to_s16_nch_neon, export=1
cmp r3, #2
itt lt
ldrlt r1, [r1]
blt swri_oldapi_conv_flt_to_s16_neon
beq swri_oldapi_conv_fltp_to_s16_2ch_neon
 
push {r4-r8, lr}
cmp r3, #4
lsl r12, r3, #1
blt 4f
 
@ 4 channels
5: ldm r1!, {r4-r7}
mov lr, r2
mov r8, r0
vld1.32 {q8}, [r4,:128]!
vcvt.s32.f32 q8, q8, #31
vld1.32 {q9}, [r5,:128]!
vcvt.s32.f32 q9, q9, #31
vld1.32 {q10}, [r6,:128]!
vcvt.s32.f32 q10, q10, #31
vld1.32 {q11}, [r7,:128]!
vcvt.s32.f32 q11, q11, #31
6: subs lr, lr, #8
vld1.32 {q0}, [r4,:128]!
vcvt.s32.f32 q0, q0, #31
vsri.32 q9, q8, #16
vld1.32 {q1}, [r5,:128]!
vcvt.s32.f32 q1, q1, #31
vsri.32 q11, q10, #16
vld1.32 {q2}, [r6,:128]!
vcvt.s32.f32 q2, q2, #31
vzip.32 d18, d22
vld1.32 {q3}, [r7,:128]!
vcvt.s32.f32 q3, q3, #31
vzip.32 d19, d23
vst1.16 {d18}, [r8], r12
vsri.32 q1, q0, #16
vst1.16 {d22}, [r8], r12
vsri.32 q3, q2, #16
vst1.16 {d19}, [r8], r12
vzip.32 d2, d6
vst1.16 {d23}, [r8], r12
vzip.32 d3, d7
beq 7f
vld1.32 {q8}, [r4,:128]!
vcvt.s32.f32 q8, q8, #31
vst1.16 {d2}, [r8], r12
vld1.32 {q9}, [r5,:128]!
vcvt.s32.f32 q9, q9, #31
vst1.16 {d6}, [r8], r12
vld1.32 {q10}, [r6,:128]!
vcvt.s32.f32 q10, q10, #31
vst1.16 {d3}, [r8], r12
vld1.32 {q11}, [r7,:128]!
vcvt.s32.f32 q11, q11, #31
vst1.16 {d7}, [r8], r12
b 6b
7: vst1.16 {d2}, [r8], r12
vst1.16 {d6}, [r8], r12
vst1.16 {d3}, [r8], r12
vst1.16 {d7}, [r8], r12
subs r3, r3, #4
it eq
popeq {r4-r8, pc}
cmp r3, #4
add r0, r0, #8
bge 5b
 
@ 2 channels
4: cmp r3, #2
blt 4f
ldm r1!, {r4-r5}
mov lr, r2
mov r8, r0
tst lr, #8
vld1.32 {q8}, [r4,:128]!
vcvt.s32.f32 q8, q8, #31
vld1.32 {q9}, [r5,:128]!
vcvt.s32.f32 q9, q9, #31
vld1.32 {q10}, [r4,:128]!
vcvt.s32.f32 q10, q10, #31
vld1.32 {q11}, [r5,:128]!
vcvt.s32.f32 q11, q11, #31
beq 6f
subs lr, lr, #8
beq 7f
vsri.32 d18, d16, #16
vsri.32 d19, d17, #16
vld1.32 {q8}, [r4,:128]!
vcvt.s32.f32 q8, q8, #31
vst1.32 {d18[0]}, [r8], r12
vsri.32 d22, d20, #16
vst1.32 {d18[1]}, [r8], r12
vsri.32 d23, d21, #16
vst1.32 {d19[0]}, [r8], r12
vst1.32 {d19[1]}, [r8], r12
vld1.32 {q9}, [r5,:128]!
vcvt.s32.f32 q9, q9, #31
vst1.32 {d22[0]}, [r8], r12
vst1.32 {d22[1]}, [r8], r12
vld1.32 {q10}, [r4,:128]!
vcvt.s32.f32 q10, q10, #31
vst1.32 {d23[0]}, [r8], r12
vst1.32 {d23[1]}, [r8], r12
vld1.32 {q11}, [r5,:128]!
vcvt.s32.f32 q11, q11, #31
6: subs lr, lr, #16
vld1.32 {q0}, [r4,:128]!
vcvt.s32.f32 q0, q0, #31
vsri.32 d18, d16, #16
vld1.32 {q1}, [r5,:128]!
vcvt.s32.f32 q1, q1, #31
vsri.32 d19, d17, #16
vld1.32 {q2}, [r4,:128]!
vcvt.s32.f32 q2, q2, #31
vld1.32 {q3}, [r5,:128]!
vcvt.s32.f32 q3, q3, #31
vst1.32 {d18[0]}, [r8], r12
vsri.32 d22, d20, #16
vst1.32 {d18[1]}, [r8], r12
vsri.32 d23, d21, #16
vst1.32 {d19[0]}, [r8], r12
vsri.32 d2, d0, #16
vst1.32 {d19[1]}, [r8], r12
vsri.32 d3, d1, #16
vst1.32 {d22[0]}, [r8], r12
vsri.32 d6, d4, #16
vst1.32 {d22[1]}, [r8], r12
vsri.32 d7, d5, #16
vst1.32 {d23[0]}, [r8], r12
vst1.32 {d23[1]}, [r8], r12
beq 6f
vld1.32 {q8}, [r4,:128]!
vcvt.s32.f32 q8, q8, #31
vst1.32 {d2[0]}, [r8], r12
vst1.32 {d2[1]}, [r8], r12
vld1.32 {q9}, [r5,:128]!
vcvt.s32.f32 q9, q9, #31
vst1.32 {d3[0]}, [r8], r12
vst1.32 {d3[1]}, [r8], r12
vld1.32 {q10}, [r4,:128]!
vcvt.s32.f32 q10, q10, #31
vst1.32 {d6[0]}, [r8], r12
vst1.32 {d6[1]}, [r8], r12
vld1.32 {q11}, [r5,:128]!
vcvt.s32.f32 q11, q11, #31
vst1.32 {d7[0]}, [r8], r12
vst1.32 {d7[1]}, [r8], r12
bgt 6b
6: vst1.32 {d2[0]}, [r8], r12
vst1.32 {d2[1]}, [r8], r12
vst1.32 {d3[0]}, [r8], r12
vst1.32 {d3[1]}, [r8], r12
vst1.32 {d6[0]}, [r8], r12
vst1.32 {d6[1]}, [r8], r12
vst1.32 {d7[0]}, [r8], r12
vst1.32 {d7[1]}, [r8], r12
b 8f
7: vsri.32 d18, d16, #16
vsri.32 d19, d17, #16
vst1.32 {d18[0]}, [r8], r12
vsri.32 d22, d20, #16
vst1.32 {d18[1]}, [r8], r12
vsri.32 d23, d21, #16
vst1.32 {d19[0]}, [r8], r12
vst1.32 {d19[1]}, [r8], r12
vst1.32 {d22[0]}, [r8], r12
vst1.32 {d22[1]}, [r8], r12
vst1.32 {d23[0]}, [r8], r12
vst1.32 {d23[1]}, [r8], r12
8: subs r3, r3, #2
add r0, r0, #4
it eq
popeq {r4-r8, pc}
 
@ 1 channel
4: ldr r4, [r1]
tst r2, #8
mov lr, r2
mov r5, r0
vld1.32 {q0}, [r4,:128]!
vcvt.s32.f32 q0, q0, #31
vld1.32 {q1}, [r4,:128]!
vcvt.s32.f32 q1, q1, #31
bne 8f
6: subs lr, lr, #16
vld1.32 {q2}, [r4,:128]!
vcvt.s32.f32 q2, q2, #31
vld1.32 {q3}, [r4,:128]!
vcvt.s32.f32 q3, q3, #31
vst1.16 {d0[1]}, [r5,:16], r12
vst1.16 {d0[3]}, [r5,:16], r12
vst1.16 {d1[1]}, [r5,:16], r12
vst1.16 {d1[3]}, [r5,:16], r12
vst1.16 {d2[1]}, [r5,:16], r12
vst1.16 {d2[3]}, [r5,:16], r12
vst1.16 {d3[1]}, [r5,:16], r12
vst1.16 {d3[3]}, [r5,:16], r12
beq 7f
vld1.32 {q0}, [r4,:128]!
vcvt.s32.f32 q0, q0, #31
vld1.32 {q1}, [r4,:128]!
vcvt.s32.f32 q1, q1, #31
7: vst1.16 {d4[1]}, [r5,:16], r12
vst1.16 {d4[3]}, [r5,:16], r12
vst1.16 {d5[1]}, [r5,:16], r12
vst1.16 {d5[3]}, [r5,:16], r12
vst1.16 {d6[1]}, [r5,:16], r12
vst1.16 {d6[3]}, [r5,:16], r12
vst1.16 {d7[1]}, [r5,:16], r12
vst1.16 {d7[3]}, [r5,:16], r12
bgt 6b
pop {r4-r8, pc}
8: subs lr, lr, #8
vst1.16 {d0[1]}, [r5,:16], r12
vst1.16 {d0[3]}, [r5,:16], r12
vst1.16 {d1[1]}, [r5,:16], r12
vst1.16 {d1[3]}, [r5,:16], r12
vst1.16 {d2[1]}, [r5,:16], r12
vst1.16 {d2[3]}, [r5,:16], r12
vst1.16 {d3[1]}, [r5,:16], r12
vst1.16 {d3[3]}, [r5,:16], r12
it eq
popeq {r4-r8, pc}
vld1.32 {q0}, [r4,:128]!
vcvt.s32.f32 q0, q0, #31
vld1.32 {q1}, [r4,:128]!
vcvt.s32.f32 q1, q1, #31
b 6b
endfunc
/contrib/sdk/sources/ffmpeg/libswresample/audioconvert.c
0,0 → 1,224
/*
* audio conversion
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
*
* 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
*/
 
/**
* @file
* audio conversion
* @author Michael Niedermayer <michaelni@gmx.at>
*/
 
#include "libavutil/avstring.h"
#include "libavutil/avassert.h"
#include "libavutil/libm.h"
#include "libavutil/samplefmt.h"
#include "audioconvert.h"
 
 
#define CONV_FUNC_NAME(dst_fmt, src_fmt) conv_ ## src_fmt ## _to_ ## dst_fmt
 
//FIXME rounding ?
#define CONV_FUNC(ofmt, otype, ifmt, expr)\
static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end)\
{\
uint8_t *end2 = end - 3*os;\
while(po < end2){\
*(otype*)po = expr; pi += is; po += os;\
*(otype*)po = expr; pi += is; po += os;\
*(otype*)po = expr; pi += is; po += os;\
*(otype*)po = expr; pi += is; po += os;\
}\
while(po < end){\
*(otype*)po = expr; pi += is; po += os;\
}\
}
 
//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi)
CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0f/ (1<<7)))
CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi)
CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16)
CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0f/ (1<<15)))
CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16)
CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi)
CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0f/ (1U<<31)))
CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31)))
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80))
CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15))))
CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi)
CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80))
CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15))))
CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi)
CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
 
#define FMT_PAIR_FUNC(out, in) [out + AV_SAMPLE_FMT_NB*in] = CONV_FUNC_NAME(out, in)
 
static conv_func_type * const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB*AV_SAMPLE_FMT_NB] = {
FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_U8 ),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8 ),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8 ),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8 ),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8 ),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_S16),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_S32),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_FLT),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_DBL),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL),
FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL),
};
 
static void cpy1(uint8_t **dst, const uint8_t **src, int len){
memcpy(*dst, *src, len);
}
static void cpy2(uint8_t **dst, const uint8_t **src, int len){
memcpy(*dst, *src, 2*len);
}
static void cpy4(uint8_t **dst, const uint8_t **src, int len){
memcpy(*dst, *src, 4*len);
}
static void cpy8(uint8_t **dst, const uint8_t **src, int len){
memcpy(*dst, *src, 8*len);
}
 
AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt,
enum AVSampleFormat in_fmt,
int channels, const int *ch_map,
int flags)
{
AudioConvert *ctx;
conv_func_type *f = fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt) + AV_SAMPLE_FMT_NB*av_get_packed_sample_fmt(in_fmt)];
 
if (!f)
return NULL;
ctx = av_mallocz(sizeof(*ctx));
if (!ctx)
return NULL;
 
if(channels == 1){
in_fmt = av_get_planar_sample_fmt( in_fmt);
out_fmt = av_get_planar_sample_fmt(out_fmt);
}
 
ctx->channels = channels;
ctx->conv_f = f;
ctx->ch_map = ch_map;
if (in_fmt == AV_SAMPLE_FMT_U8 || in_fmt == AV_SAMPLE_FMT_U8P)
memset(ctx->silence, 0x80, sizeof(ctx->silence));
 
if(out_fmt == in_fmt && !ch_map) {
switch(av_get_bytes_per_sample(in_fmt)){
case 1:ctx->simd_f = cpy1; break;
case 2:ctx->simd_f = cpy2; break;
case 4:ctx->simd_f = cpy4; break;
case 8:ctx->simd_f = cpy8; break;
}
}
 
if(HAVE_YASM && HAVE_MMX) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);
if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);
 
return ctx;
}
 
void swri_audio_convert_free(AudioConvert **ctx)
{
av_freep(ctx);
}
 
int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len)
{
int ch;
int off=0;
const int os= (out->planar ? 1 :out->ch_count) *out->bps;
unsigned misaligned = 0;
 
av_assert0(ctx->channels == out->ch_count);
 
if (ctx->in_simd_align_mask) {
int planes = in->planar ? in->ch_count : 1;
unsigned m = 0;
for (ch = 0; ch < planes; ch++)
m |= (intptr_t)in->ch[ch];
misaligned |= m & ctx->in_simd_align_mask;
}
if (ctx->out_simd_align_mask) {
int planes = out->planar ? out->ch_count : 1;
unsigned m = 0;
for (ch = 0; ch < planes; ch++)
m |= (intptr_t)out->ch[ch];
misaligned |= m & ctx->out_simd_align_mask;
}
 
//FIXME optimize common cases
 
if(ctx->simd_f && !ctx->ch_map && !misaligned){
off = len&~15;
av_assert1(off>=0);
av_assert1(off<=len);
av_assert2(ctx->channels == SWR_CH_MAX || !in->ch[ctx->channels]);
if(off>0){
if(out->planar == in->planar){
int planes = out->planar ? out->ch_count : 1;
for(ch=0; ch<planes; ch++){
ctx->simd_f(out->ch+ch, (const uint8_t **)in->ch+ch, off * (out->planar ? 1 :out->ch_count));
}
}else{
ctx->simd_f(out->ch, (const uint8_t **)in->ch, off);
}
}
if(off == len)
return 0;
}
 
for(ch=0; ch<ctx->channels; ch++){
const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch;
const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps;
const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich];
uint8_t *po= out->ch[ch];
uint8_t *end= po + os*len;
if(!po)
continue;
ctx->conv_f(po+off*os, pi+off*is, is, os, end);
}
return 0;
}
/contrib/sdk/sources/ffmpeg/libswresample/audioconvert.h
0,0 → 1,78
/*
* audio conversion
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2008 Peter Ross
*
* 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 SWR_AUDIOCONVERT_H
#define SWR_AUDIOCONVERT_H
 
/**
* @file
* Audio format conversion routines
*/
 
 
#include "swresample_internal.h"
#include "libavutil/cpu.h"
 
 
typedef void (conv_func_type)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end);
typedef void (simd_func_type)(uint8_t **dst, const uint8_t **src, int len);
 
typedef struct AudioConvert {
int channels;
int in_simd_align_mask;
int out_simd_align_mask;
conv_func_type *conv_f;
simd_func_type *simd_f;
const int *ch_map;
uint8_t silence[8]; ///< silence input sample
}AudioConvert;
 
/**
* Create an audio sample format converter context
* @param out_fmt Output sample format
* @param in_fmt Input sample format
* @param channels Number of channels
* @param flags See AV_CPU_FLAG_xx
* @param ch_map list of the channels id to pick from the source stream, NULL
* if all channels must be selected
* @return NULL on error
*/
AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt,
enum AVSampleFormat in_fmt,
int channels, const int *ch_map,
int flags);
 
/**
* Free audio sample format converter context.
* and set the pointer to NULL
*/
void swri_audio_convert_free(AudioConvert **ctx);
 
/**
* Convert between audio sample formats
* @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel.
* @param[in] in array of input buffers for each channel
* @param len length of audio frame size (measured in samples)
*/
int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len);
 
#endif /* AUDIOCONVERT_H */
/contrib/sdk/sources/ffmpeg/libswresample/dither.c
0,0 → 1,148
/*
* Copyright (C) 2012-2013 Michael Niedermayer (michaelni@gmx.at)
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#include "libavutil/avassert.h"
#include "swresample_internal.h"
 
#include "noise_shaping_data.c"
 
void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt) {
double scale = s->dither.noise_scale;
#define TMP_EXTRA 2
double *tmp = av_malloc((len + TMP_EXTRA) * sizeof(double));
int i;
 
for(i=0; i<len + TMP_EXTRA; i++){
double v;
seed = seed* 1664525 + 1013904223;
 
switch(s->dither.method){
case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
default:
av_assert0(s->dither.method < SWR_DITHER_NB);
v = ((double)seed) / UINT_MAX;
seed = seed*1664525 + 1013904223;
v-= ((double)seed) / UINT_MAX;
break;
}
tmp[i] = v;
}
 
for(i=0; i<len; i++){
double v;
 
switch(s->dither.method){
default:
av_assert0(s->dither.method < SWR_DITHER_NB);
v = tmp[i];
break;
case SWR_DITHER_TRIANGULAR_HIGHPASS :
v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6);
break;
}
 
v*= scale;
 
switch(noise_fmt){
case AV_SAMPLE_FMT_S16P: ((int16_t*)dst)[i] = v; break;
case AV_SAMPLE_FMT_S32P: ((int32_t*)dst)[i] = v; break;
case AV_SAMPLE_FMT_FLTP: ((float *)dst)[i] = v; break;
case AV_SAMPLE_FMT_DBLP: ((double *)dst)[i] = v; break;
default: av_assert0(0);
}
}
 
av_free(tmp);
}
 
int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt)
{
int i;
double scale = 0;
 
if (s->dither.method > SWR_DITHER_TRIANGULAR_HIGHPASS && s->dither.method <= SWR_DITHER_NS)
return AVERROR(EINVAL);
 
out_fmt = av_get_packed_sample_fmt(out_fmt);
in_fmt = av_get_packed_sample_fmt( in_fmt);
 
if(in_fmt == AV_SAMPLE_FMT_FLT || in_fmt == AV_SAMPLE_FMT_DBL){
if(out_fmt == AV_SAMPLE_FMT_S32) scale = 1.0/(1L<<31);
if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1L<<15);
if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1L<< 7);
}
if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S32 && (s->dither.output_sample_bits&31)) scale = 1;
if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1L<<16;
if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24;
if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8;
 
scale *= s->dither.scale;
 
if (out_fmt == AV_SAMPLE_FMT_S32 && s->dither.output_sample_bits)
scale *= 1<<(32-s->dither.output_sample_bits);
 
s->dither.ns_pos = 0;
s->dither.noise_scale= scale;
s->dither.ns_scale = scale;
s->dither.ns_scale_1 = scale ? 1/scale : 0;
memset(s->dither.ns_errors, 0, sizeof(s->dither.ns_errors));
for (i=0; filters[i].coefs; i++) {
const filter_t *f = &filters[i];
if (fabs(s->out_sample_rate - f->rate) / f->rate <= .05 && f->name == s->dither.method) {
int j;
s->dither.ns_taps = f->len;
for (j=0; j<f->len; j++)
s->dither.ns_coeffs[j] = f->coefs[j];
s->dither.ns_scale_1 *= 1 - exp(f->gain_cB * M_LN10 * 0.005) * 2 / (1<<(8*av_get_bytes_per_sample(out_fmt)));
break;
}
}
if (!filters[i].coefs && s->dither.method > SWR_DITHER_NS) {
av_log(s, AV_LOG_WARNING, "Requested noise shaping dither not available at this sampling rate, using triangular hp dither\n");
s->dither.method = SWR_DITHER_TRIANGULAR_HIGHPASS;
}
 
av_assert0(!s->preout.count);
s->dither.noise = s->preout;
s->dither.temp = s->preout;
if (s->dither.method > SWR_DITHER_NS) {
s->dither.noise.bps = 4;
s->dither.noise.fmt = AV_SAMPLE_FMT_FLTP;
s->dither.noise_scale = 1;
}
 
return 0;
}
 
#define TEMPLATE_DITHER_S16
#include "dither_template.c"
#undef TEMPLATE_DITHER_S16
 
#define TEMPLATE_DITHER_S32
#include "dither_template.c"
#undef TEMPLATE_DITHER_S32
 
#define TEMPLATE_DITHER_FLT
#include "dither_template.c"
#undef TEMPLATE_DITHER_FLT
 
#define TEMPLATE_DITHER_DBL
#include "dither_template.c"
#undef TEMPLATE_DITHER_DBL
/contrib/sdk/sources/ffmpeg/libswresample/dither_template.c
0,0 → 1,67
 
#if defined(TEMPLATE_DITHER_DBL)
# define RENAME(N) N ## _double
# define DELEM double
# define CLIP(v)
 
#elif defined(TEMPLATE_DITHER_FLT)
# define RENAME(N) N ## _float
# define DELEM float
# define CLIP(v)
 
#elif defined(TEMPLATE_DITHER_S32)
# define RENAME(N) N ## _int32
# define DELEM int32_t
# define CLIP(v) v = FFMAX(FFMIN(v, INT32_MAX), INT32_MIN)
 
#elif defined(TEMPLATE_DITHER_S16)
# define RENAME(N) N ## _int16
# define DELEM int16_t
# define CLIP(v) v = FFMAX(FFMIN(v, INT16_MAX), INT16_MIN)
 
#else
ERROR
#endif
 
void RENAME(swri_noise_shaping)(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count){
int pos = s->dither.ns_pos;
int i, j, ch;
int taps = s->dither.ns_taps;
float S = s->dither.ns_scale;
float S_1 = s->dither.ns_scale_1;
 
av_assert2((taps&3) != 2);
av_assert2((taps&3) != 3 || s->dither.ns_coeffs[taps] == 0);
 
for (ch=0; ch<srcs->ch_count; ch++) {
const float *noise = ((const float *)noises->ch[ch]) + s->dither.noise_pos;
const DELEM *src = (const DELEM*)srcs->ch[ch];
DELEM *dst = (DELEM*)dsts->ch[ch];
float *ns_errors = s->dither.ns_errors[ch];
const float *ns_coeffs = s->dither.ns_coeffs;
pos = s->dither.ns_pos;
for (i=0; i<count; i++) {
double d1, d = src[i]*S_1;
for(j=0; j<taps-2; j+=4) {
d -= ns_coeffs[j ] * ns_errors[pos + j ]
+ns_coeffs[j + 1] * ns_errors[pos + j + 1]
+ns_coeffs[j + 2] * ns_errors[pos + j + 2]
+ns_coeffs[j + 3] * ns_errors[pos + j + 3];
}
if(j < taps)
d -= ns_coeffs[j] * ns_errors[pos + j];
pos = pos ? pos - 1 : taps - 1;
d1 = rint(d + noise[i]);
ns_errors[pos + taps] = ns_errors[pos] = d1 - d;
d1 *= S;
CLIP(d1);
dst[i] = d1;
}
}
 
s->dither.ns_pos = pos;
}
 
#undef RENAME
#undef DELEM
#undef CLIP
/contrib/sdk/sources/ffmpeg/libswresample/libswresample.pc
0,0 → 1,14
prefix=/usr/local
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
 
Name: libswresample
Description: FFmpeg audio resampling library
Version: 0.17.104
Requires:
Requires.private: libavutil = 52.48.101
Conflicts:
Libs: -L${libdir} -lswresample
Libs.private: -lm
Cflags: -I${includedir}
/contrib/sdk/sources/ffmpeg/libswresample/libswresample.v
0,0 → 1,4
LIBSWRESAMPLE_$MAJOR {
global: swr_*; ff_*; swresample_*;
local: *;
};
/contrib/sdk/sources/ffmpeg/libswresample/libswresample.ver
0,0 → 1,4
LIBSWRESAMPLE_0 {
global: swr_*; ff_*; swresample_*;
local: *;
};
/contrib/sdk/sources/ffmpeg/libswresample/log2_tab.c
0,0 → 1,0
#include "libavutil/log2_tab.c"
/contrib/sdk/sources/ffmpeg/libswresample/noise_shaping_data.c
0,0 → 1,224
/* Effect: dither/noise-shape Copyright (c) 2008-9 robs@users.sourceforge.net
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
typedef struct {
int rate;
enum {fir, iir} type;
size_t len;
int gain_cB; /* Chosen so clips are few if any, but not guaranteed none. */
double const * coefs;
enum SwrDitherType name;
} filter_t;
 
static double const lip44[] = {2.033, -2.165, 1.959, -1.590, .6149};
static double const fwe44[] = {
2.412, -3.370, 3.937, -4.174, 3.353, -2.205, 1.281, -.569, .0847};
static double const mew44[] = {
1.662, -1.263, .4827, -.2913, .1268, -.1124, .03252, -.01265, -.03524};
static double const iew44[] = {
2.847, -4.685, 6.214, -7.184, 6.639, -5.032, 3.263, -1.632, .4191};
static double const ges44[] = {
2.2061, -.4706, -.2534, -.6214, 1.0587, .0676, -.6054, -.2738};
static double const ges48[] = {
2.2374, -.7339, -.1251, -.6033, .903, .0116, -.5853, -.2571};
 
static double const shi48[] = {
2.8720729351043701172, -5.0413231849670410156, 6.2442994117736816406,
-5.8483986854553222656, 3.7067542076110839844, -1.0495119094848632812,
-1.1830236911773681641, 2.1126792430877685547, -1.9094531536102294922,
0.99913084506988525391, -0.17090806365013122559, -0.32615602016448974609,
0.39127644896507263184, -0.26876461505889892578, 0.097676105797290802002,
-0.023473845794796943665,
};
static double const shi44[] = {
2.6773197650909423828, -4.8308925628662109375, 6.570110321044921875,
-7.4572014808654785156, 6.7263274192810058594, -4.8481650352478027344,
2.0412089824676513672, 0.7006359100341796875, -2.9537565708160400391,
4.0800385475158691406, -4.1845216751098632812, 3.3311812877655029297,
-2.1179926395416259766, 0.879302978515625, -0.031759146600961685181,
-0.42382788658142089844, 0.47882103919982910156, -0.35490813851356506348,
0.17496839165687561035, -0.060908168554306030273,
};
static double const shi38[] = {
1.6335992813110351562, -2.2615492343902587891, 2.4077029228210449219,
-2.6341717243194580078, 2.1440362930297851562, -1.8153258562088012695,
1.0816224813461303711, -0.70302653312683105469, 0.15991993248462677002,
0.041549518704414367676, -0.29416576027870178223, 0.2518316805362701416,
-0.27766478061676025391, 0.15785403549671173096, -0.10165894031524658203,
0.016833892092108726501,
};
static double const shi32[] =
{ /* dmaker 32000: bestmax=4.99659 (inverted) */
0.82118552923202515,
-1.0063692331314087,
0.62341964244842529,
-1.0447187423706055,
0.64532512426376343,
-0.87615132331848145,
0.52219754457473755,
-0.67434263229370117,
0.44954317808151245,
-0.52557498216629028,
0.34567299485206604,
-0.39618203043937683,
0.26791760325431824,
-0.28936097025871277,
0.1883765310049057,
-0.19097308814525604,
0.10431359708309174,
-0.10633844882249832,
0.046832218766212463,
-0.039653312414884567,
};
static double const shi22[] =
{ /* dmaker 22050: bestmax=5.77762 (inverted) */
0.056581053882837296,
-0.56956905126571655,
-0.40727734565734863,
-0.33870288729667664,
-0.29810553789138794,
-0.19039161503314972,
-0.16510021686553955,
-0.13468159735202789,
-0.096633769571781158,
-0.081049129366874695,
-0.064953058958053589,
-0.054459091275930405,
-0.043378707021474838,
-0.03660014271736145,
-0.026256965473294258,
-0.018786206841468811,
-0.013387725688517094,
-0.0090983230620622635,
-0.0026585909072309732,
-0.00042083300650119781,
};
static double const shi16[] =
{ /* dmaker 16000: bestmax=5.97128 (inverted) */
-0.37251132726669312,
-0.81423574686050415,
-0.55010956525802612,
-0.47405767440795898,
-0.32624706625938416,
-0.3161766529083252,
-0.2286367267370224,
-0.22916607558727264,
-0.19565616548061371,
-0.18160104751586914,
-0.15423151850700378,
-0.14104481041431427,
-0.11844276636838913,
-0.097583092749118805,
-0.076493598520755768,
-0.068106919527053833,
-0.041881654411554337,
-0.036922425031661987,
-0.019364040344953537,
-0.014994367957115173,
};
static double const shi11[] =
{ /* dmaker 11025: bestmax=5.9406 (inverted) */
-0.9264228343963623,
-0.98695987462997437,
-0.631156325340271,
-0.51966935396194458,
-0.39738872647285461,
-0.35679301619529724,
-0.29720726609230042,
-0.26310476660728455,
-0.21719355881214142,
-0.18561814725399017,
-0.15404847264289856,
-0.12687471508979797,
-0.10339745879173279,
-0.083688631653785706,
-0.05875682458281517,
-0.046893671154975891,
-0.027950936928391457,
-0.020740609616041183,
-0.009366452693939209,
-0.0060260160826146603,
};
static double const shi08[] =
{ /* dmaker 8000: bestmax=5.56234 (inverted) */
-1.202863335609436,
-0.94103097915649414,
-0.67878556251525879,
-0.57650017738342285,
-0.50004476308822632,
-0.44349345564842224,
-0.37833768129348755,
-0.34028723835945129,
-0.29413089156150818,
-0.24994957447052002,
-0.21715600788593292,
-0.18792112171649933,
-0.15268312394618988,
-0.12135542929172516,
-0.099610626697540283,
-0.075273610651493073,
-0.048787496984004974,
-0.042586319148540497,
-0.028991291299462318,
-0.011869125068187714,
};
static double const shl48[] = {
2.3925774097442626953, -3.4350297451019287109, 3.1853709220886230469,
-1.8117271661758422852, -0.20124770700931549072, 1.4759907722473144531,
-1.7210904359817504883, 0.97746700048446655273, -0.13790138065814971924,
-0.38185903429985046387, 0.27421241998672485352, 0.066584214568138122559,
-0.35223302245140075684, 0.37672343850135803223, -0.23964276909828186035,
0.068674825131893157959,
};
static double const shl44[] = {
2.0833916664123535156, -3.0418450832366943359, 3.2047898769378662109,
-2.7571926116943359375, 1.4978630542755126953, -0.3427594602108001709,
-0.71733748912811279297, 1.0737057924270629883, -1.0225815773010253906,
0.56649994850158691406, -0.20968692004680633545, -0.065378531813621520996,
0.10322438180446624756, -0.067442022264003753662, -0.00495197344571352005,
0,
};
static double const shh44[] = {
3.0259189605712890625, -6.0268716812133789062, 9.195003509521484375,
-11.824929237365722656, 12.767142295837402344, -11.917946815490722656,
9.1739168167114257812, -5.3712320327758789062, 1.1393624544143676758,
2.4484779834747314453, -4.9719839096069335938, 6.0392003059387207031,
-5.9359521865844726562, 4.903278350830078125, -3.5527443885803222656,
2.1909697055816650391, -1.1672389507293701172, 0.4903914332389831543,
-0.16519790887832641602, 0.023217858746647834778,
};
 
static const filter_t filters[] = {
{44100, fir, 5, 210, lip44, SWR_DITHER_NS_LIPSHITZ},
{46000, fir, 9, 276, fwe44, SWR_DITHER_NS_F_WEIGHTED},
{46000, fir, 9, 160, mew44, SWR_DITHER_NS_MODIFIED_E_WEIGHTED},
{46000, fir, 9, 321, iew44, SWR_DITHER_NS_IMPROVED_E_WEIGHTED},
// {48000, iir, 4, 220, ges48, SWR_DITHER_NS_GESEMANN},
// {44100, iir, 4, 230, ges44, SWR_DITHER_NS_GESEMANN},
{48000, fir, 16, 301, shi48, SWR_DITHER_NS_SHIBATA},
{44100, fir, 20, 333, shi44, SWR_DITHER_NS_SHIBATA},
{37800, fir, 16, 240, shi38, SWR_DITHER_NS_SHIBATA},
{32000, fir, 20, 240/*TBD*/, shi32, SWR_DITHER_NS_SHIBATA},
{22050, fir, 20, 240/*TBD*/, shi22, SWR_DITHER_NS_SHIBATA},
{16000, fir, 20, 240/*TBD*/, shi16, SWR_DITHER_NS_SHIBATA},
{11025, fir, 20, 240/*TBD*/, shi11, SWR_DITHER_NS_SHIBATA},
{ 8000, fir, 20, 240/*TBD*/, shi08, SWR_DITHER_NS_SHIBATA},
{48000, fir, 16, 250, shl48, SWR_DITHER_NS_LOW_SHIBATA},
{44100, fir, 15, 250, shl44, SWR_DITHER_NS_LOW_SHIBATA},
{44100, fir, 20, 383, shh44, SWR_DITHER_NS_HIGH_SHIBATA},
{ 0, fir, 0, 0, NULL, SWR_DITHER_NONE},
};
/contrib/sdk/sources/ffmpeg/libswresample/rematrix.c
0,0 → 1,500
/*
* Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#include "swresample_internal.h"
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
 
#define TEMPLATE_REMATRIX_FLT
#include "rematrix_template.c"
#undef TEMPLATE_REMATRIX_FLT
 
#define TEMPLATE_REMATRIX_DBL
#include "rematrix_template.c"
#undef TEMPLATE_REMATRIX_DBL
 
#define TEMPLATE_REMATRIX_S16
#include "rematrix_template.c"
#undef TEMPLATE_REMATRIX_S16
 
#define TEMPLATE_REMATRIX_S32
#include "rematrix_template.c"
#undef TEMPLATE_REMATRIX_S32
 
#define FRONT_LEFT 0
#define FRONT_RIGHT 1
#define FRONT_CENTER 2
#define LOW_FREQUENCY 3
#define BACK_LEFT 4
#define BACK_RIGHT 5
#define FRONT_LEFT_OF_CENTER 6
#define FRONT_RIGHT_OF_CENTER 7
#define BACK_CENTER 8
#define SIDE_LEFT 9
#define SIDE_RIGHT 10
#define TOP_CENTER 11
#define TOP_FRONT_LEFT 12
#define TOP_FRONT_CENTER 13
#define TOP_FRONT_RIGHT 14
#define TOP_BACK_LEFT 15
#define TOP_BACK_CENTER 16
#define TOP_BACK_RIGHT 17
 
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
{
int nb_in, nb_out, in, out;
 
if (!s || s->in_convert) // s needs to be allocated but not initialized
return AVERROR(EINVAL);
memset(s->matrix, 0, sizeof(s->matrix));
nb_in = av_get_channel_layout_nb_channels(s->in_ch_layout);
nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
for (out = 0; out < nb_out; out++) {
for (in = 0; in < nb_in; in++)
s->matrix[out][in] = matrix[in];
matrix += stride;
}
s->rematrix_custom = 1;
return 0;
}
 
static int even(int64_t layout){
if(!layout) return 1;
if(layout&(layout-1)) return 1;
return 0;
}
 
static int clean_layout(SwrContext *s, int64_t layout){
if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) {
char buf[128];
av_get_channel_layout_string(buf, sizeof(buf), -1, layout);
av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
return AV_CH_FRONT_CENTER;
}
 
return layout;
}
 
static int sane_layout(int64_t layout){
if(!(layout & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
return 0;
if(!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no asymetric front
return 0;
if(!even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT))) // no asymetric side
return 0;
if(!even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)))
return 0;
if(!even(layout & (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)))
return 0;
if(av_get_channel_layout_nb_channels(layout) >= SWR_CH_MAX)
return 0;
 
return 1;
}
 
av_cold static int auto_matrix(SwrContext *s)
{
int i, j, out_i;
double matrix[64][64]={{0}};
int64_t unaccounted, in_ch_layout, out_ch_layout;
double maxcoef=0;
char buf[128];
const int matrix_encoding = s->matrix_encoding;
float maxval;
 
in_ch_layout = clean_layout(s, s->in_ch_layout);
out_ch_layout = clean_layout(s, s->out_ch_layout);
 
if( out_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX
&& (in_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0
)
out_ch_layout = AV_CH_LAYOUT_STEREO;
 
if(!sane_layout(in_ch_layout)){
av_get_channel_layout_string(buf, sizeof(buf), -1, s->in_ch_layout);
av_log(s, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
return AVERROR(EINVAL);
}
 
if(!sane_layout(out_ch_layout)){
av_get_channel_layout_string(buf, sizeof(buf), -1, s->out_ch_layout);
av_log(s, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
return AVERROR(EINVAL);
}
 
memset(s->matrix, 0, sizeof(s->matrix));
for(i=0; i<64; i++){
if(in_ch_layout & out_ch_layout & (1ULL<<i))
matrix[i][i]= 1.0;
}
 
unaccounted= in_ch_layout & ~out_ch_layout;
 
//FIXME implement dolby surround
//FIXME implement full ac3
 
 
if(unaccounted & AV_CH_FRONT_CENTER){
if((out_ch_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO){
if(in_ch_layout & AV_CH_LAYOUT_STEREO) {
matrix[ FRONT_LEFT][FRONT_CENTER]+= s->clev;
matrix[FRONT_RIGHT][FRONT_CENTER]+= s->clev;
} else {
matrix[ FRONT_LEFT][FRONT_CENTER]+= M_SQRT1_2;
matrix[FRONT_RIGHT][FRONT_CENTER]+= M_SQRT1_2;
}
}else
av_assert0(0);
}
if(unaccounted & AV_CH_LAYOUT_STEREO){
if(out_ch_layout & AV_CH_FRONT_CENTER){
matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2;
matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2;
if(in_ch_layout & AV_CH_FRONT_CENTER)
matrix[FRONT_CENTER][ FRONT_CENTER] = s->clev*sqrt(2);
}else
av_assert0(0);
}
 
if(unaccounted & AV_CH_BACK_CENTER){
if(out_ch_layout & AV_CH_BACK_LEFT){
matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2;
matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2;
}else if(out_ch_layout & AV_CH_SIDE_LEFT){
matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2;
matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2;
}else if(out_ch_layout & AV_CH_FRONT_LEFT){
if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][BACK_CENTER] += s->slev * M_SQRT1_2;
} else {
matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev;
matrix[FRONT_RIGHT][BACK_CENTER] += s->slev;
}
} else {
matrix[ FRONT_LEFT][BACK_CENTER]+= s->slev*M_SQRT1_2;
matrix[FRONT_RIGHT][BACK_CENTER]+= s->slev*M_SQRT1_2;
}
}else if(out_ch_layout & AV_CH_FRONT_CENTER){
matrix[ FRONT_CENTER][BACK_CENTER]+= s->slev*M_SQRT1_2;
}else
av_assert0(0);
}
if(unaccounted & AV_CH_BACK_LEFT){
if(out_ch_layout & AV_CH_BACK_CENTER){
matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2;
matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2;
}else if(out_ch_layout & AV_CH_SIDE_LEFT){
if(in_ch_layout & AV_CH_SIDE_LEFT){
matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2;
matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2;
}else{
matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
}
}else if(out_ch_layout & AV_CH_FRONT_LEFT){
if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * M_SQRT1_2;
matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * M_SQRT1_2;
} else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * SQRT3_2;
matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * SQRT3_2;
} else {
matrix[ FRONT_LEFT][ BACK_LEFT] += s->slev;
matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev;
}
}else if(out_ch_layout & AV_CH_FRONT_CENTER){
matrix[ FRONT_CENTER][BACK_LEFT ]+= s->slev*M_SQRT1_2;
matrix[ FRONT_CENTER][BACK_RIGHT]+= s->slev*M_SQRT1_2;
}else
av_assert0(0);
}
 
if(unaccounted & AV_CH_SIDE_LEFT){
if(out_ch_layout & AV_CH_BACK_LEFT){
/* if back channels do not exist in the input, just copy side
channels to back channels, otherwise mix side into back */
if (in_ch_layout & AV_CH_BACK_LEFT) {
matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2;
matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2;
} else {
matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
}
}else if(out_ch_layout & AV_CH_BACK_CENTER){
matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2;
matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2;
}else if(out_ch_layout & AV_CH_FRONT_LEFT){
if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * M_SQRT1_2;
matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * M_SQRT1_2;
} else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * SQRT3_2;
matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * SQRT3_2;
} else {
matrix[ FRONT_LEFT][ SIDE_LEFT] += s->slev;
matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev;
}
}else if(out_ch_layout & AV_CH_FRONT_CENTER){
matrix[ FRONT_CENTER][SIDE_LEFT ]+= s->slev*M_SQRT1_2;
matrix[ FRONT_CENTER][SIDE_RIGHT]+= s->slev*M_SQRT1_2;
}else
av_assert0(0);
}
 
if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
if(out_ch_layout & AV_CH_FRONT_LEFT){
matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0;
matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0;
}else if(out_ch_layout & AV_CH_FRONT_CENTER){
matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2;
matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2;
}else
av_assert0(0);
}
/* mix LFE into front left/right or center */
if (unaccounted & AV_CH_LOW_FREQUENCY) {
if (out_ch_layout & AV_CH_FRONT_CENTER) {
matrix[FRONT_CENTER][LOW_FREQUENCY] += s->lfe_mix_level;
} else if (out_ch_layout & AV_CH_FRONT_LEFT) {
matrix[FRONT_LEFT ][LOW_FREQUENCY] += s->lfe_mix_level * M_SQRT1_2;
matrix[FRONT_RIGHT][LOW_FREQUENCY] += s->lfe_mix_level * M_SQRT1_2;
} else
av_assert0(0);
}
 
for(out_i=i=0; i<64; i++){
double sum=0;
int in_i=0;
for(j=0; j<64; j++){
s->matrix[out_i][in_i]= matrix[i][j];
if(matrix[i][j]){
sum += fabs(matrix[i][j]);
}
if(in_ch_layout & (1ULL<<j))
in_i++;
}
maxcoef= FFMAX(maxcoef, sum);
if(out_ch_layout & (1ULL<<i))
out_i++;
}
if(s->rematrix_volume < 0)
maxcoef = -s->rematrix_volume;
 
if (s->rematrix_maxval > 0) {
maxval = s->rematrix_maxval;
} else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
|| av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
maxval = 1.0;
} else
maxval = INT_MAX;
 
if(maxcoef > maxval || s->rematrix_volume < 0){
maxcoef /= maxval;
for(i=0; i<SWR_CH_MAX; i++)
for(j=0; j<SWR_CH_MAX; j++){
s->matrix[i][j] /= maxcoef;
}
}
 
if(s->rematrix_volume > 0){
for(i=0; i<SWR_CH_MAX; i++)
for(j=0; j<SWR_CH_MAX; j++){
s->matrix[i][j] *= s->rematrix_volume;
}
}
 
for(i=0; i<av_get_channel_layout_nb_channels(out_ch_layout); i++){
for(j=0; j<av_get_channel_layout_nb_channels(in_ch_layout); j++){
av_log(NULL, AV_LOG_DEBUG, "%f ", s->matrix[i][j]);
}
av_log(NULL, AV_LOG_DEBUG, "\n");
}
return 0;
}
 
av_cold int swri_rematrix_init(SwrContext *s){
int i, j;
int nb_in = av_get_channel_layout_nb_channels(s->in_ch_layout);
int nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
 
s->mix_any_f = NULL;
 
if (!s->rematrix_custom) {
int r = auto_matrix(s);
if (r)
return r;
}
if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
s->native_one = av_mallocz(sizeof(int));
for (i = 0; i < nb_out; i++)
for (j = 0; j < nb_in; j++)
((int*)s->native_matrix)[i * nb_in + j] = lrintf(s->matrix[i][j] * 32768);
*((int*)s->native_one) = 32768;
s->mix_1_1_f = (mix_1_1_func_type*)copy_s16;
s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16;
s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s);
}else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
s->native_one = av_mallocz(sizeof(float));
for (i = 0; i < nb_out; i++)
for (j = 0; j < nb_in; j++)
((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
*((float*)s->native_one) = 1.0;
s->mix_1_1_f = (mix_1_1_func_type*)copy_float;
s->mix_2_1_f = (mix_2_1_func_type*)sum2_float;
s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s);
}else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
s->native_one = av_mallocz(sizeof(double));
for (i = 0; i < nb_out; i++)
for (j = 0; j < nb_in; j++)
((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
*((double*)s->native_one) = 1.0;
s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
}else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
// Only for dithering currently
// s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
s->native_one = av_mallocz(sizeof(int));
// for (i = 0; i < nb_out; i++)
// for (j = 0; j < nb_in; j++)
// ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
*((int*)s->native_one) = 32768;
s->mix_1_1_f = (mix_1_1_func_type*)copy_s32;
s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32;
s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s);
}else
av_assert0(0);
//FIXME quantize for integeres
for (i = 0; i < SWR_CH_MAX; i++) {
int ch_in=0;
for (j = 0; j < SWR_CH_MAX; j++) {
s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
if(s->matrix[i][j])
s->matrix_ch[i][++ch_in]= j;
}
s->matrix_ch[i][0]= ch_in;
}
 
if(HAVE_YASM && HAVE_MMX) swri_rematrix_init_x86(s);
 
return 0;
}
 
av_cold void swri_rematrix_free(SwrContext *s){
av_freep(&s->native_matrix);
av_freep(&s->native_one);
av_freep(&s->native_simd_matrix);
av_freep(&s->native_simd_one);
}
 
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
int out_i, in_i, i, j;
int len1 = 0;
int off = 0;
 
if(s->mix_any_f) {
s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
return 0;
}
 
if(s->mix_2_1_simd || s->mix_1_1_simd){
len1= len&~15;
off = len1 * out->bps;
}
 
av_assert0(out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout));
av_assert0(in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
 
for(out_i=0; out_i<out->ch_count; out_i++){
switch(s->matrix_ch[out_i][0]){
case 0:
if(mustcopy)
memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
break;
case 1:
in_i= s->matrix_ch[out_i][1];
if(s->matrix[out_i][in_i]!=1.0){
if(s->mix_1_1_simd && len1)
s->mix_1_1_simd(out->ch[out_i] , in->ch[in_i] , s->native_simd_matrix, in->ch_count*out_i + in_i, len1);
if(len != len1)
s->mix_1_1_f (out->ch[out_i]+off, in->ch[in_i]+off, s->native_matrix, in->ch_count*out_i + in_i, len-len1);
}else if(mustcopy){
memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
}else{
out->ch[out_i]= in->ch[in_i];
}
break;
case 2: {
int in_i1 = s->matrix_ch[out_i][1];
int in_i2 = s->matrix_ch[out_i][2];
if(s->mix_2_1_simd && len1)
s->mix_2_1_simd(out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_simd_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
else
s->mix_2_1_f (out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
if(len != len1)
s->mix_2_1_f (out->ch[out_i]+off, in->ch[in_i1]+off, in->ch[in_i2]+off, s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len-len1);
break;}
default:
if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
for(i=0; i<len; i++){
float v=0;
for(j=0; j<s->matrix_ch[out_i][0]; j++){
in_i= s->matrix_ch[out_i][1+j];
v+= ((float*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
}
((float*)out->ch[out_i])[i]= v;
}
}else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
for(i=0; i<len; i++){
double v=0;
for(j=0; j<s->matrix_ch[out_i][0]; j++){
in_i= s->matrix_ch[out_i][1+j];
v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
}
((double*)out->ch[out_i])[i]= v;
}
}else{
for(i=0; i<len; i++){
int v=0;
for(j=0; j<s->matrix_ch[out_i][0]; j++){
in_i= s->matrix_ch[out_i][1+j];
v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
}
((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
}
}
}
}
return 0;
}
/contrib/sdk/sources/ffmpeg/libswresample/rematrix_template.c
0,0 → 1,106
/*
* Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#if defined(TEMPLATE_REMATRIX_FLT)
# define R(x) x
# define SAMPLE float
# define COEFF float
# define INTER float
# define RENAME(x) x ## _float
#elif defined(TEMPLATE_REMATRIX_DBL)
# define R(x) x
# define SAMPLE double
# define COEFF double
# define INTER double
# define RENAME(x) x ## _double
#elif defined(TEMPLATE_REMATRIX_S16)
# define R(x) (((x) + 16384)>>15)
# define SAMPLE int16_t
# define COEFF int
# define INTER int
# define RENAME(x) x ## _s16
#elif defined(TEMPLATE_REMATRIX_S32)
# define R(x) (((x) + 16384)>>15)
# define SAMPLE int32_t
# define COEFF int
# define INTER int64_t
# define RENAME(x) x ## _s32
#endif
 
typedef void (RENAME(mix_any_func_type))(SAMPLE **out, const SAMPLE **in1, COEFF *coeffp, integer len);
 
static void RENAME(sum2)(SAMPLE *out, const SAMPLE *in1, const SAMPLE *in2, COEFF *coeffp, integer index1, integer index2, integer len){
int i;
INTER coeff1 = coeffp[index1];
INTER coeff2 = coeffp[index2];
 
for(i=0; i<len; i++)
out[i] = R(coeff1*in1[i] + coeff2*in2[i]);
}
 
static void RENAME(copy)(SAMPLE *out, const SAMPLE *in, COEFF *coeffp, integer index, integer len){
int i;
INTER coeff = coeffp[index];
for(i=0; i<len; i++)
out[i] = R(coeff*in[i]);
}
 
static void RENAME(mix6to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, integer len){
int i;
 
for(i=0; i<len; i++) {
INTER t = in[2][i]*(INTER)coeffp[0*6+2] + in[3][i]*(INTER)coeffp[0*6+3];
out[0][i] = R(t + in[0][i]*(INTER)coeffp[0*6+0] + in[4][i]*(INTER)coeffp[0*6+4]);
out[1][i] = R(t + in[1][i]*(INTER)coeffp[1*6+1] + in[5][i]*(INTER)coeffp[1*6+5]);
}
}
 
static void RENAME(mix8to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, integer len){
int i;
 
for(i=0; i<len; i++) {
INTER t = in[2][i]*(INTER)coeffp[0*8+2] + in[3][i]*(INTER)coeffp[0*8+3];
out[0][i] = R(t + in[0][i]*(INTER)coeffp[0*8+0] + in[4][i]*(INTER)coeffp[0*8+4] + in[6][i]*(INTER)coeffp[0*8+6]);
out[1][i] = R(t + in[1][i]*(INTER)coeffp[1*8+1] + in[5][i]*(INTER)coeffp[1*8+5] + in[7][i]*(INTER)coeffp[1*8+7]);
}
}
 
static RENAME(mix_any_func_type) *RENAME(get_mix_any_func)(SwrContext *s){
if( s->out_ch_layout == AV_CH_LAYOUT_STEREO && (s->in_ch_layout == AV_CH_LAYOUT_5POINT1 || s->in_ch_layout == AV_CH_LAYOUT_5POINT1_BACK)
&& s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == s->matrix[1][3]
&& !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && !s->matrix[1][4]
)
return RENAME(mix6to2);
 
if( s->out_ch_layout == AV_CH_LAYOUT_STEREO && s->in_ch_layout == AV_CH_LAYOUT_7POINT1
&& s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == s->matrix[1][3]
&& !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && !s->matrix[1][4]
&& !s->matrix[0][7] && !s->matrix[1][6]
)
return RENAME(mix8to2);
 
return NULL;
}
 
#undef R
#undef SAMPLE
#undef COEFF
#undef INTER
#undef RENAME
/contrib/sdk/sources/ffmpeg/libswresample/resample.c
0,0 → 1,372
/*
* audio resampling
* Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at>
*
* 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
*/
 
/**
* @file
* audio resampling
* @author Michael Niedermayer <michaelni@gmx.at>
*/
 
#include "libavutil/log.h"
#include "libavutil/avassert.h"
#include "swresample_internal.h"
 
 
typedef struct ResampleContext {
const AVClass *av_class;
uint8_t *filter_bank;
int filter_length;
int filter_alloc;
int ideal_dst_incr;
int dst_incr;
int index;
int frac;
int src_incr;
int compensation_distance;
int phase_shift;
int phase_mask;
int linear;
enum SwrFilterType filter_type;
int kaiser_beta;
double factor;
enum AVSampleFormat format;
int felem_size;
int filter_shift;
} ResampleContext;
 
/**
* 0th order modified bessel function of the first kind.
*/
static double bessel(double x){
double v=1;
double lastv=0;
double t=1;
int i;
static const double inv[100]={
1.0/( 1* 1), 1.0/( 2* 2), 1.0/( 3* 3), 1.0/( 4* 4), 1.0/( 5* 5), 1.0/( 6* 6), 1.0/( 7* 7), 1.0/( 8* 8), 1.0/( 9* 9), 1.0/(10*10),
1.0/(11*11), 1.0/(12*12), 1.0/(13*13), 1.0/(14*14), 1.0/(15*15), 1.0/(16*16), 1.0/(17*17), 1.0/(18*18), 1.0/(19*19), 1.0/(20*20),
1.0/(21*21), 1.0/(22*22), 1.0/(23*23), 1.0/(24*24), 1.0/(25*25), 1.0/(26*26), 1.0/(27*27), 1.0/(28*28), 1.0/(29*29), 1.0/(30*30),
1.0/(31*31), 1.0/(32*32), 1.0/(33*33), 1.0/(34*34), 1.0/(35*35), 1.0/(36*36), 1.0/(37*37), 1.0/(38*38), 1.0/(39*39), 1.0/(40*40),
1.0/(41*41), 1.0/(42*42), 1.0/(43*43), 1.0/(44*44), 1.0/(45*45), 1.0/(46*46), 1.0/(47*47), 1.0/(48*48), 1.0/(49*49), 1.0/(50*50),
1.0/(51*51), 1.0/(52*52), 1.0/(53*53), 1.0/(54*54), 1.0/(55*55), 1.0/(56*56), 1.0/(57*57), 1.0/(58*58), 1.0/(59*59), 1.0/(60*60),
1.0/(61*61), 1.0/(62*62), 1.0/(63*63), 1.0/(64*64), 1.0/(65*65), 1.0/(66*66), 1.0/(67*67), 1.0/(68*68), 1.0/(69*69), 1.0/(70*70),
1.0/(71*71), 1.0/(72*72), 1.0/(73*73), 1.0/(74*74), 1.0/(75*75), 1.0/(76*76), 1.0/(77*77), 1.0/(78*78), 1.0/(79*79), 1.0/(80*80),
1.0/(81*81), 1.0/(82*82), 1.0/(83*83), 1.0/(84*84), 1.0/(85*85), 1.0/(86*86), 1.0/(87*87), 1.0/(88*88), 1.0/(89*89), 1.0/(90*90),
1.0/(91*91), 1.0/(92*92), 1.0/(93*93), 1.0/(94*94), 1.0/(95*95), 1.0/(96*96), 1.0/(97*97), 1.0/(98*98), 1.0/(99*99), 1.0/(10000)
};
 
x= x*x/4;
for(i=0; v != lastv; i++){
lastv=v;
t *= x*inv[i];
v += t;
av_assert2(i<99);
}
return v;
}
 
/**
* builds a polyphase filterbank.
* @param factor resampling factor
* @param scale wanted sum of coefficients for each filter
* @param filter_type filter type
* @param kaiser_beta kaiser window beta
* @return 0 on success, negative on error
*/
static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale,
int filter_type, int kaiser_beta){
int ph, i;
double x, y, w;
double *tab = av_malloc(tap_count * sizeof(*tab));
const int center= (tap_count-1)/2;
 
if (!tab)
return AVERROR(ENOMEM);
 
/* if upsampling, only need to interpolate, no filter */
if (factor > 1.0)
factor = 1.0;
 
for(ph=0;ph<phase_count;ph++) {
double norm = 0;
for(i=0;i<tap_count;i++) {
x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
if (x == 0) y = 1.0;
else y = sin(x) / x;
switch(filter_type){
case SWR_FILTER_TYPE_CUBIC:{
const float d= -0.5; //first order derivative = -0.5
x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x);
else y= d*(-4 + 8*x - 5*x*x + x*x*x);
break;}
case SWR_FILTER_TYPE_BLACKMAN_NUTTALL:
w = 2.0*x / (factor*tap_count) + M_PI;
y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w);
break;
case SWR_FILTER_TYPE_KAISER:
w = 2.0*x / (factor*tap_count*M_PI);
y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0)));
break;
default:
av_assert0(0);
}
 
tab[i] = y;
norm += y;
}
 
/* normalize so that an uniform color remains the same */
switch(c->format){
case AV_SAMPLE_FMT_S16P:
for(i=0;i<tap_count;i++)
((int16_t*)filter)[ph * alloc + i] = av_clip(lrintf(tab[i] * scale / norm), INT16_MIN, INT16_MAX);
break;
case AV_SAMPLE_FMT_S32P:
for(i=0;i<tap_count;i++)
((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm));
break;
case AV_SAMPLE_FMT_FLTP:
for(i=0;i<tap_count;i++)
((float*)filter)[ph * alloc + i] = tab[i] * scale / norm;
break;
case AV_SAMPLE_FMT_DBLP:
for(i=0;i<tap_count;i++)
((double*)filter)[ph * alloc + i] = tab[i] * scale / norm;
break;
}
}
#if 0
{
#define LEN 1024
int j,k;
double sine[LEN + tap_count];
double filtered[LEN];
double maxff=-2, minff=2, maxsf=-2, minsf=2;
for(i=0; i<LEN; i++){
double ss=0, sf=0, ff=0;
for(j=0; j<LEN+tap_count; j++)
sine[j]= cos(i*j*M_PI/LEN);
for(j=0; j<LEN; j++){
double sum=0;
ph=0;
for(k=0; k<tap_count; k++)
sum += filter[ph * tap_count + k] * sine[k+j];
filtered[j]= sum / (1<<FILTER_SHIFT);
ss+= sine[j + center] * sine[j + center];
ff+= filtered[j] * filtered[j];
sf+= sine[j + center] * filtered[j];
}
ss= sqrt(2*ss/LEN);
ff= sqrt(2*ff/LEN);
sf= 2*sf/LEN;
maxff= FFMAX(maxff, ff);
minff= FFMIN(minff, ff);
maxsf= FFMAX(maxsf, sf);
minsf= FFMIN(minsf, sf);
if(i%11==0){
av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
minff=minsf= 2;
maxff=maxsf= -2;
}
}
}
#endif
 
av_free(tab);
return 0;
}
 
static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta,
double precision, int cheby){
double cutoff = cutoff0? cutoff0 : 0.97;
double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
int phase_count= 1<<phase_shift;
 
if (!c || c->phase_shift != phase_shift || c->linear!=linear || c->factor != factor
|| c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format
|| c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) {
c = av_mallocz(sizeof(*c));
if (!c)
return NULL;
 
c->format= format;
 
c->felem_size= av_get_bytes_per_sample(c->format);
 
switch(c->format){
case AV_SAMPLE_FMT_S16P:
c->filter_shift = 15;
break;
case AV_SAMPLE_FMT_S32P:
c->filter_shift = 30;
break;
case AV_SAMPLE_FMT_FLTP:
case AV_SAMPLE_FMT_DBLP:
c->filter_shift = 0;
break;
default:
av_log(NULL, AV_LOG_ERROR, "Unsupported sample format\n");
av_assert0(0);
}
 
c->phase_shift = phase_shift;
c->phase_mask = phase_count - 1;
c->linear = linear;
c->factor = factor;
c->filter_length = FFMAX((int)ceil(filter_size/factor), 1);
c->filter_alloc = FFALIGN(c->filter_length, 8);
c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size);
c->filter_type = filter_type;
c->kaiser_beta = kaiser_beta;
if (!c->filter_bank)
goto error;
if (build_filter(c, (void*)c->filter_bank, factor, c->filter_length, c->filter_alloc, phase_count, 1<<c->filter_shift, filter_type, kaiser_beta))
goto error;
memcpy(c->filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, c->filter_bank, (c->filter_alloc-1)*c->felem_size);
memcpy(c->filter_bank + (c->filter_alloc*phase_count )*c->felem_size, c->filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size);
}
 
c->compensation_distance= 0;
if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
goto error;
c->ideal_dst_incr= c->dst_incr;
 
c->index= -phase_count*((c->filter_length-1)/2);
c->frac= 0;
 
return c;
error:
av_freep(&c->filter_bank);
av_free(c);
return NULL;
}
 
static void resample_free(ResampleContext **c){
if(!*c)
return;
av_freep(&(*c)->filter_bank);
av_freep(c);
}
 
static int set_compensation(ResampleContext *c, int sample_delta, int compensation_distance){
c->compensation_distance= compensation_distance;
if (compensation_distance)
c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
else
c->dst_incr = c->ideal_dst_incr;
return 0;
}
 
#define TEMPLATE_RESAMPLE_S16
#include "resample_template.c"
#undef TEMPLATE_RESAMPLE_S16
 
#define TEMPLATE_RESAMPLE_S32
#include "resample_template.c"
#undef TEMPLATE_RESAMPLE_S32
 
#define TEMPLATE_RESAMPLE_FLT
#include "resample_template.c"
#undef TEMPLATE_RESAMPLE_FLT
 
#define TEMPLATE_RESAMPLE_DBL
#include "resample_template.c"
#undef TEMPLATE_RESAMPLE_DBL
 
// XXX FIXME the whole C loop should be written in asm so this x86 specific code here isnt needed
#if HAVE_MMXEXT_INLINE
 
#include "x86/resample_mmx.h"
 
#define TEMPLATE_RESAMPLE_S16_MMX2
#include "resample_template.c"
#undef TEMPLATE_RESAMPLE_S16_MMX2
 
#if HAVE_SSSE3_INLINE
#define TEMPLATE_RESAMPLE_S16_SSSE3
#include "resample_template.c"
#undef TEMPLATE_RESAMPLE_S16_SSSE3
#endif
 
#endif // HAVE_MMXEXT_INLINE
 
static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){
int i, ret= -1;
int av_unused mm_flags = av_get_cpu_flags();
int need_emms= 0;
 
for(i=0; i<dst->ch_count; i++){
#if HAVE_MMXEXT_INLINE
#if HAVE_SSSE3_INLINE
if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_SSSE3)) ret= swri_resample_int16_ssse3(c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
else
#endif
if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_MMX2 )){
ret= swri_resample_int16_mmx2 (c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
need_emms= 1;
} else
#endif
if(c->format == AV_SAMPLE_FMT_S16P) ret= swri_resample_int16(c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
else if(c->format == AV_SAMPLE_FMT_S32P) ret= swri_resample_int32(c, (int32_t*)dst->ch[i], (const int32_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
else if(c->format == AV_SAMPLE_FMT_FLTP) ret= swri_resample_float(c, (float *)dst->ch[i], (const float *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
else if(c->format == AV_SAMPLE_FMT_DBLP) ret= swri_resample_double(c,(double *)dst->ch[i], (const double *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
}
if(need_emms)
emms_c();
return ret;
}
 
static int64_t get_delay(struct SwrContext *s, int64_t base){
ResampleContext *c = s->resample;
int64_t num = s->in_buffer_count - (c->filter_length-1)/2;
num <<= c->phase_shift;
num -= c->index;
num *= c->src_incr;
num -= c->frac;
return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr << c->phase_shift);
}
 
static int resample_flush(struct SwrContext *s) {
AudioData *a= &s->in_buffer;
int i, j, ret;
if((ret = swri_realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0)
return ret;
av_assert0(a->planar);
for(i=0; i<a->ch_count; i++){
for(j=0; j<s->in_buffer_count; j++){
memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j )*a->bps,
a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
}
}
s->in_buffer_count += (s->in_buffer_count+1)/2;
return 0;
}
 
struct Resampler const swri_resampler={
resample_init,
resample_free,
multiple_resample,
resample_flush,
set_compensation,
get_delay,
};
/contrib/sdk/sources/ffmpeg/libswresample/resample_template.c
0,0 → 1,211
/*
* audio resampling
* Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at>
*
* 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
*/
 
/**
* @file
* audio resampling
* @author Michael Niedermayer <michaelni@gmx.at>
*/
 
#if defined(TEMPLATE_RESAMPLE_DBL)
# define RENAME(N) N ## _double
# define FILTER_SHIFT 0
# define DELEM double
# define FELEM double
# define FELEM2 double
# define FELEML double
# define OUT(d, v) d = v
 
#elif defined(TEMPLATE_RESAMPLE_FLT)
# define RENAME(N) N ## _float
# define FILTER_SHIFT 0
# define DELEM float
# define FELEM float
# define FELEM2 float
# define FELEML float
# define OUT(d, v) d = v
 
#elif defined(TEMPLATE_RESAMPLE_S32)
# define RENAME(N) N ## _int32
# define FILTER_SHIFT 30
# define DELEM int32_t
# define FELEM int32_t
# define FELEM2 int64_t
# define FELEML int64_t
# define FELEM_MAX INT32_MAX
# define FELEM_MIN INT32_MIN
# define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
d = (uint64_t)(v + 0x80000000) > 0xFFFFFFFF ? (v>>63) ^ 0x7FFFFFFF : v
 
#elif defined(TEMPLATE_RESAMPLE_S16) \
|| defined(TEMPLATE_RESAMPLE_S16_MMX2) \
|| defined(TEMPLATE_RESAMPLE_S16_SSSE3)
 
# define FILTER_SHIFT 15
# define DELEM int16_t
# define FELEM int16_t
# define FELEM2 int32_t
# define FELEML int64_t
# define FELEM_MAX INT16_MAX
# define FELEM_MIN INT16_MIN
# define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
d = (unsigned)(v + 32768) > 65535 ? (v>>31) ^ 32767 : v
 
# if defined(TEMPLATE_RESAMPLE_S16)
# define RENAME(N) N ## _int16
# elif defined(TEMPLATE_RESAMPLE_S16_MMX2)
# define COMMON_CORE COMMON_CORE_INT16_MMX2
# define RENAME(N) N ## _int16_mmx2
# elif defined(TEMPLATE_RESAMPLE_S16_SSSE3)
# define COMMON_CORE COMMON_CORE_INT16_SSSE3
# define RENAME(N) N ## _int16_ssse3
# endif
 
#endif
 
int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int *consumed, int src_size, int dst_size, int update_ctx){
int dst_index, i;
int index= c->index;
int frac= c->frac;
int dst_incr_frac= c->dst_incr % c->src_incr;
int dst_incr= c->dst_incr / c->src_incr;
int compensation_distance= c->compensation_distance;
 
av_assert1(c->filter_shift == FILTER_SHIFT);
av_assert1(c->felem_size == sizeof(FELEM));
 
if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){
int64_t index2= ((int64_t)index)<<32;
int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);
 
for(dst_index=0; dst_index < dst_size; dst_index++){
dst[dst_index] = src[index2>>32];
index2 += incr;
}
index += dst_index * dst_incr;
index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
av_assert2(index >= 0);
*consumed= index >> c->phase_shift;
index &= c->phase_mask;
}else if(compensation_distance == 0 && !c->linear && index >= 0){
int sample_index = 0;
for(dst_index=0; dst_index < dst_size; dst_index++){
FELEM *filter;
sample_index += index >> c->phase_shift;
index &= c->phase_mask;
filter= ((FELEM*)c->filter_bank) + c->filter_alloc*index;
 
if(sample_index + c->filter_length > src_size){
break;
}else{
#ifdef COMMON_CORE
COMMON_CORE
#else
FELEM2 val=0;
for(i=0; i<c->filter_length; i++){
val += src[sample_index + i] * (FELEM2)filter[i];
}
OUT(dst[dst_index], val);
#endif
}
 
frac += dst_incr_frac;
index += dst_incr;
if(frac >= c->src_incr){
frac -= c->src_incr;
index++;
}
}
*consumed = sample_index;
}else{
int sample_index = 0;
for(dst_index=0; dst_index < dst_size; dst_index++){
FELEM *filter;
FELEM2 val=0;
 
sample_index += index >> c->phase_shift;
index &= c->phase_mask;
filter = ((FELEM*)c->filter_bank) + c->filter_alloc*index;
 
if(sample_index + c->filter_length > src_size || -sample_index >= src_size){
break;
}else if(sample_index < 0){
for(i=0; i<c->filter_length; i++)
val += src[FFABS(sample_index + i)] * (FELEM2)filter[i];
}else if(c->linear){
FELEM2 v2=0;
for(i=0; i<c->filter_length; i++){
val += src[sample_index + i] * (FELEM2)filter[i];
v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc];
}
val+=(v2-val)*(FELEML)frac / c->src_incr;
}else{
for(i=0; i<c->filter_length; i++){
val += src[sample_index + i] * (FELEM2)filter[i];
}
}
 
OUT(dst[dst_index], val);
 
frac += dst_incr_frac;
index += dst_incr;
if(frac >= c->src_incr){
frac -= c->src_incr;
index++;
}
 
if(dst_index + 1 == compensation_distance){
compensation_distance= 0;
dst_incr_frac= c->ideal_dst_incr % c->src_incr;
dst_incr= c->ideal_dst_incr / c->src_incr;
}
}
*consumed= FFMAX(sample_index, 0);
index += FFMIN(sample_index, 0) << c->phase_shift;
 
if(compensation_distance){
compensation_distance -= dst_index;
av_assert1(compensation_distance > 0);
}
}
 
if(update_ctx){
c->frac= frac;
c->index= index;
c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
c->compensation_distance= compensation_distance;
}
 
return dst_index;
}
 
#undef COMMON_CORE
#undef RENAME
#undef FILTER_SHIFT
#undef DELEM
#undef FELEM
#undef FELEM2
#undef FELEML
#undef FELEM_MAX
#undef FELEM_MIN
#undef OUT
/contrib/sdk/sources/ffmpeg/libswresample/soxr_resample.c
0,0 → 1,93
/*
* audio resampling with soxr
* Copyright (c) 2012 Rob Sykes <robs@users.sourceforge.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
*/
 
/**
* @file
* audio resampling with soxr
*/
 
#include "libavutil/log.h"
#include "swresample_internal.h"
 
#include <soxr.h>
 
static struct ResampleContext *create(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta, double precision, int cheby){
soxr_error_t error;
 
soxr_datatype_t type =
format == AV_SAMPLE_FMT_S16P? SOXR_INT16_S :
format == AV_SAMPLE_FMT_S16 ? SOXR_INT16_I :
format == AV_SAMPLE_FMT_S32P? SOXR_INT32_S :
format == AV_SAMPLE_FMT_S32 ? SOXR_INT32_I :
format == AV_SAMPLE_FMT_FLTP? SOXR_FLOAT32_S :
format == AV_SAMPLE_FMT_FLT ? SOXR_FLOAT32_I :
format == AV_SAMPLE_FMT_DBLP? SOXR_FLOAT64_S :
format == AV_SAMPLE_FMT_DBL ? SOXR_FLOAT64_I : (soxr_datatype_t)-1;
 
soxr_io_spec_t io_spec = soxr_io_spec(type, type);
 
soxr_quality_spec_t q_spec = soxr_quality_spec((int)((precision-2)/4), (SOXR_HI_PREC_CLOCK|SOXR_ROLLOFF_NONE)*!!cheby);
q_spec.precision = linear? 0 : precision;
#if !defined SOXR_VERSION /* Deprecated @ March 2013: */
q_spec.bw_pc = cutoff? FFMAX(FFMIN(cutoff,.995),.8)*100 : q_spec.bw_pc;
#else
q_spec.passband_end = cutoff? FFMAX(FFMIN(cutoff,.995),.8) : q_spec.passband_end;
#endif
 
soxr_delete((soxr_t)c);
c = (struct ResampleContext *)
soxr_create(in_rate, out_rate, 0, &error, &io_spec, &q_spec, 0);
if (!c)
av_log(NULL, AV_LOG_ERROR, "soxr_create: %s\n", error);
return c;
}
 
static void destroy(struct ResampleContext * *c){
soxr_delete((soxr_t)*c);
*c = NULL;
}
 
static int flush(struct SwrContext *s){
soxr_process((soxr_t)s->resample, NULL, 0, NULL, NULL, 0, NULL);
return 0;
}
 
static int process(
struct ResampleContext * c, AudioData *dst, int dst_size,
AudioData *src, int src_size, int *consumed){
size_t idone, odone;
soxr_error_t error = soxr_set_error((soxr_t)c, soxr_set_num_channels((soxr_t)c, src->ch_count));
error = soxr_process((soxr_t)c, src->ch, (size_t)src_size,
&idone, dst->ch, (size_t)dst_size, &odone);
*consumed = (int)idone;
return error? -1 : odone;
}
 
static int64_t get_delay(struct SwrContext *s, int64_t base){
double delay_s = soxr_delay((soxr_t)s->resample) / s->out_sample_rate;
return (int64_t)(delay_s * base + .5);
}
 
struct Resampler const soxr_resampler={
create, destroy, process, flush, NULL /* set_compensation */, get_delay,
};
 
/contrib/sdk/sources/ffmpeg/libswresample/swresample-0.def
0,0 → 1,93
EXPORTS
ff_float_to_int16_a_sse2 DATA
ff_float_to_int16_u_sse2 DATA
ff_float_to_int32_a_sse2 DATA
ff_float_to_int32_u_sse2 DATA
ff_int16_to_float_a_sse2 DATA
ff_int16_to_float_u_sse2 DATA
ff_int16_to_int32_a_mmx DATA
ff_int16_to_int32_a_sse2 DATA
ff_int16_to_int32_u_mmx DATA
ff_int16_to_int32_u_sse2 DATA
ff_int32_to_float_a_sse2 DATA
ff_int32_to_float_u_sse2 DATA
ff_int32_to_int16_a_mmx DATA
ff_int32_to_int16_a_sse2 DATA
ff_int32_to_int16_u_mmx DATA
ff_int32_to_int16_u_sse2 DATA
ff_log2_tab DATA
ff_mix_1_1_a_float_sse DATA
ff_mix_1_1_a_int16_mmx DATA
ff_mix_1_1_a_int16_sse2 DATA
ff_mix_1_1_u_float_sse DATA
ff_mix_1_1_u_int16_mmx DATA
ff_mix_1_1_u_int16_sse2 DATA
ff_mix_2_1_a_float_sse DATA
ff_mix_2_1_a_int16_mmx DATA
ff_mix_2_1_a_int16_sse2 DATA
ff_mix_2_1_u_float_sse DATA
ff_mix_2_1_u_int16_mmx DATA
ff_mix_2_1_u_int16_sse2 DATA
ff_pack_2ch_float_to_int16_a_sse2 DATA
ff_pack_2ch_float_to_int16_u_sse2 DATA
ff_pack_2ch_float_to_int32_a_sse2 DATA
ff_pack_2ch_float_to_int32_u_sse2 DATA
ff_pack_2ch_int16_to_float_a_sse2 DATA
ff_pack_2ch_int16_to_float_u_sse2 DATA
ff_pack_2ch_int16_to_int16_a_sse2 DATA
ff_pack_2ch_int16_to_int16_u_sse2 DATA
ff_pack_2ch_int16_to_int32_a_sse2 DATA
ff_pack_2ch_int16_to_int32_u_sse2 DATA
ff_pack_2ch_int32_to_float_a_sse2 DATA
ff_pack_2ch_int32_to_float_u_sse2 DATA
ff_pack_2ch_int32_to_int16_a_sse2 DATA
ff_pack_2ch_int32_to_int16_u_sse2 DATA
ff_pack_2ch_int32_to_int32_a_sse2 DATA
ff_pack_2ch_int32_to_int32_u_sse2 DATA
ff_pack_6ch_float_to_float_a_mmx DATA
ff_pack_6ch_float_to_float_a_sse4 DATA
ff_pack_6ch_float_to_float_u_mmx DATA
ff_pack_6ch_float_to_float_u_sse4 DATA
ff_pack_6ch_float_to_int32_a_sse4 DATA
ff_pack_6ch_float_to_int32_u_sse4 DATA
ff_pack_6ch_int32_to_float_a_sse4 DATA
ff_pack_6ch_int32_to_float_u_sse4 DATA
ff_resample_int16_rounder DATA
ff_unpack_2ch_float_to_int16_a_sse2 DATA
ff_unpack_2ch_float_to_int16_u_sse2 DATA
ff_unpack_2ch_float_to_int32_a_sse2 DATA
ff_unpack_2ch_float_to_int32_u_sse2 DATA
ff_unpack_2ch_int16_to_float_a_sse2 DATA
ff_unpack_2ch_int16_to_float_a_ssse3 DATA
ff_unpack_2ch_int16_to_float_u_sse2 DATA
ff_unpack_2ch_int16_to_float_u_ssse3 DATA
ff_unpack_2ch_int16_to_int16_a_sse2 DATA
ff_unpack_2ch_int16_to_int16_a_ssse3 DATA
ff_unpack_2ch_int16_to_int16_u_sse2 DATA
ff_unpack_2ch_int16_to_int16_u_ssse3 DATA
ff_unpack_2ch_int16_to_int32_a_sse2 DATA
ff_unpack_2ch_int16_to_int32_a_ssse3 DATA
ff_unpack_2ch_int16_to_int32_u_sse2 DATA
ff_unpack_2ch_int16_to_int32_u_ssse3 DATA
ff_unpack_2ch_int32_to_float_a_sse2 DATA
ff_unpack_2ch_int32_to_float_u_sse2 DATA
ff_unpack_2ch_int32_to_int16_a_sse2 DATA
ff_unpack_2ch_int32_to_int16_u_sse2 DATA
ff_unpack_2ch_int32_to_int32_a_sse2 DATA
ff_unpack_2ch_int32_to_int32_u_sse2 DATA
swr_alloc
swr_alloc_set_opts
swr_convert
swr_drop_output
swr_free
swr_get_class
swr_get_delay
swr_init
swr_inject_silence
swr_next_pts
swr_set_channel_mapping
swr_set_compensation
swr_set_matrix
swresample_configuration
swresample_license
swresample_version
/contrib/sdk/sources/ffmpeg/libswresample/swresample-0.orig.def
0,0 → 1,93
EXPORTS
ff_float_to_int16_a_sse2 @1 DATA
ff_float_to_int16_u_sse2 @2 DATA
ff_float_to_int32_a_sse2 @3 DATA
ff_float_to_int32_u_sse2 @4 DATA
ff_int16_to_float_a_sse2 @5 DATA
ff_int16_to_float_u_sse2 @6 DATA
ff_int16_to_int32_a_mmx @7 DATA
ff_int16_to_int32_a_sse2 @8 DATA
ff_int16_to_int32_u_mmx @9 DATA
ff_int16_to_int32_u_sse2 @10 DATA
ff_int32_to_float_a_sse2 @11 DATA
ff_int32_to_float_u_sse2 @12 DATA
ff_int32_to_int16_a_mmx @13 DATA
ff_int32_to_int16_a_sse2 @14 DATA
ff_int32_to_int16_u_mmx @15 DATA
ff_int32_to_int16_u_sse2 @16 DATA
ff_log2_tab @17 DATA
ff_mix_1_1_a_float_sse @18 DATA
ff_mix_1_1_a_int16_mmx @19 DATA
ff_mix_1_1_a_int16_sse2 @20 DATA
ff_mix_1_1_u_float_sse @21 DATA
ff_mix_1_1_u_int16_mmx @22 DATA
ff_mix_1_1_u_int16_sse2 @23 DATA
ff_mix_2_1_a_float_sse @24 DATA
ff_mix_2_1_a_int16_mmx @25 DATA
ff_mix_2_1_a_int16_sse2 @26 DATA
ff_mix_2_1_u_float_sse @27 DATA
ff_mix_2_1_u_int16_mmx @28 DATA
ff_mix_2_1_u_int16_sse2 @29 DATA
ff_pack_2ch_float_to_int16_a_sse2 @30 DATA
ff_pack_2ch_float_to_int16_u_sse2 @31 DATA
ff_pack_2ch_float_to_int32_a_sse2 @32 DATA
ff_pack_2ch_float_to_int32_u_sse2 @33 DATA
ff_pack_2ch_int16_to_float_a_sse2 @34 DATA
ff_pack_2ch_int16_to_float_u_sse2 @35 DATA
ff_pack_2ch_int16_to_int16_a_sse2 @36 DATA
ff_pack_2ch_int16_to_int16_u_sse2 @37 DATA
ff_pack_2ch_int16_to_int32_a_sse2 @38 DATA
ff_pack_2ch_int16_to_int32_u_sse2 @39 DATA
ff_pack_2ch_int32_to_float_a_sse2 @40 DATA
ff_pack_2ch_int32_to_float_u_sse2 @41 DATA
ff_pack_2ch_int32_to_int16_a_sse2 @42 DATA
ff_pack_2ch_int32_to_int16_u_sse2 @43 DATA
ff_pack_2ch_int32_to_int32_a_sse2 @44 DATA
ff_pack_2ch_int32_to_int32_u_sse2 @45 DATA
ff_pack_6ch_float_to_float_a_mmx @46 DATA
ff_pack_6ch_float_to_float_a_sse4 @47 DATA
ff_pack_6ch_float_to_float_u_mmx @48 DATA
ff_pack_6ch_float_to_float_u_sse4 @49 DATA
ff_pack_6ch_float_to_int32_a_sse4 @50 DATA
ff_pack_6ch_float_to_int32_u_sse4 @51 DATA
ff_pack_6ch_int32_to_float_a_sse4 @52 DATA
ff_pack_6ch_int32_to_float_u_sse4 @53 DATA
ff_resample_int16_rounder @54 DATA
ff_unpack_2ch_float_to_int16_a_sse2 @55 DATA
ff_unpack_2ch_float_to_int16_u_sse2 @56 DATA
ff_unpack_2ch_float_to_int32_a_sse2 @57 DATA
ff_unpack_2ch_float_to_int32_u_sse2 @58 DATA
ff_unpack_2ch_int16_to_float_a_sse2 @59 DATA
ff_unpack_2ch_int16_to_float_a_ssse3 @60 DATA
ff_unpack_2ch_int16_to_float_u_sse2 @61 DATA
ff_unpack_2ch_int16_to_float_u_ssse3 @62 DATA
ff_unpack_2ch_int16_to_int16_a_sse2 @63 DATA
ff_unpack_2ch_int16_to_int16_a_ssse3 @64 DATA
ff_unpack_2ch_int16_to_int16_u_sse2 @65 DATA
ff_unpack_2ch_int16_to_int16_u_ssse3 @66 DATA
ff_unpack_2ch_int16_to_int32_a_sse2 @67 DATA
ff_unpack_2ch_int16_to_int32_a_ssse3 @68 DATA
ff_unpack_2ch_int16_to_int32_u_sse2 @69 DATA
ff_unpack_2ch_int16_to_int32_u_ssse3 @70 DATA
ff_unpack_2ch_int32_to_float_a_sse2 @71 DATA
ff_unpack_2ch_int32_to_float_u_sse2 @72 DATA
ff_unpack_2ch_int32_to_int16_a_sse2 @73 DATA
ff_unpack_2ch_int32_to_int16_u_sse2 @74 DATA
ff_unpack_2ch_int32_to_int32_a_sse2 @75 DATA
ff_unpack_2ch_int32_to_int32_u_sse2 @76 DATA
swr_alloc @77
swr_alloc_set_opts @78
swr_convert @79
swr_drop_output @80
swr_free @81
swr_get_class @82
swr_get_delay @83
swr_init @84
swr_inject_silence @85
swr_next_pts @86
swr_set_channel_mapping @87
swr_set_compensation @88
swr_set_matrix @89
swresample_configuration @90
swresample_license @91
swresample_version @92
/contrib/sdk/sources/ffmpeg/libswresample/swresample-test.c
0,0 → 1,414
/*
* Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
* Copyright (c) 2002 Fabrice Bellard
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/opt.h"
#include "swresample.h"
 
#undef time
#include "time.h"
#undef fprintf
 
#define SAMPLES 1000
 
#define ASSERT_LEVEL 2
 
static double get(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f){
const uint8_t *p;
if(av_sample_fmt_is_planar(f)){
f= av_get_alt_sample_fmt(f, 0);
p= a[ch];
}else{
p= a[0];
index= ch + index*ch_count;
}
 
switch(f){
case AV_SAMPLE_FMT_U8 : return ((const uint8_t*)p)[index]/127.0-1.0;
case AV_SAMPLE_FMT_S16: return ((const int16_t*)p)[index]/32767.0;
case AV_SAMPLE_FMT_S32: return ((const int32_t*)p)[index]/2147483647.0;
case AV_SAMPLE_FMT_FLT: return ((const float *)p)[index];
case AV_SAMPLE_FMT_DBL: return ((const double *)p)[index];
default: av_assert0(0);
}
}
 
static void set(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f, double v){
uint8_t *p;
if(av_sample_fmt_is_planar(f)){
f= av_get_alt_sample_fmt(f, 0);
p= a[ch];
}else{
p= a[0];
index= ch + index*ch_count;
}
switch(f){
case AV_SAMPLE_FMT_U8 : ((uint8_t*)p)[index]= av_clip_uint8 (lrint((v+1.0)*127)); break;
case AV_SAMPLE_FMT_S16: ((int16_t*)p)[index]= av_clip_int16 (lrint(v*32767)); break;
case AV_SAMPLE_FMT_S32: ((int32_t*)p)[index]= av_clipl_int32(llrint(v*2147483647)); break;
case AV_SAMPLE_FMT_FLT: ((float *)p)[index]= v; break;
case AV_SAMPLE_FMT_DBL: ((double *)p)[index]= v; break;
default: av_assert2(0);
}
}
 
static void shift(uint8_t *a[], int index, int ch_count, enum AVSampleFormat f){
int ch;
 
if(av_sample_fmt_is_planar(f)){
f= av_get_alt_sample_fmt(f, 0);
for(ch= 0; ch<ch_count; ch++)
a[ch] += index*av_get_bytes_per_sample(f);
}else{
a[0] += index*ch_count*av_get_bytes_per_sample(f);
}
}
 
static const enum AVSampleFormat formats[] = {
AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_FLT,
AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_U8P,
AV_SAMPLE_FMT_U8,
AV_SAMPLE_FMT_DBLP,
AV_SAMPLE_FMT_DBL,
};
 
static const int rates[] = {
8000,
11025,
16000,
22050,
32000,
48000,
};
 
uint64_t layouts[]={
AV_CH_LAYOUT_MONO ,
AV_CH_LAYOUT_STEREO ,
AV_CH_LAYOUT_2_1 ,
AV_CH_LAYOUT_SURROUND ,
AV_CH_LAYOUT_4POINT0 ,
AV_CH_LAYOUT_2_2 ,
AV_CH_LAYOUT_QUAD ,
AV_CH_LAYOUT_5POINT0 ,
AV_CH_LAYOUT_5POINT1 ,
AV_CH_LAYOUT_5POINT0_BACK ,
AV_CH_LAYOUT_5POINT1_BACK ,
AV_CH_LAYOUT_7POINT0 ,
AV_CH_LAYOUT_7POINT1 ,
AV_CH_LAYOUT_7POINT1_WIDE ,
};
 
static void setup_array(uint8_t *out[SWR_CH_MAX], uint8_t *in, enum AVSampleFormat format, int samples){
if(av_sample_fmt_is_planar(format)){
int i;
int plane_size= av_get_bytes_per_sample(format&0xFF)*samples;
format&=0xFF;
for(i=0; i<SWR_CH_MAX; i++){
out[i]= in + i*plane_size;
}
}else{
out[0]= in;
}
}
 
static int cmp(const int *a, const int *b){
return *a - *b;
}
 
static void audiogen(void *data, enum AVSampleFormat sample_fmt,
int channels, int sample_rate, int nb_samples)
{
int i, ch, k;
double v, f, a, ampa;
double tabf1[SWR_CH_MAX];
double tabf2[SWR_CH_MAX];
double taba[SWR_CH_MAX];
unsigned static rnd;
 
#define PUT_SAMPLE set(data, ch, k, channels, sample_fmt, v);
#define uint_rand(x) (x = x * 1664525 + 1013904223)
#define dbl_rand(x) (uint_rand(x)*2.0 / (double)UINT_MAX - 1)
k = 0;
 
/* 1 second of single freq sinus at 1000 Hz */
a = 0;
for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
v = sin(a) * 0.30;
for (ch = 0; ch < channels; ch++)
PUT_SAMPLE
a += M_PI * 1000.0 * 2.0 / sample_rate;
}
 
/* 1 second of varing frequency between 100 and 10000 Hz */
a = 0;
for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
v = sin(a) * 0.30;
for (ch = 0; ch < channels; ch++)
PUT_SAMPLE
f = 100.0 + (((10000.0 - 100.0) * i) / sample_rate);
a += M_PI * f * 2.0 / sample_rate;
}
 
/* 0.5 second of low amplitude white noise */
for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
v = dbl_rand(rnd) * 0.30;
for (ch = 0; ch < channels; ch++)
PUT_SAMPLE
}
 
/* 0.5 second of high amplitude white noise */
for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
v = dbl_rand(rnd);
for (ch = 0; ch < channels; ch++)
PUT_SAMPLE
}
 
/* 1 second of unrelated ramps for each channel */
for (ch = 0; ch < channels; ch++) {
taba[ch] = 0;
tabf1[ch] = 100 + uint_rand(rnd) % 5000;
tabf2[ch] = 100 + uint_rand(rnd) % 5000;
}
for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
for (ch = 0; ch < channels; ch++) {
v = sin(taba[ch]) * 0.30;
PUT_SAMPLE
f = tabf1[ch] + (((tabf2[ch] - tabf1[ch]) * i) / sample_rate);
taba[ch] += M_PI * f * 2.0 / sample_rate;
}
}
 
/* 2 seconds of 500 Hz with varying volume */
a = 0;
ampa = 0;
for (i = 0; i < 2 * sample_rate && k < nb_samples; i++, k++) {
for (ch = 0; ch < channels; ch++) {
double amp = (1.0 + sin(ampa)) * 0.15;
if (ch & 1)
amp = 0.30 - amp;
v = sin(a) * amp;
PUT_SAMPLE
a += M_PI * 500.0 * 2.0 / sample_rate;
ampa += M_PI * 2.0 / sample_rate;
}
}
}
 
int main(int argc, char **argv){
int in_sample_rate, out_sample_rate, ch ,i, flush_count;
uint64_t in_ch_layout, out_ch_layout;
enum AVSampleFormat in_sample_fmt, out_sample_fmt;
uint8_t array_in[SAMPLES*8*8];
uint8_t array_mid[SAMPLES*8*8*3];
uint8_t array_out[SAMPLES*8*8+100];
uint8_t *ain[SWR_CH_MAX];
uint8_t *aout[SWR_CH_MAX];
uint8_t *amid[SWR_CH_MAX];
int flush_i=0;
int mode;
int num_tests = 10000;
uint32_t seed = 0;
uint32_t rand_seed = 0;
int remaining_tests[FF_ARRAY_ELEMS(rates) * FF_ARRAY_ELEMS(layouts) * FF_ARRAY_ELEMS(formats) * FF_ARRAY_ELEMS(layouts) * FF_ARRAY_ELEMS(formats)];
int max_tests = FF_ARRAY_ELEMS(remaining_tests);
int test;
int specific_test= -1;
 
struct SwrContext * forw_ctx= NULL;
struct SwrContext *backw_ctx= NULL;
 
if (argc > 1) {
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
av_log(NULL, AV_LOG_INFO, "Usage: swresample-test [<num_tests>[ <test>]] \n"
"num_tests Default is %d\n", num_tests);
return 0;
}
num_tests = strtol(argv[1], NULL, 0);
if(num_tests < 0) {
num_tests = -num_tests;
rand_seed = time(0);
}
if(num_tests<= 0 || num_tests>max_tests)
num_tests = max_tests;
if(argc > 2) {
specific_test = strtol(argv[1], NULL, 0);
}
}
 
for(i=0; i<max_tests; i++)
remaining_tests[i] = i;
 
for(test=0; test<num_tests; test++){
unsigned r;
uint_rand(seed);
r = (seed * (uint64_t)(max_tests - test)) >>32;
FFSWAP(int, remaining_tests[r], remaining_tests[max_tests - test - 1]);
}
qsort(remaining_tests + max_tests - num_tests, num_tests, sizeof(remaining_tests[0]), (void*)cmp);
in_sample_rate=16000;
for(test=0; test<num_tests; test++){
char in_layout_string[256];
char out_layout_string[256];
unsigned vector= remaining_tests[max_tests - test - 1];
int in_ch_count;
int out_count, mid_count, out_ch_count;
 
in_ch_layout = layouts[vector % FF_ARRAY_ELEMS(layouts)]; vector /= FF_ARRAY_ELEMS(layouts);
out_ch_layout = layouts[vector % FF_ARRAY_ELEMS(layouts)]; vector /= FF_ARRAY_ELEMS(layouts);
in_sample_fmt = formats[vector % FF_ARRAY_ELEMS(formats)]; vector /= FF_ARRAY_ELEMS(formats);
out_sample_fmt = formats[vector % FF_ARRAY_ELEMS(formats)]; vector /= FF_ARRAY_ELEMS(formats);
out_sample_rate = rates [vector % FF_ARRAY_ELEMS(rates )]; vector /= FF_ARRAY_ELEMS(rates);
av_assert0(!vector);
 
if(specific_test == 0){
if(out_sample_rate != in_sample_rate || in_ch_layout != out_ch_layout)
continue;
}
 
in_ch_count= av_get_channel_layout_nb_channels(in_ch_layout);
out_ch_count= av_get_channel_layout_nb_channels(out_ch_layout);
av_get_channel_layout_string( in_layout_string, sizeof( in_layout_string), in_ch_count, in_ch_layout);
av_get_channel_layout_string(out_layout_string, sizeof(out_layout_string), out_ch_count, out_ch_layout);
fprintf(stderr, "TEST: %s->%s, rate:%5d->%5d, fmt:%s->%s\n",
in_layout_string, out_layout_string,
in_sample_rate, out_sample_rate,
av_get_sample_fmt_name(in_sample_fmt), av_get_sample_fmt_name(out_sample_fmt));
forw_ctx = swr_alloc_set_opts(forw_ctx, out_ch_layout, out_sample_fmt, out_sample_rate,
in_ch_layout, in_sample_fmt, in_sample_rate,
0, 0);
backw_ctx = swr_alloc_set_opts(backw_ctx, in_ch_layout, in_sample_fmt, in_sample_rate,
out_ch_layout, out_sample_fmt, out_sample_rate,
0, 0);
if(!forw_ctx) {
fprintf(stderr, "Failed to init forw_cts\n");
return 1;
}
if(!backw_ctx) {
fprintf(stderr, "Failed to init backw_ctx\n");
return 1;
}
if(swr_init( forw_ctx) < 0)
fprintf(stderr, "swr_init(->) failed\n");
if(swr_init(backw_ctx) < 0)
fprintf(stderr, "swr_init(<-) failed\n");
//FIXME test planar
setup_array(ain , array_in , in_sample_fmt, SAMPLES);
setup_array(amid, array_mid, out_sample_fmt, 3*SAMPLES);
setup_array(aout, array_out, in_sample_fmt , SAMPLES);
#if 0
for(ch=0; ch<in_ch_count; ch++){
for(i=0; i<SAMPLES; i++)
set(ain, ch, i, in_ch_count, in_sample_fmt, sin(i*i*3/SAMPLES));
}
#else
audiogen(ain, in_sample_fmt, in_ch_count, SAMPLES/6+1, SAMPLES);
#endif
mode = uint_rand(rand_seed) % 3;
if(mode==0 /*|| out_sample_rate == in_sample_rate*/) {
mid_count= swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, SAMPLES);
} else if(mode==1){
mid_count= swr_convert(forw_ctx, amid, 0, (const uint8_t **)ain, SAMPLES);
mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, 0);
} else {
int tmp_count;
mid_count= swr_convert(forw_ctx, amid, 0, (const uint8_t **)ain, 1);
av_assert0(mid_count==0);
shift(ain, 1, in_ch_count, in_sample_fmt);
mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, 0);
shift(amid, mid_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
mid_count+=swr_convert(forw_ctx, amid, 2, (const uint8_t **)ain, 2);
shift(amid, mid_count-tmp_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
shift(ain, 2, in_ch_count, in_sample_fmt);
mid_count+=swr_convert(forw_ctx, amid, 1, (const uint8_t **)ain, SAMPLES-3);
shift(amid, mid_count-tmp_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
shift(ain, -3, in_ch_count, in_sample_fmt);
mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, 0);
shift(amid, -tmp_count, out_ch_count, out_sample_fmt);
}
out_count= swr_convert(backw_ctx,aout, SAMPLES, (const uint8_t **)amid, mid_count);
 
for(ch=0; ch<in_ch_count; ch++){
double sse, maxdiff=0;
double sum_a= 0;
double sum_b= 0;
double sum_aa= 0;
double sum_bb= 0;
double sum_ab= 0;
for(i=0; i<out_count; i++){
double a= get(ain , ch, i, in_ch_count, in_sample_fmt);
double b= get(aout, ch, i, in_ch_count, in_sample_fmt);
sum_a += a;
sum_b += b;
sum_aa+= a*a;
sum_bb+= b*b;
sum_ab+= a*b;
maxdiff= FFMAX(maxdiff, FFABS(a-b));
}
sse= sum_aa + sum_bb - 2*sum_ab;
if(sse < 0 && sse > -0.00001) sse=0; //fix rounding error
 
fprintf(stderr, "[e:%f c:%f max:%f] len:%5d\n", out_count ? sqrt(sse/out_count) : 0, sum_ab/(sqrt(sum_aa*sum_bb)), maxdiff, out_count);
}
 
flush_i++;
flush_i%=21;
flush_count = swr_convert(backw_ctx,aout, flush_i, 0, 0);
shift(aout, flush_i, in_ch_count, in_sample_fmt);
flush_count+= swr_convert(backw_ctx,aout, SAMPLES-flush_i, 0, 0);
shift(aout, -flush_i, in_ch_count, in_sample_fmt);
if(flush_count){
for(ch=0; ch<in_ch_count; ch++){
double sse, maxdiff=0;
double sum_a= 0;
double sum_b= 0;
double sum_aa= 0;
double sum_bb= 0;
double sum_ab= 0;
for(i=0; i<flush_count; i++){
double a= get(ain , ch, i+out_count, in_ch_count, in_sample_fmt);
double b= get(aout, ch, i, in_ch_count, in_sample_fmt);
sum_a += a;
sum_b += b;
sum_aa+= a*a;
sum_bb+= b*b;
sum_ab+= a*b;
maxdiff= FFMAX(maxdiff, FFABS(a-b));
}
sse= sum_aa + sum_bb - 2*sum_ab;
if(sse < 0 && sse > -0.00001) sse=0; //fix rounding error
 
fprintf(stderr, "[e:%f c:%f max:%f] len:%5d F:%3d\n", sqrt(sse/flush_count), sum_ab/(sqrt(sum_aa*sum_bb)), maxdiff, flush_count, flush_i);
}
}
 
 
fprintf(stderr, "\n");
}
 
return 0;
}
/contrib/sdk/sources/ffmpeg/libswresample/swresample.c
0,0 → 1,934
/*
* Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#include "libavutil/opt.h"
#include "swresample_internal.h"
#include "audioconvert.h"
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
 
#include <float.h>
 
#define C30DB M_SQRT2
#define C15DB 1.189207115
#define C__0DB 1.0
#define C_15DB 0.840896415
#define C_30DB M_SQRT1_2
#define C_45DB 0.594603558
#define C_60DB 0.5
 
#define ALIGN 32
 
//TODO split options array out?
#define OFFSET(x) offsetof(SwrContext,x)
#define PARAM AV_OPT_FLAG_AUDIO_PARAM
 
static const AVOption options[]={
{"ich" , "set input channel count" , OFFSET( in.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM},
{"in_channel_count" , "set input channel count" , OFFSET( in.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM},
{"och" , "set output channel count" , OFFSET(out.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM},
{"out_channel_count" , "set output channel count" , OFFSET(out.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM},
{"uch" , "set used channel count" , OFFSET(used_ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM},
{"used_channel_count" , "set used channel count" , OFFSET(used_ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM},
{"isr" , "set input sample rate" , OFFSET( in_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM},
{"in_sample_rate" , "set input sample rate" , OFFSET( in_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM},
{"osr" , "set output sample rate" , OFFSET(out_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM},
{"out_sample_rate" , "set output sample rate" , OFFSET(out_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM},
{"isf" , "set input sample format" , OFFSET( in_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"in_sample_fmt" , "set input sample format" , OFFSET( in_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"osf" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"out_sample_fmt" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"tsf" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"internal_sample_fmt" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"icl" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
{"in_channel_layout" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
{"ocl" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
{"out_channel_layout" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
{"clev" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM},
{"center_mix_level" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM},
{"slev" , "set surround mix level" , OFFSET(slev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM},
{"surround_mix_level" , "set surround mix Level" , OFFSET(slev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM},
{"lfe_mix_level" , "set LFE mix level" , OFFSET(lfe_mix_level ), AV_OPT_TYPE_FLOAT, {.dbl=0 }, -32 , 32 , PARAM},
{"rmvol" , "set rematrix volume" , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0 }, -1000 , 1000 , PARAM},
{"rematrix_volume" , "set rematrix volume" , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0 }, -1000 , 1000 , PARAM},
{"rematrix_maxval" , "set rematrix maxval" , OFFSET(rematrix_maxval), AV_OPT_TYPE_FLOAT, {.dbl=0.0 }, 0 , 1000 , PARAM},
 
{"flags" , "set flags" , OFFSET(flags ), AV_OPT_TYPE_FLAGS, {.i64=0 }, 0 , UINT_MAX , PARAM, "flags"},
{"swr_flags" , "set flags" , OFFSET(flags ), AV_OPT_TYPE_FLAGS, {.i64=0 }, 0 , UINT_MAX , PARAM, "flags"},
{"res" , "force resampling" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_FLAG_RESAMPLE }, INT_MIN, INT_MAX , PARAM, "flags"},
 
{"dither_scale" , "set dither scale" , OFFSET(dither.scale ), AV_OPT_TYPE_FLOAT, {.dbl=1 }, 0 , INT_MAX , PARAM},
 
{"dither_method" , "set dither method" , OFFSET(dither.method ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_DITHER_NB-1, PARAM, "dither_method"},
{"rectangular" , "select rectangular dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_RECTANGULAR}, INT_MIN, INT_MAX , PARAM, "dither_method"},
{"triangular" , "select triangular dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR }, INT_MIN, INT_MAX , PARAM, "dither_method"},
{"triangular_hp" , "select triangular dither with high pass" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
{"lipshitz" , "select lipshitz noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_LIPSHITZ}, INT_MIN, INT_MAX, PARAM, "dither_method"},
{"shibata" , "select shibata noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"},
{"low_shibata" , "select low shibata noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_LOW_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"},
{"high_shibata" , "select high shibata noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_HIGH_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"},
{"f_weighted" , "select f-weighted noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_F_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"},
{"modified_e_weighted" , "select modified-e-weighted noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_MODIFIED_E_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"},
{"improved_e_weighted" , "select improved-e-weighted noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_IMPROVED_E_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"},
 
{"filter_size" , "set swr resampling filter size", OFFSET(filter_size) , AV_OPT_TYPE_INT , {.i64=32 }, 0 , INT_MAX , PARAM },
{"phase_shift" , "set swr resampling phase shift", OFFSET(phase_shift) , AV_OPT_TYPE_INT , {.i64=10 }, 0 , 24 , PARAM },
{"linear_interp" , "enable linear interpolation" , OFFSET(linear_interp) , AV_OPT_TYPE_INT , {.i64=0 }, 0 , 1 , PARAM },
{"cutoff" , "set cutoff frequency ratio" , OFFSET(cutoff) , AV_OPT_TYPE_DOUBLE,{.dbl=0. }, 0 , 1 , PARAM },
 
/* duplicate option in order to work with avconv */
{"resample_cutoff" , "set cutoff frequency ratio" , OFFSET(cutoff) , AV_OPT_TYPE_DOUBLE,{.dbl=0. }, 0 , 1 , PARAM },
 
{"resampler" , "set resampling Engine" , OFFSET(engine) , AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_ENGINE_NB-1, PARAM, "resampler"},
{"swr" , "select SW Resampler" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_ENGINE_SWR }, INT_MIN, INT_MAX , PARAM, "resampler"},
{"soxr" , "select SoX Resampler" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_ENGINE_SOXR }, INT_MIN, INT_MAX , PARAM, "resampler"},
{"precision" , "set soxr resampling precision (in bits)"
, OFFSET(precision) , AV_OPT_TYPE_DOUBLE,{.dbl=20.0 }, 15.0 , 33.0 , PARAM },
{"cheby" , "enable soxr Chebyshev passband & higher-precision irrational ratio approximation"
, OFFSET(cheby) , AV_OPT_TYPE_INT , {.i64=0 }, 0 , 1 , PARAM },
{"min_comp" , "set minimum difference between timestamps and audio data (in seconds) below which no timestamp compensation of either kind is applied"
, OFFSET(min_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=FLT_MAX }, 0 , FLT_MAX , PARAM },
{"min_hard_comp" , "set minimum difference between timestamps and audio data (in seconds) to trigger padding/trimming the data."
, OFFSET(min_hard_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0.1 }, 0 , INT_MAX , PARAM },
{"comp_duration" , "set duration (in seconds) over which data is stretched/squeezed to make it match the timestamps."
, OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1 }, 0 , INT_MAX , PARAM },
{"max_soft_comp" , "set maximum factor by which data is stretched/squeezed to make it match the timestamps."
, OFFSET(max_soft_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0 }, INT_MIN, INT_MAX , PARAM },
{"async" , "simplified 1 parameter audio timestamp matching, 0(disabled), 1(filling and trimming), >1(maximum stretch/squeeze in samples per second)"
, OFFSET(async) , AV_OPT_TYPE_FLOAT ,{.dbl=0 }, INT_MIN, INT_MAX , PARAM },
{"first_pts" , "Assume the first pts should be this value (in samples)."
, OFFSET(firstpts_in_samples), AV_OPT_TYPE_INT64 ,{.i64=AV_NOPTS_VALUE }, INT64_MIN,INT64_MAX, PARAM },
 
{ "matrix_encoding" , "set matrixed stereo encoding" , OFFSET(matrix_encoding), AV_OPT_TYPE_INT ,{.i64 = AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE, AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
{ "none", "select none", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
{ "dolby", "select Dolby", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
{ "dplii", "select Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
 
{ "filter_type" , "select swr filter type" , OFFSET(filter_type) , AV_OPT_TYPE_INT , { .i64 = SWR_FILTER_TYPE_KAISER }, SWR_FILTER_TYPE_CUBIC, SWR_FILTER_TYPE_KAISER, PARAM, "filter_type" },
{ "cubic" , "select cubic" , 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_CUBIC }, INT_MIN, INT_MAX, PARAM, "filter_type" },
{ "blackman_nuttall", "select Blackman Nuttall Windowed Sinc", 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
{ "kaiser" , "select Kaiser Windowed Sinc" , 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_KAISER }, INT_MIN, INT_MAX, PARAM, "filter_type" },
 
{ "kaiser_beta" , "set swr Kaiser Window Beta" , OFFSET(kaiser_beta) , AV_OPT_TYPE_INT , {.i64=9 }, 2 , 16 , PARAM },
 
{ "output_sample_bits" , "set swr number of output sample bits", OFFSET(dither.output_sample_bits), AV_OPT_TYPE_INT , {.i64=0 }, 0 , 64 , PARAM },
{0}
};
 
static const char* context_to_name(void* ptr) {
return "SWR";
}
 
static const AVClass av_class = {
.class_name = "SWResampler",
.item_name = context_to_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
.log_level_offset_offset = OFFSET(log_level_offset),
.parent_log_context_offset = OFFSET(log_ctx),
.category = AV_CLASS_CATEGORY_SWRESAMPLER,
};
 
unsigned swresample_version(void)
{
av_assert0(LIBSWRESAMPLE_VERSION_MICRO >= 100);
return LIBSWRESAMPLE_VERSION_INT;
}
 
const char *swresample_configuration(void)
{
return FFMPEG_CONFIGURATION;
}
 
const char *swresample_license(void)
{
#define LICENSE_PREFIX "libswresample license: "
return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}
 
int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){
if(!s || s->in_convert) // s needs to be allocated but not initialized
return AVERROR(EINVAL);
s->channel_map = channel_map;
return 0;
}
 
const AVClass *swr_get_class(void)
{
return &av_class;
}
 
av_cold struct SwrContext *swr_alloc(void){
SwrContext *s= av_mallocz(sizeof(SwrContext));
if(s){
s->av_class= &av_class;
av_opt_set_defaults(s);
}
return s;
}
 
struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
int log_offset, void *log_ctx){
if(!s) s= swr_alloc();
if(!s) return NULL;
 
s->log_level_offset= log_offset;
s->log_ctx= log_ctx;
 
av_opt_set_int(s, "ocl", out_ch_layout, 0);
av_opt_set_int(s, "osf", out_sample_fmt, 0);
av_opt_set_int(s, "osr", out_sample_rate, 0);
av_opt_set_int(s, "icl", in_ch_layout, 0);
av_opt_set_int(s, "isf", in_sample_fmt, 0);
av_opt_set_int(s, "isr", in_sample_rate, 0);
av_opt_set_int(s, "tsf", AV_SAMPLE_FMT_NONE, 0);
av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> in_ch_layout), 0);
av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->out_ch_layout), 0);
av_opt_set_int(s, "uch", 0, 0);
return s;
}
 
static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt){
a->fmt = fmt;
a->bps = av_get_bytes_per_sample(fmt);
a->planar= av_sample_fmt_is_planar(fmt);
}
 
static void free_temp(AudioData *a){
av_free(a->data);
memset(a, 0, sizeof(*a));
}
 
av_cold void swr_free(SwrContext **ss){
SwrContext *s= *ss;
if(s){
free_temp(&s->postin);
free_temp(&s->midbuf);
free_temp(&s->preout);
free_temp(&s->in_buffer);
free_temp(&s->silence);
free_temp(&s->drop_temp);
free_temp(&s->dither.noise);
free_temp(&s->dither.temp);
swri_audio_convert_free(&s-> in_convert);
swri_audio_convert_free(&s->out_convert);
swri_audio_convert_free(&s->full_convert);
if (s->resampler)
s->resampler->free(&s->resample);
swri_rematrix_free(s);
}
 
av_freep(ss);
}
 
av_cold int swr_init(struct SwrContext *s){
int ret;
s->in_buffer_index= 0;
s->in_buffer_count= 0;
s->resample_in_constraint= 0;
free_temp(&s->postin);
free_temp(&s->midbuf);
free_temp(&s->preout);
free_temp(&s->in_buffer);
free_temp(&s->silence);
free_temp(&s->drop_temp);
free_temp(&s->dither.noise);
free_temp(&s->dither.temp);
memset(s->in.ch, 0, sizeof(s->in.ch));
memset(s->out.ch, 0, sizeof(s->out.ch));
swri_audio_convert_free(&s-> in_convert);
swri_audio_convert_free(&s->out_convert);
swri_audio_convert_free(&s->full_convert);
swri_rematrix_free(s);
 
s->flushed = 0;
 
if(s-> in_sample_fmt >= AV_SAMPLE_FMT_NB){
av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt);
return AVERROR(EINVAL);
}
if(s->out_sample_fmt >= AV_SAMPLE_FMT_NB){
av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt);
return AVERROR(EINVAL);
}
 
if(av_get_channel_layout_nb_channels(s-> in_ch_layout) > SWR_CH_MAX) {
av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is invalid or unsupported.\n", s-> in_ch_layout);
s->in_ch_layout = 0;
}
 
if(av_get_channel_layout_nb_channels(s->out_ch_layout) > SWR_CH_MAX) {
av_log(s, AV_LOG_WARNING, "Output channel layout 0x%"PRIx64" is invalid or unsupported.\n", s->out_ch_layout);
s->out_ch_layout = 0;
}
 
switch(s->engine){
#if CONFIG_LIBSOXR
extern struct Resampler const soxr_resampler;
case SWR_ENGINE_SOXR: s->resampler = &soxr_resampler; break;
#endif
case SWR_ENGINE_SWR : s->resampler = &swri_resampler; break;
default:
av_log(s, AV_LOG_ERROR, "Requested resampling engine is unavailable\n");
return AVERROR(EINVAL);
}
 
if(!s->used_ch_count)
s->used_ch_count= s->in.ch_count;
 
if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s-> in_ch_layout)){
av_log(s, AV_LOG_WARNING, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
s-> in_ch_layout= 0;
}
 
if(!s-> in_ch_layout)
s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count);
if(!s->out_ch_layout)
s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
 
s->rematrix= s->out_ch_layout !=s->in_ch_layout || s->rematrix_volume!=1.0 ||
s->rematrix_custom;
 
if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){
if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_S16P){
s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
}else if( av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P
&& av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P
&& !s->rematrix
&& s->engine != SWR_ENGINE_SOXR){
s->int_sample_fmt= AV_SAMPLE_FMT_S32P;
}else if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_FLTP){
s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
}else{
av_log(s, AV_LOG_DEBUG, "Using double precision mode\n");
s->int_sample_fmt= AV_SAMPLE_FMT_DBLP;
}
}
 
if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
&&s->int_sample_fmt != AV_SAMPLE_FMT_S32P
&&s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
&&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){
av_log(s, AV_LOG_ERROR, "Requested sample format %s is not supported internally, S16/S32/FLT/DBL is supported\n", av_get_sample_fmt_name(s->int_sample_fmt));
return AVERROR(EINVAL);
}
 
set_audiodata_fmt(&s-> in, s-> in_sample_fmt);
set_audiodata_fmt(&s->out, s->out_sample_fmt);
 
if (s->firstpts_in_samples != AV_NOPTS_VALUE) {
if (!s->async && s->min_compensation >= FLT_MAX/2)
s->async = 1;
s->firstpts =
s->outpts = s->firstpts_in_samples * s->out_sample_rate;
} else
s->firstpts = AV_NOPTS_VALUE;
 
if (s->async) {
if (s->min_compensation >= FLT_MAX/2)
s->min_compensation = 0.001;
if (s->async > 1.0001) {
s->max_soft_compensation = s->async / (double) s->in_sample_rate;
}
}
 
if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){
s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby);
}else
s->resampler->free(&s->resample);
if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
&& s->int_sample_fmt != AV_SAMPLE_FMT_S32P
&& s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
&& s->int_sample_fmt != AV_SAMPLE_FMT_DBLP
&& s->resample){
av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16/s32/flt/dbl\n");
return -1;
}
 
#define RSC 1 //FIXME finetune
if(!s-> in.ch_count)
s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout);
if(!s->used_ch_count)
s->used_ch_count= s->in.ch_count;
if(!s->out.ch_count)
s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout);
 
if(!s-> in.ch_count){
av_assert0(!s->in_ch_layout);
av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n");
return -1;
}
 
if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) {
char l1[1024], l2[1024];
av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout);
av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout);
av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "
"but there is not enough information to do it\n", l1, l2);
return -1;
}
 
av_assert0(s->used_ch_count);
av_assert0(s->out.ch_count);
s->resample_first= RSC*s->out.ch_count/s->in.ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
 
s->in_buffer= s->in;
s->silence = s->in;
s->drop_temp= s->out;
 
if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){
s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
return 0;
}
 
s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,
s-> in_sample_fmt, s->used_ch_count, s->channel_map, 0);
s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
s->int_sample_fmt, s->out.ch_count, NULL, 0);
 
if (!s->in_convert || !s->out_convert)
return AVERROR(ENOMEM);
 
s->postin= s->in;
s->preout= s->out;
s->midbuf= s->in;
 
if(s->channel_map){
s->postin.ch_count=
s->midbuf.ch_count= s->used_ch_count;
if(s->resample)
s->in_buffer.ch_count= s->used_ch_count;
}
if(!s->resample_first){
s->midbuf.ch_count= s->out.ch_count;
if(s->resample)
s->in_buffer.ch_count = s->out.ch_count;
}
 
set_audiodata_fmt(&s->postin, s->int_sample_fmt);
set_audiodata_fmt(&s->midbuf, s->int_sample_fmt);
set_audiodata_fmt(&s->preout, s->int_sample_fmt);
 
if(s->resample){
set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
}
 
if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0)
return ret;
 
if(s->rematrix || s->dither.method)
return swri_rematrix_init(s);
 
return 0;
}
 
int swri_realloc_audio(AudioData *a, int count){
int i, countb;
AudioData old;
 
if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count)
return AVERROR(EINVAL);
 
if(a->count >= count)
return 0;
 
count*=2;
 
countb= FFALIGN(count*a->bps, ALIGN);
old= *a;
 
av_assert0(a->bps);
av_assert0(a->ch_count);
 
a->data= av_mallocz(countb*a->ch_count);
if(!a->data)
return AVERROR(ENOMEM);
for(i=0; i<a->ch_count; i++){
a->ch[i]= a->data + i*(a->planar ? countb : a->bps);
if(a->planar) memcpy(a->ch[i], old.ch[i], a->count*a->bps);
}
if(!a->planar) memcpy(a->ch[0], old.ch[0], a->count*a->ch_count*a->bps);
av_freep(&old.data);
a->count= count;
 
return 1;
}
 
static void copy(AudioData *out, AudioData *in,
int count){
av_assert0(out->planar == in->planar);
av_assert0(out->bps == in->bps);
av_assert0(out->ch_count == in->ch_count);
if(out->planar){
int ch;
for(ch=0; ch<out->ch_count; ch++)
memcpy(out->ch[ch], in->ch[ch], count*out->bps);
}else
memcpy(out->ch[0], in->ch[0], count*out->ch_count*out->bps);
}
 
static void fill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
int i;
if(!in_arg){
memset(out->ch, 0, sizeof(out->ch));
}else if(out->planar){
for(i=0; i<out->ch_count; i++)
out->ch[i]= in_arg[i];
}else{
for(i=0; i<out->ch_count; i++)
out->ch[i]= in_arg[0] + i*out->bps;
}
}
 
static void reversefill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
int i;
if(out->planar){
for(i=0; i<out->ch_count; i++)
in_arg[i]= out->ch[i];
}else{
in_arg[0]= out->ch[0];
}
}
 
/**
*
* out may be equal in.
*/
static void buf_set(AudioData *out, AudioData *in, int count){
int ch;
if(in->planar){
for(ch=0; ch<out->ch_count; ch++)
out->ch[ch]= in->ch[ch] + count*out->bps;
}else{
for(ch=out->ch_count-1; ch>=0; ch--)
out->ch[ch]= in->ch[0] + (ch + count*out->ch_count) * out->bps;
}
}
 
/**
*
* @return number of samples output per channel
*/
static int resample(SwrContext *s, AudioData *out_param, int out_count,
const AudioData * in_param, int in_count){
AudioData in, out, tmp;
int ret_sum=0;
int border=0;
 
av_assert1(s->in_buffer.ch_count == in_param->ch_count);
av_assert1(s->in_buffer.planar == in_param->planar);
av_assert1(s->in_buffer.fmt == in_param->fmt);
 
tmp=out=*out_param;
in = *in_param;
 
do{
int ret, size, consumed;
if(!s->resample_in_constraint && s->in_buffer_count){
buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
ret= s->resampler->multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed);
out_count -= ret;
ret_sum += ret;
buf_set(&out, &out, ret);
s->in_buffer_count -= consumed;
s->in_buffer_index += consumed;
 
if(!in_count)
break;
if(s->in_buffer_count <= border){
buf_set(&in, &in, -s->in_buffer_count);
in_count += s->in_buffer_count;
s->in_buffer_count=0;
s->in_buffer_index=0;
border = 0;
}
}
 
if((s->flushed || in_count) && !s->in_buffer_count){
s->in_buffer_index=0;
ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, in_count, &consumed);
out_count -= ret;
ret_sum += ret;
buf_set(&out, &out, ret);
in_count -= consumed;
buf_set(&in, &in, consumed);
}
 
//TODO is this check sane considering the advanced copy avoidance below
size= s->in_buffer_index + s->in_buffer_count + in_count;
if( size > s->in_buffer.count
&& s->in_buffer_count + in_count <= s->in_buffer_index){
buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
copy(&s->in_buffer, &tmp, s->in_buffer_count);
s->in_buffer_index=0;
}else
if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
return ret;
 
if(in_count){
int count= in_count;
if(s->in_buffer_count && s->in_buffer_count+2 < count && out_count) count= s->in_buffer_count+2;
 
buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
copy(&tmp, &in, /*in_*/count);
s->in_buffer_count += count;
in_count -= count;
border += count;
buf_set(&in, &in, count);
s->resample_in_constraint= 0;
if(s->in_buffer_count != count || in_count)
continue;
}
break;
}while(1);
 
s->resample_in_constraint= !!out_count;
 
return ret_sum;
}
 
static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count,
AudioData *in , int in_count){
AudioData *postin, *midbuf, *preout;
int ret/*, in_max*/;
AudioData preout_tmp, midbuf_tmp;
 
if(s->full_convert){
av_assert0(!s->resample);
swri_audio_convert(s->full_convert, out, in, in_count);
return out_count;
}
 
// in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
// in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
 
if((ret=swri_realloc_audio(&s->postin, in_count))<0)
return ret;
if(s->resample_first){
av_assert0(s->midbuf.ch_count == s->used_ch_count);
if((ret=swri_realloc_audio(&s->midbuf, out_count))<0)
return ret;
}else{
av_assert0(s->midbuf.ch_count == s->out.ch_count);
if((ret=swri_realloc_audio(&s->midbuf, in_count))<0)
return ret;
}
if((ret=swri_realloc_audio(&s->preout, out_count))<0)
return ret;
 
postin= &s->postin;
 
midbuf_tmp= s->midbuf;
midbuf= &midbuf_tmp;
preout_tmp= s->preout;
preout= &preout_tmp;
 
if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map)
postin= in;
 
if(s->resample_first ? !s->resample : !s->rematrix)
midbuf= postin;
 
if(s->resample_first ? !s->rematrix : !s->resample)
preout= midbuf;
 
if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar
&& !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){
if(preout==in){
out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant
av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though
copy(out, in, out_count);
return out_count;
}
else if(preout==postin) preout= midbuf= postin= out;
else if(preout==midbuf) preout= midbuf= out;
else preout= out;
}
 
if(in != postin){
swri_audio_convert(s->in_convert, postin, in, in_count);
}
 
if(s->resample_first){
if(postin != midbuf)
out_count= resample(s, midbuf, out_count, postin, in_count);
if(midbuf != preout)
swri_rematrix(s, preout, midbuf, out_count, preout==out);
}else{
if(postin != midbuf)
swri_rematrix(s, midbuf, postin, in_count, midbuf==out);
if(midbuf != preout)
out_count= resample(s, preout, out_count, midbuf, in_count);
}
 
if(preout != out && out_count){
AudioData *conv_src = preout;
if(s->dither.method){
int ch;
int dither_count= FFMAX(out_count, 1<<16);
 
if (preout == in) {
conv_src = &s->dither.temp;
if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0)
return ret;
}
 
if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0)
return ret;
if(ret)
for(ch=0; ch<s->dither.noise.ch_count; ch++)
swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, 12345678913579<<ch, s->dither.noise.fmt);
av_assert0(s->dither.noise.ch_count == preout->ch_count);
 
if(s->dither.noise_pos + out_count > s->dither.noise.count)
s->dither.noise_pos = 0;
 
if (s->dither.method < SWR_DITHER_NS){
if (s->mix_2_1_simd) {
int len1= out_count&~15;
int off = len1 * preout->bps;
 
if(len1)
for(ch=0; ch<preout->ch_count; ch++)
s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_simd_one, 0, 0, len1);
if(out_count != len1)
for(ch=0; ch<preout->ch_count; ch++)
s->mix_2_1_f(conv_src->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos + off + len1, s->native_one, 0, 0, out_count - len1);
} else {
for(ch=0; ch<preout->ch_count; ch++)
s->mix_2_1_f(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_one, 0, 0, out_count);
}
} else {
switch(s->int_sample_fmt) {
case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break;
case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break;
case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break;
case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break;
}
}
s->dither.noise_pos += out_count;
}
//FIXME packed doesn't need more than 1 chan here!
swri_audio_convert(s->out_convert, out, conv_src, out_count);
}
return out_count;
}
 
int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count,
const uint8_t *in_arg [SWR_CH_MAX], int in_count){
AudioData * in= &s->in;
AudioData *out= &s->out;
 
while(s->drop_output > 0){
int ret;
uint8_t *tmp_arg[SWR_CH_MAX];
#define MAX_DROP_STEP 16384
if((ret=swri_realloc_audio(&s->drop_temp, FFMIN(s->drop_output, MAX_DROP_STEP)))<0)
return ret;
 
reversefill_audiodata(&s->drop_temp, tmp_arg);
s->drop_output *= -1; //FIXME find a less hackish solution
ret = swr_convert(s, tmp_arg, FFMIN(-s->drop_output, MAX_DROP_STEP), in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesn't matter
s->drop_output *= -1;
in_count = 0;
if(ret>0) {
s->drop_output -= ret;
continue;
}
 
if(s->drop_output || !out_arg)
return 0;
}
 
if(!in_arg){
if(s->resample){
if (!s->flushed)
s->resampler->flush(s);
s->resample_in_constraint = 0;
s->flushed = 1;
}else if(!s->in_buffer_count){
return 0;
}
}else
fill_audiodata(in , (void*)in_arg);
 
fill_audiodata(out, out_arg);
 
if(s->resample){
int ret = swr_convert_internal(s, out, out_count, in, in_count);
if(ret>0 && !s->drop_output)
s->outpts += ret * (int64_t)s->in_sample_rate;
return ret;
}else{
AudioData tmp= *in;
int ret2=0;
int ret, size;
size = FFMIN(out_count, s->in_buffer_count);
if(size){
buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
ret= swr_convert_internal(s, out, size, &tmp, size);
if(ret<0)
return ret;
ret2= ret;
s->in_buffer_count -= ret;
s->in_buffer_index += ret;
buf_set(out, out, ret);
out_count -= ret;
if(!s->in_buffer_count)
s->in_buffer_index = 0;
}
 
if(in_count){
size= s->in_buffer_index + s->in_buffer_count + in_count - out_count;
 
if(in_count > out_count) { //FIXME move after swr_convert_internal
if( size > s->in_buffer.count
&& s->in_buffer_count + in_count - out_count <= s->in_buffer_index){
buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
copy(&s->in_buffer, &tmp, s->in_buffer_count);
s->in_buffer_index=0;
}else
if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
return ret;
}
 
if(out_count){
size = FFMIN(in_count, out_count);
ret= swr_convert_internal(s, out, size, in, size);
if(ret<0)
return ret;
buf_set(in, in, ret);
in_count -= ret;
ret2 += ret;
}
if(in_count){
buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
copy(&tmp, in, in_count);
s->in_buffer_count += in_count;
}
}
if(ret2>0 && !s->drop_output)
s->outpts += ret2 * (int64_t)s->in_sample_rate;
return ret2;
}
}
 
int swr_drop_output(struct SwrContext *s, int count){
s->drop_output += count;
 
if(s->drop_output <= 0)
return 0;
 
av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count);
return swr_convert(s, NULL, s->drop_output, NULL, 0);
}
 
int swr_inject_silence(struct SwrContext *s, int count){
int ret, i;
uint8_t *tmp_arg[SWR_CH_MAX];
 
if(count <= 0)
return 0;
 
#define MAX_SILENCE_STEP 16384
while (count > MAX_SILENCE_STEP) {
if ((ret = swr_inject_silence(s, MAX_SILENCE_STEP)) < 0)
return ret;
count -= MAX_SILENCE_STEP;
}
 
if((ret=swri_realloc_audio(&s->silence, count))<0)
return ret;
 
if(s->silence.planar) for(i=0; i<s->silence.ch_count; i++) {
memset(s->silence.ch[i], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps);
} else
memset(s->silence.ch[0], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps*s->silence.ch_count);
 
reversefill_audiodata(&s->silence, tmp_arg);
av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count);
ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count);
return ret;
}
 
int64_t swr_get_delay(struct SwrContext *s, int64_t base){
if (s->resampler && s->resample){
return s->resampler->get_delay(s, base);
}else{
return (s->in_buffer_count*base + (s->in_sample_rate>>1))/ s->in_sample_rate;
}
}
 
int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){
int ret;
 
if (!s || compensation_distance < 0)
return AVERROR(EINVAL);
if (!compensation_distance && sample_delta)
return AVERROR(EINVAL);
if (!s->resample) {
s->flags |= SWR_FLAG_RESAMPLE;
ret = swr_init(s);
if (ret < 0)
return ret;
}
if (!s->resampler->set_compensation){
return AVERROR(EINVAL);
}else{
return s->resampler->set_compensation(s->resample, sample_delta, compensation_distance);
}
}
 
int64_t swr_next_pts(struct SwrContext *s, int64_t pts){
if(pts == INT64_MIN)
return s->outpts;
 
if (s->firstpts == AV_NOPTS_VALUE)
s->outpts = s->firstpts = pts;
 
if(s->min_compensation >= FLT_MAX) {
return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
} else {
int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts + s->drop_output*(int64_t)s->in_sample_rate;
double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
 
if(fabs(fdelta) > s->min_compensation) {
if(s->outpts == s->firstpts || fabs(fdelta) > s->min_hard_compensation){
int ret;
if(delta > 0) ret = swr_inject_silence(s, delta / s->out_sample_rate);
else ret = swr_drop_output (s, -delta / s-> in_sample_rate);
if(ret<0){
av_log(s, AV_LOG_ERROR, "Failed to compensate for timestamp delta of %f\n", fdelta);
}
} else if(s->soft_compensation_duration && s->max_soft_compensation) {
int duration = s->out_sample_rate * s->soft_compensation_duration;
double max_soft_compensation = s->max_soft_compensation / (s->max_soft_compensation < 0 ? -s->in_sample_rate : 1);
int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) * duration ;
av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
swr_set_compensation(s, comp, duration);
}
}
 
return s->outpts;
}
}
/contrib/sdk/sources/ffmpeg/libswresample/swresample.h
0,0 → 1,311
/*
* Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#ifndef SWRESAMPLE_SWRESAMPLE_H
#define SWRESAMPLE_SWRESAMPLE_H
 
/**
* @file
* @ingroup lswr
* libswresample public header
*/
 
/**
* @defgroup lswr Libswresample
* @{
*
* Libswresample (lswr) is a library that handles audio resampling, sample
* format conversion and mixing.
*
* Interaction with lswr is done through SwrContext, which is
* allocated with swr_alloc() or swr_alloc_set_opts(). It is opaque, so all parameters
* must be set with the @ref avoptions API.
*
* For example the following code will setup conversion from planar float sample
* format to interleaved signed 16-bit integer, downsampling from 48kHz to
* 44.1kHz and downmixing from 5.1 channels to stereo (using the default mixing
* matrix):
* @code
* SwrContext *swr = swr_alloc();
* av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0);
* av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
* av_opt_set_int(swr, "in_sample_rate", 48000, 0);
* av_opt_set_int(swr, "out_sample_rate", 44100, 0);
* av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
* av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
* @endcode
*
* Once all values have been set, it must be initialized with swr_init(). If
* you need to change the conversion parameters, you can change the parameters
* as described above, or by using swr_alloc_set_opts(), then call swr_init()
* again.
*
* The conversion itself is done by repeatedly calling swr_convert().
* Note that the samples may get buffered in swr if you provide insufficient
* output space or if sample rate conversion is done, which requires "future"
* samples. Samples that do not require future input can be retrieved at any
* time by using swr_convert() (in_count can be set to 0).
* At the end of conversion the resampling buffer can be flushed by calling
* swr_convert() with NULL in and 0 in_count.
*
* The delay between input and output, can at any time be found by using
* swr_get_delay().
*
* The following code demonstrates the conversion loop assuming the parameters
* from above and caller-defined functions get_input() and handle_output():
* @code
* uint8_t **input;
* int in_samples;
*
* while (get_input(&input, &in_samples)) {
* uint8_t *output;
* int out_samples = av_rescale_rnd(swr_get_delay(swr, 48000) +
* in_samples, 44100, 48000, AV_ROUND_UP);
* av_samples_alloc(&output, NULL, 2, out_samples,
* AV_SAMPLE_FMT_S16, 0);
* out_samples = swr_convert(swr, &output, out_samples,
* input, in_samples);
* handle_output(output, out_samples);
* av_freep(&output);
* }
* @endcode
*
* When the conversion is finished, the conversion
* context and everything associated with it must be freed with swr_free().
* There will be no memory leak if the data is not completely flushed before
* swr_free().
*/
 
#include <stdint.h>
#include "libavutil/samplefmt.h"
 
#include "libswresample/version.h"
 
#if LIBSWRESAMPLE_VERSION_MAJOR < 1
#define SWR_CH_MAX 32 ///< Maximum number of channels
#endif
 
#define SWR_FLAG_RESAMPLE 1 ///< Force resampling even if equal sample rate
//TODO use int resample ?
//long term TODO can we enable this dynamically?
 
enum SwrDitherType {
SWR_DITHER_NONE = 0,
SWR_DITHER_RECTANGULAR,
SWR_DITHER_TRIANGULAR,
SWR_DITHER_TRIANGULAR_HIGHPASS,
 
SWR_DITHER_NS = 64, ///< not part of API/ABI
SWR_DITHER_NS_LIPSHITZ,
SWR_DITHER_NS_F_WEIGHTED,
SWR_DITHER_NS_MODIFIED_E_WEIGHTED,
SWR_DITHER_NS_IMPROVED_E_WEIGHTED,
SWR_DITHER_NS_SHIBATA,
SWR_DITHER_NS_LOW_SHIBATA,
SWR_DITHER_NS_HIGH_SHIBATA,
SWR_DITHER_NB, ///< not part of API/ABI
};
 
/** Resampling Engines */
enum SwrEngine {
SWR_ENGINE_SWR, /**< SW Resampler */
SWR_ENGINE_SOXR, /**< SoX Resampler */
SWR_ENGINE_NB, ///< not part of API/ABI
};
 
/** Resampling Filter Types */
enum SwrFilterType {
SWR_FILTER_TYPE_CUBIC, /**< Cubic */
SWR_FILTER_TYPE_BLACKMAN_NUTTALL, /**< Blackman Nuttall Windowed Sinc */
SWR_FILTER_TYPE_KAISER, /**< Kaiser Windowed Sinc */
};
 
typedef struct SwrContext SwrContext;
 
/**
* Get the AVClass for swrContext. It can be used in combination with
* AV_OPT_SEARCH_FAKE_OBJ for examining options.
*
* @see av_opt_find().
*/
const AVClass *swr_get_class(void);
 
/**
* Allocate SwrContext.
*
* If you use this function you will need to set the parameters (manually or
* with swr_alloc_set_opts()) before calling swr_init().
*
* @see swr_alloc_set_opts(), swr_init(), swr_free()
* @return NULL on error, allocated context otherwise
*/
struct SwrContext *swr_alloc(void);
 
/**
* Initialize context after user parameters have been set.
*
* @return AVERROR error code in case of failure.
*/
int swr_init(struct SwrContext *s);
 
/**
* Allocate SwrContext if needed and set/reset common parameters.
*
* This function does not require s to be allocated with swr_alloc(). On the
* other hand, swr_alloc() can use swr_alloc_set_opts() to set the parameters
* on the allocated context.
*
* @param s Swr context, can be NULL
* @param out_ch_layout output channel layout (AV_CH_LAYOUT_*)
* @param out_sample_fmt output sample format (AV_SAMPLE_FMT_*).
* @param out_sample_rate output sample rate (frequency in Hz)
* @param in_ch_layout input channel layout (AV_CH_LAYOUT_*)
* @param in_sample_fmt input sample format (AV_SAMPLE_FMT_*).
* @param in_sample_rate input sample rate (frequency in Hz)
* @param log_offset logging level offset
* @param log_ctx parent logging context, can be NULL
*
* @see swr_init(), swr_free()
* @return NULL on error, allocated context otherwise
*/
struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
int log_offset, void *log_ctx);
 
/**
* Free the given SwrContext and set the pointer to NULL.
*/
void swr_free(struct SwrContext **s);
 
/**
* Convert audio.
*
* in and in_count can be set to 0 to flush the last few samples out at the
* end.
*
* If more input is provided than output space then the input will be buffered.
* You can avoid this buffering by providing more output space than input.
* Convertion will run directly without copying whenever possible.
*
* @param s allocated Swr context, with parameters set
* @param out output buffers, only the first one need be set in case of packed audio
* @param out_count amount of space available for output in samples per channel
* @param in input buffers, only the first one need to be set in case of packed audio
* @param in_count number of input samples available in one channel
*
* @return number of samples output per channel, negative value on error
*/
int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
const uint8_t **in , int in_count);
 
/**
* Convert the next timestamp from input to output
* timestamps are in 1/(in_sample_rate * out_sample_rate) units.
*
* @note There are 2 slightly differently behaving modes.
* First is when automatic timestamp compensation is not used, (min_compensation >= FLT_MAX)
* in this case timestamps will be passed through with delays compensated
* Second is when automatic timestamp compensation is used, (min_compensation < FLT_MAX)
* in this case the output timestamps will match output sample numbers
*
* @param pts timestamp for the next input sample, INT64_MIN if unknown
* @return the output timestamp for the next output sample
*/
int64_t swr_next_pts(struct SwrContext *s, int64_t pts);
 
/**
* Activate resampling compensation.
*/
int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance);
 
/**
* Set a customized input channel mapping.
*
* @param s allocated Swr context, not yet initialized
* @param channel_map customized input channel mapping (array of channel
* indexes, -1 for a muted channel)
* @return AVERROR error code in case of failure.
*/
int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map);
 
/**
* Set a customized remix matrix.
*
* @param s allocated Swr context, not yet initialized
* @param matrix remix coefficients; matrix[i + stride * o] is
* the weight of input channel i in output channel o
* @param stride offset between lines of the matrix
* @return AVERROR error code in case of failure.
*/
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride);
 
/**
* Drops the specified number of output samples.
*/
int swr_drop_output(struct SwrContext *s, int count);
 
/**
* Injects the specified number of silence samples.
*/
int swr_inject_silence(struct SwrContext *s, int count);
 
/**
* Gets the delay the next input sample will experience relative to the next output sample.
*
* Swresample can buffer data if more input has been provided than available
* output space, also converting between sample rates needs a delay.
* This function returns the sum of all such delays.
* The exact delay is not necessarily an integer value in either input or
* output sample rate. Especially when downsampling by a large value, the
* output sample rate may be a poor choice to represent the delay, similarly
* for upsampling and the input sample rate.
*
* @param s swr context
* @param base timebase in which the returned delay will be
* if its set to 1 the returned delay is in seconds
* if its set to 1000 the returned delay is in milli seconds
* if its set to the input sample rate then the returned delay is in input samples
* if its set to the output sample rate then the returned delay is in output samples
* an exact rounding free delay can be found by using LCM(in_sample_rate, out_sample_rate)
* @returns the delay in 1/base units.
*/
int64_t swr_get_delay(struct SwrContext *s, int64_t base);
 
/**
* Return the LIBSWRESAMPLE_VERSION_INT constant.
*/
unsigned swresample_version(void);
 
/**
* Return the swr build-time configuration.
*/
const char *swresample_configuration(void);
 
/**
* Return the swr license.
*/
const char *swresample_license(void);
 
/**
* @}
*/
 
#endif /* SWRESAMPLE_SWRESAMPLE_H */
/contrib/sdk/sources/ffmpeg/libswresample/swresample.lib
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/sdk/sources/ffmpeg/libswresample/swresample_internal.h
0,0 → 1,199
/*
* Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#ifndef SWR_INTERNAL_H
#define SWR_INTERNAL_H
 
#include "swresample.h"
#include "libavutil/channel_layout.h"
#include "config.h"
 
#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
 
#define NS_TAPS 20
 
#if ARCH_X86_64
typedef int64_t integer;
#else
typedef int integer;
#endif
 
typedef void (mix_1_1_func_type)(void *out, const void *in, void *coeffp, integer index, integer len);
typedef void (mix_2_1_func_type)(void *out, const void *in1, const void *in2, void *coeffp, integer index1, integer index2, integer len);
 
typedef void (mix_any_func_type)(uint8_t **out, const uint8_t **in1, void *coeffp, integer len);
 
typedef struct AudioData{
uint8_t *ch[SWR_CH_MAX]; ///< samples buffer per channel
uint8_t *data; ///< samples buffer
int ch_count; ///< number of channels
int bps; ///< bytes per sample
int count; ///< number of samples
int planar; ///< 1 if planar audio, 0 otherwise
enum AVSampleFormat fmt; ///< sample format
} AudioData;
 
struct DitherContext {
enum SwrDitherType method;
int noise_pos;
float scale;
float noise_scale; ///< Noise scale
int ns_taps; ///< Noise shaping dither taps
float ns_scale; ///< Noise shaping dither scale
float ns_scale_1; ///< Noise shaping dither scale^-1
int ns_pos; ///< Noise shaping dither position
float ns_coeffs[NS_TAPS]; ///< Noise shaping filter coefficients
float ns_errors[SWR_CH_MAX][2*NS_TAPS];
AudioData noise; ///< noise used for dithering
AudioData temp; ///< temporary storage when writing into the input buffer isnt possible
int output_sample_bits; ///< the number of used output bits, needed to scale dither correctly
};
 
struct SwrContext {
const AVClass *av_class; ///< AVClass used for AVOption and av_log()
int log_level_offset; ///< logging level offset
void *log_ctx; ///< parent logging context
enum AVSampleFormat in_sample_fmt; ///< input sample format
enum AVSampleFormat int_sample_fmt; ///< internal sample format (AV_SAMPLE_FMT_FLTP or AV_SAMPLE_FMT_S16P)
enum AVSampleFormat out_sample_fmt; ///< output sample format
int64_t in_ch_layout; ///< input channel layout
int64_t out_ch_layout; ///< output channel layout
int in_sample_rate; ///< input sample rate
int out_sample_rate; ///< output sample rate
int flags; ///< miscellaneous flags such as SWR_FLAG_RESAMPLE
float slev; ///< surround mixing level
float clev; ///< center mixing level
float lfe_mix_level; ///< LFE mixing level
float rematrix_volume; ///< rematrixing volume coefficient
float rematrix_maxval; ///< maximum value for rematrixing output
enum AVMatrixEncoding matrix_encoding; /**< matrixed stereo encoding */
const int *channel_map; ///< channel index (or -1 if muted channel) map
int used_ch_count; ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count)
enum SwrEngine engine;
 
struct DitherContext dither;
 
int filter_size; /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */
int linear_interp; /**< if 1 then the resampling FIR filter will be linearly interpolated */
double cutoff; /**< resampling cutoff frequency (swr: 6dB point; soxr: 0dB point). 1.0 corresponds to half the output sample rate */
enum SwrFilterType filter_type; /**< swr resampling filter type */
int kaiser_beta; /**< swr beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
double precision; /**< soxr resampling precision (in bits) */
int cheby; /**< soxr: if 1 then passband rolloff will be none (Chebyshev) & irrational ratio approximation precision will be higher */
 
float min_compensation; ///< swr minimum below which no compensation will happen
float min_hard_compensation; ///< swr minimum below which no silence inject / sample drop will happen
float soft_compensation_duration; ///< swr duration over which soft compensation is applied
float max_soft_compensation; ///< swr maximum soft compensation in seconds over soft_compensation_duration
float async; ///< swr simple 1 parameter async, similar to ffmpegs -async
int64_t firstpts_in_samples; ///< swr first pts in samples
 
int resample_first; ///< 1 if resampling must come first, 0 if rematrixing
int rematrix; ///< flag to indicate if rematrixing is needed (basically if input and output layouts mismatch)
int rematrix_custom; ///< flag to indicate that a custom matrix has been defined
 
AudioData in; ///< input audio data
AudioData postin; ///< post-input audio data: used for rematrix/resample
AudioData midbuf; ///< intermediate audio data (postin/preout)
AudioData preout; ///< pre-output audio data: used for rematrix/resample
AudioData out; ///< converted output audio data
AudioData in_buffer; ///< cached audio data (convert and resample purpose)
AudioData silence; ///< temporary with silence
AudioData drop_temp; ///< temporary used to discard output
int in_buffer_index; ///< cached buffer position
int in_buffer_count; ///< cached buffer length
int resample_in_constraint; ///< 1 if the input end was reach before the output end, 0 otherwise
int flushed; ///< 1 if data is to be flushed and no further input is expected
int64_t outpts; ///< output PTS
int64_t firstpts; ///< first PTS
int drop_output; ///< number of output samples to drop
 
struct AudioConvert *in_convert; ///< input conversion context
struct AudioConvert *out_convert; ///< output conversion context
struct AudioConvert *full_convert; ///< full conversion context (single conversion for input and output)
struct ResampleContext *resample; ///< resampling context
struct Resampler const *resampler; ///< resampler virtual function table
 
float matrix[SWR_CH_MAX][SWR_CH_MAX]; ///< floating point rematrixing coefficients
uint8_t *native_matrix;
uint8_t *native_one;
uint8_t *native_simd_one;
uint8_t *native_simd_matrix;
int32_t matrix32[SWR_CH_MAX][SWR_CH_MAX]; ///< 17.15 fixed point rematrixing coefficients
uint8_t matrix_ch[SWR_CH_MAX][SWR_CH_MAX+1]; ///< Lists of input channels per output channel that have non zero rematrixing coefficients
mix_1_1_func_type *mix_1_1_f;
mix_1_1_func_type *mix_1_1_simd;
 
mix_2_1_func_type *mix_2_1_f;
mix_2_1_func_type *mix_2_1_simd;
 
mix_any_func_type *mix_any_f;
 
/* TODO: callbacks for ASM optimizations */
};
 
typedef struct ResampleContext * (* resample_init_func)(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta, double precision, int cheby);
typedef void (* resample_free_func)(struct ResampleContext **c);
typedef int (* multiple_resample_func)(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed);
typedef int (* resample_flush_func)(struct SwrContext *c);
typedef int (* set_compensation_func)(struct ResampleContext *c, int sample_delta, int compensation_distance);
typedef int64_t (* get_delay_func)(struct SwrContext *s, int64_t base);
 
struct Resampler {
resample_init_func init;
resample_free_func free;
multiple_resample_func multiple_resample;
resample_flush_func flush;
set_compensation_func set_compensation;
get_delay_func get_delay;
};
 
extern struct Resampler const swri_resampler;
 
int swri_realloc_audio(AudioData *a, int count);
int swri_resample_int16(struct ResampleContext *c, int16_t *dst, const int16_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
int swri_resample_int32(struct ResampleContext *c, int32_t *dst, const int32_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
int swri_resample_float(struct ResampleContext *c, float *dst, const float *src, int *consumed, int src_size, int dst_size, int update_ctx);
int swri_resample_double(struct ResampleContext *c,double *dst, const double *src, int *consumed, int src_size, int dst_size, int update_ctx);
 
void swri_noise_shaping_int16 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
void swri_noise_shaping_int32 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
void swri_noise_shaping_float (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
void swri_noise_shaping_double(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count);
 
int swri_rematrix_init(SwrContext *s);
void swri_rematrix_free(SwrContext *s);
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy);
void swri_rematrix_init_x86(struct SwrContext *s);
 
void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt);
int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt);
 
void swri_audio_convert_init_arm(struct AudioConvert *ac,
enum AVSampleFormat out_fmt,
enum AVSampleFormat in_fmt,
int channels);
void swri_audio_convert_init_x86(struct AudioConvert *ac,
enum AVSampleFormat out_fmt,
enum AVSampleFormat in_fmt,
int channels);
#endif
/contrib/sdk/sources/ffmpeg/libswresample/version.h
0,0 → 1,45
/*
* Version macros.
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#ifndef SWR_VERSION_H
#define SWR_VERSION_H
 
/**
* @file
* Libswresample version macros
*/
 
#include "libavutil/avutil.h"
 
#define LIBSWRESAMPLE_VERSION_MAJOR 0
#define LIBSWRESAMPLE_VERSION_MINOR 17
#define LIBSWRESAMPLE_VERSION_MICRO 104
 
#define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
LIBSWRESAMPLE_VERSION_MINOR, \
LIBSWRESAMPLE_VERSION_MICRO)
#define LIBSWRESAMPLE_VERSION AV_VERSION(LIBSWRESAMPLE_VERSION_MAJOR, \
LIBSWRESAMPLE_VERSION_MINOR, \
LIBSWRESAMPLE_VERSION_MICRO)
#define LIBSWRESAMPLE_BUILD LIBSWRESAMPLE_VERSION_INT
 
#define LIBSWRESAMPLE_IDENT "SwR" AV_STRINGIFY(LIBSWRESAMPLE_VERSION)
 
#endif /* SWR_VERSION_H */
/contrib/sdk/sources/ffmpeg/libswresample/x86/Makefile
0,0 → 1,3
YASM-OBJS += x86/swresample_x86.o\
x86/audio_convert.o\
x86/rematrix.o\
/contrib/sdk/sources/ffmpeg/libswresample/x86/audio_convert.asm
0,0 → 1,465
;******************************************************************************
;* Copyright (c) 2012 Michael Niedermayer
;*
;* 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 32
flt2pm31: times 8 dd 4.6566129e-10
flt2p31 : times 8 dd 2147483648.0
flt2p15 : times 8 dd 32768.0
 
word_unpack_shuf : db 0, 1, 4, 5, 8, 9,12,13, 2, 3, 6, 7,10,11,14,15
 
SECTION .text
 
 
;to, from, a/u, log2_outsize, log_intsize, const
%macro PACK_2CH 5-7
cglobal pack_2ch_%2_to_%1_%3, 3, 4, 6, dst, src, len, src2
mov src2q , [srcq+gprsize]
mov srcq , [srcq]
mov dstq , [dstq]
%ifidn %3, a
test dstq, mmsize-1
jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
test srcq, mmsize-1
jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
test src2q, mmsize-1
jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
%else
pack_2ch_%2_to_%1_u_int %+ SUFFIX
%endif
lea srcq , [srcq + (1<<%5)*lenq]
lea src2q, [src2q + (1<<%5)*lenq]
lea dstq , [dstq + (2<<%4)*lenq]
neg lenq
%7 m0,m1,m2,m3,m4,m5
.next:
%if %4 >= %5
mov%3 m0, [ srcq +(1<<%5)*lenq]
mova m1, m0
mov%3 m2, [ src2q+(1<<%5)*lenq]
%if %5 == 1
punpcklwd m0, m2
punpckhwd m1, m2
%else
punpckldq m0, m2
punpckhdq m1, m2
%endif
%6 m0,m1,m2,m3,m4,m5
%else
mov%3 m0, [ srcq +(1<<%5)*lenq]
mov%3 m1, [mmsize + srcq +(1<<%5)*lenq]
mov%3 m2, [ src2q+(1<<%5)*lenq]
mov%3 m3, [mmsize + src2q+(1<<%5)*lenq]
%6 m0,m1,m2,m3,m4,m5
mova m2, m0
punpcklwd m0, m1
punpckhwd m2, m1
SWAP 1,2
%endif
mov%3 [ dstq+(2<<%4)*lenq], m0
mov%3 [ mmsize + dstq+(2<<%4)*lenq], m1
%if %4 > %5
mov%3 [2*mmsize + dstq+(2<<%4)*lenq], m2
mov%3 [3*mmsize + dstq+(2<<%4)*lenq], m3
add lenq, 4*mmsize/(2<<%4)
%else
add lenq, 2*mmsize/(2<<%4)
%endif
jl .next
REP_RET
%endmacro
 
%macro UNPACK_2CH 5-7
cglobal unpack_2ch_%2_to_%1_%3, 3, 4, 7, dst, src, len, dst2
mov dst2q , [dstq+gprsize]
mov srcq , [srcq]
mov dstq , [dstq]
%ifidn %3, a
test dstq, mmsize-1
jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
test srcq, mmsize-1
jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
test dst2q, mmsize-1
jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
%else
unpack_2ch_%2_to_%1_u_int %+ SUFFIX
%endif
lea srcq , [srcq + (2<<%5)*lenq]
lea dstq , [dstq + (1<<%4)*lenq]
lea dst2q, [dst2q + (1<<%4)*lenq]
neg lenq
%7 m0,m1,m2,m3,m4,m5
mova m6, [word_unpack_shuf]
.next:
mov%3 m0, [ srcq +(2<<%5)*lenq]
mov%3 m2, [ mmsize + srcq +(2<<%5)*lenq]
%if %5 == 1
%ifidn SUFFIX, _ssse3
pshufb m0, m6
mova m1, m0
pshufb m2, m6
punpcklqdq m0,m2
punpckhqdq m1,m2
%else
mova m1, m0
punpcklwd m0,m2
punpckhwd m1,m2
 
mova m2, m0
punpcklwd m0,m1
punpckhwd m2,m1
 
mova m1, m0
punpcklwd m0,m2
punpckhwd m1,m2
%endif
%else
mova m1, m0
shufps m0, m2, 10001000b
shufps m1, m2, 11011101b
%endif
%if %4 < %5
mov%3 m2, [2*mmsize + srcq +(2<<%5)*lenq]
mova m3, m2
mov%3 m4, [3*mmsize + srcq +(2<<%5)*lenq]
shufps m2, m4, 10001000b
shufps m3, m4, 11011101b
SWAP 1,2
%endif
%6 m0,m1,m2,m3,m4,m5
mov%3 [ dstq+(1<<%4)*lenq], m0
%if %4 > %5
mov%3 [ dst2q+(1<<%4)*lenq], m2
mov%3 [ mmsize + dstq+(1<<%4)*lenq], m1
mov%3 [ mmsize + dst2q+(1<<%4)*lenq], m3
add lenq, 2*mmsize/(1<<%4)
%else
mov%3 [ dst2q+(1<<%4)*lenq], m1
add lenq, mmsize/(1<<%4)
%endif
jl .next
REP_RET
%endmacro
 
%macro CONV 5-7
cglobal %2_to_%1_%3, 3, 3, 6, dst, src, len
mov srcq , [srcq]
mov dstq , [dstq]
%ifidn %3, a
test dstq, mmsize-1
jne %2_to_%1_u_int %+ SUFFIX
test srcq, mmsize-1
jne %2_to_%1_u_int %+ SUFFIX
%else
%2_to_%1_u_int %+ SUFFIX
%endif
lea srcq , [srcq + (1<<%5)*lenq]
lea dstq , [dstq + (1<<%4)*lenq]
neg lenq
%7 m0,m1,m2,m3,m4,m5
.next:
mov%3 m0, [ srcq +(1<<%5)*lenq]
mov%3 m1, [ mmsize + srcq +(1<<%5)*lenq]
%if %4 < %5
mov%3 m2, [2*mmsize + srcq +(1<<%5)*lenq]
mov%3 m3, [3*mmsize + srcq +(1<<%5)*lenq]
%endif
%6 m0,m1,m2,m3,m4,m5
mov%3 [ dstq+(1<<%4)*lenq], m0
mov%3 [ mmsize + dstq+(1<<%4)*lenq], m1
%if %4 > %5
mov%3 [2*mmsize + dstq+(1<<%4)*lenq], m2
mov%3 [3*mmsize + dstq+(1<<%4)*lenq], m3
add lenq, 4*mmsize/(1<<%4)
%else
add lenq, 2*mmsize/(1<<%4)
%endif
jl .next
%if mmsize == 8
emms
RET
%else
REP_RET
%endif
%endmacro
 
%macro PACK_6CH 5-7
cglobal pack_6ch_%2_to_%1_%3, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
%if ARCH_X86_64
mov lend, r2d
%else
%define lend dword r2m
%endif
mov src1q, [srcq+1*gprsize]
mov src2q, [srcq+2*gprsize]
mov src3q, [srcq+3*gprsize]
mov src4q, [srcq+4*gprsize]
mov src5q, [srcq+5*gprsize]
mov srcq, [srcq]
mov dstq, [dstq]
%ifidn %3, a
test dstq, mmsize-1
jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
test srcq, mmsize-1
jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
test src2q, mmsize-1
jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
test src3q, mmsize-1
jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
test src4q, mmsize-1
jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
test src5q, mmsize-1
jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
%else
pack_6ch_%2_to_%1_u_int %+ SUFFIX
%endif
sub src1q, srcq
sub src2q, srcq
sub src3q, srcq
sub src4q, srcq
sub src5q, srcq
.loop:
mov%3 m0, [srcq ]
mov%3 m1, [srcq+src1q]
mov%3 m2, [srcq+src2q]
mov%3 m3, [srcq+src3q]
mov%3 m4, [srcq+src4q]
mov%3 m5, [srcq+src5q]
%7 x,x,x,x,m7,x
%if cpuflag(sse4)
SBUTTERFLYPS 0, 1, 6
SBUTTERFLYPS 2, 3, 6
SBUTTERFLYPS 4, 5, 6
 
blendps m6, m4, m0, 1100b
movlhps m0, m2
movhlps m4, m2
blendps m2, m5, m1, 1100b
movlhps m1, m3
movhlps m5, m3
 
%6 m0,m6,x,x,m7,m3
%6 m4,m1,x,x,m7,m3
%6 m2,m5,x,x,m7,m3
 
mov %+ %3 %+ ps [dstq ], m0
mov %+ %3 %+ ps [dstq+16], m6
mov %+ %3 %+ ps [dstq+32], m4
mov %+ %3 %+ ps [dstq+48], m1
mov %+ %3 %+ ps [dstq+64], m2
mov %+ %3 %+ ps [dstq+80], m5
%else ; mmx
SBUTTERFLY dq, 0, 1, 6
SBUTTERFLY dq, 2, 3, 6
SBUTTERFLY dq, 4, 5, 6
 
movq [dstq ], m0
movq [dstq+ 8], m2
movq [dstq+16], m4
movq [dstq+24], m1
movq [dstq+32], m3
movq [dstq+40], m5
%endif
add srcq, mmsize
add dstq, mmsize*6
sub lend, mmsize/4
jg .loop
%if mmsize == 8
emms
RET
%else
REP_RET
%endif
%endmacro
 
%macro INT16_TO_INT32_N 6
pxor m2, m2
pxor m3, m3
punpcklwd m2, m1
punpckhwd m3, m1
SWAP 4,0
pxor m0, m0
pxor m1, m1
punpcklwd m0, m4
punpckhwd m1, m4
%endmacro
 
%macro INT32_TO_INT16_N 6
psrad m0, 16
psrad m1, 16
psrad m2, 16
psrad m3, 16
packssdw m0, m1
packssdw m2, m3
SWAP 1,2
%endmacro
 
%macro INT32_TO_FLOAT_INIT 6
mova %5, [flt2pm31]
%endmacro
%macro INT32_TO_FLOAT_N 6
cvtdq2ps %1, %1
cvtdq2ps %2, %2
mulps %1, %1, %5
mulps %2, %2, %5
%endmacro
 
%macro FLOAT_TO_INT32_INIT 6
mova %5, [flt2p31]
%endmacro
%macro FLOAT_TO_INT32_N 6
mulps %1, %5
mulps %2, %5
cvtps2dq %6, %1
cmpnltps %1, %5
paddd %1, %6
cvtps2dq %6, %2
cmpnltps %2, %5
paddd %2, %6
%endmacro
 
%macro INT16_TO_FLOAT_INIT 6
mova m5, [flt2pm31]
%endmacro
%macro INT16_TO_FLOAT_N 6
INT16_TO_INT32_N %1,%2,%3,%4,%5,%6
cvtdq2ps m0, m0
cvtdq2ps m1, m1
cvtdq2ps m2, m2
cvtdq2ps m3, m3
mulps m0, m0, m5
mulps m1, m1, m5
mulps m2, m2, m5
mulps m3, m3, m5
%endmacro
 
%macro FLOAT_TO_INT16_INIT 6
mova m5, [flt2p15]
%endmacro
%macro FLOAT_TO_INT16_N 6
mulps m0, m5
mulps m1, m5
mulps m2, m5
mulps m3, m5
cvtps2dq m0, m0
cvtps2dq m1, m1
packssdw m0, m1
cvtps2dq m1, m2
cvtps2dq m3, m3
packssdw m1, m3
%endmacro
 
%macro NOP_N 0-6
%endmacro
 
INIT_MMX mmx
CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
 
PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
 
INIT_XMM sse2
CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
 
PACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
PACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
PACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
PACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
PACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
PACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
PACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
PACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
 
UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
UNPACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
UNPACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
UNPACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
UNPACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
 
CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
CONV int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
CONV int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
CONV float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
CONV float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
CONV int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
CONV int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
 
PACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
PACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
PACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
PACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
PACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
PACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
PACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
PACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
 
UNPACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
UNPACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
UNPACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
UNPACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
UNPACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
UNPACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
 
 
INIT_XMM ssse3
UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
 
INIT_XMM sse4
PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
 
PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
 
%if HAVE_AVX_EXTERNAL
INIT_XMM avx
PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
 
PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
 
INIT_YMM avx
CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
%endif
/contrib/sdk/sources/ffmpeg/libswresample/x86/rematrix.asm
0,0 → 1,250
;******************************************************************************
;* Copyright (c) 2012 Michael Niedermayer
;*
;* 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 32
dw1: times 8 dd 1
w1 : times 16 dw 1
 
SECTION .text
 
%macro MIX2_FLT 1
cglobal mix_2_1_%1_float, 7, 7, 6, out, in1, in2, coeffp, index1, index2, len
%ifidn %1, a
test in1q, mmsize-1
jne mix_2_1_float_u_int %+ SUFFIX
test in2q, mmsize-1
jne mix_2_1_float_u_int %+ SUFFIX
test outq, mmsize-1
jne mix_2_1_float_u_int %+ SUFFIX
%else
mix_2_1_float_u_int %+ SUFFIX
%endif
VBROADCASTSS m4, [coeffpq + 4*index1q]
VBROADCASTSS m5, [coeffpq + 4*index2q]
shl lend , 2
add in1q , lenq
add in2q , lenq
add outq , lenq
neg lenq
.next:
%ifidn %1, a
mulps m0, m4, [in1q + lenq ]
mulps m1, m5, [in2q + lenq ]
mulps m2, m4, [in1q + lenq + mmsize]
mulps m3, m5, [in2q + lenq + mmsize]
%else
movu m0, [in1q + lenq ]
movu m1, [in2q + lenq ]
movu m2, [in1q + lenq + mmsize]
movu m3, [in2q + lenq + mmsize]
mulps m0, m0, m4
mulps m1, m1, m5
mulps m2, m2, m4
mulps m3, m3, m5
%endif
addps m0, m0, m1
addps m2, m2, m3
mov%1 [outq + lenq ], m0
mov%1 [outq + lenq + mmsize], m2
add lenq, mmsize*2
jl .next
REP_RET
%endmacro
 
%macro MIX1_FLT 1
cglobal mix_1_1_%1_float, 5, 5, 3, out, in, coeffp, index, len
%ifidn %1, a
test inq, mmsize-1
jne mix_1_1_float_u_int %+ SUFFIX
test outq, mmsize-1
jne mix_1_1_float_u_int %+ SUFFIX
%else
mix_1_1_float_u_int %+ SUFFIX
%endif
VBROADCASTSS m2, [coeffpq + 4*indexq]
shl lenq , 2
add inq , lenq
add outq , lenq
neg lenq
.next:
%ifidn %1, a
mulps m0, m2, [inq + lenq ]
mulps m1, m2, [inq + lenq + mmsize]
%else
movu m0, [inq + lenq ]
movu m1, [inq + lenq + mmsize]
mulps m0, m0, m2
mulps m1, m1, m2
%endif
mov%1 [outq + lenq ], m0
mov%1 [outq + lenq + mmsize], m1
add lenq, mmsize*2
jl .next
REP_RET
%endmacro
 
%macro MIX1_INT16 1
cglobal mix_1_1_%1_int16, 5, 5, 6, out, in, coeffp, index, len
%ifidn %1, a
test inq, mmsize-1
jne mix_1_1_int16_u_int %+ SUFFIX
test outq, mmsize-1
jne mix_1_1_int16_u_int %+ SUFFIX
%else
mix_1_1_int16_u_int %+ SUFFIX
%endif
movd m4, [coeffpq + 4*indexq]
SPLATW m5, m4
psllq m4, 32
psrlq m4, 48
mova m0, [w1]
psllw m0, m4
psrlw m0, 1
punpcklwd m5, m0
add lenq , lenq
add inq , lenq
add outq , lenq
neg lenq
.next:
mov%1 m0, [inq + lenq ]
mov%1 m2, [inq + lenq + mmsize]
mova m1, m0
mova m3, m2
punpcklwd m0, [w1]
punpckhwd m1, [w1]
punpcklwd m2, [w1]
punpckhwd m3, [w1]
pmaddwd m0, m5
pmaddwd m1, m5
pmaddwd m2, m5
pmaddwd m3, m5
psrad m0, m4
psrad m1, m4
psrad m2, m4
psrad m3, m4
packssdw m0, m1
packssdw m2, m3
mov%1 [outq + lenq ], m0
mov%1 [outq + lenq + mmsize], m2
add lenq, mmsize*2
jl .next
%if mmsize == 8
emms
RET
%else
REP_RET
%endif
%endmacro
 
%macro MIX2_INT16 1
cglobal mix_2_1_%1_int16, 7, 7, 8, out, in1, in2, coeffp, index1, index2, len
%ifidn %1, a
test in1q, mmsize-1
jne mix_2_1_int16_u_int %+ SUFFIX
test in2q, mmsize-1
jne mix_2_1_int16_u_int %+ SUFFIX
test outq, mmsize-1
jne mix_2_1_int16_u_int %+ SUFFIX
%else
mix_2_1_int16_u_int %+ SUFFIX
%endif
movd m4, [coeffpq + 4*index1q]
movd m6, [coeffpq + 4*index2q]
SPLATW m5, m4
SPLATW m6, m6
psllq m4, 32
psrlq m4, 48
mova m7, [dw1]
pslld m7, m4
psrld m7, 1
punpcklwd m5, m6
add lend , lend
add in1q , lenq
add in2q , lenq
add outq , lenq
neg lenq
.next:
mov%1 m0, [in1q + lenq ]
mov%1 m2, [in2q + lenq ]
mova m1, m0
punpcklwd m0, m2
punpckhwd m1, m2
 
mov%1 m2, [in1q + lenq + mmsize]
mov%1 m6, [in2q + lenq + mmsize]
mova m3, m2
punpcklwd m2, m6
punpckhwd m3, m6
 
pmaddwd m0, m5
pmaddwd m1, m5
pmaddwd m2, m5
pmaddwd m3, m5
paddd m0, m7
paddd m1, m7
paddd m2, m7
paddd m3, m7
psrad m0, m4
psrad m1, m4
psrad m2, m4
psrad m3, m4
packssdw m0, m1
packssdw m2, m3
mov%1 [outq + lenq ], m0
mov%1 [outq + lenq + mmsize], m2
add lenq, mmsize*2
jl .next
%if mmsize == 8
emms
RET
%else
REP_RET
%endif
%endmacro
 
 
INIT_MMX mmx
MIX1_INT16 u
MIX1_INT16 a
MIX2_INT16 u
MIX2_INT16 a
 
INIT_XMM sse
MIX2_FLT u
MIX2_FLT a
MIX1_FLT u
MIX1_FLT a
 
INIT_XMM sse2
MIX1_INT16 u
MIX1_INT16 a
MIX2_INT16 u
MIX2_INT16 a
 
%if HAVE_AVX_EXTERNAL
INIT_YMM avx
MIX2_FLT u
MIX2_FLT a
MIX1_FLT u
MIX1_FLT a
%endif
/contrib/sdk/sources/ffmpeg/libswresample/x86/resample_mmx.h
0,0 → 1,70
/*
* Copyright (c) 2012 Michael Niedermayer <michaelni@gmx.at>
*
* 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/asm.h"
#include "libavutil/cpu.h"
#include "libswresample/swresample_internal.h"
 
int swri_resample_int16_mmx2 (struct ResampleContext *c, int16_t *dst, const int16_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
int swri_resample_int16_ssse3(struct ResampleContext *c, int16_t *dst, const int16_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
 
DECLARE_ALIGNED(16, const uint64_t, ff_resample_int16_rounder)[2] = { 0x0000000000004000ULL, 0x0000000000000000ULL};
 
#define COMMON_CORE_INT16_MMX2 \
x86_reg len= -2*c->filter_length;\
__asm__ volatile(\
"movq "MANGLE(ff_resample_int16_rounder)", %%mm0 \n\t"\
"1: \n\t"\
"movq (%1, %0), %%mm1 \n\t"\
"pmaddwd (%2, %0), %%mm1 \n\t"\
"paddd %%mm1, %%mm0 \n\t"\
"add $8, %0 \n\t"\
" js 1b \n\t"\
"pshufw $0x0E, %%mm0, %%mm1 \n\t"\
"paddd %%mm1, %%mm0 \n\t"\
"psrad $15, %%mm0 \n\t"\
"packssdw %%mm0, %%mm0 \n\t"\
"movd %%mm0, (%3) \n\t"\
: "+r" (len)\
: "r" (((uint8_t*)(src+sample_index))-len),\
"r" (((uint8_t*)filter)-len),\
"r" (dst+dst_index)\
);
 
#define COMMON_CORE_INT16_SSSE3 \
x86_reg len= -2*c->filter_length;\
__asm__ volatile(\
"movdqa "MANGLE(ff_resample_int16_rounder)", %%xmm0 \n\t"\
"1: \n\t"\
"movdqu (%1, %0), %%xmm1 \n\t"\
"pmaddwd (%2, %0), %%xmm1 \n\t"\
"paddd %%xmm1, %%xmm0 \n\t"\
"add $16, %0 \n\t"\
" js 1b \n\t"\
"phaddd %%xmm0, %%xmm0 \n\t"\
"phaddd %%xmm0, %%xmm0 \n\t"\
"psrad $15, %%xmm0 \n\t"\
"packssdw %%xmm0, %%xmm0 \n\t"\
"movd %%xmm0, (%3) \n\t"\
: "+r" (len)\
: "r" (((uint8_t*)(src+sample_index))-len),\
"r" (((uint8_t*)filter)-len),\
"r" (dst+dst_index)\
);
/contrib/sdk/sources/ffmpeg/libswresample/x86/swresample_x86.c
0,0 → 1,200
/*
* Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at)
*
* This file is part of libswresample
*
* libswresample 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.
*
* libswresample 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 libswresample; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
#include "libswresample/swresample_internal.h"
#include "libswresample/audioconvert.h"
 
#define PROTO(pre, in, out, cap) void ff ## pre ## _ ##in## _to_ ##out## _a_ ##cap(uint8_t **dst, const uint8_t **src, int len);
#define PROTO2(pre, out, cap) PROTO(pre, int16, out, cap) PROTO(pre, int32, out, cap) PROTO(pre, float, out, cap)
#define PROTO3(pre, cap) PROTO2(pre, int16, cap) PROTO2(pre, int32, cap) PROTO2(pre, float, cap)
#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx)
PROTO4()
PROTO4(_pack_2ch)
PROTO4(_pack_6ch)
PROTO4(_unpack_2ch)
 
av_cold void swri_audio_convert_init_x86(struct AudioConvert *ac,
enum AVSampleFormat out_fmt,
enum AVSampleFormat in_fmt,
int channels){
int mm_flags = av_get_cpu_flags();
 
ac->simd_f= NULL;
 
//FIXME add memcpy case
 
#define MULTI_CAPS_FUNC(flag, cap) \
if (mm_flags & flag) {\
if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16P)\
ac->simd_f = ff_int16_to_int32_a_ ## cap;\
if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32P)\
ac->simd_f = ff_int32_to_int16_a_ ## cap;\
}
 
MULTI_CAPS_FUNC(AV_CPU_FLAG_MMX, mmx)
MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE2, sse2)
 
if(mm_flags & AV_CPU_FLAG_MMX) {
if(channels == 6) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_6ch_float_to_float_a_mmx;
}
}
 
if(mm_flags & AV_CPU_FLAG_SSE2) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_int32_to_float_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16P)
ac->simd_f = ff_int16_to_float_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP)
ac->simd_f = ff_float_to_int32_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP)
ac->simd_f = ff_float_to_int16_a_sse2;
 
if(channels == 2) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_2ch_int32_to_int32_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S16P)
ac->simd_f = ff_pack_2ch_int16_to_int16_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16P)
ac->simd_f = ff_pack_2ch_int16_to_int32_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_2ch_int32_to_int16_a_sse2;
 
if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32)
ac->simd_f = ff_unpack_2ch_int32_to_int32_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S16)
ac->simd_f = ff_unpack_2ch_int16_to_int16_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16)
ac->simd_f = ff_unpack_2ch_int16_to_int32_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32)
ac->simd_f = ff_unpack_2ch_int32_to_int16_a_sse2;
 
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_2ch_int32_to_float_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP)
ac->simd_f = ff_pack_2ch_float_to_int32_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16P)
ac->simd_f = ff_pack_2ch_int16_to_float_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP)
ac->simd_f = ff_pack_2ch_float_to_int16_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32)
ac->simd_f = ff_unpack_2ch_int32_to_float_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLT)
ac->simd_f = ff_unpack_2ch_float_to_int32_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16)
ac->simd_f = ff_unpack_2ch_int16_to_float_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLT)
ac->simd_f = ff_unpack_2ch_float_to_int16_a_sse2;
}
}
if(mm_flags & AV_CPU_FLAG_SSSE3) {
if(channels == 2) {
if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S16)
ac->simd_f = ff_unpack_2ch_int16_to_int16_a_ssse3;
if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16)
ac->simd_f = ff_unpack_2ch_int16_to_int32_a_ssse3;
if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16)
ac->simd_f = ff_unpack_2ch_int16_to_float_a_ssse3;
}
}
if(mm_flags & AV_CPU_FLAG_SSE4) {
if(channels == 6) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_6ch_float_to_float_a_sse4;
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_6ch_int32_to_float_a_sse4;
if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP)
ac->simd_f = ff_pack_6ch_float_to_int32_a_sse4;
}
}
if(HAVE_AVX_EXTERNAL && mm_flags & AV_CPU_FLAG_AVX) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_int32_to_float_a_avx;
if(channels == 6) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_6ch_float_to_float_a_avx;
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_pack_6ch_int32_to_float_a_avx;
if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP)
ac->simd_f = ff_pack_6ch_float_to_int32_a_avx;
}
}
}
 
#define D(type, simd) \
mix_1_1_func_type ff_mix_1_1_a_## type ## _ ## simd;\
mix_2_1_func_type ff_mix_2_1_a_## type ## _ ## simd;
 
D(float, sse)
D(float, avx)
D(int16, mmx)
D(int16, sse2)
 
 
av_cold void swri_rematrix_init_x86(struct SwrContext *s){
int mm_flags = av_get_cpu_flags();
int nb_in = av_get_channel_layout_nb_channels(s->in_ch_layout);
int nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
int num = nb_in * nb_out;
int i,j;
 
s->mix_1_1_simd = NULL;
s->mix_2_1_simd = NULL;
 
if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
if(mm_flags & AV_CPU_FLAG_MMX) {
s->mix_1_1_simd = ff_mix_1_1_a_int16_mmx;
s->mix_2_1_simd = ff_mix_2_1_a_int16_mmx;
}
if(mm_flags & AV_CPU_FLAG_SSE2) {
s->mix_1_1_simd = ff_mix_1_1_a_int16_sse2;
s->mix_2_1_simd = ff_mix_2_1_a_int16_sse2;
}
s->native_simd_matrix = av_mallocz(2 * num * sizeof(int16_t));
s->native_simd_one = av_mallocz(2 * sizeof(int16_t));
for(i=0; i<nb_out; i++){
int sh = 0;
for(j=0; j<nb_in; j++)
sh = FFMAX(sh, FFABS(((int*)s->native_matrix)[i * nb_in + j]));
sh = FFMAX(av_log2(sh) - 14, 0);
for(j=0; j<nb_in; j++) {
((int16_t*)s->native_simd_matrix)[2*(i * nb_in + j)+1] = 15 - sh;
((int16_t*)s->native_simd_matrix)[2*(i * nb_in + j)] =
((((int*)s->native_matrix)[i * nb_in + j]) + (1<<sh>>1)) >> sh;
}
}
((int16_t*)s->native_simd_one)[1] = 14;
((int16_t*)s->native_simd_one)[0] = 16384;
} else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
if(mm_flags & AV_CPU_FLAG_SSE) {
s->mix_1_1_simd = ff_mix_1_1_a_float_sse;
s->mix_2_1_simd = ff_mix_2_1_a_float_sse;
}
if(HAVE_AVX_EXTERNAL && mm_flags & AV_CPU_FLAG_AVX) {
s->mix_1_1_simd = ff_mix_1_1_a_float_avx;
s->mix_2_1_simd = ff_mix_2_1_a_float_avx;
}
s->native_simd_matrix = av_mallocz(num * sizeof(float));
memcpy(s->native_simd_matrix, s->native_matrix, num * sizeof(float));
s->native_simd_one = av_mallocz(sizeof(float));
memcpy(s->native_simd_one, s->native_one, sizeof(float));
}
}