summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libswresample/resample.c46
-rw-r--r--libswresample/resample_template.c55
-rw-r--r--libswresample/soxr_resample.c7
-rw-r--r--libswresample/swresample.c6
-rw-r--r--libswresample/swresample_internal.h2
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; 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){
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;