[pulseaudio-commits] r1717 - /branches/lennart/src/pulsecore/resampler.c

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Sat Aug 25 15:27:00 PDT 2007


Author: lennart
Date: Sun Aug 26 00:26:59 2007
New Revision: 1717

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1717&root=3Dpulseaudio&vi=
ew=3Drev
Log:
make ffmpeg resampler actually work

Modified:
    branches/lennart/src/pulsecore/resampler.c

Modified: branches/lennart/src/pulsecore/resampler.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
resampler.c?rev=3D1717&root=3Dpulseaudio&r1=3D1716&r2=3D1717&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/lennart/src/pulsecore/resampler.c (original)
+++ branches/lennart/src/pulsecore/resampler.c Sun Aug 26 00:26:59 2007
@@ -80,7 +80,7 @@
 =

     struct { /* data specific to ffmpeg */
         struct AVResampleContext *state;
-        unsigned initial_i_rate, initial_o_rate;
+        pa_memchunk buf[PA_CHANNELS_MAX];
     } ffmpeg;
 };
 =

@@ -848,41 +848,100 @@
 /*** ffmpeg based implementation ***/
 =

 static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, uns=
igned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
-    short *src, *dst;
-    int consumed;
-    int c;
+    unsigned used_frames =3D 0, c;
     =

     pa_assert(r);
     pa_assert(input);
     pa_assert(output);
     pa_assert(out_n_frames);
-    =

-    src =3D (short*) ((uint8_t*) pa_memblock_acquire(input->memblock) + in=
put->index);
-    dst =3D (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + o=
utput->index);
-
-    for (c =3D 0; c < r->o_ss.channels; c++) =

-        *out_n_frames =3D av_resample(r->ffmpeg.state,
-                                    dst + r->w_sz*c,
-                                    src + r->w_sz*c,
-                                    &consumed,
-                                    in_n_frames, *out_n_frames,
-                                    c >=3D r->o_ss.channels-1);
-
-    pa_assert(*out_n_frames > 0);
-    pa_assert(consumed =3D=3D in_n_frames);
-    =

-    pa_memblock_release(input->memblock);
-    pa_memblock_release(output->memblock);
+
+    for (c =3D 0; c < r->o_ss.channels; c++) {
+        unsigned u;
+        pa_memblock *b, *w;
+        int16_t *p, *t, *k, *q, *s;
+        int consumed_frames;
+        unsigned in, l;
+
+        /* Allocate a new block */
+        b =3D pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_f=
rames * sizeof(int16_t));
+        p =3D pa_memblock_acquire(b);
+
+        /* Copy the remaining data into it */
+        l =3D r->ffmpeg.buf[c].length;
+        if (r->ffmpeg.buf[c].memblock) {
+            t =3D (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf=
[c].memblock) + r->ffmpeg.buf[c].index);
+            memcpy(p, t, l);
+            pa_memblock_release(r->ffmpeg.buf[c].memblock);
+            pa_memblock_unref(r->ffmpeg.buf[c].memblock);
+            pa_memchunk_reset(&r->ffmpeg.buf[c]);
+        }
+
+        /* Now append the new data, splitting up channels */
+        t =3D ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock)=
 + input->index)) + c;
+        k =3D (int16_t*) ((uint8_t*) p + l);
+        for (u =3D 0; u < in_n_frames; u++) {
+            *k =3D *t;
+            t +=3D r->o_ss.channels;
+            k ++;
+        }
+        pa_memblock_release(input->memblock);
+
+        /* Calculate the resulting number of frames */
+        in =3D in_n_frames + l / sizeof(int16_t);
+
+        /* Allocate buffer for the result */
+        w =3D pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
+        q =3D pa_memblock_acquire(w);
+
+        /* Now, resample */
+        used_frames =3D av_resample(r->ffmpeg.state,
+                                  q, p,
+                                  &consumed_frames,
+                                  in, *out_n_frames,
+                                  c >=3D (unsigned) r->o_ss.channels-1);
+
+        pa_memblock_release(b);
+
+        /* Now store the remaining samples away */
+        pa_assert(consumed_frames <=3D (int) in);
+        if (consumed_frames < (int) in) {
+            r->ffmpeg.buf[c].memblock =3D b;
+            r->ffmpeg.buf[c].index =3D consumed_frames * sizeof(int16_t);
+            r->ffmpeg.buf[c].length =3D (in - consumed_frames) * sizeof(in=
t16_t);
+        } else
+            pa_memblock_unref(b);
+
+        /* And place the results in the output buffer */
+        s =3D (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) +=
 output->index) + c;
+        for (u =3D 0; u < used_frames; u++) {
+            *s =3D *q;
+            q++;
+            s +=3D r->o_ss.channels;
+        }
+        pa_memblock_release(output->memblock);
+        pa_memblock_release(w);
+        pa_memblock_unref(w);
+    }
+
+    *out_n_frames =3D used_frames;
 }
 =

 static void ffmpeg_free(pa_resampler *r) {
+    unsigned c;
+    =

     pa_assert(r);
     =

     if (r->ffmpeg.state)
         av_resample_close(r->ffmpeg.state);
+
+    for (c =3D 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
+        if (r->ffmpeg.buf[c].memblock)
+            pa_memblock_unref(r->ffmpeg.buf[c].memblock);
 }
 =

 static int ffmpeg_init(pa_resampler *r) {
+    unsigned c;
+    =

     pa_assert(r);
 =

     /* We could probably implement different quality levels by
@@ -896,5 +955,8 @@
     r->impl_free =3D ffmpeg_free;
     r->impl_resample =3D ffmpeg_resample;
 =

+    for (c =3D 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++) =

+        pa_memchunk_reset(&r->ffmpeg.buf[c]);
+
     return 0;
 }




More information about the pulseaudio-commits mailing list