[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