mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
pulsesink: Use the extended stream API if available
This uses the new extended API for creating streams. This will allow us to support compressed formats natively in pulsesink as well.
This commit is contained in:
parent
379049809c
commit
a67b536741
4 changed files with 131 additions and 0 deletions
|
@ -839,6 +839,10 @@ AG_GST_CHECK_FEATURE(PULSE, [pulseaudio plug-in], pulseaudio, [
|
|||
if test x$HAVE_PULSE_0_9_20 = xyes; then
|
||||
AC_DEFINE(HAVE_PULSE_0_9_20, 1, [defined if pulseaudio >= 0.9.20 is available])
|
||||
fi
|
||||
AG_GST_PKG_CHECK_MODULES(PULSE_1_0, libpulse >= 0.98)
|
||||
if test x$HAVE_PULSE_1_0 = xyes; then
|
||||
AC_DEFINE(HAVE_PULSE_1_0, 1, [defined if pulseaudio >= 1.0 is available])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl *** dv1394 ***
|
||||
|
|
|
@ -138,7 +138,12 @@ struct _GstPulseRingBuffer
|
|||
pa_context *context;
|
||||
pa_stream *stream;
|
||||
|
||||
#if HAVE_PULSE_1_0
|
||||
pa_format_info *format;
|
||||
guint channels;
|
||||
#else
|
||||
pa_sample_spec sample_spec;
|
||||
#endif
|
||||
|
||||
void *m_data;
|
||||
size_t m_towrite;
|
||||
|
@ -222,7 +227,12 @@ gst_pulseringbuffer_init (GstPulseRingBuffer * pbuf)
|
|||
pbuf->context = NULL;
|
||||
pbuf->stream = NULL;
|
||||
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
pbuf->format = NULL;
|
||||
pbuf->channels = 0;
|
||||
#else
|
||||
pa_sample_spec_init (&pbuf->sample_spec);
|
||||
#endif
|
||||
|
||||
pbuf->m_data = NULL;
|
||||
pbuf->m_towrite = 0;
|
||||
|
@ -251,6 +261,13 @@ gst_pulsering_destroy_stream (GstPulseRingBuffer * pbuf)
|
|||
pbuf->m_offset = 0;
|
||||
pbuf->m_lastoffset = 0;
|
||||
}
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
if (pbuf->format) {
|
||||
pa_format_info_free (pbuf->format);
|
||||
pbuf->format = NULL;
|
||||
pbuf->channels = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
pa_stream_disconnect (pbuf->stream);
|
||||
|
||||
|
@ -718,14 +735,22 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
|||
pa_stream_flags_t flags;
|
||||
const gchar *name;
|
||||
GstAudioClock *clock;
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
pa_format_info *formats[1];
|
||||
#endif
|
||||
|
||||
psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (buf));
|
||||
pbuf = GST_PULSERING_BUFFER_CAST (buf);
|
||||
|
||||
GST_LOG_OBJECT (psink, "creating sample spec");
|
||||
/* convert the gstreamer sample spec to the pulseaudio format */
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
if (!gst_pulse_fill_format_info (spec, &pbuf->format, &pbuf->channels))
|
||||
goto invalid_spec;
|
||||
#else
|
||||
if (!gst_pulse_fill_sample_spec (spec, &pbuf->sample_spec))
|
||||
goto invalid_spec;
|
||||
#endif
|
||||
|
||||
pa_threaded_mainloop_lock (mainloop);
|
||||
|
||||
|
@ -742,7 +767,13 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
|||
pa_operation_unref (o);
|
||||
|
||||
/* initialize the channel map */
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
if (pa_format_info_is_pcm (pbuf->format) &&
|
||||
gst_pulse_gst_to_channel_map (&channel_map, spec))
|
||||
pa_format_info_set_channel_map (pbuf->format, &channel_map);
|
||||
#else
|
||||
gst_pulse_gst_to_channel_map (&channel_map, spec);
|
||||
#endif
|
||||
|
||||
/* find a good name for the stream */
|
||||
if (psink->stream_name)
|
||||
|
@ -751,10 +782,17 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
|||
name = "Playback Stream";
|
||||
|
||||
/* create a stream */
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
formats[0] = pbuf->format;
|
||||
if (!(pbuf->stream = pa_stream_new_extended (pbuf->context, name, formats, 1,
|
||||
psink->proplist)))
|
||||
goto stream_failed;
|
||||
#else
|
||||
GST_LOG_OBJECT (psink, "creating stream with name %s", name);
|
||||
if (!(pbuf->stream = pa_stream_new_with_proplist (pbuf->context, name,
|
||||
&pbuf->sample_spec, &channel_map, psink->proplist)))
|
||||
goto stream_failed;
|
||||
#endif
|
||||
|
||||
/* install essential callbacks */
|
||||
pa_stream_set_state_callback (pbuf->stream,
|
||||
|
@ -792,8 +830,13 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
|||
if (psink->volume_set) {
|
||||
GST_LOG_OBJECT (psink, "have volume of %f", psink->volume);
|
||||
pv = &v;
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
if (pa_format_info_is_pcm (pbuf->format))
|
||||
gst_pulse_cvolume_from_linear (pv, pbuf->channels, psink->volume);
|
||||
#else
|
||||
gst_pulse_cvolume_from_linear (pv, pbuf->sample_spec.channels,
|
||||
psink->volume);
|
||||
#endif
|
||||
} else {
|
||||
pv = NULL;
|
||||
}
|
||||
|
@ -1923,7 +1966,12 @@ gst_pulsesink_set_volume (GstPulseSink * psink, gdouble volume)
|
|||
if ((idx = pa_stream_get_index (pbuf->stream)) == PA_INVALID_INDEX)
|
||||
goto no_index;
|
||||
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
if (pa_format_info_is_pcm (pbuf->format))
|
||||
gst_pulse_cvolume_from_linear (&v, pbuf->channels, volume);
|
||||
#else
|
||||
gst_pulse_cvolume_from_linear (&v, pbuf->sample_spec.channels, volume);
|
||||
#endif
|
||||
|
||||
if (!(o = pa_context_set_sink_input_volume (pbuf->context, idx,
|
||||
&v, NULL, NULL)))
|
||||
|
|
|
@ -118,6 +118,81 @@ gst_pulse_fill_sample_spec (GstRingBufferSpec * spec, pa_sample_spec * ss)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
gboolean
|
||||
gst_pulse_fill_format_info (GstRingBufferSpec * spec, pa_format_info ** f,
|
||||
guint * channels)
|
||||
{
|
||||
pa_format_info *format;
|
||||
pa_sample_format_t sf = PA_SAMPLE_INVALID;
|
||||
|
||||
format = pa_format_info_new ();
|
||||
|
||||
if (spec->format == GST_MU_LAW && spec->width == 8) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_ULAW;
|
||||
} else if (spec->format == GST_A_LAW && spec->width == 8) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_ALAW;
|
||||
} else if (spec->format == GST_U8 && spec->width == 8) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_U8;
|
||||
} else if (spec->format == GST_S16_LE && spec->width == 16) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S16LE;
|
||||
} else if (spec->format == GST_S16_BE && spec->width == 16) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S16BE;
|
||||
} else if (spec->format == GST_FLOAT32_LE && spec->width == 32) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_FLOAT32LE;
|
||||
} else if (spec->format == GST_FLOAT32_BE && spec->width == 32) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_FLOAT32BE;
|
||||
} else if (spec->format == GST_S32_LE && spec->width == 32) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S32LE;
|
||||
} else if (spec->format == GST_S32_BE && spec->width == 32) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S32BE;
|
||||
} else if (spec->format == GST_S24_3LE && spec->width == 24) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S24LE;
|
||||
} else if (spec->format == GST_S24_3BE && spec->width == 24) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S24BE;
|
||||
} else if (spec->format == GST_S24_LE && spec->width == 32) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S24_32LE;
|
||||
} else if (spec->format == GST_S24_BE && spec->width == 32) {
|
||||
format->encoding = PA_ENCODING_PCM;
|
||||
sf = PA_SAMPLE_S24_32BE;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (format->encoding == PA_ENCODING_PCM) {
|
||||
pa_format_info_set_sample_format (format, sf);
|
||||
pa_format_info_set_channels (format, spec->channels);
|
||||
}
|
||||
|
||||
pa_format_info_set_rate (format, spec->rate);
|
||||
|
||||
if (!pa_format_info_valid (format))
|
||||
goto fail;
|
||||
|
||||
*f = format;
|
||||
*channels = spec->channels;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (format)
|
||||
pa_format_info_free (format);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PATH_MAX is not defined everywhere, e.g. on GNU Hurd */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
|
||||
gboolean gst_pulse_fill_sample_spec (GstRingBufferSpec * spec,
|
||||
pa_sample_spec * ss);
|
||||
#ifdef HAVE_PULSE_1_0
|
||||
gboolean gst_pulse_fill_format_info (GstRingBufferSpec * spec,
|
||||
pa_format_info ** f, guint * channels);
|
||||
#endif
|
||||
|
||||
gchar *gst_pulse_client_name (void);
|
||||
|
||||
|
|
Loading…
Reference in a new issue