summaryrefslogtreecommitdiff
path: root/libswresample
diff options
context:
space:
mode:
authorMuhammad Faiz <mfcc64@gmail.com>2017-03-08 22:21:34 +0700
committerMuhammad Faiz <mfcc64@gmail.com>2017-03-09 13:09:14 +0700
commit53a5cea478616d2caa1c07aa58b6b911bd80c285 (patch)
tree00ac695c96d411c01361efe29c4f2c344b76300c /libswresample
parent3016e919d4e1d90da98af19ce2a9d4979506eaf3 (diff)
downloadffmpeg-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.c56
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;