swr: handle initial negative sample index outside DSP function.
authorRonald S. Bultje <rsbultje@gmail.com>
Fri, 13 Jun 2014 23:06:30 +0000 (19:06 -0400)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 14 Jun 2014 12:36:18 +0000 (14:36 +0200)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libswresample/resample.c
libswresample/resample_template.c
libswresample/soxr_resample.c
libswresample/swresample.c
libswresample/swresample_internal.h

index af76aa2..4b456c2 100644 (file)
@@ -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,
 };
index 65bde6e..40def7a 100644 (file)
 #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){
index 4c000db..064451d 100644 (file)
@@ -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,
 };
 
index 7076650..2d063cd 100644 (file)
@@ -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){
index ab19f21..407bbac 100644 (file)
@@ -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;