Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-06-18 22:05:32 +0400
committerMichael Niedermayer <michaelni@gmx.at>2012-06-18 22:07:00 +0400
commit82edf6727f0663601351081ca1e4fb20d1752972 (patch)
tree12479c3ec8cedfa0ec4dda38a72023224f2b5b73 /libavresample
parentf87dacb27de93f995cb18f9dcc73581ef8fc157b (diff)
parentf61ce90caa909d131ea6ec205823568a38115529 (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: lavr: add x86-optimized functions for mixing 1-to-2 s16p with flt coeffs lavr: add x86-optimized functions for mixing 1-to-2 fltp with flt coeffs Add Dolby/DPLII downmix support to libavresample vorbisdec: replace div/mod in loop with a counter fate: vorbis: add 5.1 surround test rtpenc: Allow requesting H264 RTP packetization mode 0 configure: Sort the library listings in the help text alphabetically dwt: remove variable-length arrays RTMPT protocol support http: Properly handle chunked transfer-encoding for replies to post data http: Fail reading if the connection has gone away amr: Mark an array const amr: More space cleanup rtpenc: Fix memory leaks in the muxer open function Conflicts: Changelog configure doc/APIchanges libavformat/version.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavresample')
-rw-r--r--libavresample/audio_mix.c3
-rw-r--r--libavresample/audio_mix_matrix.c60
-rw-r--r--libavresample/avresample.h3
-rw-r--r--libavresample/internal.h1
-rw-r--r--libavresample/options.c4
-rw-r--r--libavresample/version.h2
-rw-r--r--libavresample/x86/audio_mix.asm81
-rw-r--r--libavresample/x86/audio_mix_init.c22
8 files changed, 165 insertions, 11 deletions
diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c
index 7ab11b0d4d..93192221cd 100644
--- a/libavresample/audio_mix.c
+++ b/libavresample/audio_mix.c
@@ -320,7 +320,8 @@ int ff_audio_mix_init(AVAudioResampleContext *avr)
avr->center_mix_level,
avr->surround_mix_level,
avr->lfe_mix_level, 1, matrix_dbl,
- avr->in_channels);
+ avr->in_channels,
+ avr->matrix_encoding);
if (ret < 0) {
av_free(matrix_dbl);
return ret;
diff --git a/libavresample/audio_mix_matrix.c b/libavresample/audio_mix_matrix.c
index 6135b02422..f7121c846d 100644
--- a/libavresample/audio_mix_matrix.c
+++ b/libavresample/audio_mix_matrix.c
@@ -54,6 +54,8 @@
#define SURROUND_DIRECT_LEFT 33
#define SURROUND_DIRECT_RIGHT 34
+#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
+
static av_always_inline int even(uint64_t layout)
{
return (!layout || (layout & (layout - 1)));
@@ -83,14 +85,21 @@ static int sane_layout(uint64_t layout)
int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
double center_mix_level, double surround_mix_level,
double lfe_mix_level, int normalize,
- double *matrix_out, int stride)
+ double *matrix_out, int stride,
+ enum AVMatrixEncoding matrix_encoding)
{
int i, j, out_i, out_j;
double matrix[64][64] = {{0}};
- int64_t unaccounted = in_layout & ~out_layout;
+ int64_t unaccounted;
double maxcoef = 0;
int in_channels, out_channels;
+ if ((out_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX) {
+ out_layout = AV_CH_LAYOUT_STEREO;
+ }
+
+ unaccounted = in_layout & ~out_layout;
+
in_channels = av_get_channel_layout_nb_channels( in_layout);
out_channels = av_get_channel_layout_nb_channels(out_layout);
@@ -140,8 +149,19 @@ int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
matrix[SIDE_LEFT ][BACK_CENTER] += M_SQRT1_2;
matrix[SIDE_RIGHT][BACK_CENTER] += M_SQRT1_2;
} else if (out_layout & AV_CH_FRONT_LEFT) {
- matrix[FRONT_LEFT ][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
- matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
+ matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+ if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
+ matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ } else {
+ matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
+ matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
+ }
+ } else {
+ matrix[FRONT_LEFT ][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
+ }
} else if (out_layout & AV_CH_FRONT_CENTER) {
matrix[FRONT_CENTER][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
} else
@@ -163,8 +183,20 @@ int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
matrix[SIDE_RIGHT][BACK_RIGHT] += 1.0;
}
} else if (out_layout & AV_CH_FRONT_LEFT) {
- matrix[FRONT_LEFT ][BACK_LEFT ] += surround_mix_level;
- matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
+ if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
+ matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
+ } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+ matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
+ matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
+ } else {
+ matrix[FRONT_LEFT ][BACK_LEFT ] += surround_mix_level;
+ matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
+ }
} else if (out_layout & AV_CH_FRONT_CENTER) {
matrix[FRONT_CENTER][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
matrix[FRONT_CENTER][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
@@ -187,8 +219,20 @@ int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
matrix[BACK_CENTER][SIDE_LEFT ] += M_SQRT1_2;
matrix[BACK_CENTER][SIDE_RIGHT] += M_SQRT1_2;
} else if (out_layout & AV_CH_FRONT_LEFT) {
- matrix[FRONT_LEFT ][SIDE_LEFT ] += surround_mix_level;
- matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
+ if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
+ matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
+ } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+ matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
+ matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
+ matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
+ } else {
+ matrix[FRONT_LEFT ][SIDE_LEFT ] += surround_mix_level;
+ matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
+ }
} else if (out_layout & AV_CH_FRONT_CENTER) {
matrix[FRONT_CENTER][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
matrix[FRONT_CENTER][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
diff --git a/libavresample/avresample.h b/libavresample/avresample.h
index 65d4d2d6e2..002bec21fb 100644
--- a/libavresample/avresample.h
+++ b/libavresample/avresample.h
@@ -131,12 +131,13 @@ void avresample_free(AVAudioResampleContext **avr);
* the weight of input channel i in output channel o.
* @param stride distance between adjacent input channels in the
* matrix array
+ * @param matrix_encoding matrixed stereo downmix mode (e.g. dplii)
* @return 0 on success, negative AVERROR code on failure
*/
int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
double center_mix_level, double surround_mix_level,
double lfe_mix_level, int normalize, double *matrix,
- int stride);
+ int stride, enum AVMatrixEncoding matrix_encoding);
/**
* Get the current channel mixing matrix.
diff --git a/libavresample/internal.h b/libavresample/internal.h
index 49ea6a668e..fa9499a8ef 100644
--- a/libavresample/internal.h
+++ b/libavresample/internal.h
@@ -70,6 +70,7 @@ struct AVAudioResampleContext {
AudioConvert *ac_out; /**< output sample format conversion context */
ResampleContext *resample; /**< resampling context */
AudioMix *am; /**< channel mixing context */
+ enum AVMatrixEncoding matrix_encoding; /**< matrixed stereo encoding */
};
#endif /* AVRESAMPLE_INTERNAL_H */
diff --git a/libavresample/options.c b/libavresample/options.c
index 5430c4ddf2..a1a0b0ca21 100644
--- a/libavresample/options.c
+++ b/libavresample/options.c
@@ -52,6 +52,10 @@ static const AVOption options[] = {
{ "phase_shift", "Resampling Phase Shift", OFFSET(phase_shift), AV_OPT_TYPE_INT, { 10 }, 0, 30, /* ??? */ PARAM },
{ "linear_interp", "Use Linear Interpolation", OFFSET(linear_interp), AV_OPT_TYPE_INT, { 0 }, 0, 1, PARAM },
{ "cutoff", "Cutoff Frequency Ratio", OFFSET(cutoff), AV_OPT_TYPE_DOUBLE, { 0.8 }, 0.0, 1.0, PARAM },
+ { "matrix_encoding", "Matrixed Stereo Encoding", OFFSET(matrix_encoding), AV_OPT_TYPE_INT, { AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE, AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
+ { "none", "None", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_NONE }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
+ { "dolby", "Dolby", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
+ { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
{ NULL },
};
diff --git a/libavresample/version.h b/libavresample/version.h
index 6211a56352..63f07f5e84 100644
--- a/libavresample/version.h
+++ b/libavresample/version.h
@@ -21,7 +21,7 @@
#define LIBAVRESAMPLE_VERSION_MAJOR 0
#define LIBAVRESAMPLE_VERSION_MINOR 0
-#define LIBAVRESAMPLE_VERSION_MICRO 2
+#define LIBAVRESAMPLE_VERSION_MICRO 3
#define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \
LIBAVRESAMPLE_VERSION_MINOR, \
diff --git a/libavresample/x86/audio_mix.asm b/libavresample/x86/audio_mix.asm
index 8a4cf061cd..4b0434dd6d 100644
--- a/libavresample/x86/audio_mix.asm
+++ b/libavresample/x86/audio_mix.asm
@@ -150,3 +150,84 @@ cglobal mix_2_to_1_s16p_q8, 3,4,6, src, matrix, len, src1
sub lend, mmsize/2
jg .loop
REP_RET
+
+;-----------------------------------------------------------------------------
+; void ff_mix_1_to_2_fltp_flt(float **src, float **matrix, int len,
+; int out_ch, int in_ch);
+;-----------------------------------------------------------------------------
+
+%macro MIX_1_TO_2_FLTP_FLT 0
+cglobal mix_1_to_2_fltp_flt, 3,5,4, src0, matrix0, len, src1, matrix1
+ mov src1q, [src0q+gprsize]
+ mov src0q, [src0q]
+ sub src1q, src0q
+ mov matrix1q, [matrix0q+gprsize]
+ mov matrix0q, [matrix0q]
+ VBROADCASTSS m2, [matrix0q]
+ VBROADCASTSS m3, [matrix1q]
+ ALIGN 16
+.loop:
+ mova m0, [src0q]
+ mulps m1, m0, m3
+ mulps m0, m0, m2
+ mova [src0q ], m0
+ mova [src0q+src1q], m1
+ add src0q, mmsize
+ sub lend, mmsize/4
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse
+MIX_1_TO_2_FLTP_FLT
+%if HAVE_AVX
+INIT_YMM avx
+MIX_1_TO_2_FLTP_FLT
+%endif
+
+;-----------------------------------------------------------------------------
+; void ff_mix_1_to_2_s16p_flt(int16_t **src, float **matrix, int len,
+; int out_ch, int in_ch);
+;-----------------------------------------------------------------------------
+
+%macro MIX_1_TO_2_S16P_FLT 0
+cglobal mix_1_to_2_s16p_flt, 3,5,6, src0, matrix0, len, src1, matrix1
+ mov src1q, [src0q+gprsize]
+ mov src0q, [src0q]
+ sub src1q, src0q
+ mov matrix1q, [matrix0q+gprsize]
+ mov matrix0q, [matrix0q]
+ VBROADCASTSS m4, [matrix0q]
+ VBROADCASTSS m5, [matrix1q]
+ ALIGN 16
+.loop:
+ mova m0, [src0q]
+ S16_TO_S32_SX 0, 2
+ cvtdq2ps m0, m0
+ cvtdq2ps m2, m2
+ mulps m1, m0, m5
+ mulps m0, m0, m4
+ mulps m3, m2, m5
+ mulps m2, m2, m4
+ cvtps2dq m0, m0
+ cvtps2dq m1, m1
+ cvtps2dq m2, m2
+ cvtps2dq m3, m3
+ packssdw m0, m2
+ packssdw m1, m3
+ mova [src0q ], m0
+ mova [src0q+src1q], m1
+ add src0q, mmsize
+ sub lend, mmsize/2
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+MIX_1_TO_2_S16P_FLT
+INIT_XMM sse4
+MIX_1_TO_2_S16P_FLT
+%if HAVE_AVX
+INIT_XMM avx
+MIX_1_TO_2_S16P_FLT
+%endif
diff --git a/libavresample/x86/audio_mix_init.c b/libavresample/x86/audio_mix_init.c
index fa204d6d36..b8f3a90eef 100644
--- a/libavresample/x86/audio_mix_init.c
+++ b/libavresample/x86/audio_mix_init.c
@@ -35,6 +35,18 @@ extern void ff_mix_2_to_1_s16p_flt_sse4(int16_t **src, float **matrix, int len,
extern void ff_mix_2_to_1_s16p_q8_sse2(int16_t **src, int16_t **matrix,
int len, int out_ch, int in_ch);
+extern void ff_mix_1_to_2_fltp_flt_sse(float **src, float **matrix, int len,
+ int out_ch, int in_ch);
+extern void ff_mix_1_to_2_fltp_flt_avx(float **src, float **matrix, int len,
+ int out_ch, int in_ch);
+
+extern void ff_mix_1_to_2_s16p_flt_sse2(int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+extern void ff_mix_1_to_2_s16p_flt_sse4(int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+extern void ff_mix_1_to_2_s16p_flt_avx (int16_t **src, float **matrix, int len,
+ int out_ch, int in_ch);
+
av_cold void ff_audio_mix_init_x86(AudioMix *am)
{
#if HAVE_YASM
@@ -43,20 +55,30 @@ av_cold void ff_audio_mix_init_x86(AudioMix *am)
if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) {
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
2, 1, 16, 8, "SSE", ff_mix_2_to_1_fltp_flt_sse);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 4, "SSE", ff_mix_1_to_2_fltp_flt_sse);
}
if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) {
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_flt_sse2);
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_q8_sse2);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 8, "SSE2", ff_mix_1_to_2_s16p_flt_sse2);
}
if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) {
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
2, 1, 16, 8, "SSE4", ff_mix_2_to_1_s16p_flt_sse4);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 8, "SSE4", ff_mix_1_to_2_s16p_flt_sse4);
}
if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
2, 1, 32, 16, "AVX", ff_mix_2_to_1_fltp_flt_avx);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 32, 8, "AVX", ff_mix_1_to_2_fltp_flt_avx);
+ ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
+ 1, 2, 16, 8, "AVX", ff_mix_1_to_2_s16p_flt_avx);
}
#endif
}