diff options
author | Zeno Albisser <zeno.albisser@theqtcompany.com> | 2014-12-05 15:04:29 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@theqtcompany.com> | 2014-12-09 10:49:28 +0100 |
commit | af6588f8d723931a298c995fa97259bb7f7deb55 (patch) | |
tree | 060ca707847ba1735f01af2372e0d5e494dc0366 /chromium/third_party/ffmpeg/libswresample | |
parent | 2fff84d821cc7b1c785f6404e0f8091333283e74 (diff) | |
download | qtwebengine-chromium-af6588f8d723931a298c995fa97259bb7f7deb55.tar.gz |
BASELINE: Update chromium to 40.0.2214.28 and ninja to 1.5.3.
Change-Id: I759465284fd64d59ad120219cbe257f7402c4181
Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/third_party/ffmpeg/libswresample')
26 files changed, 2215 insertions, 742 deletions
diff --git a/chromium/third_party/ffmpeg/libswresample/Makefile b/chromium/third_party/ffmpeg/libswresample/Makefile index 953c9452a9e..120ee3385d8 100644 --- a/chromium/third_party/ffmpeg/libswresample/Makefile +++ b/chromium/third_party/ffmpeg/libswresample/Makefile @@ -8,9 +8,12 @@ HEADERS = swresample.h \ OBJS = audioconvert.o \ dither.o \ + options.o \ rematrix.o \ resample.o \ + resample_dsp.o \ swresample.o \ + swresample_frame.o \ OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o OBJS-$(CONFIG_SHARED) += log2_tab.o diff --git a/chromium/third_party/ffmpeg/libswresample/aarch64/Makefile b/chromium/third_party/ffmpeg/libswresample/aarch64/Makefile new file mode 100644 index 00000000000..320ed67e82f --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/aarch64/Makefile @@ -0,0 +1,5 @@ +OBJS += aarch64/audio_convert_init.o + +OBJS-$(CONFIG_NEON_CLOBBER_TEST) += aarch64/neontest.o + +NEON-OBJS += aarch64/audio_convert_neon.o diff --git a/chromium/third_party/ffmpeg/libswresample/aarch64/audio_convert_init.c b/chromium/third_party/ffmpeg/libswresample/aarch64/audio_convert_init.c new file mode 100644 index 00000000000..60e24adb1c6 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/aarch64/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/aarch64/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_aarch64(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; + } +} diff --git a/chromium/third_party/ffmpeg/libswresample/aarch64/audio_convert_neon.S b/chromium/third_party/ffmpeg/libswresample/aarch64/audio_convert_neon.S new file mode 100644 index 00000000000..74feff448a3 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/aarch64/audio_convert_neon.S @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> + * Copyright (c) 2014 Janne Grunau <janne-libav@jannau.net> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/aarch64/asm.S" + +function swri_oldapi_conv_flt_to_s16_neon, export=1 + subs x2, x2, #8 + ld1 {v0.4s}, [x1], #16 + fcvtzs v4.4s, v0.4s, #31 + ld1 {v1.4s}, [x1], #16 + fcvtzs v5.4s, v1.4s, #31 + b.eq 3f + ands x12, x2, #~15 + b.eq 2f +1: subs x12, x12, #16 + sqrshrn v4.4h, v4.4s, #16 + ld1 {v2.4s}, [x1], #16 + fcvtzs v6.4s, v2.4s, #31 + sqrshrn2 v4.8h, v5.4s, #16 + ld1 {v3.4s}, [x1], #16 + fcvtzs v7.4s, v3.4s, #31 + sqrshrn v6.4h, v6.4s, #16 + st1 {v4.8h}, [x0], #16 + sqrshrn2 v6.8h, v7.4s, #16 + ld1 {v0.4s}, [x1], #16 + fcvtzs v4.4s, v0.4s, #31 + ld1 {v1.4s}, [x1], #16 + fcvtzs v5.4s, v1.4s, #31 + st1 {v6.8h}, [x0], #16 + b.ne 1b + ands x2, x2, #15 + b.eq 3f +2: ld1 {v2.4s}, [x1], #16 + sqrshrn v4.4h, v4.4s, #16 + fcvtzs v6.4s, v2.4s, #31 + ld1 {v3.4s}, [x1], #16 + sqrshrn2 v4.8h, v5.4s, #16 + fcvtzs v7.4s, v3.4s, #31 + sqrshrn v6.4h, v6.4s, #16 + st1 {v4.8h}, [x0], #16 + sqrshrn2 v6.8h, v7.4s, #16 + st1 {v6.8h}, [x0] + ret +3: sqrshrn v4.4h, v4.4s, #16 + sqrshrn2 v4.8h, v5.4s, #16 + st1 {v4.8h}, [x0] + ret +endfunc + +function swri_oldapi_conv_fltp_to_s16_2ch_neon, export=1 + ldp x4, x5, [x1] + subs x2, x2, #8 + ld1 {v0.4s}, [x4], #16 + fcvtzs v4.4s, v0.4s, #31 + ld1 {v1.4s}, [x4], #16 + fcvtzs v5.4s, v1.4s, #31 + ld1 {v2.4s}, [x5], #16 + fcvtzs v6.4s, v2.4s, #31 + ld1 {v3.4s}, [x5], #16 + fcvtzs v7.4s, v3.4s, #31 + b.eq 3f + ands x12, x2, #~15 + b.eq 2f +1: subs x12, x12, #16 + ld1 {v16.4s}, [x4], #16 + fcvtzs v20.4s, v16.4s, #31 + sri v6.4s, v4.4s, #16 + ld1 {v17.4s}, [x4], #16 + fcvtzs v21.4s, v17.4s, #31 + ld1 {v18.4s}, [x5], #16 + fcvtzs v22.4s, v18.4s, #31 + ld1 {v19.4s}, [x5], #16 + sri v7.4s, v5.4s, #16 + st1 {v6.4s}, [x0], #16 + fcvtzs v23.4s, v19.4s, #31 + st1 {v7.4s}, [x0], #16 + sri v22.4s, v20.4s, #16 + ld1 {v0.4s}, [x4], #16 + sri v23.4s, v21.4s, #16 + st1 {v22.4s}, [x0], #16 + fcvtzs v4.4s, v0.4s, #31 + ld1 {v1.4s}, [x4], #16 + fcvtzs v5.4s, v1.4s, #31 + ld1 {v2.4s}, [x5], #16 + fcvtzs v6.4s, v2.4s, #31 + ld1 {v3.4s}, [x5], #16 + fcvtzs v7.4s, v3.4s, #31 + st1 {v23.4s}, [x0], #16 + b.ne 1b + ands x2, x2, #15 + b.eq 3f +2: sri v6.4s, v4.4s, #16 + ld1 {v0.4s}, [x4], #16 + fcvtzs v0.4s, v0.4s, #31 + ld1 {v1.4s}, [x4], #16 + fcvtzs v1.4s, v1.4s, #31 + ld1 {v2.4s}, [x5], #16 + fcvtzs v2.4s, v2.4s, #31 + sri v7.4s, v5.4s, #16 + ld1 {v3.4s}, [x5], #16 + fcvtzs v3.4s, v3.4s, #31 + sri v2.4s, v0.4s, #16 + st1 {v6.4s,v7.4s}, [x0], #32 + sri v3.4s, v1.4s, #16 + st1 {v2.4s,v3.4s}, [x0], #32 + ret +3: sri v6.4s, v4.4s, #16 + sri v7.4s, v5.4s, #16 + st1 {v6.4s,v7.4s}, [x0] + ret +endfunc + +function swri_oldapi_conv_fltp_to_s16_nch_neon, export=1 + cmp w3, #2 + b.eq X(swri_oldapi_conv_fltp_to_s16_2ch_neon) + b.gt 1f + ldr x1, [x1] + b X(swri_oldapi_conv_flt_to_s16_neon) +1: + cmp w3, #4 + lsl x12, x3, #1 + b.lt 4f + +5: // 4 channels + ldp x4, x5, [x1], #16 + ldp x6, x7, [x1], #16 + mov w9, w2 + mov x8, x0 + ld1 {v4.4s}, [x4], #16 + fcvtzs v4.4s, v4.4s, #31 + ld1 {v5.4s}, [x5], #16 + fcvtzs v5.4s, v5.4s, #31 + ld1 {v6.4s}, [x6], #16 + fcvtzs v6.4s, v6.4s, #31 + ld1 {v7.4s}, [x7], #16 + fcvtzs v7.4s, v7.4s, #31 +6: + subs w9, w9, #8 + ld1 {v0.4s}, [x4], #16 + fcvtzs v0.4s, v0.4s, #31 + sri v5.4s, v4.4s, #16 + ld1 {v1.4s}, [x5], #16 + fcvtzs v1.4s, v1.4s, #31 + sri v7.4s, v6.4s, #16 + ld1 {v2.4s}, [x6], #16 + fcvtzs v2.4s, v2.4s, #31 + zip1 v16.4s, v5.4s, v7.4s + ld1 {v3.4s}, [x7], #16 + fcvtzs v3.4s, v3.4s, #31 + zip2 v17.4s, v5.4s, v7.4s + st1 {v16.d}[0], [x8], x12 + sri v1.4s, v0.4s, #16 + st1 {v16.d}[1], [x8], x12 + sri v3.4s, v2.4s, #16 + st1 {v17.d}[0], [x8], x12 + zip1 v18.4s, v1.4s, v3.4s + st1 {v17.d}[1], [x8], x12 + zip2 v19.4s, v1.4s, v3.4s + b.eq 7f + ld1 {v4.4s}, [x4], #16 + fcvtzs v4.4s, v4.4s, #31 + st1 {v18.d}[0], [x8], x12 + ld1 {v5.4s}, [x5], #16 + fcvtzs v5.4s, v5.4s, #31 + st1 {v18.d}[1], [x8], x12 + ld1 {v6.4s}, [x6], #16 + fcvtzs v6.4s, v6.4s, #31 + st1 {v19.d}[0], [x8], x12 + ld1 {v7.4s}, [x7], #16 + fcvtzs v7.4s, v7.4s, #31 + st1 {v19.d}[1], [x8], x12 + b 6b +7: + st1 {v18.d}[0], [x8], x12 + st1 {v18.d}[1], [x8], x12 + st1 {v19.d}[0], [x8], x12 + st1 {v19.d}[1], [x8], x12 + subs w3, w3, #4 + b.eq end + cmp w3, #4 + add x0, x0, #8 + b.ge 5b + +4: // 2 channels + cmp w3, #2 + b.lt 4f + ldp x4, x5, [x1], #16 + mov w9, w2 + mov x8, x0 + tst w9, #8 + ld1 {v4.4s}, [x4], #16 + fcvtzs v4.4s, v4.4s, #31 + ld1 {v5.4s}, [x5], #16 + fcvtzs v5.4s, v5.4s, #31 + ld1 {v6.4s}, [x4], #16 + fcvtzs v6.4s, v6.4s, #31 + ld1 {v7.4s}, [x5], #16 + fcvtzs v7.4s, v7.4s, #31 + b.eq 6f + subs w9, w9, #8 + b.eq 7f + sri v5.4s, v4.4s, #16 + ld1 {v4.4s}, [x4], #16 + fcvtzs v4.4s, v4.4s, #31 + st1 {v5.s}[0], [x8], x12 + sri v7.4s, v6.4s, #16 + st1 {v5.s}[1], [x8], x12 + ld1 {v6.4s}, [x4], #16 + fcvtzs v6.4s, v6.4s, #31 + st1 {v5.s}[2], [x8], x12 + st1 {v5.s}[3], [x8], x12 + st1 {v7.s}[0], [x8], x12 + st1 {v7.s}[1], [x8], x12 + ld1 {v5.4s}, [x5], #16 + fcvtzs v5.4s, v5.4s, #31 + st1 {v7.s}[2], [x8], x12 + st1 {v7.s}[3], [x8], x12 + ld1 {v7.4s}, [x5], #16 + fcvtzs v7.4s, v7.4s, #31 +6: + subs w9, w9, #16 + ld1 {v0.4s}, [x4], #16 + sri v5.4s, v4.4s, #16 + fcvtzs v0.4s, v0.4s, #31 + ld1 {v1.4s}, [x5], #16 + sri v7.4s, v6.4s, #16 + st1 {v5.s}[0], [x8], x12 + st1 {v5.s}[1], [x8], x12 + fcvtzs v1.4s, v1.4s, #31 + st1 {v5.s}[2], [x8], x12 + st1 {v5.s}[3], [x8], x12 + ld1 {v2.4s}, [x4], #16 + st1 {v7.s}[0], [x8], x12 + fcvtzs v2.4s, v2.4s, #31 + st1 {v7.s}[1], [x8], x12 + ld1 {v3.4s}, [x5], #16 + st1 {v7.s}[2], [x8], x12 + fcvtzs v3.4s, v3.4s, #31 + st1 {v7.s}[3], [x8], x12 + sri v1.4s, v0.4s, #16 + sri v3.4s, v2.4s, #16 + b.eq 6f + ld1 {v4.4s}, [x4], #16 + st1 {v1.s}[0], [x8], x12 + fcvtzs v4.4s, v4.4s, #31 + st1 {v1.s}[1], [x8], x12 + ld1 {v5.4s}, [x5], #16 + st1 {v1.s}[2], [x8], x12 + fcvtzs v5.4s, v5.4s, #31 + st1 {v1.s}[3], [x8], x12 + ld1 {v6.4s}, [x4], #16 + st1 {v3.s}[0], [x8], x12 + fcvtzs v6.4s, v6.4s, #31 + st1 {v3.s}[1], [x8], x12 + ld1 {v7.4s}, [x5], #16 + st1 {v3.s}[2], [x8], x12 + fcvtzs v7.4s, v7.4s, #31 + st1 {v3.s}[3], [x8], x12 + b.gt 6b +6: + st1 {v1.s}[0], [x8], x12 + st1 {v1.s}[1], [x8], x12 + st1 {v1.s}[2], [x8], x12 + st1 {v1.s}[3], [x8], x12 + st1 {v3.s}[0], [x8], x12 + st1 {v3.s}[1], [x8], x12 + st1 {v3.s}[2], [x8], x12 + st1 {v3.s}[3], [x8], x12 + b 8f +7: + sri v5.4s, v4.4s, #16 + sri v7.4s, v6.4s, #16 + st1 {v5.s}[0], [x8], x12 + st1 {v5.s}[1], [x8], x12 + st1 {v5.s}[2], [x8], x12 + st1 {v5.s}[3], [x8], x12 + st1 {v7.s}[0], [x8], x12 + st1 {v7.s}[1], [x8], x12 + st1 {v7.s}[2], [x8], x12 + st1 {v7.s}[3], [x8], x12 +8: + subs w3, w3, #2 + add x0, x0, #4 + b.eq end + +4: // 1 channel + ldr x4, [x1] + tst w2, #8 + mov w9, w2 + mov x5, x0 + ld1 {v0.4s}, [x4], #16 + fcvtzs v0.4s, v0.4s, #31 + ld1 {v1.4s}, [x4], #16 + fcvtzs v1.4s, v1.4s, #31 + b.ne 8f +6: + subs w9, w9, #16 + ld1 {v2.4s}, [x4], #16 + fcvtzs v2.4s, v2.4s, #31 + ld1 {v3.4s}, [x4], #16 + fcvtzs v3.4s, v3.4s, #31 + st1 {v0.h}[1], [x5], x12 + st1 {v0.h}[3], [x5], x12 + st1 {v0.h}[5], [x5], x12 + st1 {v0.h}[7], [x5], x12 + st1 {v1.h}[1], [x5], x12 + st1 {v1.h}[3], [x5], x12 + st1 {v1.h}[5], [x5], x12 + st1 {v1.h}[7], [x5], x12 + b.eq 7f + ld1 {v0.4s}, [x4], #16 + fcvtzs v0.4s, v0.4s, #31 + ld1 {v1.4s}, [x4], #16 + fcvtzs v1.4s, v1.4s, #31 +7: + st1 {v2.h}[1], [x5], x12 + st1 {v2.h}[3], [x5], x12 + st1 {v2.h}[5], [x5], x12 + st1 {v2.h}[7], [x5], x12 + st1 {v3.h}[1], [x5], x12 + st1 {v3.h}[3], [x5], x12 + st1 {v3.h}[5], [x5], x12 + st1 {v3.h}[7], [x5], x12 + b.gt 6b + ret +8: + subs w9, w9, #8 + st1 {v0.h}[1], [x5], x12 + st1 {v0.h}[3], [x5], x12 + st1 {v0.h}[5], [x5], x12 + st1 {v0.h}[7], [x5], x12 + st1 {v1.h}[1], [x5], x12 + st1 {v1.h}[3], [x5], x12 + st1 {v1.h}[5], [x5], x12 + st1 {v1.h}[7], [x5], x12 + b.eq end + ld1 {v0.4s}, [x4], #16 + fcvtzs v0.4s, v0.4s, #31 + ld1 {v1.4s}, [x4], #16 + fcvtzs v1.4s, v1.4s, #31 + b 6b +end: + ret +endfunc diff --git a/chromium/third_party/ffmpeg/libswresample/aarch64/neontest.c b/chromium/third_party/ffmpeg/libswresample/aarch64/neontest.c new file mode 100644 index 00000000000..85c71bf4c97 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/aarch64/neontest.c @@ -0,0 +1,29 @@ +/* + * check NEON registers for clobbers + * Copyright (c) 2013 Martin Storsjo + * + * 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 "libswresample/swresample.h" +#include "libavutil/aarch64/neontest.h" + +wrap(swr_convert(struct SwrContext *s, uint8_t **out, int out_count, + const uint8_t **in , int in_count)) +{ + testneonclobbers(swr_convert, s, out, out_count, in, in_count); +} diff --git a/chromium/third_party/ffmpeg/libswresample/audioconvert.c b/chromium/third_party/ffmpeg/libswresample/audioconvert.c index 4ba0ff13b16..efdc9b5a897 100644 --- a/chromium/third_party/ffmpeg/libswresample/audioconvert.c +++ b/chromium/third_party/ffmpeg/libswresample/audioconvert.c @@ -77,7 +77,7 @@ CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(* 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) +#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 ), @@ -156,6 +156,7 @@ AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, 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); + if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels); return ctx; } diff --git a/chromium/third_party/ffmpeg/libswresample/libswresample.v b/chromium/third_party/ffmpeg/libswresample/libswresample.v index 9b797bde77c..0d5efe4706c 100644 --- a/chromium/third_party/ffmpeg/libswresample/libswresample.v +++ b/chromium/third_party/ffmpeg/libswresample/libswresample.v @@ -1,4 +1,4 @@ LIBSWRESAMPLE_$MAJOR { - global: swr_*; ff_*; swresample_*; + global: swr_*; swresample_*; local: *; }; diff --git a/chromium/third_party/ffmpeg/libswresample/options.c b/chromium/third_party/ffmpeg/libswresample/options.c new file mode 100644 index 00000000000..01cdb1e1418 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/options.c @@ -0,0 +1,155 @@ +/* + * 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 <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 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 , INT_MAX, PARAM}, +{"in_sample_fmt" , "set input sample format" , OFFSET( in_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"osf" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"out_sample_fmt" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"tsf" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"internal_sample_fmt" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, 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, +}; + +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; +} diff --git a/chromium/third_party/ffmpeg/libswresample/rematrix.c b/chromium/third_party/ffmpeg/libswresample/rematrix.c index bf2abcfb20e..6552a2fea2d 100644 --- a/chromium/third_party/ffmpeg/libswresample/rematrix.c +++ b/chromium/third_party/ffmpeg/libswresample/rematrix.c @@ -56,6 +56,7 @@ #define TOP_BACK_LEFT 15 #define TOP_BACK_CENTER 16 #define TOP_BACK_RIGHT 17 +#define NUM_NAMED_CHANNELS 18 int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) { @@ -112,7 +113,7 @@ static int sane_layout(int64_t layout){ av_cold static int auto_matrix(SwrContext *s) { int i, j, out_i; - double matrix[64][64]={{0}}; + double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; int64_t unaccounted, in_ch_layout, out_ch_layout; double maxcoef=0; char buf[128]; @@ -145,7 +146,7 @@ av_cold static int auto_matrix(SwrContext *s) } memset(s->matrix, 0, sizeof(s->matrix)); - for(i=0; i<64; i++){ + for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ if(in_ch_layout & out_ch_layout & (1ULL<<i)) matrix[i][i]= 1.0; } @@ -298,17 +299,20 @@ av_cold static int auto_matrix(SwrContext *s) for(out_i=i=0; i<64; i++){ double sum=0; int in_i=0; + if((out_ch_layout & (1ULL<<i)) == 0) + continue; 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++; + if((in_ch_layout & (1ULL<<j)) == 0) + continue; + if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) + s->matrix[out_i][in_i]= matrix[i][j]; + else + s->matrix[out_i][in_i]= i == j && (in_ch_layout & out_ch_layout & (1ULL<<i)); + sum += fabs(s->matrix[out_i][in_i]); + in_i++; } maxcoef= FFMAX(maxcoef, sum); - if(out_ch_layout & (1ULL<<i)) - out_i++; + out_i++; } if(s->rematrix_volume < 0) maxcoef = -s->rematrix_volume; diff --git a/chromium/third_party/ffmpeg/libswresample/resample.c b/chromium/third_party/ffmpeg/libswresample/resample.c index 0ce74d076cf..2a8aa7e2d0f 100644 --- a/chromium/third_party/ffmpeg/libswresample/resample.c +++ b/chromium/third_party/ffmpeg/libswresample/resample.c @@ -25,32 +25,8 @@ * @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; +#include "resample.h" /** * 0th order modified bessel function of the first kind. @@ -197,7 +173,8 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap 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 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; @@ -254,11 +231,15 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r 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->ideal_dst_incr = c->dst_incr; + c->dst_incr_div = c->dst_incr / c->src_incr; + c->dst_incr_mod = c->dst_incr % c->src_incr; c->index= -phase_count*((c->filter_length-1)/2); c->frac= 0; + swri_resample_dsp_init(c); + return c; error: av_freep(&c->filter_bank); @@ -279,83 +260,78 @@ static int set_compensation(ResampleContext *c, int sample_delta, int compensati 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_SSE_INLINE -#define TEMPLATE_RESAMPLE_FLT_SSE -#include "resample_template.c" -#undef TEMPLATE_RESAMPLE_FLT_SSE -#endif + c->dst_incr_div = c->dst_incr / c->src_incr; + c->dst_incr_mod = c->dst_incr % c->src_incr; -#if HAVE_SSE2_INLINE -#define TEMPLATE_RESAMPLE_S16_SSE2 -#include "resample_template.c" -#undef TEMPLATE_RESAMPLE_S16_SSE2 + return 0; +} -#define TEMPLATE_RESAMPLE_DBL_SSE2 -#include "resample_template.c" -#undef TEMPLATE_RESAMPLE_DBL_SSE2 -#endif +static int swri_resample(ResampleContext *c, + uint8_t *dst, const uint8_t *src, int *consumed, + int src_size, int dst_size, int update_ctx) +{ + if (c->filter_length == 1 && c->phase_shift == 0) { + int index= c->index; + int frac= c->frac; + int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index; + int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; + int new_size = (src_size * (int64_t)c->src_incr - frac + c->dst_incr - 1) / c->dst_incr; + + dst_size= FFMIN(dst_size, new_size); + c->dsp.resample_one(dst, src, dst_size, index2, incr); + + index += dst_size * c->dst_incr_div; + index += (frac + dst_size * (int64_t)c->dst_incr_mod) / c->src_incr; + av_assert2(index >= 0); + *consumed= index; + if (update_ctx) { + c->frac = (frac + dst_size * (int64_t)c->dst_incr_mod) % c->src_incr; + c->index = 0; + } + } else { + int64_t end_index = (1LL + src_size - c->filter_length) << c->phase_shift; + int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac; + int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr; + + dst_size = FFMIN(dst_size, delta_n); + if (dst_size > 0) { + *consumed = c->dsp.resample(c, dst, src, dst_size, update_ctx); + } else { + *consumed = 0; + } + } -#endif // HAVE_MMXEXT_INLINE + return dst_size; +} 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; + int need_emms = c->format == AV_SAMPLE_FMT_S16P && ARCH_X86_32 && + (mm_flags & (AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE2)) == AV_CPU_FLAG_MMX2; + int64_t max_src_size = (INT64_MAX >> (c->phase_shift+1)) / c->src_incr; + + if (c->compensation_distance) + dst_size = FFMIN(dst_size, c->compensation_distance); + src_size = FFMIN(src_size, max_src_size); for(i=0; i<dst->ch_count; i++){ -#if HAVE_MMXEXT_INLINE -#if HAVE_SSE2_INLINE - if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_SSE2)) ret= swri_resample_int16_sse2 (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); -#if HAVE_SSE_INLINE - else if(c->format == AV_SAMPLE_FMT_FLTP && (mm_flags&AV_CPU_FLAG_SSE)) - ret= swri_resample_float_sse (c, (float*)dst->ch[i], (const float*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); -#endif - 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); -#if HAVE_SSE2_INLINE - else if(c->format == AV_SAMPLE_FMT_DBLP && (mm_flags&AV_CPU_FLAG_SSE2)) - ret= swri_resample_double_sse2(c,(double *)dst->ch[i], (const double *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count); -#endif - 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); + ret= swri_resample(c, dst->ch[i], src->ch[i], + consumed, src_size, dst_size, i+1==dst->ch_count); } if(need_emms) emms_c(); + + if (c->compensation_distance) { + c->compensation_distance -= ret; + if (!c->compensation_distance) { + c->dst_incr = c->ideal_dst_incr; + c->dst_incr_div = c->dst_incr / c->src_incr; + c->dst_incr_mod = c->dst_incr % c->src_incr; + } + } + return ret; } @@ -385,6 +361,51 @@ static int resample_flush(struct SwrContext *s) { return 0; } +// in fact the whole handle multiple ridiculously small buffers might need more thinking... +static int invert_initial_buffer(ResampleContext *c, AudioData *dst, const AudioData *src, + int in_count, int *out_idx, int *out_sz) +{ + int n, ch, num = FFMIN(in_count + *out_sz, c->filter_length + 1), res; + + if (c->index >= 0) + return 0; + + if ((res = swri_realloc_audio(dst, c->filter_length * 2 + 1)) < 0) + return res; + + // copy + for (n = *out_sz; n < num; n++) { + for (ch = 0; ch < src->ch_count; ch++) { + memcpy(dst->ch[ch] + ((c->filter_length + n) * c->felem_size), + src->ch[ch] + ((n - *out_sz) * c->felem_size), c->felem_size); + } + } + + // if not enough data is in, return and wait for more + if (num < c->filter_length + 1) { + *out_sz = num; + *out_idx = c->filter_length; + return INT_MAX; + } + + // else invert + for (n = 1; n <= c->filter_length; n++) { + for (ch = 0; ch < src->ch_count; ch++) { + memcpy(dst->ch[ch] + ((c->filter_length - n) * c->felem_size), + dst->ch[ch] + ((c->filter_length + n) * c->felem_size), + c->felem_size); + } + } + + res = num - *out_sz; + *out_idx = c->filter_length + (c->index >> c->phase_shift); + *out_sz = 1 + c->filter_length * 2 - *out_idx; + c->index &= c->phase_mask; + av_assert1(res > 0); + + return res; +} + struct Resampler const swri_resampler={ resample_init, resample_free, @@ -392,4 +413,5 @@ struct Resampler const swri_resampler={ resample_flush, set_compensation, get_delay, + invert_initial_buffer, }; diff --git a/chromium/third_party/ffmpeg/libswresample/resample.h b/chromium/third_party/ffmpeg/libswresample/resample.h new file mode 100644 index 00000000000..99a89b7945e --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/resample.h @@ -0,0 +1,64 @@ +/* + * 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 + */ + +#ifndef SWRESAMPLE_RESAMPLE_H +#define SWRESAMPLE_RESAMPLE_H + +#include "libavutil/log.h" +#include "libavutil/samplefmt.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 dst_incr_div; + int dst_incr_mod; + 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; + + struct { + void (*resample_one)(void *dst, const void *src, + int n, int64_t index, int64_t incr); + int (*resample)(struct ResampleContext *c, void *dst, + const void *src, int n, int update_ctx); + } dsp; +} ResampleContext; + +void swri_resample_dsp_init(ResampleContext *c); +void swri_resample_dsp_x86_init(ResampleContext *c); + +#endif /* SWRESAMPLE_RESAMPLE_H */ diff --git a/chromium/third_party/ffmpeg/libswresample/resample_dsp.c b/chromium/third_party/ffmpeg/libswresample/resample_dsp.c new file mode 100644 index 00000000000..a811b8b6fa8 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/resample_dsp.c @@ -0,0 +1,68 @@ +/* + * 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 "resample.h" + +#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 + +void swri_resample_dsp_init(ResampleContext *c) +{ + switch(c->format){ + case AV_SAMPLE_FMT_S16P: + c->dsp.resample_one = resample_one_int16; + c->dsp.resample = c->linear ? resample_linear_int16 : resample_common_int16; + break; + case AV_SAMPLE_FMT_S32P: + c->dsp.resample_one = resample_one_int32; + c->dsp.resample = c->linear ? resample_linear_int32 : resample_common_int32; + break; + case AV_SAMPLE_FMT_FLTP: + c->dsp.resample_one = resample_one_float; + c->dsp.resample = c->linear ? resample_linear_float : resample_common_float; + break; + case AV_SAMPLE_FMT_DBLP: + c->dsp.resample_one = resample_one_double; + c->dsp.resample = c->linear ? resample_linear_double : resample_common_double; + break; + } + + if (ARCH_X86) swri_resample_dsp_x86_init(c); +} diff --git a/chromium/third_party/ffmpeg/libswresample/resample_template.c b/chromium/third_party/ffmpeg/libswresample/resample_template.c index 7624d9291ba..069b19cafda 100644 --- a/chromium/third_party/ffmpeg/libswresample/resample_template.c +++ b/chromium/third_party/ffmpeg/libswresample/resample_template.c @@ -25,58 +25,39 @@ * @author Michael Niedermayer <michaelni@gmx.at> */ -#if defined(TEMPLATE_RESAMPLE_DBL) \ - || defined(TEMPLATE_RESAMPLE_DBL_SSE2) +#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 -# if defined(TEMPLATE_RESAMPLE_DBL) -# define RENAME(N) N ## _double -# elif defined(TEMPLATE_RESAMPLE_DBL_SSE2) -# define COMMON_CORE COMMON_CORE_DBL_SSE2 -# define LINEAR_CORE LINEAR_CORE_DBL_SSE2 -# define RENAME(N) N ## _double_sse2 -# endif - -#elif defined(TEMPLATE_RESAMPLE_FLT) \ - || defined(TEMPLATE_RESAMPLE_FLT_SSE) +#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 -# if defined(TEMPLATE_RESAMPLE_FLT) -# define RENAME(N) N ## _float -# elif defined(TEMPLATE_RESAMPLE_FLT_SSE) -# define COMMON_CORE COMMON_CORE_FLT_SSE -# define LINEAR_CORE LINEAR_CORE_FLT_SSE -# define RENAME(N) N ## _float_sse -# endif - #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_SSE2) +#elif defined(TEMPLATE_RESAMPLE_S16) +# define RENAME(N) N ## _int16 # define FILTER_SHIFT 15 # define DELEM int16_t # define FELEM int16_t @@ -87,151 +68,114 @@ # 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 LINEAR_CORE LINEAR_CORE_INT16_MMX2 -# define RENAME(N) N ## _int16_mmx2 -# elif defined(TEMPLATE_RESAMPLE_S16_SSE2) -# define COMMON_CORE COMMON_CORE_INT16_SSE2 -# define LINEAR_CORE LINEAR_CORE_INT16_SSE2 -# define RENAME(N) N ## _int16_sse2 -# 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; +static void RENAME(resample_one)(void *dest, const void *source, + int dst_size, int64_t index2, int64_t incr) +{ + DELEM *dst = dest; + const DELEM *src = source; + int dst_index; + + for (dst_index = 0; dst_index < dst_size; dst_index++) { + dst[dst_index] = src[index2 >> 32]; + index2 += incr; + } +} + +static int RENAME(resample_common)(ResampleContext *c, + void *dest, const void *source, + int n, int update_ctx) +{ + DELEM *dst = dest; + const DELEM *src = source; + int dst_index; 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; + int sample_index = index >> c->phase_shift; - av_assert1(c->filter_shift == FILTER_SHIFT); - av_assert1(c->felem_size == sizeof(FELEM)); + index &= c->phase_mask; + for (dst_index = 0; dst_index < n; dst_index++) { + FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; - if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){ - int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index; - int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; - int new_size = (src_size * (int64_t)c->src_incr - frac + c->dst_incr - 1) / c->dst_incr; - - dst_size= FFMIN(dst_size, new_size); + FELEM2 val=0; + int i; + for (i = 0; i < c->filter_length; i++) { + val += src[sample_index + i] * (FELEM2)filter[i]; + } + OUT(dst[dst_index], val); - for(dst_index=0; dst_index < dst_size; dst_index++){ - dst[dst_index] = src[index2>>32]; - index2 += incr; + frac += c->dst_incr_mod; + index += c->dst_incr_div; + if (frac >= c->src_incr) { + frac -= c->src_incr; + index++; } - 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; - index = 0; - }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); + sample_index += index >> c->phase_shift; + index &= c->phase_mask; + } + + if(update_ctx){ + c->frac= frac; + c->index= index; + } + + return sample_index; +} + +static int RENAME(resample_linear)(ResampleContext *c, + void *dest, const void *source, + int n, int update_ctx) +{ + DELEM *dst = dest; + const DELEM *src = source; + int dst_index; + int index= c->index; + int frac= c->frac; + int sample_index = index >> c->phase_shift; +#if FILTER_SHIFT == 0 + double inv_src_incr = 1.0 / c->src_incr; #endif - } - - frac += dst_incr_frac; - index += dst_incr; - if(frac >= c->src_incr){ - frac -= c->src_incr; - index++; - } + + index &= c->phase_mask; + for (dst_index = 0; dst_index < n; dst_index++) { + FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; + FELEM2 val=0, v2 = 0; + + int i; + 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]; } - *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]; - OUT(dst[dst_index], val); - }else if(c->linear){ - FELEM2 v2=0; -#ifdef LINEAR_CORE - LINEAR_CORE +#ifdef FELEML + 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]; - v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; - } -#endif - val+=(v2-val)*(FELEML)frac / c->src_incr; - OUT(dst[dst_index], val); - }else{ -#ifdef COMMON_CORE - COMMON_CORE -#else - for(i=0; i<c->filter_length; i++){ - val += src[sample_index + i] * (FELEM2)filter[i]; - } - OUT(dst[dst_index], val); +# if FILTER_SHIFT == 0 + val += (v2 - val) * inv_src_incr * frac; +# else + val += (v2 - val) / c->src_incr * frac; +# endif #endif - } - - 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; + OUT(dst[dst_index], val); - if(compensation_distance){ - compensation_distance -= dst_index; - av_assert1(compensation_distance > 0); + frac += c->dst_incr_mod; + index += c->dst_incr_div; + if (frac >= c->src_incr) { + frac -= c->src_incr; + index++; } + sample_index += index >> c->phase_shift; + index &= c->phase_mask; } 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; + return sample_index; } -#undef COMMON_CORE -#undef LINEAR_CORE #undef RENAME #undef FILTER_SHIFT #undef DELEM diff --git a/chromium/third_party/ffmpeg/libswresample/soxr_resample.c b/chromium/third_party/ffmpeg/libswresample/soxr_resample.c index 4c000db0ca7..064451df452 100644 --- a/chromium/third_party/ffmpeg/libswresample/soxr_resample.c +++ b/chromium/third_party/ffmpeg/libswresample/soxr_resample.c @@ -87,7 +87,14 @@ static int64_t get_delay(struct SwrContext *s, int64_t base){ return (int64_t)(delay_s * base + .5); } +static int invert_initial_buffer(struct ResampleContext *c, AudioData *dst, const AudioData *src, + int in_count, int *out_idx, int *out_sz) +{ + return 0; +} + struct Resampler const soxr_resampler={ create, destroy, process, flush, NULL /* set_compensation */, get_delay, + invert_initial_buffer, }; diff --git a/chromium/third_party/ffmpeg/libswresample/swresample-test.c b/chromium/third_party/ffmpeg/libswresample/swresample-test.c index 379d385315a..c0162cd6463 100644 --- a/chromium/third_party/ffmpeg/libswresample/swresample-test.c +++ b/chromium/third_party/ffmpeg/libswresample/swresample-test.c @@ -31,6 +31,8 @@ #define SAMPLES 1000 +#define SWR_CH_MAX 32 + #define ASSERT_LEVEL 2 static double get(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f){ @@ -164,7 +166,7 @@ static void audiogen(void *data, enum AVSampleFormat sample_fmt, a += M_PI * 1000.0 * 2.0 / sample_rate; } - /* 1 second of varing frequency between 100 and 10000 Hz */ + /* 1 second of varying 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; diff --git a/chromium/third_party/ffmpeg/libswresample/swresample.c b/chromium/third_party/ffmpeg/libswresample/swresample.c index 7076650106f..32bbee33409 100644 --- a/chromium/third_party/ffmpeg/libswresample/swresample.c +++ b/chromium/third_party/ffmpeg/libswresample/swresample.c @@ -26,126 +26,8 @@ #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 , INT_MAX, PARAM}, -{"in_sample_fmt" , "set input sample format" , OFFSET( in_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, -{"osf" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, -{"out_sample_fmt" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, -{"tsf" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, -{"internal_sample_fmt" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, 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); @@ -170,20 +52,6 @@ int swr_set_channel_mapping(struct SwrContext *s, const int *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, @@ -194,23 +62,47 @@ struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, 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); + if (av_opt_set_int(s, "ocl", out_ch_layout, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "osf", out_sample_fmt, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "osr", out_sample_rate, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "icl", in_ch_layout, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "isf", in_sample_fmt, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "isr", in_sample_rate, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "tsf", AV_SAMPLE_FMT_NONE, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> in_ch_layout), 0) < 0) + goto fail; + + if (av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->out_ch_layout), 0) < 0) + goto fail; + av_opt_set_int(s, "uch", 0, 0); return s; +fail: + av_log(s, AV_LOG_ERROR, "Failed to set option\n"); + swr_free(&s); + return NULL; } 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); + if (a->ch_count == 1) + a->planar = 1; } static void free_temp(AudioData *a){ @@ -541,6 +433,12 @@ static int resample(SwrContext *s, AudioData *out_param, int out_count, tmp=out=*out_param; in = *in_param; + border = s->resampler->invert_initial_buffer(s->resample, &s->in_buffer, + &in, in_count, &s->in_buffer_index, &s->in_buffer_count); + if (border == INT_MAX) return 0; + else if (border < 0) return border; + else if (border) { buf_set(&in, &in, border); in_count -= border; s->resample_in_constraint = 0; } + do{ int ret, size, consumed; if(!s->resample_in_constraint && s->in_buffer_count){ diff --git a/chromium/third_party/ffmpeg/libswresample/swresample.h b/chromium/third_party/ffmpeg/libswresample/swresample.h index 017a320c014..37656a667dd 100644 --- a/chromium/third_party/ffmpeg/libswresample/swresample.h +++ b/chromium/third_party/ffmpeg/libswresample/swresample.h @@ -38,10 +38,16 @@ * allocated with swr_alloc() or swr_alloc_set_opts(). It is opaque, so all parameters * must be set with the @ref avoptions API. * + * The first thing you will need to do in order to use lswr is to allocate + * SwrContext. This can be done with swr_alloc() or swr_alloc_set_opts(). If you + * are using the former, you must set options through the @ref avoptions API. + * The latter function provides the same feature, but it allows you to set some + * common options in the same statement. + * * 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): + * matrix). This is using the swr_alloc() function. * @code * SwrContext *swr = swr_alloc(); * av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); @@ -52,10 +58,24 @@ * av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); * @endcode * + * The same job can be done using swr_alloc_set_opts() as well: + * @code + * SwrContext *swr = swr_alloc_set_opts(NULL, // we're allocating a new context + * AV_CH_LAYOUT_STEREO, // out_ch_layout + * AV_SAMPLE_FMT_S16, // out_sample_fmt + * 44100, // out_sample_rate + * AV_CH_LAYOUT_5POINT1, // in_ch_layout + * AV_SAMPLE_FMT_FLTP, // in_sample_fmt + * 48000, // in_sample_rate + * 0, // log_offset + * NULL); // log_ctx + * @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. + * using @ref AVOptions, as described above in the first example; or by using + * swr_alloc_set_opts(), but with the first argument the allocated context. + * You must 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 @@ -65,6 +85,10 @@ * At the end of conversion the resampling buffer can be flushed by calling * swr_convert() with NULL in and 0 in_count. * + * The samples used in the conversion process can be managed with the libavutil + * @ref lavu_sampmanip "samples manipulation" API, including av_samples_alloc() + * function used in the following example. + * * The delay between input and output, can at any time be found by using * swr_get_delay(). * @@ -89,11 +113,15 @@ * * When the conversion is finished, the conversion * context and everything associated with it must be freed with swr_free(). + * A swr_close() function is also available, but it exists mainly for + * compatibility with libavresample, and is not required to be called. + * * There will be no memory leak if the data is not completely flushed before * swr_free(). */ #include <stdint.h> +#include "libavutil/frame.h" #include "libavutil/samplefmt.h" #include "libswresample/version.h" @@ -102,10 +130,18 @@ #define SWR_CH_MAX 32 ///< Maximum number of channels #endif +/** + * @name Option constants + * These constants are used for the @ref avoptions interface for lswr. + * @{ + * + */ + #define SWR_FLAG_RESAMPLE 1 ///< Force resampling even if equal sample rate //TODO use int resample ? //long term TODO can we enable this dynamically? +/** Dithering algorithms */ enum SwrDitherType { SWR_DITHER_NONE = 0, SWR_DITHER_RECTANGULAR, @@ -137,17 +173,33 @@ enum SwrFilterType { SWR_FILTER_TYPE_KAISER, /**< Kaiser Windowed Sinc */ }; +/** + * @} + */ + +/** + * The libswresample context. Unlike libavcodec and libavformat, this structure + * is opaque. This means that if you would like to set options, you must use + * the @ref avoptions API and cannot directly set values to members of the + * structure. + */ typedef struct SwrContext SwrContext; /** - * Get the AVClass for swrContext. It can be used in combination with + * Get the AVClass for SwrContext. It can be used in combination with * AV_OPT_SEARCH_FAKE_OBJ for examining options. * * @see av_opt_find(). + * @return the AVClass of SwrContext */ const AVClass *swr_get_class(void); /** + * @name SwrContext constructor functions + * @{ + */ + +/** * Allocate SwrContext. * * If you use this function you will need to set the parameters (manually or @@ -160,7 +212,12 @@ struct SwrContext *swr_alloc(void); /** * Initialize context after user parameters have been set. + * @note The context must be configured using the AVOption API. * + * @see av_opt_set_int() + * @see av_opt_set_dict() + * + * @param[in,out] s Swr context to initialize * @return AVERROR error code in case of failure. */ int swr_init(struct SwrContext *s); @@ -168,6 +225,8 @@ int swr_init(struct SwrContext *s); /** * Check whether an swr context has been initialized or not. * + * @param[in] s Swr context to check + * @see swr_init() * @return positive if it has been initialized, 0 if not initialized */ int swr_is_initialized(struct SwrContext *s); @@ -179,7 +238,7 @@ int swr_is_initialized(struct SwrContext *s); * 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 s existing Swr context if available, or NULL if not * @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) @@ -198,22 +257,39 @@ struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int log_offset, void *log_ctx); /** + * @} + * + * @name SwrContext destructor functions + * @{ + */ + +/** * Free the given SwrContext and set the pointer to NULL. + * + * @param[in] s a pointer to a pointer to Swr context */ void swr_free(struct SwrContext **s); /** * Closes the context so that swr_is_initialized() returns 0. * - * the context can be brougt back to life by running swr_init(), + * The context can be brought back to life by running swr_init(), * swr_init() can also be used without swr_close(). * This function is mainly provided for simplifying the usecase - * where one tries to support libavresample and libswresample + * where one tries to support libavresample and libswresample. + * + * @param[in,out] s Swr context to be closed */ void swr_close(struct SwrContext *s); /** - * Convert audio. + * @} + * + * @name Core conversion functions + * @{ + */ + +/** Convert audio. * * in and in_count can be set to 0 to flush the last few samples out at the * end. @@ -238,28 +314,54 @@ int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, * 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) + * @li 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 + * @li When automatic timestamp compensation is used, (min_compensation < FLT_MAX) + * in this case the output timestamps will match output sample numbers. + * See ffmpeg-resampler(1) for the two modes of compensation. + * + * @param s[in] initialized Swr context + * @param pts[in] timestamp for the next input sample, INT64_MIN if unknown + * @see swr_set_compensation(), swr_drop_output(), and swr_inject_silence() are + * function used internally for timestamp compensation. * @return the output timestamp for the next output sample */ int64_t swr_next_pts(struct SwrContext *s, int64_t pts); /** - * Activate resampling compensation. + * @} + * + * @name Low-level option setting functions + * These functons provide a means to set low-level options that is not possible + * with the AVOption API. + * @{ + */ + +/** + * Activate resampling compensation ("soft" compensation). This function is + * internally called when needed in swr_next_pts(). + * + * @param[in,out] s allocated Swr context. If it is not initialized, + * or SWR_FLAG_RESAMPLE is not set, swr_init() is + * called with the flag set. + * @param[in] sample_delta delta in PTS per sample + * @param[in] compensation_distance number of samples to compensate for + * @return >= 0 on success, AVERROR error codes if: + * @li @c s is NULL, + * @li @c compensation_distance is less than 0, + * @li @c compensation_distance is 0 but sample_delta is not, + * @li compensation unsupported by resampler, or + * @li swr_init() fails when called. */ 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. + * @param[in,out] s allocated Swr context, not yet initialized + * @param[in] channel_map customized input channel mapping (array of channel + * indexes, -1 for a muted channel) + * @return >= 0 on success, or AVERROR error code in case of failure. */ int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map); @@ -270,17 +372,40 @@ int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map); * @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. + * @return >= 0 on success, or AVERROR error code in case of failure. */ int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride); /** + * @} + * + * @name Sample handling functions + * @{ + */ + +/** * Drops the specified number of output samples. + * + * This function, along with swr_inject_silence(), is called by swr_next_pts() + * if needed for "hard" compensation. + * + * @param s allocated Swr context + * @param count number of samples to be dropped + * + * @return >= 0 on success, or a negative AVERROR code on failure */ int swr_drop_output(struct SwrContext *s, int count); /** * Injects the specified number of silence samples. + * + * This function, along with swr_drop_output(), is called by swr_next_pts() + * if needed for "hard" compensation. + * + * @param s allocated Swr context + * @param count number of samples to be dropped + * + * @return >= 0 on success, or a negative AVERROR code on failure */ int swr_inject_silence(struct SwrContext *s, int count); @@ -296,33 +421,114 @@ int swr_inject_silence(struct SwrContext *s, int count); * 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. + * @param base timebase in which the returned delay will be: + * @li if it's set to 1 the returned delay is in seconds + * @li if it's set to 1000 the returned delay is in milliseconds + * @li if it's set to the input sample rate then the returned + * delay is in input samples + * @li if it's set to the output sample rate then the returned + * delay is in output samples + * @li if it's the least common multiple of in_sample_rate and + * out_sample_rate then an exact rounding-free delay will be + * returned + * @returns the delay in 1 / @c base units. */ int64_t swr_get_delay(struct SwrContext *s, int64_t base); /** - * Return the LIBSWRESAMPLE_VERSION_INT constant. + * @} + * + * @name Configuration accessors + * @{ + */ + +/** + * Return the @ref LIBSWRESAMPLE_VERSION_INT constant. + * + * This is useful to check if the build-time libswresample has the same version + * as the run-time one. + * + * @returns the unsigned int-typed version */ unsigned swresample_version(void); /** * Return the swr build-time configuration. + * + * @returns the build-time @c ./configure flags */ const char *swresample_configuration(void); /** * Return the swr license. + * + * @returns the license of libswresample, determined at build-time */ const char *swresample_license(void); /** * @} + * + * @name AVFrame based API + * @{ + */ + +/** + * Convert the samples in the input AVFrame and write them to the output AVFrame. + * + * Input and output AVFrames must have channel_layout, sample_rate and format set. + * + * If the output AVFrame does not have the data pointers allocated the nb_samples + * field will be set using av_frame_get_buffer() + * is called to allocate the frame. + * + * The output AVFrame can be NULL or have fewer allocated samples than required. + * In this case, any remaining samples not written to the output will be added + * to an internal FIFO buffer, to be returned at the next call to this function + * or to swr_convert(). + * + * If converting sample rate, there may be data remaining in the internal + * resampling delay buffer. swr_get_delay() tells the number of + * remaining samples. To get this data as output, call this function or + * swr_convert() with NULL input. + * + * If the SwrContext configuration does not match the output and + * input AVFrame settings the conversion does not take place and depending on + * which AVFrame is not matching AVERROR_OUTPUT_CHANGED, AVERROR_INPUT_CHANGED + * or the result of a bitwise-OR of them is returned. + * + * @see swr_delay() + * @see swr_convert() + * @see swr_get_delay() + * + * @param swr audio resample context + * @param output output AVFrame + * @param input input AVFrame + * @return 0 on success, AVERROR on failure or nonmatching + * configuration. + */ +int swr_convert_frame(SwrContext *swr, + AVFrame *output, const AVFrame *input); + +/** + * Configure or reconfigure the SwrContext using the information + * provided by the AVFrames. + * + * The original resampling context is reset even on failure. + * The function calls swr_close() internally if the context is open. + * + * @see swr_close(); + * + * @param swr audio resample context + * @param output output AVFrame + * @param input input AVFrame + * @return 0 on success, AVERROR on failure. + */ +int swr_config_frame(SwrContext *swr, const AVFrame *out, const AVFrame *in); + +/** + * @} + * @} */ #endif /* SWRESAMPLE_SWRESAMPLE_H */ diff --git a/chromium/third_party/ffmpeg/libswresample/swresample_frame.c b/chromium/third_party/ffmpeg/libswresample/swresample_frame.c new file mode 100644 index 00000000000..71d3ed711ac --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/swresample_frame.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2014 Luca Barbato <lu_zero@gentoo.org> + * Copyright (c) 2014 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 "swresample_internal.h" +#include "libavutil/frame.h" +#include "libavutil/opt.h" + +int swr_config_frame(SwrContext *s, const AVFrame *out, const AVFrame *in) +{ + swr_close(s); + + if (in) { + if (av_opt_set_int(s, "icl", in->channel_layout, 0) < 0) + goto fail; + if (av_opt_set_int(s, "isf", in->format, 0) < 0) + goto fail; + if (av_opt_set_int(s, "isr", in->sample_rate, 0) < 0) + goto fail; + } + + if (out) { + if (av_opt_set_int(s, "ocl", out->channel_layout, 0) < 0) + goto fail; + if (av_opt_set_int(s, "osf", out->format, 0) < 0) + goto fail; + if (av_opt_set_int(s, "osr", out->sample_rate, 0) < 0) + goto fail; + } + + return 0; +fail: + av_log(s, AV_LOG_ERROR, "Failed to set option\n"); + return AVERROR(EINVAL); +} + +static int config_changed(SwrContext *s, + const AVFrame *out, const AVFrame *in) +{ + int ret = 0; + + if (in) { + if (s->in_ch_layout != in->channel_layout || + s->in_sample_rate != in->sample_rate || + s->in_sample_fmt != in->format) { + ret |= AVERROR_INPUT_CHANGED; + } + } + + if (out) { + if (s->out_ch_layout != out->channel_layout || + s->out_sample_rate != out->sample_rate || + s->out_sample_fmt != out->format) { + ret |= AVERROR_OUTPUT_CHANGED; + } + } + + return ret; +} + +static inline int convert_frame(SwrContext *s, + AVFrame *out, const AVFrame *in) +{ + int ret; + uint8_t **out_data = NULL; + const uint8_t **in_data = NULL; + int out_nb_samples = 0, in_nb_samples = 0; + + if (out) { + out_data = out->extended_data; + out_nb_samples = out->nb_samples; + } + + if (in) { + in_data = (const uint8_t **)in->extended_data; + in_nb_samples = in->nb_samples; + } + + ret = swr_convert(s, out_data, out_nb_samples, in_data, in_nb_samples); + + if (ret < 0) { + if (out) + out->nb_samples = 0; + return ret; + } + + if (out) + out->nb_samples = ret; + + return 0; +} + +static inline int available_samples(AVFrame *out) +{ + int bytes_per_sample = av_get_bytes_per_sample(out->format); + int samples = out->linesize[0] / bytes_per_sample; + + if (av_sample_fmt_is_planar(out->format)) { + return samples; + } else { + int channels = av_get_channel_layout_nb_channels(out->channel_layout); + return samples / channels; + } +} + +int swr_convert_frame(SwrContext *s, + AVFrame *out, const AVFrame *in) +{ + int ret, setup = 0; + + if (!swr_is_initialized(s)) { + if ((ret = swr_config_frame(s, out, in)) < 0) + return ret; + if ((ret = swr_init(s)) < 0) + return ret; + setup = 1; + } else { + // return as is or reconfigure for input changes? + if ((ret = config_changed(s, out, in))) + return ret; + } + + if (out) { + if (!out->linesize[0]) { + out->nb_samples = swr_get_delay(s, s->out_sample_rate) + + in->nb_samples*(int64_t)s->out_sample_rate / s->in_sample_rate + + 3; + if ((ret = av_frame_get_buffer(out, 0)) < 0) { + if (setup) + swr_close(s); + return ret; + } + } else { + if (!out->nb_samples) + out->nb_samples = available_samples(out); + } + } + + return convert_frame(s, out, in); +} + diff --git a/chromium/third_party/ffmpeg/libswresample/swresample_internal.h b/chromium/third_party/ffmpeg/libswresample/swresample_internal.h index ab19f212fee..3761843e3b4 100644 --- a/chromium/third_party/ffmpeg/libswresample/swresample_internal.h +++ b/chromium/third_party/ffmpeg/libswresample/swresample_internal.h @@ -25,6 +25,8 @@ #include "libavutil/channel_layout.h" #include "config.h" +#define SWR_CH_MAX 32 + #define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */ #define NS_TAPS 20 @@ -62,7 +64,7 @@ struct DitherContext { 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 + AudioData temp; ///< temporary storage when writing into the input buffer isn't possible int output_sample_bits; ///< the number of used output bits, needed to scale dither correctly }; @@ -157,6 +159,7 @@ typedef int (* multiple_resample_func)(struct ResampleContext *c, AudioData 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); +typedef int (* invert_initial_buffer_func)(struct ResampleContext *c, AudioData *dst, const AudioData *src, int src_size, int *dst_idx, int *dst_count); struct Resampler { resample_init_func init; @@ -165,15 +168,12 @@ struct Resampler { resample_flush_func flush; set_compensation_func set_compensation; get_delay_func get_delay; + invert_initial_buffer_func invert_initial_buffer; }; 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); @@ -188,6 +188,10 @@ 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_aarch64(struct AudioConvert *ac, + enum AVSampleFormat out_fmt, + enum AVSampleFormat in_fmt, + int channels); void swri_audio_convert_init_arm(struct AudioConvert *ac, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, diff --git a/chromium/third_party/ffmpeg/libswresample/version.h b/chromium/third_party/ffmpeg/libswresample/version.h index 8ca9f59102d..61c76fa2f40 100644 --- a/chromium/third_party/ffmpeg/libswresample/version.h +++ b/chromium/third_party/ffmpeg/libswresample/version.h @@ -28,8 +28,8 @@ #include "libavutil/avutil.h" -#define LIBSWRESAMPLE_VERSION_MAJOR 0 -#define LIBSWRESAMPLE_VERSION_MINOR 19 +#define LIBSWRESAMPLE_VERSION_MAJOR 1 +#define LIBSWRESAMPLE_VERSION_MINOR 1 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/chromium/third_party/ffmpeg/libswresample/x86/Makefile b/chromium/third_party/ffmpeg/libswresample/x86/Makefile index 1d1ab6ead64..be44df56aa6 100644 --- a/chromium/third_party/ffmpeg/libswresample/x86/Makefile +++ b/chromium/third_party/ffmpeg/libswresample/x86/Makefile @@ -1,5 +1,9 @@ -YASM-OBJS += x86/swresample_x86.o\ - x86/audio_convert.o\ +YASM-OBJS += x86/audio_convert.o\ x86/rematrix.o\ + x86/resample.o\ + +OBJS += x86/audio_convert_init.o\ + x86/rematrix_init.o\ + x86/resample_init.o\ OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o diff --git a/chromium/third_party/ffmpeg/libswresample/x86/swresample_x86.c b/chromium/third_party/ffmpeg/libswresample/x86/audio_convert_init.c index 7483ba0bed9..a26cdf6ea6b 100644 --- a/chromium/third_party/ffmpeg/libswresample/x86/swresample_x86.c +++ b/chromium/third_party/ffmpeg/libswresample/x86/audio_convert_init.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/x86/cpu.h" #include "libswresample/swresample_internal.h" #include "libswresample/audioconvert.h" @@ -41,24 +42,24 @@ av_cold void swri_audio_convert_init_x86(struct AudioConvert *ac, //FIXME add memcpy case #define MULTI_CAPS_FUNC(flag, cap) \ - if (mm_flags & flag) {\ + if (EXTERNAL_##flag(mm_flags)) {\ 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) +MULTI_CAPS_FUNC(MMX, mmx) +MULTI_CAPS_FUNC(SSE2, sse2) - if(mm_flags & AV_CPU_FLAG_MMX) { + if(EXTERNAL_MMX(mm_flags)) { 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(EXTERNAL_SSE2(mm_flags)) { 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) @@ -105,7 +106,7 @@ MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE2, sse2) ac->simd_f = ff_unpack_2ch_float_to_int16_a_sse2; } } - if(mm_flags & AV_CPU_FLAG_SSSE3) { + if(EXTERNAL_SSSE3(mm_flags)) { 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; @@ -115,7 +116,7 @@ MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE2, sse2) ac->simd_f = ff_unpack_2ch_int16_to_float_a_ssse3; } } - if(mm_flags & AV_CPU_FLAG_SSE4) { + if(EXTERNAL_SSE4(mm_flags)) { 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; @@ -125,7 +126,7 @@ MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE2, sse2) ac->simd_f = ff_pack_6ch_float_to_int32_a_sse4; } } - if(HAVE_AVX_EXTERNAL && mm_flags & AV_CPU_FLAG_AVX) { + if(EXTERNAL_AVX(mm_flags)) { 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) { @@ -138,63 +139,3 @@ MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE2, sse2) } } } - -#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)); - } -} diff --git a/chromium/third_party/ffmpeg/libswresample/x86/rematrix_init.c b/chromium/third_party/ffmpeg/libswresample/x86/rematrix_init.c new file mode 100644 index 00000000000..e2ee29189f6 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/x86/rematrix_init.c @@ -0,0 +1,83 @@ +/* + * 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 "libavutil/x86/cpu.h" +#include "libswresample/swresample_internal.h" + +#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){ +#if HAVE_YASM + 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(EXTERNAL_MMX(mm_flags)) { + 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(EXTERNAL_SSE2(mm_flags)) { + 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(EXTERNAL_SSE(mm_flags)) { + 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(EXTERNAL_AVX(mm_flags)) { + 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)); + } +#endif +} diff --git a/chromium/third_party/ffmpeg/libswresample/x86/resample.asm b/chromium/third_party/ffmpeg/libswresample/x86/resample.asm new file mode 100644 index 00000000000..a57ff37bb99 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/x86/resample.asm @@ -0,0 +1,600 @@ +;****************************************************************************** +;* Copyright (c) 2012 Michael Niedermayer +;* Copyright (c) 2014 James Almer <jamrial <at> gmail.com> +;* Copyright (c) 2014 Ronald S. Bultje <rsbultje@gmail.com> +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg is distributed in the hope that it will be useful, +;* but WITHOUT ANY WARRANTY; without even the implied warranty of +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +%if ARCH_X86_64 +%define pointer resq +%else +%define pointer resd +%endif + +struc ResampleContext + .av_class: pointer 1 + .filter_bank: pointer 1 + .filter_length: resd 1 + .filter_alloc: resd 1 + .ideal_dst_incr: resd 1 + .dst_incr: resd 1 + .dst_incr_div: resd 1 + .dst_incr_mod: resd 1 + .index: resd 1 + .frac: resd 1 + .src_incr: resd 1 + .compensation_distance: resd 1 + .phase_shift: resd 1 + .phase_mask: resd 1 + + ; there's a few more here but we only care about the first few +endstruc + +SECTION_RODATA + +pf_1: dd 1.0 +pdbl_1: dq 1.0 +pd_0x4000: dd 0x4000 + +SECTION .text + +%macro RESAMPLE_FNS 3-5 ; format [float or int16], bps, log2_bps, float op suffix [s or d], 1.0 constant +; int resample_common_$format(ResampleContext *ctx, $format *dst, +; const $format *src, int size, int update_ctx) +%if ARCH_X86_64 ; unix64 and win64 +cglobal resample_common_%1, 0, 15, 2, ctx, dst, src, phase_shift, index, frac, \ + dst_incr_mod, size, min_filter_count_x4, \ + min_filter_len_x4, dst_incr_div, src_incr, \ + phase_mask, dst_end, filter_bank + + ; use red-zone for variable storage +%define ctx_stackq [rsp-0x8] +%define src_stackq [rsp-0x10] +%if WIN64 +%define update_context_stackd r4m +%else ; unix64 +%define update_context_stackd [rsp-0x14] +%endif + + ; load as many variables in registers as possible; for the rest, store + ; on stack so that we have 'ctx' available as one extra register + mov sized, r3d + mov phase_maskd, [ctxq+ResampleContext.phase_mask] +%if UNIX64 + mov update_context_stackd, r4d +%endif + mov indexd, [ctxq+ResampleContext.index] + mov fracd, [ctxq+ResampleContext.frac] + mov dst_incr_modd, [ctxq+ResampleContext.dst_incr_mod] + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + mov src_incrd, [ctxq+ResampleContext.src_incr] + mov ctx_stackq, ctxq + mov min_filter_len_x4d, [ctxq+ResampleContext.filter_length] + mov dst_incr_divd, [ctxq+ResampleContext.dst_incr_div] + shl min_filter_len_x4d, %3 + lea dst_endq, [dstq+sizeq*%2] + +%if UNIX64 + mov ecx, [ctxq+ResampleContext.phase_shift] + mov edi, [ctxq+ResampleContext.filter_alloc] + + DEFINE_ARGS filter_alloc, dst, src, phase_shift, index, frac, dst_incr_mod, \ + filter, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%elif WIN64 + mov R9d, [ctxq+ResampleContext.filter_alloc] + mov ecx, [ctxq+ResampleContext.phase_shift] + + DEFINE_ARGS phase_shift, dst, src, filter_alloc, index, frac, dst_incr_mod, \ + filter, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%endif + + neg min_filter_len_x4q + sub filter_bankq, min_filter_len_x4q + sub srcq, min_filter_len_x4q + mov src_stackq, srcq +%else ; x86-32 +cglobal resample_common_%1, 1, 7, 2, ctx, phase_shift, dst, frac, \ + index, min_filter_length_x4, filter_bank + + ; push temp variables to stack +%define ctx_stackq r0mp +%define src_stackq r2mp +%define update_context_stackd r4m + + mov dstq, r1mp + mov r3, r3mp + lea r3, [dstq+r3*%2] + PUSH dword [ctxq+ResampleContext.dst_incr_div] + PUSH dword [ctxq+ResampleContext.dst_incr_mod] + PUSH dword [ctxq+ResampleContext.filter_alloc] + PUSH r3 + PUSH dword [ctxq+ResampleContext.phase_mask] + PUSH dword [ctxq+ResampleContext.src_incr] + mov min_filter_length_x4d, [ctxq+ResampleContext.filter_length] + mov indexd, [ctxq+ResampleContext.index] + shl min_filter_length_x4d, %3 + mov fracd, [ctxq+ResampleContext.frac] + neg min_filter_length_x4q + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + sub r2mp, min_filter_length_x4q + sub filter_bankq, min_filter_length_x4q + PUSH min_filter_length_x4q + PUSH filter_bankq + mov phase_shiftd, [ctxq+ResampleContext.phase_shift] + + DEFINE_ARGS src, phase_shift, dst, frac, index, min_filter_count_x4, filter + +%define filter_bankq dword [rsp+0x0] +%define min_filter_length_x4q dword [rsp+0x4] +%define src_incrd dword [rsp+0x8] +%define phase_maskd dword [rsp+0xc] +%define dst_endq dword [rsp+0x10] +%define filter_allocd dword [rsp+0x14] +%define dst_incr_modd dword [rsp+0x18] +%define dst_incr_divd dword [rsp+0x1c] + + mov srcq, r2mp +%endif + +.loop: + mov filterd, filter_allocd + imul filterd, indexd +%if ARCH_X86_64 + mov min_filter_count_x4q, min_filter_len_x4q + lea filterq, [filter_bankq+filterq*%2] +%else ; x86-32 + mov min_filter_count_x4q, filter_bankq + lea filterq, [min_filter_count_x4q+filterq*%2] + mov min_filter_count_x4q, min_filter_length_x4q +%endif +%ifidn %1, int16 + movd m0, [pd_0x4000] +%else ; float/double + xorps m0, m0, m0 +%endif + + align 16 +.inner_loop: + movu m1, [srcq+min_filter_count_x4q*1] +%ifidn %1, int16 + PMADCSWD m0, m1, [filterq+min_filter_count_x4q*1], m0, m1 +%else ; float/double +%if cpuflag(fma4) || cpuflag(fma3) + fmaddp%4 m0, m1, [filterq+min_filter_count_x4q*1], m0 +%else + mulp%4 m1, m1, [filterq+min_filter_count_x4q*1] + addp%4 m0, m0, m1 +%endif ; cpuflag +%endif + add min_filter_count_x4q, mmsize + js .inner_loop + +%ifidn %1, int16 + HADDD m0, m1 + psrad m0, 15 + add fracd, dst_incr_modd + packssdw m0, m0 + add indexd, dst_incr_divd + movd [dstq], m0 +%else ; float/double + ; horizontal sum & store +%if mmsize == 32 + vextractf128 xm1, m0, 0x1 + addps xm0, xm1 +%endif + movhlps xm1, xm0 +%ifidn %1, float + addps xm0, xm1 + shufps xm1, xm0, xm0, q0001 +%endif + add fracd, dst_incr_modd + addp%4 xm0, xm1 + add indexd, dst_incr_divd + movs%4 [dstq], xm0 +%endif + cmp fracd, src_incrd + jl .skip + sub fracd, src_incrd + inc indexd + +%if UNIX64 + DEFINE_ARGS filter_alloc, dst, src, phase_shift, index, frac, dst_incr_mod, \ + index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%elif WIN64 + DEFINE_ARGS phase_shift, dst, src, filter_alloc, index, frac, dst_incr_mod, \ + index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%else ; x86-32 + DEFINE_ARGS src, phase_shift, dst, frac, index, index_incr +%endif + +.skip: + mov index_incrd, indexd + add dstq, %2 + and indexd, phase_maskd + sar index_incrd, phase_shiftb + lea srcq, [srcq+index_incrq*%2] + cmp dstq, dst_endq + jne .loop + +%if ARCH_X86_64 + DEFINE_ARGS ctx, dst, src, phase_shift, index, frac +%else ; x86-32 + DEFINE_ARGS src, ctx, update_context, frac, index +%endif + + cmp dword update_context_stackd, 0 + jz .skip_store + ; strictly speaking, the function should always return the consumed + ; number of bytes; however, we only use the value if update_context + ; is true, so let's just leave it uninitialized otherwise + mov ctxq, ctx_stackq + movifnidn rax, srcq + mov [ctxq+ResampleContext.frac ], fracd + sub rax, src_stackq + mov [ctxq+ResampleContext.index], indexd + shr rax, %3 + +.skip_store: +%if ARCH_X86_32 + ADD rsp, 0x20 +%endif + RET + +; int resample_linear_$format(ResampleContext *ctx, float *dst, +; const float *src, int size, int update_ctx) +%if ARCH_X86_64 ; unix64 and win64 +%if UNIX64 +cglobal resample_linear_%1, 0, 15, 5, ctx, dst, phase_mask, phase_shift, index, frac, \ + size, dst_incr_mod, min_filter_count_x4, \ + min_filter_len_x4, dst_incr_div, src_incr, \ + src, dst_end, filter_bank + + mov srcq, r2mp +%else ; win64 +cglobal resample_linear_%1, 0, 15, 5, ctx, phase_mask, src, phase_shift, index, frac, \ + size, dst_incr_mod, min_filter_count_x4, \ + min_filter_len_x4, dst_incr_div, src_incr, \ + dst, dst_end, filter_bank + + mov dstq, r1mp +%endif + + ; use red-zone for variable storage +%define ctx_stackq [rsp-0x8] +%define src_stackq [rsp-0x10] +%define phase_mask_stackd [rsp-0x14] +%if WIN64 +%define update_context_stackd r4m +%else ; unix64 +%define update_context_stackd [rsp-0x18] +%endif + + ; load as many variables in registers as possible; for the rest, store + ; on stack so that we have 'ctx' available as one extra register + mov sized, r3d + mov phase_maskd, [ctxq+ResampleContext.phase_mask] +%if UNIX64 + mov update_context_stackd, r4d +%endif + mov indexd, [ctxq+ResampleContext.index] + mov fracd, [ctxq+ResampleContext.frac] + mov dst_incr_modd, [ctxq+ResampleContext.dst_incr_mod] + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + mov src_incrd, [ctxq+ResampleContext.src_incr] + mov ctx_stackq, ctxq + mov phase_mask_stackd, phase_maskd + mov min_filter_len_x4d, [ctxq+ResampleContext.filter_length] +%ifidn %1, int16 + movd m4, [pd_0x4000] +%else ; float/double + cvtsi2s%4 xm0, src_incrd + movs%4 xm4, [%5] + divs%4 xm4, xm0 +%endif + mov dst_incr_divd, [ctxq+ResampleContext.dst_incr_div] + shl min_filter_len_x4d, %3 + lea dst_endq, [dstq+sizeq*%2] + +%if UNIX64 + mov ecx, [ctxq+ResampleContext.phase_shift] + mov edi, [ctxq+ResampleContext.filter_alloc] + + DEFINE_ARGS filter_alloc, dst, filter2, phase_shift, index, frac, filter1, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, src, dst_end, filter_bank +%elif WIN64 + mov R9d, [ctxq+ResampleContext.filter_alloc] + mov ecx, [ctxq+ResampleContext.phase_shift] + + DEFINE_ARGS phase_shift, filter2, src, filter_alloc, index, frac, filter1, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, dst, dst_end, filter_bank +%endif + + neg min_filter_len_x4q + sub filter_bankq, min_filter_len_x4q + sub srcq, min_filter_len_x4q + mov src_stackq, srcq +%else ; x86-32 +cglobal resample_linear_%1, 1, 7, 5, ctx, min_filter_length_x4, filter2, \ + frac, index, dst, filter_bank + + ; push temp variables to stack +%define ctx_stackq r0mp +%define src_stackq r2mp +%define update_context_stackd r4m + + mov dstq, r1mp + mov r3, r3mp + lea r3, [dstq+r3*%2] + PUSH dword [ctxq+ResampleContext.dst_incr_div] + PUSH r3 + mov r3, dword [ctxq+ResampleContext.filter_alloc] + PUSH dword [ctxq+ResampleContext.dst_incr_mod] + PUSH r3 + shl r3, %3 + PUSH r3 + mov r3, dword [ctxq+ResampleContext.src_incr] + PUSH dword [ctxq+ResampleContext.phase_mask] + PUSH r3d +%ifidn %1, int16 + movd m4, [pd_0x4000] +%else ; float/double + cvtsi2s%4 xm0, r3d + movs%4 xm4, [%5] + divs%4 xm4, xm0 +%endif + mov min_filter_length_x4d, [ctxq+ResampleContext.filter_length] + mov indexd, [ctxq+ResampleContext.index] + shl min_filter_length_x4d, %3 + mov fracd, [ctxq+ResampleContext.frac] + neg min_filter_length_x4q + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + sub r2mp, min_filter_length_x4q + sub filter_bankq, min_filter_length_x4q + PUSH min_filter_length_x4q + PUSH filter_bankq + PUSH dword [ctxq+ResampleContext.phase_shift] + + DEFINE_ARGS filter1, min_filter_count_x4, filter2, frac, index, dst, src + +%define phase_shift_stackd dword [rsp+0x0] +%define filter_bankq dword [rsp+0x4] +%define min_filter_length_x4q dword [rsp+0x8] +%define src_incrd dword [rsp+0xc] +%define phase_mask_stackd dword [rsp+0x10] +%define filter_alloc_x4q dword [rsp+0x14] +%define filter_allocd dword [rsp+0x18] +%define dst_incr_modd dword [rsp+0x1c] +%define dst_endq dword [rsp+0x20] +%define dst_incr_divd dword [rsp+0x24] + + mov srcq, r2mp +%endif + +.loop: + mov filter1d, filter_allocd + imul filter1d, indexd +%if ARCH_X86_64 + mov min_filter_count_x4q, min_filter_len_x4q + lea filter1q, [filter_bankq+filter1q*%2] + lea filter2q, [filter1q+filter_allocq*%2] +%else ; x86-32 + mov min_filter_count_x4q, filter_bankq + lea filter1q, [min_filter_count_x4q+filter1q*%2] + mov min_filter_count_x4q, min_filter_length_x4q + mov filter2q, filter1q + add filter2q, filter_alloc_x4q +%endif +%ifidn %1, int16 + mova m0, m4 + mova m2, m4 +%else ; float/double + xorps m0, m0, m0 + xorps m2, m2, m2 +%endif + + align 16 +.inner_loop: + movu m1, [srcq+min_filter_count_x4q*1] +%ifidn %1, int16 +%if cpuflag(xop) + vpmadcswd m2, m1, [filter2q+min_filter_count_x4q*1], m2 + vpmadcswd m0, m1, [filter1q+min_filter_count_x4q*1], m0 +%else + pmaddwd m3, m1, [filter2q+min_filter_count_x4q*1] + pmaddwd m1, [filter1q+min_filter_count_x4q*1] + paddd m2, m3 + paddd m0, m1 +%endif ; cpuflag +%else ; float/double +%if cpuflag(fma4) || cpuflag(fma3) + fmaddp%4 m2, m1, [filter2q+min_filter_count_x4q*1], m2 + fmaddp%4 m0, m1, [filter1q+min_filter_count_x4q*1], m0 +%else + mulp%4 m3, m1, [filter2q+min_filter_count_x4q*1] + mulp%4 m1, m1, [filter1q+min_filter_count_x4q*1] + addp%4 m2, m2, m3 + addp%4 m0, m0, m1 +%endif ; cpuflag +%endif + add min_filter_count_x4q, mmsize + js .inner_loop + +%ifidn %1, int16 +%if mmsize == 16 +%if cpuflag(xop) + vphadddq m2, m2 + vphadddq m0, m0 +%endif + pshufd m3, m2, q0032 + pshufd m1, m0, q0032 + paddd m2, m3 + paddd m0, m1 +%endif +%if notcpuflag(xop) + PSHUFLW m3, m2, q0032 + PSHUFLW m1, m0, q0032 + paddd m2, m3 + paddd m0, m1 +%endif + psubd m2, m0 + ; This is probably a really bad idea on atom and other machines with a + ; long transfer latency between GPRs and XMMs (atom). However, it does + ; make the clip a lot simpler... + movd eax, m2 + add indexd, dst_incr_divd + imul fracd + idiv src_incrd + movd m1, eax + add fracd, dst_incr_modd + paddd m0, m1 + psrad m0, 15 + packssdw m0, m0 + movd [dstq], m0 + + ; note that for imul/idiv, I need to move filter to edx/eax for each: + ; - 32bit: eax=r0[filter1], edx=r2[filter2] + ; - win64: eax=r6[filter1], edx=r1[todo] + ; - unix64: eax=r6[filter1], edx=r2[todo] +%else ; float/double + ; val += (v2 - val) * (FELEML) frac / c->src_incr; +%if mmsize == 32 + vextractf128 xm1, m0, 0x1 + vextractf128 xm3, m2, 0x1 + addps xm0, xm1 + addps xm2, xm3 +%endif + cvtsi2s%4 xm1, fracd + subp%4 xm2, xm0 + mulp%4 xm1, xm4 + shufp%4 xm1, xm1, q0000 +%if cpuflag(fma4) || cpuflag(fma3) + fmaddp%4 xm0, xm2, xm1, xm0 +%else + mulp%4 xm2, xm1 + addp%4 xm0, xm2 +%endif ; cpuflag + + ; horizontal sum & store + movhlps xm1, xm0 +%ifidn %1, float + addps xm0, xm1 + shufps xm1, xm0, xm0, q0001 +%endif + add fracd, dst_incr_modd + addp%4 xm0, xm1 + add indexd, dst_incr_divd + movs%4 [dstq], xm0 +%endif + cmp fracd, src_incrd + jl .skip + sub fracd, src_incrd + inc indexd + +%if UNIX64 + DEFINE_ARGS filter_alloc, dst, filter2, phase_shift, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, src, dst_end, filter_bank +%elif WIN64 + DEFINE_ARGS phase_shift, filter2, src, filter_alloc, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, dst, dst_end, filter_bank +%else ; x86-32 + DEFINE_ARGS filter1, phase_shift, index_incr, frac, index, dst, src +%endif + +.skip: +%if ARCH_X86_32 + mov phase_shiftd, phase_shift_stackd +%endif + mov index_incrd, indexd + add dstq, %2 + and indexd, phase_mask_stackd + sar index_incrd, phase_shiftb + lea srcq, [srcq+index_incrq*%2] + cmp dstq, dst_endq + jne .loop + +%if UNIX64 + DEFINE_ARGS ctx, dst, filter2, phase_shift, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, src, dst_end, filter_bank +%elif WIN64 + DEFINE_ARGS ctx, filter2, src, phase_shift, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, dst, dst_end, filter_bank +%else ; x86-32 + DEFINE_ARGS filter1, ctx, update_context, frac, index, dst, src +%endif + + cmp dword update_context_stackd, 0 + jz .skip_store + ; strictly speaking, the function should always return the consumed + ; number of bytes; however, we only use the value if update_context + ; is true, so let's just leave it uninitialized otherwise + mov ctxq, ctx_stackq + movifnidn rax, srcq + mov [ctxq+ResampleContext.frac ], fracd + sub rax, src_stackq + mov [ctxq+ResampleContext.index], indexd + shr rax, %3 + +.skip_store: +%if ARCH_X86_32 + ADD rsp, 0x28 +%endif + RET +%endmacro + +INIT_XMM sse +RESAMPLE_FNS float, 4, 2, s, pf_1 + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +RESAMPLE_FNS float, 4, 2, s, pf_1 +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +RESAMPLE_FNS float, 4, 2, s, pf_1 +%endif +%if HAVE_FMA4_EXTERNAL +INIT_XMM fma4 +RESAMPLE_FNS float, 4, 2, s, pf_1 +%endif + +%if ARCH_X86_32 +INIT_MMX mmxext +RESAMPLE_FNS int16, 2, 1 +%endif + +INIT_XMM sse2 +RESAMPLE_FNS int16, 2, 1 +%if HAVE_XOP_EXTERNAL +INIT_XMM xop +RESAMPLE_FNS int16, 2, 1 +%endif + +INIT_XMM sse2 +RESAMPLE_FNS double, 8, 3, d, pdbl_1 diff --git a/chromium/third_party/ffmpeg/libswresample/x86/resample_init.c b/chromium/third_party/ffmpeg/libswresample/x86/resample_init.c new file mode 100644 index 00000000000..99f5e140401 --- /dev/null +++ b/chromium/third_party/ffmpeg/libswresample/x86/resample_init.c @@ -0,0 +1,90 @@ +/* + * 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/x86/cpu.h" +#include "libswresample/resample.h" + +#define RESAMPLE_FUNCS(type, opt) \ +int ff_resample_common_##type##_##opt(ResampleContext *c, void *dst, \ + const void *src, int sz, int upd); \ +int ff_resample_linear_##type##_##opt(ResampleContext *c, void *dst, \ + const void *src, int sz, int upd) + +RESAMPLE_FUNCS(int16, mmxext); +RESAMPLE_FUNCS(int16, sse2); +RESAMPLE_FUNCS(int16, xop); +RESAMPLE_FUNCS(float, sse); +RESAMPLE_FUNCS(float, avx); +RESAMPLE_FUNCS(float, fma3); +RESAMPLE_FUNCS(float, fma4); +RESAMPLE_FUNCS(double, sse2); + +void swri_resample_dsp_x86_init(ResampleContext *c) +{ + int av_unused mm_flags = av_get_cpu_flags(); + + switch(c->format){ + case AV_SAMPLE_FMT_S16P: + if (ARCH_X86_32 && EXTERNAL_MMXEXT(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_int16_mmxext + : ff_resample_common_int16_mmxext; + } + if (EXTERNAL_SSE2(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_int16_sse2 + : ff_resample_common_int16_sse2; + } + if (EXTERNAL_XOP(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_int16_xop + : ff_resample_common_int16_xop; + } + break; + case AV_SAMPLE_FMT_FLTP: + if (EXTERNAL_SSE(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_float_sse + : ff_resample_common_float_sse; + } + if (EXTERNAL_AVX(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_float_avx + : ff_resample_common_float_avx; + } + if (EXTERNAL_FMA3(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_float_fma3 + : ff_resample_common_float_fma3; + } + if (EXTERNAL_FMA4(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_float_fma4 + : ff_resample_common_float_fma4; + } + break; + case AV_SAMPLE_FMT_DBLP: + if (EXTERNAL_SSE2(mm_flags)) { + c->dsp.resample = c->linear ? ff_resample_linear_double_sse2 + : ff_resample_common_double_sse2; + } + break; + } +} diff --git a/chromium/third_party/ffmpeg/libswresample/x86/resample_mmx.h b/chromium/third_party/ffmpeg/libswresample/x86/resample_mmx.h deleted file mode 100644 index 2bd48a92955..00000000000 --- a/chromium/third_party/ffmpeg/libswresample/x86/resample_mmx.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * 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_sse2 (struct ResampleContext *c, int16_t *dst, const int16_t *src, int *consumed, int src_size, int dst_size, int update_ctx); -int swri_resample_float_sse (struct ResampleContext *c, float *dst, const float *src, int *consumed, int src_size, int dst_size, int update_ctx); -int swri_resample_double_sse2(struct ResampleContext *c, double *dst, const double *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)\ - NAMED_CONSTRAINTS_ARRAY_ADD(ff_resample_int16_rounder)\ -); - -#define LINEAR_CORE_INT16_MMX2 \ - x86_reg len= -2*c->filter_length;\ -__asm__ volatile(\ - "pxor %%mm0, %%mm0 \n\t"\ - "pxor %%mm2, %%mm2 \n\t"\ - "1: \n\t"\ - "movq (%3, %0), %%mm1 \n\t"\ - "movq %%mm1, %%mm3 \n\t"\ - "pmaddwd (%4, %0), %%mm1 \n\t"\ - "pmaddwd (%5, %0), %%mm3 \n\t"\ - "paddd %%mm1, %%mm0 \n\t"\ - "paddd %%mm3, %%mm2 \n\t"\ - "add $8, %0 \n\t"\ - " js 1b \n\t"\ - "pshufw $0x0E, %%mm0, %%mm1 \n\t"\ - "pshufw $0x0E, %%mm2, %%mm3 \n\t"\ - "paddd %%mm1, %%mm0 \n\t"\ - "paddd %%mm3, %%mm2 \n\t"\ - "movd %%mm0, %1 \n\t"\ - "movd %%mm2, %2 \n\t"\ - : "+r" (len),\ - "=r" (val),\ - "=r" (v2)\ - : "r" (((uint8_t*)(src+sample_index))-len),\ - "r" (((uint8_t*)filter)-len),\ - "r" (((uint8_t*)(filter+c->filter_alloc))-len)\ -); - -#define COMMON_CORE_INT16_SSE2 \ - 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"\ - "pshufd $0x0E, %%xmm0, %%xmm1 \n\t"\ - "paddd %%xmm1, %%xmm0 \n\t"\ - "pshufd $0x01, %%xmm0, %%xmm1 \n\t"\ - "paddd %%xmm1, %%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)\ - NAMED_CONSTRAINTS_ARRAY_ADD(ff_resample_int16_rounder)\ - XMM_CLOBBERS_ONLY("%xmm0", "%xmm1")\ -); - -#define LINEAR_CORE_INT16_SSE2 \ - x86_reg len= -2*c->filter_length;\ -__asm__ volatile(\ - "pxor %%xmm0, %%xmm0 \n\t"\ - "pxor %%xmm2, %%xmm2 \n\t"\ - "1: \n\t"\ - "movdqu (%3, %0), %%xmm1 \n\t"\ - "movdqa %%xmm1, %%xmm3 \n\t"\ - "pmaddwd (%4, %0), %%xmm1 \n\t"\ - "pmaddwd (%5, %0), %%xmm3 \n\t"\ - "paddd %%xmm1, %%xmm0 \n\t"\ - "paddd %%xmm3, %%xmm2 \n\t"\ - "add $16, %0 \n\t"\ - " js 1b \n\t"\ - "pshufd $0x0E, %%xmm0, %%xmm1 \n\t"\ - "pshufd $0x0E, %%xmm2, %%xmm3 \n\t"\ - "paddd %%xmm1, %%xmm0 \n\t"\ - "paddd %%xmm3, %%xmm2 \n\t"\ - "pshufd $0x01, %%xmm0, %%xmm1 \n\t"\ - "pshufd $0x01, %%xmm2, %%xmm3 \n\t"\ - "paddd %%xmm1, %%xmm0 \n\t"\ - "paddd %%xmm3, %%xmm2 \n\t"\ - "movd %%xmm0, %1 \n\t"\ - "movd %%xmm2, %2 \n\t"\ - : "+r" (len),\ - "=r" (val),\ - "=r" (v2)\ - : "r" (((uint8_t*)(src+sample_index))-len),\ - "r" (((uint8_t*)filter)-len),\ - "r" (((uint8_t*)(filter+c->filter_alloc))-len)\ - XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3")\ -); - -#define COMMON_CORE_FLT_SSE \ - x86_reg len= -4*c->filter_length;\ -__asm__ volatile(\ - "xorps %%xmm0, %%xmm0 \n\t"\ - "1: \n\t"\ - "movups (%1, %0), %%xmm1 \n\t"\ - "mulps (%2, %0), %%xmm1 \n\t"\ - "addps %%xmm1, %%xmm0 \n\t"\ - "add $16, %0 \n\t"\ - " js 1b \n\t"\ - "movhlps %%xmm0, %%xmm1 \n\t"\ - "addps %%xmm1, %%xmm0 \n\t"\ - "movss %%xmm0, %%xmm1 \n\t"\ - "shufps $1, %%xmm0, %%xmm0 \n\t"\ - "addps %%xmm1, %%xmm0 \n\t"\ - "movss %%xmm0, (%3) \n\t"\ - : "+r" (len)\ - : "r" (((uint8_t*)(src+sample_index))-len),\ - "r" (((uint8_t*)filter)-len),\ - "r" (dst+dst_index)\ - XMM_CLOBBERS_ONLY("%xmm0", "%xmm1")\ -); - -#define LINEAR_CORE_FLT_SSE \ - x86_reg len= -4*c->filter_length;\ -__asm__ volatile(\ - "xorps %%xmm0, %%xmm0 \n\t"\ - "xorps %%xmm2, %%xmm2 \n\t"\ - "1: \n\t"\ - "movups (%3, %0), %%xmm1 \n\t"\ - "movaps %%xmm1, %%xmm3 \n\t"\ - "mulps (%4, %0), %%xmm1 \n\t"\ - "mulps (%5, %0), %%xmm3 \n\t"\ - "addps %%xmm1, %%xmm0 \n\t"\ - "addps %%xmm3, %%xmm2 \n\t"\ - "add $16, %0 \n\t"\ - " js 1b \n\t"\ - "movhlps %%xmm0, %%xmm1 \n\t"\ - "movhlps %%xmm2, %%xmm3 \n\t"\ - "addps %%xmm1, %%xmm0 \n\t"\ - "addps %%xmm3, %%xmm2 \n\t"\ - "movss %%xmm0, %%xmm1 \n\t"\ - "movss %%xmm2, %%xmm3 \n\t"\ - "shufps $1, %%xmm0, %%xmm0 \n\t"\ - "shufps $1, %%xmm2, %%xmm2 \n\t"\ - "addps %%xmm1, %%xmm0 \n\t"\ - "addps %%xmm3, %%xmm2 \n\t"\ - "movss %%xmm0, %1 \n\t"\ - "movss %%xmm2, %2 \n\t"\ - : "+r" (len),\ - "=m" (val),\ - "=m" (v2)\ - : "r" (((uint8_t*)(src+sample_index))-len),\ - "r" (((uint8_t*)filter)-len),\ - "r" (((uint8_t*)(filter+c->filter_alloc))-len)\ - XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3")\ -); - -#define COMMON_CORE_DBL_SSE2 \ - x86_reg len= -8*c->filter_length;\ -__asm__ volatile(\ - "xorpd %%xmm0, %%xmm0 \n\t"\ - "1: \n\t"\ - "movupd (%1, %0), %%xmm1 \n\t"\ - "mulpd (%2, %0), %%xmm1 \n\t"\ - "addpd %%xmm1, %%xmm0 \n\t"\ - "add $16, %0 \n\t"\ - " js 1b \n\t"\ - "movhlps %%xmm0, %%xmm1 \n\t"\ - "addpd %%xmm1, %%xmm0 \n\t"\ - "movsd %%xmm0, (%3) \n\t"\ - : "+r" (len)\ - : "r" (((uint8_t*)(src+sample_index))-len),\ - "r" (((uint8_t*)filter)-len),\ - "r" (dst+dst_index)\ - XMM_CLOBBERS_ONLY("%xmm0", "%xmm1")\ -); - -#define LINEAR_CORE_DBL_SSE2 \ - x86_reg len= -8*c->filter_length;\ -__asm__ volatile(\ - "xorpd %%xmm0, %%xmm0 \n\t"\ - "xorpd %%xmm2, %%xmm2 \n\t"\ - "1: \n\t"\ - "movupd (%3, %0), %%xmm1 \n\t"\ - "movapd %%xmm1, %%xmm3 \n\t"\ - "mulpd (%4, %0), %%xmm1 \n\t"\ - "mulpd (%5, %0), %%xmm3 \n\t"\ - "addpd %%xmm1, %%xmm0 \n\t"\ - "addpd %%xmm3, %%xmm2 \n\t"\ - "add $16, %0 \n\t"\ - " js 1b \n\t"\ - "movhlps %%xmm0, %%xmm1 \n\t"\ - "movhlps %%xmm2, %%xmm3 \n\t"\ - "addpd %%xmm1, %%xmm0 \n\t"\ - "addpd %%xmm3, %%xmm2 \n\t"\ - "movsd %%xmm0, %1 \n\t"\ - "movsd %%xmm2, %2 \n\t"\ - : "+r" (len),\ - "=m" (val),\ - "=m" (v2)\ - : "r" (((uint8_t*)(src+sample_index))-len),\ - "r" (((uint8_t*)filter)-len),\ - "r" (((uint8_t*)(filter+c->filter_alloc))-len)\ - XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3")\ -); |