mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-23 04:24:35 +02:00
Add Dolby/DPLII downmix support to libswresample
Based on code by John Stebbins <jstebbins.hb@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
2dd2e42951
commit
c5278cb84f
@ -126,6 +126,7 @@ static int auto_matrix(SwrContext *s)
|
|||||||
int64_t unaccounted= s->in_ch_layout & ~s->out_ch_layout;
|
int64_t unaccounted= s->in_ch_layout & ~s->out_ch_layout;
|
||||||
double maxcoef=0;
|
double maxcoef=0;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
const int matrix_encoding = s->matrix_encoding;
|
||||||
|
|
||||||
memset(s->matrix, 0, sizeof(s->matrix));
|
memset(s->matrix, 0, sizeof(s->matrix));
|
||||||
for(i=0; i<64; i++){
|
for(i=0; i<64; i++){
|
||||||
@ -178,8 +179,19 @@ static int auto_matrix(SwrContext *s)
|
|||||||
matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2;
|
matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2;
|
||||||
matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2;
|
matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2;
|
||||||
}else if(s->out_ch_layout & AV_CH_FRONT_LEFT){
|
}else if(s->out_ch_layout & AV_CH_FRONT_LEFT){
|
||||||
matrix[ FRONT_LEFT][BACK_CENTER]+= s->slev*M_SQRT1_2;
|
if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
|
||||||
matrix[FRONT_RIGHT][BACK_CENTER]+= s->slev*M_SQRT1_2;
|
matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
|
||||||
|
if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
|
||||||
|
matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][BACK_CENTER] += s->slev * M_SQRT1_2;
|
||||||
|
} else {
|
||||||
|
matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev;
|
||||||
|
matrix[FRONT_RIGHT][BACK_CENTER] += s->slev;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matrix[ FRONT_LEFT][BACK_CENTER]+= s->slev*M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][BACK_CENTER]+= s->slev*M_SQRT1_2;
|
||||||
|
}
|
||||||
}else if(s->out_ch_layout & AV_CH_FRONT_CENTER){
|
}else if(s->out_ch_layout & AV_CH_FRONT_CENTER){
|
||||||
matrix[ FRONT_CENTER][BACK_CENTER]+= s->slev*M_SQRT1_2;
|
matrix[ FRONT_CENTER][BACK_CENTER]+= s->slev*M_SQRT1_2;
|
||||||
}else
|
}else
|
||||||
@ -198,8 +210,20 @@ static int auto_matrix(SwrContext *s)
|
|||||||
matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
|
matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
|
||||||
}
|
}
|
||||||
}else if(s->out_ch_layout & AV_CH_FRONT_LEFT){
|
}else if(s->out_ch_layout & AV_CH_FRONT_LEFT){
|
||||||
matrix[ FRONT_LEFT][ BACK_LEFT]+= s->slev;
|
if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
|
||||||
matrix[FRONT_RIGHT][BACK_RIGHT]+= s->slev;
|
matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * M_SQRT1_2;
|
||||||
|
} else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
|
||||||
|
matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * SQRT3_2;
|
||||||
|
matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * SQRT3_2;
|
||||||
|
} else {
|
||||||
|
matrix[ FRONT_LEFT][ BACK_LEFT] += s->slev;
|
||||||
|
matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev;
|
||||||
|
}
|
||||||
}else if(s->out_ch_layout & AV_CH_FRONT_CENTER){
|
}else if(s->out_ch_layout & AV_CH_FRONT_CENTER){
|
||||||
matrix[ FRONT_CENTER][BACK_LEFT ]+= s->slev*M_SQRT1_2;
|
matrix[ FRONT_CENTER][BACK_LEFT ]+= s->slev*M_SQRT1_2;
|
||||||
matrix[ FRONT_CENTER][BACK_RIGHT]+= s->slev*M_SQRT1_2;
|
matrix[ FRONT_CENTER][BACK_RIGHT]+= s->slev*M_SQRT1_2;
|
||||||
@ -222,8 +246,20 @@ static int auto_matrix(SwrContext *s)
|
|||||||
matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2;
|
matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2;
|
||||||
matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2;
|
matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2;
|
||||||
}else if(s->out_ch_layout & AV_CH_FRONT_LEFT){
|
}else if(s->out_ch_layout & AV_CH_FRONT_LEFT){
|
||||||
matrix[ FRONT_LEFT][ SIDE_LEFT]+= s->slev;
|
if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
|
||||||
matrix[FRONT_RIGHT][SIDE_RIGHT]+= s->slev;
|
matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * M_SQRT1_2;
|
||||||
|
} else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
|
||||||
|
matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * SQRT3_2;
|
||||||
|
matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
|
||||||
|
matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * SQRT3_2;
|
||||||
|
} else {
|
||||||
|
matrix[ FRONT_LEFT][ SIDE_LEFT] += s->slev;
|
||||||
|
matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev;
|
||||||
|
}
|
||||||
}else if(s->out_ch_layout & AV_CH_FRONT_CENTER){
|
}else if(s->out_ch_layout & AV_CH_FRONT_CENTER){
|
||||||
matrix[ FRONT_CENTER][SIDE_LEFT ]+= s->slev*M_SQRT1_2;
|
matrix[ FRONT_CENTER][SIDE_LEFT ]+= s->slev*M_SQRT1_2;
|
||||||
matrix[ FRONT_CENTER][SIDE_RIGHT]+= s->slev*M_SQRT1_2;
|
matrix[ FRONT_CENTER][SIDE_RIGHT]+= s->slev*M_SQRT1_2;
|
||||||
|
@ -88,6 +88,10 @@ static const AVOption options[]={
|
|||||||
, OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1 }, 0 , INT_MAX , PARAM },
|
, OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1 }, 0 , INT_MAX , PARAM },
|
||||||
{"max_soft_comp" , "Maximum factor by which data is stretched/squeezed to make it match the timestamps."
|
{"max_soft_comp" , "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 },
|
, OFFSET(max_soft_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0 }, INT_MIN, INT_MAX , PARAM },
|
||||||
|
{ "matrix_encoding" , "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", "None", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
|
||||||
|
{ "dolby", "Dolby", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
|
||||||
|
{ "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
|
||||||
{ "filter_type" , "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" },
|
{ "filter_type" , "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" , "Cubic" , 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_CUBIC }, INT_MIN, INT_MAX, PARAM, "filter_type" },
|
{ "cubic" , "Cubic" , 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_CUBIC }, INT_MIN, INT_MAX, PARAM, "filter_type" },
|
||||||
{ "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
|
{ "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#define SWR_INTERNAL_H
|
#define SWR_INTERNAL_H
|
||||||
|
|
||||||
#include "swresample.h"
|
#include "swresample.h"
|
||||||
|
#include "libavutil/audioconvert.h"
|
||||||
|
|
||||||
|
#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
|
||||||
|
|
||||||
typedef void (mix_1_1_func_type)(void *out, const void *in, void *coeffp, int index, int len);
|
typedef void (mix_1_1_func_type)(void *out, const void *in, void *coeffp, int index, int len);
|
||||||
typedef void (mix_2_1_func_type)(void *out, const void *in1, const void *in2, void *coeffp, int index1, int index2, int len);
|
typedef void (mix_2_1_func_type)(void *out, const void *in1, const void *in2, void *coeffp, int index1, int index2, int len);
|
||||||
@ -54,6 +57,7 @@ struct SwrContext {
|
|||||||
float clev; ///< center mixing level
|
float clev; ///< center mixing level
|
||||||
float lfe_mix_level; ///< LFE mixing level
|
float lfe_mix_level; ///< LFE mixing level
|
||||||
float rematrix_volume; ///< rematrixing volume coefficient
|
float rematrix_volume; ///< rematrixing volume coefficient
|
||||||
|
enum AVMatrixEncoding matrix_encoding; /**< matrixed stereo encoding */
|
||||||
const int *channel_map; ///< channel index (or -1 if muted channel) map
|
const int *channel_map; ///< channel index (or -1 if muted channel) map
|
||||||
int used_ch_count; ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count)
|
int used_ch_count; ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count)
|
||||||
enum SwrDitherType dither_method;
|
enum SwrDitherType dither_method;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user