mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
vorbis: have a copy_sample func as a func pointer
Make some more variants for copy_sample funcs and use them via function pointer.
This commit is contained in:
parent
51739d562c
commit
4e6cb3e91f
4 changed files with 161 additions and 18 deletions
|
@ -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;
|
||||
|
|
|
@ -75,6 +75,8 @@ struct _GstVorbisDec {
|
|||
|
||||
GList *pendingevents;
|
||||
GstTagList *taglist;
|
||||
|
||||
CopySampleFunc copy_samples;
|
||||
};
|
||||
|
||||
struct _GstVorbisDecClass {
|
||||
|
|
|
@ -26,25 +26,51 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#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
|
||||
static void
|
||||
copy_samples_m (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
|
||||
gint channels, gint width)
|
||||
{
|
||||
memcpy (out, in[0], samples * sizeof (float));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
gint i, j;
|
||||
|
||||
g_assert (width == 4);
|
||||
|
||||
#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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue