mirror of https://git.ffmpeg.org/ffmpeg.git
lavr: resampling: add filter type and Kaiser window beta to AVOptions
This commit is contained in:
parent
8ca08066fc
commit
372647aed0
|
@ -45,6 +45,13 @@ enum AVMixCoeffType {
|
||||||
AV_MIX_COEFF_TYPE_NB, /** Number of coeff types. Not part of ABI */
|
AV_MIX_COEFF_TYPE_NB, /** Number of coeff types. Not part of ABI */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Resampling Filter Types */
|
||||||
|
enum AVResampleFilterType {
|
||||||
|
AV_RESAMPLE_FILTER_TYPE_CUBIC, /**< Cubic */
|
||||||
|
AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL, /**< Blackman Nuttall Windowed Sinc */
|
||||||
|
AV_RESAMPLE_FILTER_TYPE_KAISER, /**< Kaiser Windowed Sinc */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the LIBAVRESAMPLE_VERSION_INT constant.
|
* Return the LIBAVRESAMPLE_VERSION_INT constant.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -50,6 +50,8 @@ struct AVAudioResampleContext {
|
||||||
int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */
|
int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */
|
||||||
int linear_interp; /**< if 1 then the resampling FIR filter will be linearly interpolated */
|
int linear_interp; /**< if 1 then the resampling FIR filter will be linearly interpolated */
|
||||||
double cutoff; /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
|
double cutoff; /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
|
||||||
|
enum AVResampleFilterType filter_type; /**< resampling filter type */
|
||||||
|
int kaiser_beta; /**< beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
|
||||||
|
|
||||||
int in_channels; /**< number of input channels */
|
int in_channels; /**< number of input channels */
|
||||||
int out_channels; /**< number of output channels */
|
int out_channels; /**< number of output channels */
|
||||||
|
|
|
@ -56,6 +56,11 @@ static const AVOption options[] = {
|
||||||
{ "none", "None", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_NONE }, INT_MIN, INT_MAX, 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" },
|
{ "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" },
|
{ "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
|
||||||
|
{ "filter_type", "Filter Type", OFFSET(filter_type), AV_OPT_TYPE_INT, { AV_RESAMPLE_FILTER_TYPE_KAISER }, AV_RESAMPLE_FILTER_TYPE_CUBIC, AV_RESAMPLE_FILTER_TYPE_KAISER, PARAM, "filter_type" },
|
||||||
|
{ "cubic", "Cubic", 0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_CUBIC }, INT_MIN, INT_MAX, PARAM, "filter_type" },
|
||||||
|
{ "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
|
||||||
|
{ "kaiser", "Kaiser Windowed Sinc", 0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_KAISER }, INT_MIN, INT_MAX, PARAM, "filter_type" },
|
||||||
|
{ "kaiser_beta", "Kaiser Window Beta", OFFSET(kaiser_beta), AV_OPT_TYPE_INT, { 9 }, 2, 16, PARAM },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#define FELEM float
|
#define FELEM float
|
||||||
#define FELEM2 float
|
#define FELEM2 float
|
||||||
#define FELEML float
|
#define FELEML float
|
||||||
#define WINDOW_TYPE 24
|
|
||||||
#elifdef CONFIG_RESAMPLE_S32
|
#elifdef CONFIG_RESAMPLE_S32
|
||||||
/* s32 template */
|
/* s32 template */
|
||||||
#define FILTER_SHIFT 30
|
#define FILTER_SHIFT 30
|
||||||
|
@ -39,7 +38,6 @@
|
||||||
#define FELEML int64_t
|
#define FELEML int64_t
|
||||||
#define FELEM_MAX INT32_MAX
|
#define FELEM_MAX INT32_MAX
|
||||||
#define FELEM_MIN INT32_MIN
|
#define FELEM_MIN INT32_MIN
|
||||||
#define WINDOW_TYPE 12
|
|
||||||
#else
|
#else
|
||||||
/* s16 template */
|
/* s16 template */
|
||||||
#define FILTER_SHIFT 15
|
#define FILTER_SHIFT 15
|
||||||
|
@ -48,7 +46,6 @@
|
||||||
#define FELEML int64_t
|
#define FELEML int64_t
|
||||||
#define FELEM_MAX INT16_MAX
|
#define FELEM_MAX INT16_MAX
|
||||||
#define FELEM_MIN INT16_MIN
|
#define FELEM_MIN INT16_MIN
|
||||||
#define WINDOW_TYPE 9
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ResampleContext {
|
struct ResampleContext {
|
||||||
|
@ -65,6 +62,8 @@ struct ResampleContext {
|
||||||
int phase_shift;
|
int phase_shift;
|
||||||
int phase_mask;
|
int phase_mask;
|
||||||
int linear;
|
int linear;
|
||||||
|
enum AVResampleFilterType filter_type;
|
||||||
|
int kaiser_beta;
|
||||||
double factor;
|
double factor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,13 +94,13 @@ static double bessel(double x)
|
||||||
* @param tap_count tap count
|
* @param tap_count tap count
|
||||||
* @param phase_count phase count
|
* @param phase_count phase count
|
||||||
* @param scale wanted sum of coefficients for each filter
|
* @param scale wanted sum of coefficients for each filter
|
||||||
* @param type 0->cubic
|
* @param filter_type filter type
|
||||||
* 1->blackman nuttall windowed sinc
|
* @param kaiser_beta kaiser window beta
|
||||||
* 2..16->kaiser windowed sinc beta=2..16
|
|
||||||
* @return 0 on success, negative AVERROR code on failure
|
* @return 0 on success, negative AVERROR code on failure
|
||||||
*/
|
*/
|
||||||
static int build_filter(FELEM *filter, double factor, int tap_count,
|
static int build_filter(FELEM *filter, double factor, int tap_count,
|
||||||
int phase_count, int scale, int type)
|
int phase_count, int scale, int filter_type,
|
||||||
|
int kaiser_beta)
|
||||||
{
|
{
|
||||||
int ph, i;
|
int ph, i;
|
||||||
double x, y, w;
|
double x, y, w;
|
||||||
|
@ -122,23 +121,23 @@ static int build_filter(FELEM *filter, double factor, int tap_count,
|
||||||
x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
|
x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
|
||||||
if (x == 0) y = 1.0;
|
if (x == 0) y = 1.0;
|
||||||
else y = sin(x) / x;
|
else y = sin(x) / x;
|
||||||
switch (type) {
|
switch (filter_type) {
|
||||||
case 0: {
|
case AV_RESAMPLE_FILTER_TYPE_CUBIC: {
|
||||||
const float d = -0.5; //first order derivative = -0.5
|
const float d = -0.5; //first order derivative = -0.5
|
||||||
x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
|
x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
|
||||||
if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * ( -x*x + x*x*x);
|
if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * ( -x*x + x*x*x);
|
||||||
else y = d * (-4 + 8 * x - 5 * x*x + x*x*x);
|
else y = d * (-4 + 8 * x - 5 * x*x + x*x*x);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL:
|
||||||
w = 2.0 * x / (factor * tap_count) + M_PI;
|
w = 2.0 * x / (factor * tap_count) + M_PI;
|
||||||
y *= 0.3635819 - 0.4891775 * cos( w) +
|
y *= 0.3635819 - 0.4891775 * cos( w) +
|
||||||
0.1365995 * cos(2 * w) -
|
0.1365995 * cos(2 * w) -
|
||||||
0.0106411 * cos(3 * w);
|
0.0106411 * cos(3 * w);
|
||||||
break;
|
break;
|
||||||
default:
|
case AV_RESAMPLE_FILTER_TYPE_KAISER:
|
||||||
w = 2.0 * x / (factor * tap_count * M_PI);
|
w = 2.0 * x / (factor * tap_count * M_PI);
|
||||||
y *= bessel(type * sqrt(FFMAX(1 - w * w, 0)));
|
y *= bessel(kaiser_beta * sqrt(FFMAX(1 - w * w, 0)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,13 +185,15 @@ ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
|
||||||
c->linear = avr->linear_interp;
|
c->linear = avr->linear_interp;
|
||||||
c->factor = factor;
|
c->factor = factor;
|
||||||
c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
|
c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
|
||||||
|
c->filter_type = avr->filter_type;
|
||||||
|
c->kaiser_beta = avr->kaiser_beta;
|
||||||
|
|
||||||
c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * sizeof(FELEM));
|
c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * sizeof(FELEM));
|
||||||
if (!c->filter_bank)
|
if (!c->filter_bank)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (build_filter(c->filter_bank, factor, c->filter_length, phase_count,
|
if (build_filter(c->filter_bank, factor, c->filter_length, phase_count,
|
||||||
1 << FILTER_SHIFT, WINDOW_TYPE) < 0)
|
1 << FILTER_SHIFT, c->filter_type, c->kaiser_beta) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
memcpy(&c->filter_bank[c->filter_length * phase_count + 1],
|
memcpy(&c->filter_bank[c->filter_length * phase_count + 1],
|
||||||
|
|
Loading…
Reference in New Issue