From 19cd03c60765fc6eaf42c3f12b83a3965d58a11d Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 24 Jul 2006 14:34:42 +0000 Subject: [PATCH] ext/alsa/gstalsasink.c: Don't try to calculate silence samples, base class does this much better now. Original commit message from CVS: * ext/alsa/gstalsasink.c: (set_hwparams), (gst_alsasink_prepare): Don't try to calculate silence samples, base class does this much better now. * gst-libs/gst/audio/gstringbuffer.c: (build_linear_format), (gst_ring_buffer_debug_spec_caps), (gst_ring_buffer_parse_caps), (gst_ring_buffer_acquire): Calculate silence samples correctly. * gst-libs/gst/audio/gstringbuffer.h: Add _CAST macro. --- ChangeLog | 14 ++++ common | 2 +- ext/alsa/gstalsasink.c | 4 -- gst-libs/gst/audio/gstringbuffer.c | 129 +++++++++++++++++++++++-------------- gst-libs/gst/audio/gstringbuffer.h | 1 + 5 files changed, 98 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95c326b..3ff5f16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-07-24 Wim Taymans + + * ext/alsa/gstalsasink.c: (set_hwparams), (gst_alsasink_prepare): + Don't try to calculate silence samples, base class does this much + better now. + + * gst-libs/gst/audio/gstringbuffer.c: (build_linear_format), + (gst_ring_buffer_debug_spec_caps), (gst_ring_buffer_parse_caps), + (gst_ring_buffer_acquire): + Calculate silence samples correctly. + + * gst-libs/gst/audio/gstringbuffer.h: + Add _CAST macro. + 2006-07-22 Tim-Philipp Müller * gst/typefind/gsttypefindfunctions.c: (xml_check_first_element): diff --git a/common b/common index c22b0a7..ef97fb3 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit c22b0a7fbd8ebcf0a531f2898163d9b834f89ab1 +Subproject commit ef97fb3278d98a1fdb32e5c6b2a7467116ffc160 diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c index ebdd47a..1913960 100644 --- a/ext/alsa/gstalsasink.c +++ b/ext/alsa/gstalsasink.c @@ -657,10 +657,6 @@ gst_alsasink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) alsa->bytes_per_sample = spec->bytes_per_sample; spec->segsize = alsa->period_size * spec->bytes_per_sample; spec->segtotal = alsa->buffer_size / alsa->period_size; - spec->silence_sample[0] = 0; - spec->silence_sample[1] = 0; - spec->silence_sample[2] = 0; - spec->silence_sample[3] = 0; return TRUE; diff --git a/gst-libs/gst/audio/gstringbuffer.c b/gst-libs/gst/audio/gstringbuffer.c index 96fb1a8..ee5ad71 100644 --- a/gst-libs/gst/audio/gstringbuffer.c +++ b/gst-libs/gst/audio/gstringbuffer.c @@ -132,55 +132,61 @@ gst_ring_buffer_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (ringbuffer)); } -static const int linear_formats[4 * 2 * 2] = { - GST_S8, - GST_S8, - GST_U8, - GST_U8, - GST_S16_LE, - GST_S16_BE, - GST_U16_LE, - GST_U16_BE, - GST_S24_LE, - GST_S24_BE, - GST_U24_LE, - GST_U24_BE, - GST_S32_LE, - GST_S32_BE, - GST_U32_LE, - GST_U32_BE +typedef struct +{ + GstBufferFormat format; + guint8 silence[4]; +} FormatDef; + +static const FormatDef linear_defs[4 * 2 * 2] = { + {GST_S8, {0x00, 0x00, 0x00, 0x00}}, + {GST_S8, {0x00, 0x00, 0x00, 0x00}}, + {GST_U8, {0x80, 0x80, 0x80, 0x80}}, + {GST_U8, {0x80, 0x80, 0x80, 0x80}}, + {GST_S16_LE, {0x00, 0x00, 0x00, 0x00}}, + {GST_S16_BE, {0x00, 0x00, 0x00, 0x00}}, + {GST_U16_LE, {0x00, 0x80, 0x00, 0x80}}, + {GST_U16_BE, {0x80, 0x00, 0x80, 0x00}}, + {GST_S24_LE, {0x00, 0x00, 0x00, 0x00}}, + {GST_S24_BE, {0x00, 0x00, 0x00, 0x00}}, + {GST_U24_LE, {0x00, 0x00, 0x80, 0x00}}, + {GST_U24_BE, {0x80, 0x00, 0x00, 0x00}}, + {GST_S32_LE, {0x00, 0x00, 0x00, 0x00}}, + {GST_S32_BE, {0x00, 0x00, 0x00, 0x00}}, + {GST_U32_LE, {0x00, 0x00, 0x00, 0x80}}, + {GST_U32_BE, {0x80, 0x00, 0x00, 0x00}} }; -static const int linear24_formats[3 * 2 * 2] = { - GST_S24_3LE, - GST_S24_3BE, - GST_U24_3LE, - GST_U24_3BE, - GST_S20_3LE, - GST_S20_3BE, - GST_U20_3LE, - GST_U20_3BE, - GST_S18_3LE, - GST_S18_3BE, - GST_U18_3LE, - GST_U18_3BE, +static const FormatDef linear24_defs[3 * 2 * 2] = { + {GST_S24_3LE, {0x00, 0x00, 0x00, 0x00}}, + {GST_S24_3BE, {0x00, 0x00, 0x00, 0x00}}, + {GST_U24_3LE, {0x00, 0x00, 0x80, 0x00}}, + {GST_U24_3BE, {0x80, 0x00, 0x00, 0x00}}, + {GST_S20_3LE, {0x00, 0x00, 0x00, 0x00}}, + {GST_S20_3BE, {0x00, 0x00, 0x00, 0x00}}, + {GST_U20_3LE, {0x00, 0x00, 0x08, 0x00}}, + {GST_U20_3BE, {0x08, 0x00, 0x00, 0x00}}, + {GST_S18_3LE, {0x00, 0x00, 0x00, 0x00}}, + {GST_S18_3BE, {0x00, 0x00, 0x00, 0x00}}, + {GST_U18_3LE, {0x00, 0x00, 0x02, 0x00}}, + {GST_U18_3BE, {0x02, 0x00, 0x00, 0x00}} }; -static GstBufferFormat +static const FormatDef * build_linear_format (int depth, int width, int unsignd, int big_endian) { - const gint *formats; + const FormatDef *formats; if (width == 24) { switch (depth) { case 24: - formats = &linear24_formats[0]; + formats = &linear24_defs[0]; break; case 20: - formats = &linear24_formats[4]; + formats = &linear24_defs[4]; break; case 18: - formats = &linear24_formats[8]; + formats = &linear24_defs[8]; break; default: return GST_UNKNOWN; @@ -188,16 +194,16 @@ build_linear_format (int depth, int width, int unsignd, int big_endian) } else { switch (depth) { case 8: - formats = &linear_formats[0]; + formats = &linear_defs[0]; break; case 16: - formats = &linear_formats[4]; + formats = &linear_defs[4]; break; case 24: - formats = &linear_formats[8]; + formats = &linear_defs[8]; break; case 32: - formats = &linear_formats[12]; + formats = &linear_defs[12]; break; default: return GST_UNKNOWN; @@ -207,7 +213,8 @@ build_linear_format (int depth, int width, int unsignd, int big_endian) formats += 2; if (big_endian) formats += 1; - return (GstBufferFormat) * formats; + + return formats; } /** @@ -219,6 +226,8 @@ build_linear_format (int depth, int width, int unsignd, int big_endian) void gst_ring_buffer_debug_spec_caps (GstRingBufferSpec * spec) { + gint i, bytes; + GST_DEBUG ("spec caps: %p %" GST_PTR_FORMAT, spec->caps, spec->caps); GST_DEBUG ("parsed caps: type: %d", spec->type); GST_DEBUG ("parsed caps: format: %d", spec->format); @@ -229,6 +238,10 @@ gst_ring_buffer_debug_spec_caps (GstRingBufferSpec * spec) GST_DEBUG ("parsed caps: rate: %d", spec->rate); GST_DEBUG ("parsed caps: channels: %d", spec->channels); GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample); + bytes = (spec->width >> 3) * spec->channels; + for (i = 0; i < bytes; i++) { + GST_DEBUG ("silence byte %d: %02x", i, spec->silence_sample[i]); + } } /** @@ -266,14 +279,22 @@ gst_ring_buffer_parse_caps (GstRingBufferSpec * spec, GstCaps * caps) { const gchar *mimetype; GstStructure *structure; + gint i; structure = gst_caps_get_structure (caps, 0); /* we have to differentiate between int and float formats */ mimetype = gst_structure_get_name (structure); + /* get rate and channels */ + if (!(gst_structure_get_int (structure, "rate", &spec->rate) && + gst_structure_get_int (structure, "channels", &spec->channels))) + goto parse_error; + if (!strncmp (mimetype, "audio/x-raw-int", 15)) { gint endianness; + const FormatDef *def; + gint j, bytes; spec->type = GST_BUFTYPE_LINEAR; @@ -293,9 +314,18 @@ gst_ring_buffer_parse_caps (GstRingBufferSpec * spec, GstCaps * caps) spec->bigend = endianness == G_LITTLE_ENDIAN ? FALSE : TRUE; - spec->format = - build_linear_format (spec->depth, spec->width, spec->sign ? 0 : 1, + def = build_linear_format (spec->depth, spec->width, spec->sign ? 0 : 1, spec->bigend ? 1 : 0); + + spec->format = def->format; + + bytes = spec->width >> 3; + + for (i = 0; i < spec->channels; i++) { + for (j = 0; j < bytes; j++) { + spec->silence_sample[i * bytes + j] = def->silence[j]; + } + } } else if (!strncmp (mimetype, "audio/x-raw-float", 17)) { spec->type = GST_BUFTYPE_FLOAT; @@ -317,25 +347,26 @@ gst_ring_buffer_parse_caps (GstRingBufferSpec * spec, GstCaps * caps) default: goto parse_error; } + /* float silence is all zeros.. */ + memset (spec->silence_sample, 0, 32); } else if (!strncmp (mimetype, "audio/x-alaw", 12)) { spec->type = GST_BUFTYPE_A_LAW; spec->format = GST_A_LAW; spec->width = 8; spec->depth = 8; + for (i = 0; i < spec->channels; i++) + spec->silence_sample[i] = 0xd5; } else if (!strncmp (mimetype, "audio/x-mulaw", 13)) { spec->type = GST_BUFTYPE_MU_LAW; spec->format = GST_MU_LAW; spec->width = 8; spec->depth = 8; + for (i = 0; i < spec->channels; i++) + spec->silence_sample[i] = 0xff; } else { goto parse_error; } - /* get rate and channels */ - if (!(gst_structure_get_int (structure, "rate", &spec->rate) && - gst_structure_get_int (structure, "channels", &spec->channels))) - goto parse_error; - spec->bytes_per_sample = (spec->width >> 3) * spec->channels; gst_caps_replace (&spec->caps, caps); @@ -593,6 +624,10 @@ gst_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec) /* create an empty segment */ g_free (buf->empty_seg); buf->empty_seg = g_malloc (segsize); + + /* FIXME, we only have 32 silence samples, which might not be enough to + * represent silence in all channels */ + bps = MIN (bps, 32); for (i = 0, j = 0; i < segsize; i++) { buf->empty_seg[i] = buf->spec.silence_sample[j]; j = (j + 1) % bps; diff --git a/gst-libs/gst/audio/gstringbuffer.h b/gst-libs/gst/audio/gstringbuffer.h index 46ec169..c54857a 100644 --- a/gst-libs/gst/audio/gstringbuffer.h +++ b/gst-libs/gst/audio/gstringbuffer.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS #define GST_RING_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RING_BUFFER,GstRingBuffer)) #define GST_RING_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RING_BUFFER,GstRingBufferClass)) #define GST_RING_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RING_BUFFER, GstRingBufferClass)) +#define GST_RING_BUFFER_CAST(obj) ((GstRingBuffer *)obj) #define GST_IS_RING_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RING_BUFFER)) #define GST_IS_RING_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RING_BUFFER)) -- 2.7.4