mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-15 02:38:27 +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
|
@ -588,11 +588,18 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
|
||||||
s = gst_caps_get_structure (caps, 0);
|
s = gst_caps_get_structure (caps, 0);
|
||||||
/* template ensures 16 or 32 */
|
/* template ensures 16 or 32 */
|
||||||
gst_structure_get_int (s, "width", &width);
|
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);
|
gst_caps_unref (caps);
|
||||||
}
|
}
|
||||||
vd->width = width >> 3;
|
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));
|
caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad));
|
||||||
gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
|
gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
|
||||||
"channels", G_TYPE_INT, vd->vi.channels,
|
"channels", G_TYPE_INT, vd->vi.channels,
|
||||||
|
@ -881,8 +888,8 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
|
||||||
goto wrong_samples;
|
goto wrong_samples;
|
||||||
|
|
||||||
/* copy samples in buffer */
|
/* copy samples in buffer */
|
||||||
copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm, sample_count,
|
vd->copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm,
|
||||||
vd->vi.channels, vd->width);
|
sample_count, vd->vi.channels, vd->width);
|
||||||
|
|
||||||
GST_LOG_OBJECT (vd, "setting output size to %d", size);
|
GST_LOG_OBJECT (vd, "setting output size to %d", size);
|
||||||
GST_BUFFER_SIZE (out) = size;
|
GST_BUFFER_SIZE (out) = size;
|
||||||
|
|
|
@ -75,6 +75,8 @@ struct _GstVorbisDec {
|
||||||
|
|
||||||
GList *pendingevents;
|
GList *pendingevents;
|
||||||
GstTagList *taglist;
|
GstTagList *taglist;
|
||||||
|
|
||||||
|
CopySampleFunc copy_samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstVorbisDecClass {
|
struct _GstVorbisDecClass {
|
||||||
|
|
|
@ -26,25 +26,51 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include "gstvorbisdeclib.h"
|
#include "gstvorbisdeclib.h"
|
||||||
|
|
||||||
#ifndef TREMOR
|
#ifndef TREMOR
|
||||||
/* These samples can be outside of the float -1.0 -- 1.0 range, this
|
/* These samples can be outside of the float -1.0 -- 1.0 range, this
|
||||||
* is allowed, downstream elements are supposed to clip */
|
* 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,
|
copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
|
||||||
gint channels, gint width)
|
gint channels, gint width)
|
||||||
{
|
{
|
||||||
gint i, j;
|
|
||||||
|
|
||||||
g_assert (width == 4);
|
|
||||||
|
|
||||||
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
||||||
|
gint i;
|
||||||
|
|
||||||
for (i = 0; i < channels; i++) {
|
for (i = 0; i < channels; i++) {
|
||||||
memcpy (out, in[i], samples * sizeof (float));
|
memcpy (out, in[i], samples * sizeof (float));
|
||||||
out += samples;
|
out += samples;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
for (j = 0; j < samples; j++) {
|
for (j = 0; j < samples; j++) {
|
||||||
for (i = 0; i < channels; i++) {
|
for (i = 0; i < channels; i++) {
|
||||||
*out++ = in[i][j];
|
*out++ = in[i][j];
|
||||||
|
@ -53,6 +79,28 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
|
||||||
#endif
|
#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
|
#else
|
||||||
|
|
||||||
/* Taken from Tremor, misc.h */
|
/* Taken from Tremor, misc.h */
|
||||||
|
@ -83,8 +131,38 @@ CLIP_TO_15 (ogg_int32_t x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
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;
|
gint i, j;
|
||||||
|
|
||||||
for (j = 0; j < samples; 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
|
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;
|
gint i, j;
|
||||||
|
|
||||||
for (j = 0; j < samples; 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
|
CopySampleFunc
|
||||||
copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
|
get_copy_sample_func (gint channels, gint width)
|
||||||
gint channels, gint width)
|
|
||||||
{
|
{
|
||||||
|
CopySampleFunc f = NULL;
|
||||||
|
|
||||||
if (width == 4) {
|
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) {
|
} 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 {
|
} else {
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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_DESCRIPTION "decode raw vorbis streams to float audio"
|
||||||
|
|
||||||
#define GST_VORBIS_DEC_SRC_CAPS \
|
#define GST_VORBIS_DEC_SRC_CAPS \
|
||||||
GST_STATIC_CAPS ("audio/x-raw-float, " "rate = (int) [ 1, MAX ], " \
|
GST_STATIC_CAPS ("audio/x-raw-float, " \
|
||||||
"channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, " \
|
"rate = (int) [ 1, MAX ], " \
|
||||||
|
"channels = (int) [ 1, 256 ], " \
|
||||||
|
"endianness = (int) BYTE_ORDER, " \
|
||||||
"width = (int) 32")
|
"width = (int) 32")
|
||||||
|
|
||||||
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (32)
|
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (32)
|
||||||
|
@ -91,7 +93,8 @@ struct _ogg_packet_wrapper {
|
||||||
"channels = (int) [ 1, 6 ], " \
|
"channels = (int) [ 1, 6 ], " \
|
||||||
"endianness = (int) BYTE_ORDER, " \
|
"endianness = (int) BYTE_ORDER, " \
|
||||||
"width = (int) { 16, 32 }, " \
|
"width = (int) { 16, 32 }, " \
|
||||||
"depth = (int) 16, " "signed = (boolean) true")
|
"depth = (int) 16, " \
|
||||||
|
"signed = (boolean) true")
|
||||||
|
|
||||||
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (16)
|
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (16)
|
||||||
|
|
||||||
|
@ -147,8 +150,9 @@ gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet)
|
||||||
|
|
||||||
#endif
|
#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);
|
guint samples, gint channels, gint width);
|
||||||
|
|
||||||
|
CopySampleFunc get_copy_sample_func (gint channels, gint width);
|
||||||
|
|
||||||
#endif /* __GST_VORBIS_DEC_LIB_H__ */
|
#endif /* __GST_VORBIS_DEC_LIB_H__ */
|
||||||
|
|
Loading…
Reference in a new issue