mirror of https://git.ffmpeg.org/ffmpeg.git
swr: handle initial negative sample index outside DSP function.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
d77815eeaa
commit
b785c62681
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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; i<c->filter_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; i<c->filter_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; i<c->filter_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){
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue