From b785c62681a0a5a330b065e0754d27a313c44c8e Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 13 Jun 2014 19:06:30 -0400 Subject: [PATCH] swr: handle initial negative sample index outside DSP function. Signed-off-by: Michael Niedermayer --- libswresample/resample.c | 46 ++++++++++++++++++++++++ libswresample/resample_template.c | 55 +++-------------------------- libswresample/soxr_resample.c | 7 ++++ libswresample/swresample.c | 6 ++++ libswresample/swresample_internal.h | 2 ++ 5 files changed, 66 insertions(+), 50 deletions(-) diff --git a/libswresample/resample.c b/libswresample/resample.c index af76aa2483..4b456c27cd 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -407,6 +407,51 @@ static int resample_flush(struct SwrContext *s) { return 0; } +// in fact the whole handle multiple ridiculously small buffers might need more thinking... +static int invert_initial_buffer(ResampleContext *c, AudioData *dst, const AudioData *src, + int in_count, int *out_idx, int *out_sz) +{ + int n, ch, num = FFMIN(in_count + *out_sz, c->filter_length + 1), res; + + if (c->index >= 0) + return 0; + + if ((res = swri_realloc_audio(dst, c->filter_length * 2 + 1)) < 0) + return res; + + // copy + for (n = *out_sz; n < num; n++) { + for (ch = 0; ch < src->ch_count; ch++) { + memcpy(dst->ch[ch] + ((c->filter_length + n) * c->felem_size), + src->ch[ch] + ((n - *out_sz) * c->felem_size), c->felem_size); + } + } + + // if not enough data is in, return and wait for more + if (num < c->filter_length + 1) { + *out_sz = num; + *out_idx = c->filter_length; + return INT_MAX; + } + + // else invert + for (n = 1; n <= c->filter_length; n++) { + for (ch = 0; ch < src->ch_count; ch++) { + memcpy(dst->ch[ch] + ((c->filter_length - n) * c->felem_size), + dst->ch[ch] + ((c->filter_length + n) * c->felem_size), + c->felem_size); + } + } + + res = num - *out_sz; + *out_idx = c->filter_length + (c->index >> c->phase_shift); + *out_sz = 1 + c->filter_length * 2 - *out_idx; + c->index &= c->phase_mask; + assert(res > 0); + + return res; +} + struct Resampler const swri_resampler={ resample_init, resample_free, @@ -414,4 +459,5 @@ struct Resampler const swri_resampler={ resample_flush, set_compensation, get_delay, + invert_initial_buffer, }; diff --git a/libswresample/resample_template.c b/libswresample/resample_template.c index 65bde6e7e0..40def7a69c 100644 --- a/libswresample/resample_template.c +++ b/libswresample/resample_template.c @@ -107,7 +107,10 @@ #endif int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int *consumed, int src_size, int dst_size, int update_ctx){ - int dst_index, i; + int dst_index; +#if !defined(COMMON_CORE) || !defined(LINEAR_CORE) + int i; +#endif int index= c->index; int frac= c->frac; int dst_incr_frac= c->dst_incr % c->src_incr; @@ -133,7 +136,7 @@ int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int av_assert2(index >= 0); *consumed= index; index = 0; - } else if (index >= 0) { + } else { int64_t end_index = (1LL + src_size - c->filter_length) << c->phase_shift; int64_t delta_frac = (end_index - index) * c->src_incr - c->frac; int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr; @@ -195,54 +198,6 @@ int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int } *consumed = sample_index; - } else { - int sample_index = 0; - for(dst_index=0; dst_index < dst_size; dst_index++){ - FELEM *filter; - FELEM2 val=0; - - sample_index += index >> c->phase_shift; - index &= c->phase_mask; - filter = ((FELEM*)c->filter_bank) + c->filter_alloc*index; - - if(sample_index + c->filter_length > src_size || -sample_index >= src_size){ - break; - }else if(sample_index < 0){ - for(i=0; ifilter_length; i++) - val += src[FFABS(sample_index + i)] * (FELEM2)filter[i]; - OUT(dst[dst_index], val); - }else if(c->linear){ - FELEM2 v2=0; -#ifdef LINEAR_CORE - LINEAR_CORE -#else - for(i=0; ifilter_length; i++){ - val += src[sample_index + i] * (FELEM2)filter[i]; - v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; - } -#endif - val+=(v2-val)*(FELEML)frac / c->src_incr; - OUT(dst[dst_index], val); - }else{ -#ifdef COMMON_CORE - COMMON_CORE -#else - for(i=0; ifilter_length; i++){ - val += src[sample_index + i] * (FELEM2)filter[i]; - } - OUT(dst[dst_index], val); -#endif - } - - frac += dst_incr_frac; - index += dst_incr; - if(frac >= c->src_incr){ - frac -= c->src_incr; - index++; - } - } - *consumed= FFMAX(sample_index, 0); - index += FFMIN(sample_index, 0) << c->phase_shift; } if(update_ctx){ diff --git a/libswresample/soxr_resample.c b/libswresample/soxr_resample.c index 4c000db0ca..064451df45 100644 --- a/libswresample/soxr_resample.c +++ b/libswresample/soxr_resample.c @@ -87,7 +87,14 @@ static int64_t get_delay(struct SwrContext *s, int64_t base){ return (int64_t)(delay_s * base + .5); } +static int invert_initial_buffer(struct ResampleContext *c, AudioData *dst, const AudioData *src, + int in_count, int *out_idx, int *out_sz) +{ + return 0; +} + struct Resampler const soxr_resampler={ create, destroy, process, flush, NULL /* set_compensation */, get_delay, + invert_initial_buffer, }; diff --git a/libswresample/swresample.c b/libswresample/swresample.c index 7076650106..2d063cd2ce 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -541,6 +541,12 @@ static int resample(SwrContext *s, AudioData *out_param, int out_count, tmp=out=*out_param; in = *in_param; + border = s->resampler->invert_initial_buffer(s->resample, &s->in_buffer, + &in, in_count, &s->in_buffer_index, &s->in_buffer_count); + if (border == INT_MAX) return 0; + else if (border < 0) return border; + else if (border) { buf_set(&in, &in, border); in_count -= border; s->resample_in_constraint = 0; } + do{ int ret, size, consumed; if(!s->resample_in_constraint && s->in_buffer_count){ diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h index ab19f212fe..407bbac5fc 100644 --- a/libswresample/swresample_internal.h +++ b/libswresample/swresample_internal.h @@ -157,6 +157,7 @@ typedef int (* multiple_resample_func)(struct ResampleContext *c, AudioData typedef int (* resample_flush_func)(struct SwrContext *c); typedef int (* set_compensation_func)(struct ResampleContext *c, int sample_delta, int compensation_distance); typedef int64_t (* get_delay_func)(struct SwrContext *s, int64_t base); +typedef int (* invert_initial_buffer_func)(struct ResampleContext *c, AudioData *dst, const AudioData *src, int src_size, int *dst_idx, int *dst_count); struct Resampler { resample_init_func init; @@ -165,6 +166,7 @@ struct Resampler { resample_flush_func flush; set_compensation_func set_compensation; get_delay_func get_delay; + invert_initial_buffer_func invert_initial_buffer; }; extern struct Resampler const swri_resampler;