From: Stefan Kost Date: Thu, 6 May 2010 05:20:10 +0000 (+0300) Subject: vorbis: have a copy_sample func as a func pointer X-Git-Tag: RELEASE-0.10.30~227 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4e6cb3e91f905a96144cedd1e49b402b01ce121c;p=platform%2Fupstream%2Fgst-plugins-base.git vorbis: have a copy_sample func as a func pointer Make some more variants for copy_sample funcs and use them via function pointer. --- diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c index 1e4b50b..56f7b84 100644 --- a/ext/vorbis/gstvorbisdec.c +++ b/ext/vorbis/gstvorbisdec.c @@ -588,11 +588,18 @@ vorbis_handle_identification_packet (GstVorbisDec * vd) s = gst_caps_get_structure (caps, 0); /* template ensures 16 or 32 */ gst_structure_get_int (s, "width", &width); + + GST_INFO_OBJECT (vd, "using %s with %d channels and %d bit audio depth", + gst_structure_get_name (s), vd->vi.channels, width); } gst_caps_unref (caps); } vd->width = width >> 3; + /* select a copy_samples function, this way we can have specialized versions + * for mono/stereo and avoid the depth switch in tremor case */ + vd->copy_samples = get_copy_sample_func (vd->vi.channels, vd->width); + caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad)); gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate, "channels", G_TYPE_INT, vd->vi.channels, @@ -881,8 +888,8 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet, goto wrong_samples; /* copy samples in buffer */ - copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm, sample_count, - vd->vi.channels, vd->width); + vd->copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm, + sample_count, vd->vi.channels, vd->width); GST_LOG_OBJECT (vd, "setting output size to %d", size); GST_BUFFER_SIZE (out) = size; diff --git a/ext/vorbis/gstvorbisdec.h b/ext/vorbis/gstvorbisdec.h index 65c73ae..0f4b3dd 100644 --- a/ext/vorbis/gstvorbisdec.h +++ b/ext/vorbis/gstvorbisdec.h @@ -75,6 +75,8 @@ struct _GstVorbisDec { GList *pendingevents; GstTagList *taglist; + + CopySampleFunc copy_samples; }; struct _GstVorbisDecClass { diff --git a/ext/vorbis/gstvorbisdeclib.c b/ext/vorbis/gstvorbisdeclib.c index 9f3331c..1ddce38 100644 --- a/ext/vorbis/gstvorbisdeclib.c +++ b/ext/vorbis/gstvorbisdeclib.c @@ -26,25 +26,51 @@ #include "config.h" #endif +#include #include "gstvorbisdeclib.h" #ifndef TREMOR /* These samples can be outside of the float -1.0 -- 1.0 range, this * is allowed, downstream elements are supposed to clip */ -void -copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, +static void +copy_samples_m (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, gint channels, gint width) { - gint i, j; + memcpy (out, in[0], samples * sizeof (float)); +} - g_assert (width == 4); +static void +copy_samples_s (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, + gint channels, gint width) +{ +#ifdef GST_VORBIS_DEC_SEQUENTIAL + memcpy (out, in[0], samples * sizeof (float)); + out += samples; + memcpy (out, in[1], samples * sizeof (float)); +#else + gint j; + + for (j = 0; j < samples; j++) { + *out++ = in[0][j]; + *out++ = in[1][j]; + } +#endif +} +static void +copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, + gint channels, gint width) +{ #ifdef GST_VORBIS_DEC_SEQUENTIAL + gint i; + for (i = 0; i < channels; i++) { memcpy (out, in[i], samples * sizeof (float)); out += samples; } #else + gint i, j; + for (j = 0; j < samples; j++) { for (i = 0; i < channels; i++) { *out++ = in[i][j]; @@ -53,6 +79,28 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, #endif } +CopySampleFunc +get_copy_sample_func (gint channels, gint width) +{ + CopySampleFunc f = NULL; + + g_assert (width == 4); + + switch (channels) { + case 1: + f = copy_samples_m; + break; + case 2: + f = copy_samples_s; + break; + default: + f = copy_samples; + break; + } + + return f; +} + #else /* Taken from Tremor, misc.h */ @@ -83,8 +131,38 @@ CLIP_TO_15 (ogg_int32_t x) #endif static void -copy_samples_32 (gint32 * out, ogg_int32_t ** in, guint samples, gint channels) +copy_samples_32_m (vorbis_sample_t * _out, vorbis_sample_t ** _in, + guint samples, gint channels, gint width) { + gint32 *out = (gint32 *) _out; + ogg_int32_t **in = (ogg_int32_t **) _in; + gint j; + + for (j = 0; j < samples; j++) { + *out++ = CLIP_TO_15 (in[0][j] >> 9); + } +} + +static void +copy_samples_32_s (vorbis_sample_t * _out, vorbis_sample_t ** _in, + guint samples, gint channels, gint width) +{ + gint32 *out = (gint32 *) _out; + ogg_int32_t **in = (ogg_int32_t **) _in; + gint j; + + for (j = 0; j < samples; j++) { + *out++ = CLIP_TO_15 (in[0][j] >> 9); + *out++ = CLIP_TO_15 (in[1][j] >> 9); + } +} + +static void +copy_samples_32 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples, + gint channels, gint width) +{ + gint32 *out = (gint32 *) _out; + ogg_int32_t **in = (ogg_int32_t **) _in; gint i, j; for (j = 0; j < samples; j++) { @@ -95,8 +173,38 @@ copy_samples_32 (gint32 * out, ogg_int32_t ** in, guint samples, gint channels) } static void -copy_samples_16 (gint16 * out, ogg_int32_t ** in, guint samples, gint channels) +copy_samples_16_m (vorbis_sample_t * _out, vorbis_sample_t ** _in, + guint samples, gint channels, gint width) +{ + gint16 *out = (gint16 *) _out; + ogg_int32_t **in = (ogg_int32_t **) _in; + gint j; + + for (j = 0; j < samples; j++) { + *out++ = CLIP_TO_15 (in[0][j] >> 9); + } +} + +static void +copy_samples_16_s (vorbis_sample_t * _out, vorbis_sample_t ** _in, + guint samples, gint channels, gint width) +{ + gint16 *out = (gint16 *) _out; + ogg_int32_t **in = (ogg_int32_t **) _in; + gint j; + + for (j = 0; j < samples; j++) { + *out++ = CLIP_TO_15 (in[0][j] >> 9); + *out++ = CLIP_TO_15 (in[1][j] >> 9); + } +} + +static void +copy_samples_16 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples, + gint channels, gint width) { + gint16 *out = (gint16 *) _out; + ogg_int32_t **in = (ogg_int32_t **) _in; gint i, j; for (j = 0; j < samples; j++) { @@ -106,17 +214,39 @@ copy_samples_16 (gint16 * out, ogg_int32_t ** in, guint samples, gint channels) } } -void -copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples, - gint channels, gint width) +CopySampleFunc +get_copy_sample_func (gint channels, gint width) { + CopySampleFunc f = NULL; + if (width == 4) { - copy_samples_32 ((gint32 *) out, in, samples, channels); + switch (channels) { + case 1: + f = copy_samples_32_m; + break; + case 2: + f = copy_samples_32_s; + break; + default: + f = copy_samples_32; + break; + } } else if (width == 2) { - copy_samples_16 ((gint16 *) out, in, samples, channels); + switch (channels) { + case 1: + f = copy_samples_16_m; + break; + case 2: + f = copy_samples_16_s; + break; + default: + f = copy_samples_16; + break; + } } else { g_assert_not_reached (); } + return f; } #endif diff --git a/ext/vorbis/gstvorbisdeclib.h b/ext/vorbis/gstvorbisdeclib.h index df9093f..c82f0c8 100644 --- a/ext/vorbis/gstvorbisdeclib.h +++ b/ext/vorbis/gstvorbisdeclib.h @@ -37,8 +37,10 @@ typedef ogg_packet ogg_packet_wrapper; #define GST_VORBIS_DEC_DESCRIPTION "decode raw vorbis streams to float audio" #define GST_VORBIS_DEC_SRC_CAPS \ - GST_STATIC_CAPS ("audio/x-raw-float, " "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, " \ + GST_STATIC_CAPS ("audio/x-raw-float, " \ + "rate = (int) [ 1, MAX ], " \ + "channels = (int) [ 1, 256 ], " \ + "endianness = (int) BYTE_ORDER, " \ "width = (int) 32") #define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (32) @@ -91,7 +93,8 @@ struct _ogg_packet_wrapper { "channels = (int) [ 1, 6 ], " \ "endianness = (int) BYTE_ORDER, " \ "width = (int) { 16, 32 }, " \ - "depth = (int) 16, " "signed = (boolean) true") + "depth = (int) 16, " \ + "signed = (boolean) true") #define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (16) @@ -147,8 +150,9 @@ gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet) #endif -void copy_samples (vorbis_sample_t *out, vorbis_sample_t **in, +typedef void (*CopySampleFunc)(vorbis_sample_t *out, vorbis_sample_t **in, guint samples, gint channels, gint width); +CopySampleFunc get_copy_sample_func (gint channels, gint width); #endif /* __GST_VORBIS_DEC_LIB_H__ */