diff options
author | Muhammad Faiz <mfcc64@gmail.com> | 2017-03-08 22:21:34 +0700 |
---|---|---|
committer | Muhammad Faiz <mfcc64@gmail.com> | 2017-03-09 13:09:14 +0700 |
commit | 53a5cea478616d2caa1c07aa58b6b911bd80c285 (patch) | |
tree | 00ac695c96d411c01361efe29c4f2c344b76300c /libswresample | |
parent | 3016e919d4e1d90da98af19ce2a9d4979506eaf3 (diff) | |
download | ffmpeg-53a5cea478616d2caa1c07aa58b6b911bd80c285.tar.gz |
swresample/resample: do not allow odd filter_length
except filter_length == 1
odd filter_length gives worse frequency response,
even when compared with shorter filter_length
also makes build_filter simpler
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
Diffstat (limited to 'libswresample')
-rw-r--r-- | libswresample/resample.c | 56 |
1 files changed, 18 insertions, 38 deletions
diff --git a/libswresample/resample.c b/libswresample/resample.c index b0d14d1e95..8f3428f512 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -155,6 +155,8 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap if (!tab || !sin_lut) goto fail; + av_assert0(tap_count == 1 || tap_count % 2 == 0); + /* if upsampling, only need to interpolate, no filter */ if (factor > 1.0) factor = 1.0; @@ -165,7 +167,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap } for(ph = 0; ph < ph_nb; ph++) { s = sin_lut[ph]; - for(i=0;i<=tap_count;i++) { + for(i=0;i<tap_count;i++) { x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; if (x == 0) y = 1.0; else if (factor == 1.0) @@ -194,7 +196,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap tab[i] = y; s = -s; - if (!ph && i < tap_count) + if (!ph) norm += y; } @@ -204,55 +206,29 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap for(i=0;i<tap_count;i++) ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm)); if (phase_count % 2) break; - if (tap_count % 2 == 0 || tap_count == 1) { - for (i = 0; i < tap_count; i++) - ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i]; - } - else { - for (i = 1; i <= tap_count; i++) - ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = - av_clip_int16(lrintf(tab[i] * scale / norm)); - } + for (i = 0; i < tap_count; i++) + ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i]; break; case AV_SAMPLE_FMT_S32P: for(i=0;i<tap_count;i++) ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm)); if (phase_count % 2) break; - if (tap_count % 2 == 0 || tap_count == 1) { - for (i = 0; i < tap_count; i++) - ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i]; - } - else { - for (i = 1; i <= tap_count; i++) - ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = - av_clipl_int32(llrint(tab[i] * scale / norm)); - } + for (i = 0; i < tap_count; i++) + ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i]; break; case AV_SAMPLE_FMT_FLTP: for(i=0;i<tap_count;i++) ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm; if (phase_count % 2) break; - if (tap_count % 2 == 0 || tap_count == 1) { - for (i = 0; i < tap_count; i++) - ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i]; - } - else { - for (i = 1; i <= tap_count; i++) - ((float*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / norm; - } + for (i = 0; i < tap_count; i++) + ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i]; break; case AV_SAMPLE_FMT_DBLP: for(i=0;i<tap_count;i++) ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm; if (phase_count % 2) break; - if (tap_count % 2 == 0 || tap_count == 1) { - for (i = 0; i < tap_count; i++) - ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i]; - } - else { - for (i = 1; i <= tap_count; i++) - ((double*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / norm; - } + for (i = 0; i < tap_count; i++) + ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i]; break; } } @@ -308,6 +284,10 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); int phase_count= 1<<phase_shift; int phase_count_compensation = phase_count; + int filter_length = FFMAX((int)ceil(filter_size/factor), 1); + + if (filter_length > 1) + filter_length = FFALIGN(filter_length, 2); if (exact_rational) { int phase_count_exact, phase_count_exact_den; @@ -320,7 +300,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r } if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor - || c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format + || c->filter_length != filter_length || c->format != format || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) { c = av_mallocz(sizeof(*c)); if (!c) @@ -354,7 +334,7 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r c->phase_count = phase_count; c->linear = linear; c->factor = factor; - c->filter_length = FFMAX((int)ceil(filter_size/factor), 1); + c->filter_length = filter_length; c->filter_alloc = FFALIGN(c->filter_length, 8); c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size); c->filter_type = filter_type; |