[pulseaudio-discuss] [PATCH 10/18] resampler: Replace the big init table with a impl_table

poljar (Damir Jelić) poljarinho at gmail.com
Mon Jul 15 06:48:32 PDT 2013


This gets rid of multiple entries of a implementation in the init table.
---
 src/pulsecore/resampler.c | 192 ++++++++++++++++++++++------------------------
 src/pulsecore/resampler.h |   1 +
 2 files changed, 94 insertions(+), 99 deletions(-)

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 35342af..c297188 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -77,115 +77,117 @@ struct pa_resampler {
     pa_resampler_implementation implementation;
 };
 
-struct trivial { /* data specific to the trivial resampler */
-    unsigned o_counter;
-    unsigned i_counter;
+static int copy_init(pa_resampler *r);
+
+static pa_resampler_implementation copy_impl = {
+    .init = copy_init,
 };
 
-struct peaks{ /* data specific to the peak finder pseudo resampler */
+static int trivial_init(pa_resampler*r);
+static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames);
+static void trivial_update_rates_or_reset(pa_resampler *r);
+
+struct trivial { /* data specific to the trivial resampler */
     unsigned o_counter;
     unsigned i_counter;
-
-    float max_f[PA_CHANNELS_MAX];
-    int16_t max_i[PA_CHANNELS_MAX];
 };
 
-#ifdef HAVE_LIBSAMPLERATE
-struct src{ /* data specific to libsamplerate */
-    SRC_STATE *state;
+static pa_resampler_implementation trivial_impl = {
+    .init = trivial_init,
+    .resample = trivial_resample,
+    .update_rates = trivial_update_rates_or_reset,
+    .reset = trivial_update_rates_or_reset,
 };
-#endif
 
 #ifdef HAVE_SPEEX
+static int speex_init(pa_resampler*r);
+static void speex_free(pa_resampler *r);
+static void speex_update_rates(pa_resampler *r);
+static void speex_reset(pa_resampler *r);
+
 struct speex{ /* data specific to speex */
     SpeexResamplerState* state;
 };
+
+static pa_resampler_implementation speex_impl = {
+    .init = speex_init,
+    .free = speex_free,
+    .update_rates = speex_update_rates,
+    .reset = speex_reset,
+};
 #endif
 
+static int ffmpeg_init(pa_resampler*r);
+static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames);
+static void ffmpeg_free(pa_resampler *r);
+
 struct ffmpeg { /* data specific to ffmpeg */
     struct AVResampleContext *state;
     pa_memchunk buf[PA_CHANNELS_MAX];
 };
 
-static int copy_init(pa_resampler *r);
-static int trivial_init(pa_resampler*r);
-#ifdef HAVE_SPEEX
-static int speex_init(pa_resampler*r);
-#endif
-static int ffmpeg_init(pa_resampler*r);
+static pa_resampler_implementation ffmpeg_impl = {
+    .init = ffmpeg_init,
+    .free = ffmpeg_free,
+    .resample = ffmpeg_resample,
+};
+
 static int peaks_init(pa_resampler*r);
+static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames);
+static void peaks_update_rates_or_reset(pa_resampler *r);
+
+static pa_resampler_implementation peaks_impl = {
+    .init = peaks_init,
+    .resample = peaks_resample,
+    .update_rates = peaks_update_rates_or_reset,
+    .reset = peaks_update_rates_or_reset,
+};
+
+struct peaks{ /* data specific to the peak finder pseudo resampler */
+    unsigned o_counter;
+    unsigned i_counter;
+
+    float max_f[PA_CHANNELS_MAX];
+    int16_t max_i[PA_CHANNELS_MAX];
+};
+
 #ifdef HAVE_LIBSAMPLERATE
 static int libsamplerate_init(pa_resampler*r);
+static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames);
+static void libsamplerate_update_rates(pa_resampler *r);
+static void libsamplerate_reset(pa_resampler *r);
+static void libsamplerate_free(pa_resampler *r);
+
+struct src{ /* data specific to libsamplerate */
+    SRC_STATE *state;
+};
+
+static pa_resampler_implementation libsamplerate_impl = {
+    .init = libsamplerate_init,
+    .free = libsamplerate_free,
+    .resample = libsamplerate_resample,
+    .update_rates = libsamplerate_update_rates,
+    .reset = libsamplerate_reset,
+};
 #endif
 
 static void calc_map_table(pa_resampler *r);
 
-static int (* const init_table[])(pa_resampler*r) = {
+static pa_resampler_implementation *impl_table[] = {
 #ifdef HAVE_LIBSAMPLERATE
-    [PA_RESAMPLER_SRC_SINC_BEST_QUALITY]   = libsamplerate_init,
-    [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init,
-    [PA_RESAMPLER_SRC_SINC_FASTEST]        = libsamplerate_init,
-    [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD]     = libsamplerate_init,
-    [PA_RESAMPLER_SRC_LINEAR]              = libsamplerate_init,
+    [PA_RESAMPLER_SRC_LINEAR] = &libsamplerate_impl,
 #else
-    [PA_RESAMPLER_SRC_SINC_BEST_QUALITY]   = NULL,
-    [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL,
-    [PA_RESAMPLER_SRC_SINC_FASTEST]        = NULL,
-    [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD]     = NULL,
-    [PA_RESAMPLER_SRC_LINEAR]              = NULL,
+    [PA_RESAMPLER_SRC_LINEAR] = NULL,
 #endif
-    [PA_RESAMPLER_TRIVIAL]                 = trivial_init,
+    [PA_RESAMPLER_TRIVIAL] = &trivial_impl,
 #ifdef HAVE_SPEEX
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+0]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+1]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+2]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+3]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+4]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+5]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+6]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+7]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+8]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+9]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+10]     = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+0]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+1]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+2]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+3]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+4]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+5]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+6]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+7]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+8]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+9]      = speex_init,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+10]     = speex_init,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE] = &speex_impl,
 #else
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+0]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+1]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+2]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+3]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+4]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+5]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+6]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+7]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+8]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+9]      = NULL,
-    [PA_RESAMPLER_SPEEX_FLOAT_BASE+10]     = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+0]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+1]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+2]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+3]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+4]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+5]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+6]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+7]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+8]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+9]      = NULL,
-    [PA_RESAMPLER_SPEEX_FIXED_BASE+10]     = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE] = NULL,
 #endif
-    [PA_RESAMPLER_FFMPEG]                  = ffmpeg_init,
-    [PA_RESAMPLER_AUTO]                    = NULL,
-    [PA_RESAMPLER_COPY]                    = copy_init,
-    [PA_RESAMPLER_PEAKS]                   = peaks_init,
+    [PA_RESAMPLER_FFMPEG] = &ffmpeg_impl,
+    [PA_RESAMPLER_COPY] = &copy_impl,
+    [PA_RESAMPLER_PEAKS] = &peaks_impl,
 };
 
 static pa_resample_method_t pa_resampler_fix_method(
@@ -366,6 +368,15 @@ pa_resampler* pa_resampler_new(
     r = pa_xnew0(pa_resampler, 1);
     r->mempool = pool;
     r->method = method;
+    if (method >= PA_RESAMPLER_SPEEX_FIXED_BASE && method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
+        r->implementation = *impl_table[PA_RESAMPLER_SPEEX_FIXED_BASE];
+    else if (method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && method <= PA_RESAMPLER_SPEEX_FLOAT_MAX) {
+        r->implementation = *impl_table[PA_RESAMPLER_SPEEX_FIXED_BASE];
+    } else if (method <= PA_RESAMPLER_SRC_LINEAR)
+        r->implementation = *impl_table[PA_RESAMPLER_SRC_LINEAR];
+    else
+        r->implementation = *impl_table[method];
+
     r->flags = flags;
 
     /* Fill sample specs */
@@ -423,7 +434,7 @@ pa_resampler* pa_resampler_new(
     }
 
     /* initialize implementation */
-    if (init_table[method](r) < 0)
+    if (r->implementation.init(r) < 0)
         goto fail;
 
     return r;
@@ -1419,15 +1430,11 @@ static int libsamplerate_init(pa_resampler *r) {
     pa_assert(r);
 
     libsamplerate_data = pa_xnew(struct src, 1);
+    r->implementation.data = libsamplerate_data;
 
     if (!(libsamplerate_data->state = src_new(r->method, r->o_ss.channels, &err)))
         return -1;
 
-    r->implementation.free = libsamplerate_free;
-    r->implementation.update_rates = libsamplerate_update_rates;
-    r->implementation.resample = libsamplerate_resample;
-    r->implementation.reset = libsamplerate_reset;
-    r->implementation.data = libsamplerate_data;
 
     return 0;
 }
@@ -1520,10 +1527,6 @@ static int speex_init(pa_resampler *r) {
     pa_assert(r);
 
     speex_data = pa_xnew(struct speex, 1);
-
-    r->implementation.free = speex_free;
-    r->implementation.update_rates = speex_update_rates;
-    r->implementation.reset = speex_reset;
     r->implementation.data = speex_data;
 
     if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX) {
@@ -1610,9 +1613,6 @@ static int trivial_init(pa_resampler*r) {
 
     trivial_data = pa_xnew0(struct trivial, 1);
 
-    r->implementation.resample = trivial_resample;
-    r->implementation.update_rates = trivial_update_rates_or_reset;
-    r->implementation.reset = trivial_update_rates_or_reset;
     r->implementation.data = trivial_data;
 
     return 0;
@@ -1735,15 +1735,12 @@ static int peaks_init(pa_resampler*r) {
     pa_assert(r->work_format == PA_SAMPLE_S16NE || r->work_format == PA_SAMPLE_FLOAT32NE);
 
     peaks_data = pa_xnew(struct peaks, 1);
+    r->implementation.data = peaks_data;
+
     peaks_data->o_counter = peaks_data->i_counter = 0;
     memset(peaks_data->max_i, 0, sizeof(peaks_data->max_i));
     memset(peaks_data->max_f, 0, sizeof(peaks_data->max_f));
 
-    r->implementation.resample = peaks_resample;
-    r->implementation.update_rates = peaks_update_rates_or_reset;
-    r->implementation.reset = peaks_update_rates_or_reset;
-    r->implementation.data = peaks_data;
-
     return 0;
 }
 
@@ -1844,6 +1841,7 @@ static int ffmpeg_init(pa_resampler *r) {
     pa_assert(r);
 
     ffmpeg_data = pa_xnew(struct ffmpeg, 1);
+    r->implementation.data = (void *) ffmpeg_data;
 
     /* We could probably implement different quality levels by
      * adjusting the filter parameters here. However, ffmpeg
@@ -1853,10 +1851,6 @@ static int ffmpeg_init(pa_resampler *r) {
     if (!(ffmpeg_data->state = av_resample_init((int) r->o_ss.rate, (int) r->i_ss.rate, 16, 10, 0, 0.8)))
         return -1;
 
-    r->implementation.free = ffmpeg_free;
-    r->implementation.resample = ffmpeg_resample;
-    r->implementation.data = (void *) ffmpeg_data;
-
     for (c = 0; c < PA_ELEMENTSOF(ffmpeg_data->buf); c++)
         pa_memchunk_reset(&ffmpeg_data->buf[c]);
 
diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h
index 7dbafa8..dbe7478 100644
--- a/src/pulsecore/resampler.h
+++ b/src/pulsecore/resampler.h
@@ -31,6 +31,7 @@ typedef struct pa_resampler pa_resampler;
 typedef struct pa_resampler_implementation pa_resampler_implementation;
 
 struct pa_resampler_implementation {
+    int (*init)(pa_resampler *r);
     void (*free)(pa_resampler *r);
     void (*update_rates)(pa_resampler *r);
     void (*resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples);
-- 
1.8.3.2



More information about the pulseaudio-discuss mailing list