This simplifies the code, since we do not have to deal with a possibly
negative source index anymore.

Changes the results of the linear test, since the initial part of the
output now uses the same path as the rest of it, while before it
followed the (index < 0) special case for both linear=0 and linear=1.
---
 libavresample/resample.c          |   46 ++++++++++++++++++++++++++-----------
 libavresample/resample_template.c |   12 ++++------
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/libavresample/resample.c b/libavresample/resample.c
index 6ac33d6..01e2a3a 100644
--- a/libavresample/resample.c
+++ b/libavresample/resample.c
@@ -33,7 +33,7 @@ struct ResampleContext {
     int filter_length;
     int ideal_dst_incr;
     int dst_incr;
-    int index;
+    unsigned int index;
     int frac;
     int src_incr;
     int compensation_distance;
@@ -45,11 +45,13 @@ struct ResampleContext {
     double factor;
     void (*set_filter)(void *filter, double *tab, int phase, int tap_count);
     void (*resample_one)(struct ResampleContext *c, void *dst0,
-                         int dst_index, const void *src0, int src_size,
-                         int index, int frac);
+                         int dst_index, const void *src0,
+                         unsigned int index, int frac);
     void (*resample_nearest)(void *dst0, int dst_index,
-                             const void *src0, int index);
+                             const void *src0, unsigned int index);
     int padding_size;
+    int initial_padding_filled;
+    int initial_padding_samples;
 };
 
 
@@ -220,15 +222,18 @@ ResampleContext 
*ff_audio_resample_init(AVAudioResampleContext *avr)
     c->ideal_dst_incr = c->dst_incr;
 
     c->padding_size   = (c->filter_length - 1) / 2;
-    c->index = -phase_count * ((c->filter_length - 1) / 2);
+    c->initial_padding_filled = 0;
+    c->index = 0;
     c->frac  = 0;
 
     /* allocate internal buffer */
-    c->buffer = ff_audio_data_alloc(avr->resample_channels, 0,
+    c->buffer = ff_audio_data_alloc(avr->resample_channels, c->padding_size,
                                     avr->internal_sample_fmt,
                                     "resample buffer");
     if (!c->buffer)
         goto error;
+    c->buffer->nb_samples      = c->padding_size;
+    c->initial_padding_samples = c->padding_size;
 
     av_log(avr, AV_LOG_DEBUG, "resample: %s from %d Hz to %d Hz\n",
            av_get_sample_fmt_name(avr->internal_sample_fmt),
@@ -342,7 +347,7 @@ static int resample(ResampleContext *c, void *dst, const 
void *src,
                     int nearest_neighbour)
 {
     int dst_index;
-    int index         = c->index;
+    unsigned int index = c->index;
     int frac          = c->frac;
     int dst_incr_frac = c->dst_incr % c->src_incr;
     int dst_incr      = c->dst_incr / c->src_incr;
@@ -352,7 +357,7 @@ static int resample(ResampleContext *c, void *dst, const 
void *src,
         return AVERROR(EINVAL);
 
     if (nearest_neighbour) {
-        int64_t index2 = ((int64_t)index) << 32;
+        uint64_t index2 = ((uint64_t)index) << 32;
         int64_t incr   = (1LL << 32) * c->dst_incr / c->src_incr;
         dst_size       = FFMIN(dst_size,
                                (src_size-1-index) * (int64_t)c->src_incr /
@@ -373,12 +378,11 @@ static int resample(ResampleContext *c, void *dst, const 
void *src,
         for (dst_index = 0; dst_index < dst_size; dst_index++) {
             int sample_index = index >> c->phase_shift;
 
-            if (sample_index + c->filter_length > src_size ||
-                -sample_index >= src_size)
+            if (sample_index + c->filter_length > src_size)
                 break;
 
             if (dst)
-                c->resample_one(c, dst, dst_index, src, src_size, index, frac);
+                c->resample_one(c, dst, dst_index, src, index, frac);
 
             frac  += dst_incr_frac;
             index += dst_incr;
@@ -394,11 +398,10 @@ static int resample(ResampleContext *c, void *dst, const 
void *src,
         }
     }
     if (consumed)
-        *consumed = FFMAX(index, 0) >> c->phase_shift;
+        *consumed = index >> c->phase_shift;
 
     if (update_ctx) {
-        if (index >= 0)
-            index &= c->phase_mask;
+        index &= c->phase_mask;
 
         if (compensation_distance) {
             compensation_distance -= dst_index;
@@ -437,6 +440,20 @@ int ff_audio_resample(ResampleContext *c, AudioData *dst, 
AudioData *src)
         /* TODO: pad buffer to flush completely */
     }
 
+    if (!c->initial_padding_filled) {
+        int bps = av_get_bytes_per_sample(c->avr->internal_sample_fmt);
+        int i;
+
+        if (c->buffer->nb_samples < 2 * c->padding_size)
+            return 0;
+
+        for (i = 0; i < c->padding_size; i++)
+            for (ch = 0; ch < c->buffer->channels; ch++)
+                memcpy(c->buffer->data[ch] + bps * i,
+                       c->buffer->data[ch] + bps * (2 * c->padding_size - i), 
bps);
+        c->initial_padding_filled = 1;
+    }
+
     /* calculate output size and reallocate output buffer if needed */
     /* TODO: try to calculate this without the dummy resample() run */
     if (!dst->read_only && dst->allow_realloc) {
@@ -464,6 +481,7 @@ int ff_audio_resample(ResampleContext *c, AudioData *dst, 
AudioData *src)
 
     /* drain consumed samples from the internal buffer */
     ff_audio_data_drain(c->buffer, consumed);
+    c->initial_padding_samples = FFMAX(c->initial_padding_samples - consumed, 
0);
 
     av_dlog(c->avr, "resampled %d in + %d leftover to %d out + %d leftover\n",
             in_samples, in_leftover, out_samples, c->buffer->nb_samples);
diff --git a/libavresample/resample_template.c 
b/libavresample/resample_template.c
index 618981a..36d97e8 100644
--- a/libavresample/resample_template.c
+++ b/libavresample/resample_template.c
@@ -48,7 +48,7 @@
 #define DBL_TO_FELEM(d, v) d = av_clip_int16(lrint(v * (1 << 15)))
 #endif
 
-static void SET_TYPE(resample_nearest)(void *dst0, int dst_index, const void 
*src0, int index)
+static void SET_TYPE(resample_nearest)(void *dst0, int dst_index, const void 
*src0, unsigned int index)
 {
     FELEM *dst = dst0;
     const FELEM *src = src0;
@@ -57,21 +57,17 @@ static void SET_TYPE(resample_nearest)(void *dst0, int 
dst_index, const void *sr
 
 static void SET_TYPE(resample_one)(ResampleContext *c,
                                    void *dst0, int dst_index, const void *src0,
-                                   int src_size, int index, int frac)
+                                   unsigned int index, int frac)
 {
     FELEM *dst = dst0;
     const FELEM *src = src0;
     int i;
-    int sample_index = index >> c->phase_shift;
+    unsigned int sample_index = index >> c->phase_shift;
     FELEM2 val = 0;
     FELEM *filter = ((FELEM *)c->filter_bank) +
                     c->filter_length * (index & c->phase_mask);
 
-    if (sample_index < 0) {
-        for (i = 0; i < c->filter_length; i++)
-            val += src[FFABS(sample_index + i) % src_size] *
-                   (FELEM2)filter[i];
-    } else if (c->linear) {
+    if (c->linear) {
         FELEM2 v2 = 0;
         for (i = 0; i < c->filter_length; i++) {
             val += src[sample_index + i] * (FELEM2)filter[i];
-- 
1.7.10.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to