rpms/gstreamer-plugins-good/F-11 gstreamer-plugins-good.spec, 1.101, 1.102 pulsesink-lowering-volumes.patch, 1.1, 1.2
Bastien Nocera
hadess at fedoraproject.org
Sat Oct 17 01:21:16 UTC 2009
- Previous message (by thread): rpms/colossus/F-12 .cvsignore, 1.7, 1.8 colossus-gen-tarball.sh, 1.1, 1.2 colossus.spec, 1.9, 1.10 import.log, 1.6, 1.7 sources, 1.7, 1.8
- Next message (by thread): rpms/python-paste-script/EL-5 python-paste-script.spec,1.11,1.12
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: hadess
Update of /cvs/pkgs/rpms/gstreamer-plugins-good/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv20049
Modified Files:
gstreamer-plugins-good.spec pulsesink-lowering-volumes.patch
Log Message:
* Sat Oct 17 2009 Bastien Nocera <bnocera at redhat.com> 0.10.16-3
- Finally fix pulsesink volume lowering problems (#488532)
Index: gstreamer-plugins-good.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gstreamer-plugins-good/F-11/gstreamer-plugins-good.spec,v
retrieving revision 1.101
retrieving revision 1.102
diff -u -p -r1.101 -r1.102
--- gstreamer-plugins-good.spec 17 Oct 2009 00:50:45 -0000 1.101
+++ gstreamer-plugins-good.spec 17 Oct 2009 01:21:16 -0000 1.102
@@ -74,6 +74,7 @@ Provides: gstreamer-plugins-farsight = 0
Obsoletes: gstreamer-plugins-farsight < 0.12.12
# http://bugzilla.gnome.org/show_bug.cgi?id=595231
+# and many others
Patch2: pulsesink-lowering-volumes.patch
%description
pulsesink-lowering-volumes.patch:
pulsemixer.c | 14 +-
pulsemixerctrl.c | 77 ++++++++------
pulsemixerctrl.h | 13 +-
pulseprobe.c | 27 +++-
pulseprobe.h | 13 +-
pulsesink.c | 299 +++++++++++++++++++++++++++++++++++++++++++------------
pulsesink.h | 14 +-
pulsesrc.c | 54 +++++----
pulsesrc.h | 10 +
9 files changed, 374 insertions(+), 147 deletions(-)
Index: pulsesink-lowering-volumes.patch
===================================================================
RCS file: /cvs/pkgs/rpms/gstreamer-plugins-good/F-11/pulsesink-lowering-volumes.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- pulsesink-lowering-volumes.patch 17 Oct 2009 00:50:45 -0000 1.1
+++ pulsesink-lowering-volumes.patch 17 Oct 2009 01:21:16 -0000 1.2
@@ -1,26 +1,630 @@
-From cee7048dcd68f1d3cca3651a5aaef11145390fa4 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart at poettering.net>
-Date: Sat, 17 Oct 2009 02:18:53 +0200
-Subject: [PATCH] pulse: never apply volume more than once
-
-Generally decisions on the volume of the stream should be done inside of
-PA, not inside of Gst. Only PA knows how volumes translate between
-devices and s on.
-
-This patch makes sure that all volumes set via the volume property are
-only applied *once* to the underlying stream. After applying them the
-client side will not store them anymore. This should make sure that
-really only user-triggered volume changes are forwarded to server, but
-the client never tries to save/restore the volume internally.
----
- ext/pulse/pulsesink.c | 34 ++++++++++++++++++++--------------
- 1 files changed, 20 insertions(+), 14 deletions(-)
-
+diff --git a/ext/pulse/pulsemixer.c b/ext/pulse/pulsemixer.c
+index 99d33ae..ab99c55 100644
+--- a/ext/pulse/pulsemixer.c
++++ b/ext/pulse/pulsemixer.c
+@@ -252,6 +252,7 @@ static GstStateChangeReturn
+ gst_pulsemixer_change_state (GstElement * element, GstStateChange transition)
+ {
+ GstPulseMixer *this = GST_PULSEMIXER (element);
++ GstStateChangeReturn res;
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+@@ -260,19 +261,22 @@ gst_pulsemixer_change_state (GstElement * element, GstStateChange transition)
+ gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server,
+ this->device, GST_PULSEMIXER_UNKNOWN);
+ break;
++ default:
++ ;
++ }
++
++ res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
++
++ switch (transition) {
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ if (this->mixer) {
+ gst_pulsemixer_ctrl_free (this->mixer);
+ this->mixer = NULL;
+ }
+ break;
+-
+ default:
+ ;
+ }
+
+- if (GST_ELEMENT_CLASS (parent_class)->change_state)
+- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+-
+- return GST_STATE_CHANGE_SUCCESS;
++ return res;
+ }
+diff --git a/ext/pulse/pulsemixerctrl.c b/ext/pulse/pulsemixerctrl.c
+index ae807c6..760bd3e 100644
+--- a/ext/pulse/pulsemixerctrl.c
++++ b/ext/pulse/pulsemixerctrl.c
+@@ -1,3 +1,5 @@
++/*-*- Mode: C; c-basic-offset: 2 -*-*/
++
+ /*
+ * GStreamer pulseaudio plugin
+ *
+@@ -74,7 +76,7 @@ gst_pulsemixer_ctrl_sink_info_cb (pa_context * context, const pa_sink_info * i,
+ }
+
+ if (!i && eol < 0) {
+- c->operation_success = 0;
++ c->operation_success = FALSE;
+ pa_threaded_mainloop_signal (c->mainloop, 0);
+ return;
+ }
+@@ -89,7 +91,7 @@ gst_pulsemixer_ctrl_sink_info_cb (pa_context * context, const pa_sink_info * i,
+ c->index = i->index;
+ c->channel_map = i->channel_map;
+ c->volume = i->volume;
+- c->muted = i->mute;
++ c->muted = !!i->mute;
+ c->type = GST_PULSEMIXER_SINK;
+
+ if (c->track) {
+@@ -100,7 +102,7 @@ gst_pulsemixer_ctrl_sink_info_cb (pa_context * context, const pa_sink_info * i,
+ c->track->flags = flags;
+ }
+
+- c->operation_success = 1;
++ c->operation_success = TRUE;
+ pa_threaded_mainloop_signal (c->mainloop, 0);
+ }
+
+@@ -124,7 +126,7 @@ gst_pulsemixer_ctrl_source_info_cb (pa_context * context,
+ }
+
+ if (!i && eol < 0) {
+- c->operation_success = 0;
++ c->operation_success = FALSE;
+ pa_threaded_mainloop_signal (c->mainloop, 0);
+ return;
+ }
+@@ -139,7 +141,7 @@ gst_pulsemixer_ctrl_source_info_cb (pa_context * context,
+ c->index = i->index;
+ c->channel_map = i->channel_map;
+ c->volume = i->volume;
+- c->muted = i->mute;
++ c->muted = !!i->mute;
+ c->type = GST_PULSEMIXER_SOURCE;
+
+ if (c->track) {
+@@ -150,7 +152,7 @@ gst_pulsemixer_ctrl_source_info_cb (pa_context * context,
+ c->track->flags = flags;
+ }
+
+- c->operation_success = 1;
++ c->operation_success = TRUE;
+ pa_threaded_mainloop_signal (c->mainloop, 0);
+ }
+
+@@ -193,31 +195,40 @@ gst_pulsemixer_ctrl_success_cb (pa_context * context, int success,
+ {
+ GstPulseMixerCtrl *c = (GstPulseMixerCtrl *) userdata;
+
+- c->operation_success = success;
++ c->operation_success = !!success;
+ pa_threaded_mainloop_signal (c->mainloop, 0);
+ }
+
+-#define CHECK_DEAD_GOTO(c, label) do { \
+-if (!(c)->context || pa_context_get_state((c)->context) != PA_CONTEXT_READY) { \
+- GST_WARNING_OBJECT (c->object, "Not connected: %s", (c)->context ? pa_strerror(pa_context_errno((c)->context)) : "NULL"); \
+- goto label; \
+-} \
+-} while(0);
++#define CHECK_DEAD_GOTO(c, label) \
++ G_STMT_START { \
++ if (!(c)->context || \
++ !PA_CONTEXT_IS_GOOD(pa_context_get_state((c)->context))) { \
++ GST_WARNING_OBJECT ((c)->object, "Not connected: %s", \
++ (c)->context ? pa_strerror(pa_context_errno((c)->context)) : "NULL"); \
++ goto label; \
++ } \
++ } G_STMT_END
+
+ static gboolean
+ gst_pulsemixer_ctrl_open (GstPulseMixerCtrl * c)
+ {
+ int e;
+- gchar *name = gst_pulse_client_name ();
++ gchar *name;
+ pa_operation *o = NULL;
+
+ g_assert (c);
+
++ GST_DEBUG_OBJECT (c->object, "ctrl open");
++
+ c->mainloop = pa_threaded_mainloop_new ();
+- g_assert (c->mainloop);
++ if (!c->mainloop)
++ return FALSE;
+
+ e = pa_threaded_mainloop_start (c->mainloop);
+- g_assert (e == 0);
++ if (e < 0)
++ return FALSE;
++
++ name = gst_pulse_client_name ();
+
+ pa_threaded_mainloop_lock (c->mainloop);
+
+@@ -239,16 +250,12 @@ gst_pulsemixer_ctrl_open (GstPulseMixerCtrl * c)
+ }
+
+ /* Wait until the context is ready */
+- pa_threaded_mainloop_wait (c->mainloop);
+-
+- if (pa_context_get_state (c->context) != PA_CONTEXT_READY) {
+- GST_WARNING_OBJECT (c->object, "Failed to connect context: %s",
+- pa_strerror (pa_context_errno (c->context)));
+- goto unlock_and_fail;
++ while (pa_context_get_state (c->context) != PA_CONTEXT_READY) {
++ CHECK_DEAD_GOTO (c, unlock_and_fail);
++ pa_threaded_mainloop_wait (c->mainloop);
+ }
+
+ /* Subscribe to events */
+-
+ if (!(o =
+ pa_context_subscribe (c->context,
+ PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE,
+@@ -258,10 +265,10 @@ gst_pulsemixer_ctrl_open (GstPulseMixerCtrl * c)
+ goto unlock_and_fail;
+ }
+
+- c->operation_success = 0;
++ c->operation_success = FALSE;
+ while (pa_operation_get_state (o) != PA_OPERATION_DONE) {
+- pa_threaded_mainloop_wait (c->mainloop);
+ CHECK_DEAD_GOTO (c, unlock_and_fail);
++ pa_threaded_mainloop_wait (c->mainloop);
+ }
+
+ if (!c->operation_success) {
+@@ -275,6 +282,7 @@ gst_pulsemixer_ctrl_open (GstPulseMixerCtrl * c)
+ /* Get sink info */
+
+ if (c->type == GST_PULSEMIXER_UNKNOWN || c->type == GST_PULSEMIXER_SINK) {
++ GST_WARNING_OBJECT (c->object, "Get info for '%s'", c->device);
+ if (!(o =
+ pa_context_get_sink_info_by_name (c->context, c->device,
+ gst_pulsemixer_ctrl_sink_info_cb, c))) {
+@@ -283,10 +291,10 @@ gst_pulsemixer_ctrl_open (GstPulseMixerCtrl * c)
+ goto unlock_and_fail;
+ }
+
+- c->operation_success = 0;
++ c->operation_success = FALSE;
+ while (pa_operation_get_state (o) != PA_OPERATION_DONE) {
+- pa_threaded_mainloop_wait (c->mainloop);
+ CHECK_DEAD_GOTO (c, unlock_and_fail);
++ pa_threaded_mainloop_wait (c->mainloop);
+ }
+
+ pa_operation_unref (o);
+@@ -309,10 +317,10 @@ gst_pulsemixer_ctrl_open (GstPulseMixerCtrl * c)
+ goto unlock_and_fail;
+ }
+
+- c->operation_success = 0;
++ c->operation_success = FALSE;
+ while (pa_operation_get_state (o) != PA_OPERATION_DONE) {
+- pa_threaded_mainloop_wait (c->mainloop);
+ CHECK_DEAD_GOTO (c, unlock_and_fail);
++ pa_threaded_mainloop_wait (c->mainloop);
+ }
+
+ pa_operation_unref (o);
+@@ -353,6 +361,8 @@ gst_pulsemixer_ctrl_close (GstPulseMixerCtrl * c)
+ {
+ g_assert (c);
+
++ GST_DEBUG_OBJECT (c->object, "ctrl close");
++
+ if (c->mainloop)
+ pa_threaded_mainloop_stop (c->mainloop);
+
+@@ -386,6 +396,7 @@ gst_pulsemixer_ctrl_new (GObject * object, const gchar * server,
+ {
+ GstPulseMixerCtrl *c = NULL;
+
++ GST_DEBUG_OBJECT (object, "new mixer ctrl for %s", device);
+ c = g_new (GstPulseMixerCtrl, 1);
+ c->object = g_object_ref (object);
+ c->tracklist = NULL;
+@@ -398,7 +409,7 @@ gst_pulsemixer_ctrl_new (GObject * object, const gchar * server,
+
+ pa_cvolume_mute (&c->volume, PA_CHANNELS_MAX);
+ pa_channel_map_init (&c->channel_map);
+- c->muted = 0;
++ c->muted = FALSE;
+ c->index = PA_INVALID_INDEX;
+ c->type = type;
+ c->name = NULL;
+@@ -464,10 +475,10 @@ gst_pulsemixer_ctrl_timeout_event (pa_mainloop_api * a, pa_time_event * e,
+
+ if (c->update_mute) {
+ if (c->type == GST_PULSEMIXER_SINK)
+- o = pa_context_set_sink_mute_by_index (c->context, c->index, !!c->muted,
++ o = pa_context_set_sink_mute_by_index (c->context, c->index, c->muted,
+ NULL, NULL);
+ else
+- o = pa_context_set_source_mute_by_index (c->context, c->index, !!c->muted,
++ o = pa_context_set_source_mute_by_index (c->context, c->index, c->muted,
+ NULL, NULL);
+
+ if (!o)
+@@ -570,7 +581,7 @@ gst_pulsemixer_ctrl_set_mute (GstPulseMixerCtrl * c, GstMixerTrack * track,
+
+ pa_threaded_mainloop_lock (c->mainloop);
+
+- c->muted = !!mute;
++ c->muted = mute;
+ c->update_mute = TRUE;
+
+ if (c->track) {
+diff --git a/ext/pulse/pulsemixerctrl.h b/ext/pulse/pulsemixerctrl.h
+index 0dbc139..e6b67ad 100644
+--- a/ext/pulse/pulsemixerctrl.h
++++ b/ext/pulse/pulsemixerctrl.h
+@@ -1,3 +1,5 @@
++/*-*- Mode: C; c-basic-offset: 2 -*-*/
++
+ /*
+ * GStreamer pulseaudio plugin
+ *
+@@ -53,11 +55,17 @@ struct _GstPulseMixerCtrl
+
+ gchar *name, *description;
+ pa_channel_map channel_map;
++
+ pa_cvolume volume;
+- int muted;
++ gboolean muted:1;
++
++ gboolean update_volume:1;
++ gboolean update_mute:1;
++
++ gboolean operation_success:1;
++
+ guint32 index;
+ GstPulseMixerType type;
+- int operation_success;
+
+ GstMixerTrack *track;
+
+@@ -66,7 +74,6 @@ struct _GstPulseMixerCtrl
+ int outstandig_queries;
+ int ignore_queries;
+
+- gboolean update_volume, update_mute;
+ };
+
+ GstPulseMixerCtrl *gst_pulsemixer_ctrl_new (GObject *object, const gchar * server,
+diff --git a/ext/pulse/pulseprobe.c b/ext/pulse/pulseprobe.c
+index 588a9c3..6ebbfb2 100644
+--- a/ext/pulse/pulseprobe.c
++++ b/ext/pulse/pulseprobe.c
+@@ -1,3 +1,5 @@
++/*-*- Mode: C; c-basic-offset: 2 -*-*/
++
+ /*
+ * GStreamer pulseaudio plugin
+ *
+@@ -99,15 +101,21 @@ static gboolean
+ gst_pulseprobe_open (GstPulseProbe * c)
+ {
+ int e;
+- gchar *name = gst_pulse_client_name ();
++ gchar *name;
+
+ g_assert (c);
+
++ GST_DEBUG_OBJECT (c->object, "probe open");
++
+ c->mainloop = pa_threaded_mainloop_new ();
+- g_assert (c->mainloop);
++ if (!c->mainloop)
++ return FALSE;
+
+ e = pa_threaded_mainloop_start (c->mainloop);
+- g_assert (e == 0);
++ if (e < 0)
++ return FALSE;
++
++ name = gst_pulse_client_name ();
+
+ pa_threaded_mainloop_lock (c->mainloop);
+
+@@ -184,6 +192,8 @@ gst_pulseprobe_enumerate (GstPulseProbe * c)
+ {
+ pa_operation *o = NULL;
+
++ GST_DEBUG_OBJECT (c->object, "probe enumerate");
++
+ pa_threaded_mainloop_lock (c->mainloop);
+
+ if (c->enumerate_sinks) {
+@@ -197,7 +207,7 @@ gst_pulseprobe_enumerate (GstPulseProbe * c)
+ goto unlock_and_fail;
+ }
+
+- c->operation_success = 0;
++ c->operation_success = FALSE;
+
+ while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
+
+@@ -228,7 +238,7 @@ gst_pulseprobe_enumerate (GstPulseProbe * c)
+ goto unlock_and_fail;
+ }
+
+- c->operation_success = 0;
++ c->operation_success = FALSE;
+ while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
+
+ if (gst_pulseprobe_is_dead (c))
+@@ -268,6 +278,8 @@ gst_pulseprobe_close (GstPulseProbe * c)
+ {
+ g_assert (c);
+
++ GST_DEBUG_OBJECT (c->object, "probe close");
++
+ if (c->mainloop)
+ pa_threaded_mainloop_stop (c->mainloop);
+
+@@ -302,8 +314,11 @@ gst_pulseprobe_new (GObject * object, GObjectClass * klass,
+ c->prop_id = prop_id;
+ c->properties =
+ g_list_append (NULL, g_object_class_find_property (klass, "device"));
++
+ c->devices = NULL;
+- c->devices_valid = 0;
++ c->devices_valid = FALSE;
++
++ c->operation_success = FALSE;
+
+ return c;
+ }
+diff --git a/ext/pulse/pulseprobe.h b/ext/pulse/pulseprobe.h
+index bd20591..28cdbb8 100644
+--- a/ext/pulse/pulseprobe.h
++++ b/ext/pulse/pulseprobe.h
+@@ -1,3 +1,5 @@
++/*-*- Mode: C; c-basic-offset: 2 -*-*/
++
+ /*
+ * GStreamer pulseaudio plugin
+ *
+@@ -36,17 +38,20 @@ struct _GstPulseProbe
+ {
+ GObject *object;
+ gchar *server;
++
+ GList *devices;
+- gboolean devices_valid;
++ gboolean devices_valid:1;
++
++ gboolean operation_success:1;
++
++ gboolean enumerate_sinks:1;
++ gboolean enumerate_sources:1;
+
+ pa_threaded_mainloop *mainloop;
+ pa_context *context;
+
+ GList *properties;
+ guint prop_id;
+-
+- int enumerate_sinks, enumerate_sources;
+- int operation_success;
+ };
+
+ GstPulseProbe *gst_pulseprobe_new (GObject *object, GObjectClass * klass,
diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
-index dd47c33..1fe2b72 100644
+index 7ead4fe..1fe2b72 100644
--- a/ext/pulse/pulsesink.c
+++ b/ext/pulse/pulsesink.c
-@@ -730,6 +730,10 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
+@@ -1,3 +1,5 @@
++/*-*- Mode: C; c-basic-offset: 2 -*-*/
++
+ /* GStreamer pulseaudio plugin
+ *
+ * Copyright (c) 2004-2008 Lennart Poettering
+@@ -46,6 +48,8 @@
+
+ #include <gst/base/gstbasesink.h>
+ #include <gst/gsttaglist.h>
++#include <gst/interfaces/streamvolume.h>
++#include <gst/gst-i18n-plugin.h>
+
+ #include "pulsesink.h"
+ #include "pulseutil.h"
+@@ -62,6 +66,7 @@ GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
+ #define DEFAULT_DEVICE NULL
+ #define DEFAULT_DEVICE_NAME NULL
+ #define DEFAULT_VOLUME 1.0
++#define DEFAULT_MUTE FALSE
+ #define MAX_VOLUME 10.0
+
+ enum
+@@ -71,6 +76,7 @@ enum
+ PROP_DEVICE,
+ PROP_DEVICE_NAME,
+ PROP_VOLUME,
++ PROP_MUTE,
+ PROP_LAST
+ };
+
+@@ -105,12 +111,10 @@ struct _GstPulseRingBuffer
+ pa_stream *stream;
+
+ pa_sample_spec sample_spec;
+- gint64 offset;
+
+- gboolean corked;
+- gboolean in_commit;
+- gboolean paused;
+- guint required;
++ gboolean corked:1;
++ gboolean in_commit:1;
++ gboolean paused:1;
+ };
+
+ struct _GstPulseRingBufferClass
+@@ -216,8 +220,9 @@ gst_pulseringbuffer_init (GstPulseRingBuffer * pbuf,
+ pbuf->sample_spec.channels = 0;
+ #endif
+
+- pbuf->paused = FALSE;
+ pbuf->corked = TRUE;
++ pbuf->in_commit = FALSE;
++ pbuf->paused = FALSE;
+ }
+
+ static void
+@@ -543,6 +548,10 @@ gst_pulsering_stream_latency_cb (pa_stream * s, void *userdata)
+ pbuf = GST_PULSERING_BUFFER_CAST (userdata);
+ psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (pbuf));
+
++ if (!info) {
++ GST_LOG_OBJECT (psink, "latency update (information unknown)");
++ return;
++ }
+ #if HAVE_PULSE_0_9_11
+ sink_usec = info->configured_sink_usec;
+ #else
+@@ -557,6 +566,35 @@ gst_pulsering_stream_latency_cb (pa_stream * s, void *userdata)
+ info->sink_usec, sink_usec);
+ }
+
++#if HAVE_PULSE_0_9_15
++static void
++gst_pulsering_stream_event_cb (pa_stream * p, const char *name,
++ pa_proplist * pl, void *userdata)
++{
++ GstPulseSink *psink;
++ GstPulseRingBuffer *pbuf;
++
++ pbuf = GST_PULSERING_BUFFER_CAST (userdata);
++ psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (pbuf));
++
++ if (!strcmp (name, PA_STREAM_EVENT_REQUEST_CORK)) {
++ /* the stream wants to PAUSE, post a message for the application. */
++ GST_DEBUG_OBJECT (psink, "got request for CORK");
++ gst_element_post_message (GST_ELEMENT_CAST (psink),
++ gst_message_new_request_state (GST_OBJECT_CAST (psink),
++ GST_STATE_PAUSED));
++
++ } else if (!strcmp (name, PA_STREAM_EVENT_REQUEST_UNCORK)) {
++ GST_DEBUG_OBJECT (psink, "got request for UNCORK");
++ gst_element_post_message (GST_ELEMENT_CAST (psink),
++ gst_message_new_request_state (GST_OBJECT_CAST (psink),
++ GST_STATE_PLAYING));
++ } else {
++ GST_DEBUG_OBJECT (psink, "got unknown event %s", name);
++ }
++}
++#endif
++
+ /* This method should create a new stream of the given @spec. No playback should
+ * start yet so we start in the corked state. */
+ static gboolean
+@@ -564,15 +602,14 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
+ {
+ GstPulseSink *psink;
+ GstPulseRingBuffer *pbuf;
+- pa_buffer_attr buf_attr;
+- const pa_buffer_attr *buf_attr_ptr;
++ pa_buffer_attr wanted;
++ const pa_buffer_attr *actual;
+ pa_channel_map channel_map;
+ pa_operation *o = NULL;
+ pa_cvolume v, *pv;
+ pa_stream_flags_t flags;
+ const gchar *name;
+ GstAudioClock *clock;
+- gint64 time_offset;
+
+ psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (buf));
+ pbuf = GST_PULSERING_BUFFER_CAST (buf);
+@@ -622,19 +659,23 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
+ gst_pulsering_stream_overflow_cb, pbuf);
+ pa_stream_set_latency_update_callback (pbuf->stream,
+ gst_pulsering_stream_latency_cb, pbuf);
++#if HAVE_PULSE_0_9_15
++ pa_stream_set_event_callback (pbuf->stream,
++ gst_pulsering_stream_event_cb, pbuf);
++#endif
+
+ /* buffering requirements. When setting prebuf to 0, the stream will not pause
+ * when we cause an underrun, which causes time to continue. */
+- memset (&buf_attr, 0, sizeof (buf_attr));
+- buf_attr.tlength = spec->segtotal * spec->segsize;
+- buf_attr.maxlength = -1;
+- buf_attr.prebuf = 0;
+- buf_attr.minreq = -1;
++ memset (&wanted, 0, sizeof (wanted));
++ wanted.tlength = spec->segtotal * spec->segsize;
++ wanted.maxlength = -1;
++ wanted.prebuf = 0;
++ wanted.minreq = spec->segsize;
+
+- GST_INFO_OBJECT (psink, "tlength: %d", buf_attr.tlength);
+- GST_INFO_OBJECT (psink, "maxlength: %d", buf_attr.maxlength);
+- GST_INFO_OBJECT (psink, "prebuf: %d", buf_attr.prebuf);
+- GST_INFO_OBJECT (psink, "minreq: %d", buf_attr.minreq);
++ GST_INFO_OBJECT (psink, "tlength: %d", wanted.tlength);
++ GST_INFO_OBJECT (psink, "maxlength: %d", wanted.maxlength);
++ GST_INFO_OBJECT (psink, "prebuf: %d", wanted.prebuf);
++ GST_INFO_OBJECT (psink, "minreq: %d", wanted.minreq);
+
+ /* configure volume when we changed it, else we leave the default */
+ if (psink->volume_set) {
+@@ -653,6 +694,11 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
+ #endif
+ PA_STREAM_START_CORKED;
+
++#if HAVE_PULSE_0_9_12
++ if (psink->mute_set && psink->mute)
++ flags |= PA_STREAM_START_MUTED;
++#endif
++
+ /* we always start corked (see flags above) */
+ pbuf->corked = TRUE;
+
+@@ -660,25 +706,12 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
+ GST_LOG_OBJECT (psink, "connect for playback to device %s",
+ GST_STR_NULL (psink->device));
+ if (pa_stream_connect_playback (pbuf->stream, psink->device,
+- &buf_attr, flags, pv, NULL) < 0)
++ &wanted, flags, pv, NULL) < 0)
+ goto connect_failed;
+
+ /* our clock will now start from 0 again */
+ clock = GST_AUDIO_CLOCK (GST_BASE_AUDIO_SINK (psink)->provided_clock);
+ gst_audio_clock_reset (clock, 0);
+- time_offset = clock->abidata.ABI.time_offset;
+-
+- GST_LOG_OBJECT (psink, "got time offset %" GST_TIME_FORMAT,
+- GST_TIME_ARGS (time_offset));
+-
+- /* calculate the sample offset for 0 */
+- if (time_offset > 0)
+- pbuf->offset = gst_util_uint64_scale_int (time_offset,
+- pbuf->sample_spec.rate, GST_SECOND);
+- else
+- pbuf->offset = -gst_util_uint64_scale_int (-time_offset,
+- pbuf->sample_spec.rate, GST_SECOND);
+- GST_LOG_OBJECT (psink, "sample offset %" G_GINT64_FORMAT, pbuf->offset);
+
+ for (;;) {
+ pa_stream_state_t state;
+@@ -697,20 +730,24 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
pa_threaded_mainloop_wait (psink->mainloop);
}
@@ -31,18 +635,93 @@ index dd47c33..1fe2b72 100644
GST_LOG_OBJECT (psink, "stream is acquired now");
/* get the actual buffering properties now */
-@@ -1527,8 +1531,8 @@ gst_pulsesink_class_init (GstPulseSinkClass * klass)
+- buf_attr_ptr = pa_stream_get_buffer_attr (pbuf->stream);
++ actual = pa_stream_get_buffer_attr (pbuf->stream);
+
+- GST_INFO_OBJECT (psink, "tlength: %d (wanted: %d)", buf_attr_ptr->tlength,
+- buf_attr.tlength);
+- GST_INFO_OBJECT (psink, "maxlength: %d", buf_attr_ptr->maxlength);
+- GST_INFO_OBJECT (psink, "prebuf: %d", buf_attr_ptr->prebuf);
+- GST_INFO_OBJECT (psink, "minreq: %d (wanted %d)", buf_attr_ptr->minreq,
+- buf_attr.minreq);
++ GST_INFO_OBJECT (psink, "tlength: %d (wanted: %d)", actual->tlength,
++ wanted.tlength);
++ GST_INFO_OBJECT (psink, "maxlength: %d", actual->maxlength);
++ GST_INFO_OBJECT (psink, "prebuf: %d", actual->prebuf);
++ GST_INFO_OBJECT (psink, "minreq: %d (wanted %d)", actual->minreq,
++ wanted.minreq);
+
+- spec->segsize = buf_attr_ptr->minreq;
+- spec->segtotal = buf_attr_ptr->tlength / spec->segsize;
++ spec->segsize = actual->minreq;
++ spec->segtotal = actual->tlength / spec->segsize;
+
+ pa_threaded_mainloop_unlock (psink->mainloop);
+
+@@ -1096,8 +1133,10 @@ gst_pulseringbuffer_commit (GstRingBuffer * buf, guint64 * sample,
+ psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (pbuf));
+
+ /* FIXME post message rather than using a signal (as mixer interface) */
+- if (g_atomic_int_compare_and_exchange (&psink->notify, 1, 0))
++ if (g_atomic_int_compare_and_exchange (&psink->notify, 1, 0)) {
+ g_object_notify (G_OBJECT (psink), "volume");
++ g_object_notify (G_OBJECT (psink), "mute");
++ }
+
+ /* make sure the ringbuffer is started */
+ if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
+@@ -1139,21 +1178,8 @@ gst_pulseringbuffer_commit (GstRingBuffer * buf, guint64 * sample,
+ if (pbuf->paused)
+ goto was_paused;
+
+- /* correct for sample offset against the internal clock */
+- offset = *sample;
+- if (pbuf->offset >= 0) {
+- if (offset > pbuf->offset)
+- offset -= pbuf->offset;
+- else
+- offset = 0;
+- } else {
+- if (offset > -pbuf->offset)
+- offset += pbuf->offset;
+- else
+- offset = 0;
+- }
+ /* offset is in bytes */
+- offset *= bps;
++ offset = *sample * bps;
+
+ while (*toprocess > 0) {
+ size_t avail;
+@@ -1375,6 +1401,13 @@ gst_pulsesink_init_interfaces (GType type)
+ NULL,
+ NULL,
+ };
++#if HAVE_PULSE_0_9_12
++ static const GInterfaceInfo svol_iface_info = {
++ NULL, NULL, NULL
++ };
++
++ g_type_add_interface_static (type, GST_TYPE_STREAM_VOLUME, &svol_iface_info);
++#endif
+
+ g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
+ &implements_iface_info);
+@@ -1498,7 +1531,12 @@ gst_pulsesink_class_init (GstPulseSinkClass * klass)
g_object_class_install_property (gobject_class,
PROP_VOLUME,
g_param_spec_double ("volume", "Volume",
- "Volume of this stream, 1.0=100%", 0.0, MAX_VOLUME, DEFAULT_VOLUME,
-- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ "Linear volume of this stream, 1.0=100%", 0.0, MAX_VOLUME,
+ DEFAULT_VOLUME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class,
- PROP_MUTE,
- g_param_spec_boolean ("mute", "Mute",
-@@ -1588,10 +1592,10 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)
++ g_object_class_install_property (gobject_class,
++ PROP_MUTE,
++ g_param_spec_boolean ("mute", "Mute",
++ "Mute state of this stream", DEFAULT_MUTE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ #endif
+ }
+@@ -1554,9 +1592,12 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)
pulsesink->device = NULL;
pulsesink->device_description = NULL;
@@ -50,12 +729,13 @@ index dd47c33..1fe2b72 100644
+ pulsesink->volume = DEFAULT_VOLUME;
pulsesink->volume_set = FALSE;
-- pulsesink->mute = FALSE;
+ pulsesink->mute = DEFAULT_MUTE;
- pulsesink->mute_set = FALSE;
-
++ pulsesink->mute_set = FALSE;
++
pulsesink->notify = 0;
-@@ -1654,9 +1658,6 @@ gst_pulsesink_set_volume (GstPulseSink * psink, gdouble volume)
+
+ /* needed for conditional execution */
+@@ -1617,9 +1658,6 @@ gst_pulsesink_set_volume (GstPulseSink * psink, gdouble volume)
GST_DEBUG_OBJECT (psink, "setting volume to %f", volume);
@@ -65,7 +745,7 @@ index dd47c33..1fe2b72 100644
pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer);
if (pbuf == NULL || pbuf->stream == NULL)
goto no_buffer;
-@@ -1683,6 +1684,9 @@ unlock:
+@@ -1646,6 +1684,9 @@ unlock:
/* ERRORS */
no_buffer:
{
@@ -75,27 +755,81 @@ index dd47c33..1fe2b72 100644
GST_DEBUG_OBJECT (psink, "we have no ringbuffer");
goto unlock;
}
-@@ -1711,9 +1715,6 @@ gst_pulsesink_set_mute (GstPulseSink * psink, gboolean mute)
-
- GST_DEBUG_OBJECT (psink, "setting mute state to %d", mute);
+@@ -1664,6 +1705,61 @@ volume_failed:
+ }
-- psink->mute = mute;
-- psink->mute_set = TRUE;
--
- pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer);
- if (pbuf == NULL || pbuf->stream == NULL)
- goto no_buffer;
-@@ -1738,6 +1739,9 @@ unlock:
- /* ERRORS */
- no_buffer:
- {
+ static void
++gst_pulsesink_set_mute (GstPulseSink * psink, gboolean mute)
++{
++ pa_operation *o = NULL;
++ GstPulseRingBuffer *pbuf;
++ uint32_t idx;
++
++ pa_threaded_mainloop_lock (psink->mainloop);
++
++ GST_DEBUG_OBJECT (psink, "setting mute state to %d", mute);
++
++ pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer);
++ if (pbuf == NULL || pbuf->stream == NULL)
++ goto no_buffer;
++
++ if ((idx = pa_stream_get_index (pbuf->stream)) == PA_INVALID_INDEX)
++ goto no_index;
++
++ if (!(o = pa_context_set_sink_input_mute (pbuf->context, idx,
++ mute, NULL, NULL)))
++ goto mute_failed;
++
++ /* We don't really care about the result of this call */
++unlock:
++
++ if (o)
++ pa_operation_unref (o);
++
++ pa_threaded_mainloop_unlock (psink->mainloop);
++
++ return;
++
++ /* ERRORS */
++no_buffer:
++ {
+ psink->mute = mute;
+ psink->mute_set = TRUE;
+
- GST_DEBUG_OBJECT (psink, "we have no ringbuffer");
- goto unlock;
- }
-@@ -1788,7 +1792,7 @@ gst_pulsesink_get_volume (GstPulseSink * psink)
++ GST_DEBUG_OBJECT (psink, "we have no ringbuffer");
++ goto unlock;
++ }
++no_index:
++ {
++ GST_DEBUG_OBJECT (psink, "we don't have a stream index");
++ goto unlock;
++ }
++mute_failed:
++ {
++ GST_ELEMENT_ERROR (psink, RESOURCE, FAILED,
++ ("pa_stream_set_sink_input_mute() failed: %s",
++ pa_strerror (pa_context_errno (pbuf->context))), (NULL));
++ goto unlock;
++ }
++}
++
++static void
+ gst_pulsesink_sink_input_info_cb (pa_context * c, const pa_sink_input_info * i,
+ int eol, void *userdata)
+ {
+@@ -1682,8 +1778,10 @@ gst_pulsesink_sink_input_info_cb (pa_context * c, const pa_sink_input_info * i,
+ /* If the index doesn't match our current stream,
+ * it implies we just recreated the stream (caps change)
+ */
+- if (i->index == pa_stream_get_index (pbuf->stream))
++ if (i->index == pa_stream_get_index (pbuf->stream)) {
+ psink->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume));
++ psink->mute = i->mute;
++ }
+
+ done:
+ pa_threaded_mainloop_signal (psink->mainloop, 0);
+@@ -1694,7 +1792,7 @@ gst_pulsesink_get_volume (GstPulseSink * psink)
{
GstPulseRingBuffer *pbuf;
pa_operation *o = NULL;
@@ -104,7 +838,7 @@ index dd47c33..1fe2b72 100644
uint32_t idx;
pa_threaded_mainloop_lock (psink->mainloop);
-@@ -1810,11 +1814,12 @@ gst_pulsesink_get_volume (GstPulseSink * psink)
+@@ -1716,11 +1814,12 @@ gst_pulsesink_get_volume (GstPulseSink * psink)
goto unlock;
}
@@ -118,29 +852,257 @@ index dd47c33..1fe2b72 100644
pa_threaded_mainloop_unlock (psink->mainloop);
if (v > MAX_VOLUME) {
-@@ -1850,7 +1855,7 @@ gst_pulsesink_get_mute (GstPulseSink * psink)
- GstPulseRingBuffer *pbuf;
- pa_operation *o = NULL;
- uint32_t idx;
-- gboolean mute;
+@@ -1749,6 +1848,63 @@ info_failed:
+ goto unlock;
+ }
+ }
++
++static gboolean
++gst_pulsesink_get_mute (GstPulseSink * psink)
++{
++ GstPulseRingBuffer *pbuf;
++ pa_operation *o = NULL;
++ uint32_t idx;
+ gboolean mute = FALSE;
++
++ pa_threaded_mainloop_lock (psink->mainloop);
++
++ pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer);
++ if (pbuf == NULL || pbuf->stream == NULL)
++ goto no_buffer;
++
++ if ((idx = pa_stream_get_index (pbuf->stream)) == PA_INVALID_INDEX)
++ goto no_index;
++
++ if (!(o = pa_context_get_sink_input_info (pbuf->context, idx,
++ gst_pulsesink_sink_input_info_cb, pbuf)))
++ goto info_failed;
++
++ while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
++ pa_threaded_mainloop_wait (psink->mainloop);
++ if (gst_pulsering_is_dead (psink, pbuf))
++ goto unlock;
++ }
++
++ mute = psink->mute;
++
++unlock:
++ if (o)
++ pa_operation_unref (o);
++
++ pa_threaded_mainloop_unlock (psink->mainloop);
++
++ return mute;
++
++ /* ERRORS */
++no_buffer:
++ {
++ GST_DEBUG_OBJECT (psink, "we have no ringbuffer");
++ goto unlock;
++ }
++no_index:
++ {
++ GST_DEBUG_OBJECT (psink, "we don't have a stream index");
++ goto unlock;
++ }
++info_failed:
++ {
++ GST_ELEMENT_ERROR (psink, RESOURCE, FAILED,
++ ("pa_context_get_sink_input_info() failed: %s",
++ pa_strerror (pa_context_errno (pbuf->context))), (NULL));
++ goto unlock;
++ }
++}
+ #endif
- pa_threaded_mainloop_lock (psink->mainloop);
+ static void
+@@ -1844,6 +2000,9 @@ gst_pulsesink_set_property (GObject * object,
+ case PROP_VOLUME:
+ gst_pulsesink_set_volume (pulsesink, g_value_get_double (value));
+ break;
++ case PROP_MUTE:
++ gst_pulsesink_set_mute (pulsesink, g_value_get_boolean (value));
++ break;
+ #endif
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+@@ -1872,6 +2031,9 @@ gst_pulsesink_get_property (GObject * object,
+ case PROP_VOLUME:
+ g_value_set_double (value, gst_pulsesink_get_volume (pulsesink));
+ break;
++ case PROP_MUTE:
++ g_value_set_boolean (value, gst_pulsesink_get_mute (pulsesink));
++ break;
+ #endif
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+@@ -1927,6 +2089,10 @@ gst_pulsesink_change_props (GstPulseSink * psink, GstTagList * l)
+ {
+ static const gchar *const map[] = {
+ GST_TAG_TITLE, PA_PROP_MEDIA_TITLE,
++
++ /* might get overriden in the next iteration by GST_TAG_ARTIST */
++ GST_TAG_PERFORMER, PA_PROP_MEDIA_ARTIST,
++
+ GST_TAG_ARTIST, PA_PROP_MEDIA_ARTIST,
+ GST_TAG_LANGUAGE_CODE, PA_PROP_MEDIA_LANGUAGE,
+ GST_TAG_LOCATION, PA_PROP_MEDIA_FILENAME,
+@@ -2015,9 +2181,12 @@ gst_pulsesink_event (GstBaseSink * sink, GstEvent * event)
+ gst_tag_list_get_string (l, GST_TAG_LOCATION, &location);
+ gst_tag_list_get_string (l, GST_TAG_DESCRIPTION, &description);
-@@ -1871,11 +1876,12 @@ gst_pulsesink_get_mute (GstPulseSink * psink)
- goto unlock;
++ if (!artist)
++ gst_tag_list_get_string (l, GST_TAG_PERFORMER, &artist);
++
+ if (title && artist)
+ t = buf =
+- g_strdup_printf ("'%s' by '%s'", g_strstrip (title),
++ g_strdup_printf (_("'%s' by '%s'"), g_strstrip (title),
+ g_strstrip (artist));
+ else if (title)
+ t = g_strstrip (title);
+diff --git a/ext/pulse/pulsesink.h b/ext/pulse/pulsesink.h
+index 8db3cbd..ae0ad95 100644
+--- a/ext/pulse/pulsesink.h
++++ b/ext/pulse/pulsesink.h
+@@ -1,3 +1,5 @@
++/*-*- Mode: C; c-basic-offset: 2 -*-*/
++
+ /*
+ * GStreamer pulseaudio plugin
+ *
+@@ -60,12 +62,16 @@ struct _GstPulseSink
+ GstPulseProbe *probe;
+
+ gdouble volume;
+- gboolean volume_set;
+- gint notify;
+-
++ gboolean volume_set:1;
++ gboolean mute:1;
++ gboolean mute_set:1;
++
++ gboolean pa_defer_ran:1;
++
++ gint notify; /* atomic */
++
+ const gchar *pa_version;
+
+- gboolean pa_defer_ran;
+ };
+
+ struct _GstPulseSinkClass
+diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c
+index fa60345..d53acf8 100644
+--- a/ext/pulse/pulsesrc.c
++++ b/ext/pulse/pulsesrc.c
+@@ -528,6 +528,11 @@ gst_pulsesrc_stream_latency_update_cb (pa_stream * s, void *userdata)
+
+ info = pa_stream_get_timing_info (s);
+
++ if (!info) {
++ GST_LOG_OBJECT (GST_PULSESRC_CAST (userdata),
++ "latency update (information unknown)");
++ return;
++ }
+ #if HAVE_PULSE_0_9_11
+ source_usec = info->configured_source_usec;
+ #else
+@@ -945,25 +950,25 @@ no_nego_needed:
+ static gboolean
+ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
+ {
+- pa_buffer_attr buf_attr;
+- const pa_buffer_attr *buf_attr_ptr;
++ pa_buffer_attr wanted;
++ const pa_buffer_attr *actual;
+ GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
+
+ pa_threaded_mainloop_lock (pulsesrc->mainloop);
+
+- buf_attr.maxlength = -1;
+- buf_attr.tlength = -1;
+- buf_attr.prebuf = 0;
+- buf_attr.minreq = -1;
+- buf_attr.fragsize = spec->segsize;
++ wanted.maxlength = -1;
++ wanted.tlength = -1;
++ wanted.prebuf = 0;
++ wanted.minreq = -1;
++ wanted.fragsize = spec->segsize;
+
+- GST_INFO_OBJECT (pulsesrc, "maxlength: %d", buf_attr.maxlength);
+- GST_INFO_OBJECT (pulsesrc, "tlength: %d", buf_attr.tlength);
+- GST_INFO_OBJECT (pulsesrc, "prebuf: %d", buf_attr.prebuf);
+- GST_INFO_OBJECT (pulsesrc, "minreq: %d", buf_attr.minreq);
+- GST_INFO_OBJECT (pulsesrc, "fragsize: %d", buf_attr.fragsize);
++ GST_INFO_OBJECT (pulsesrc, "maxlength: %d", wanted.maxlength);
++ GST_INFO_OBJECT (pulsesrc, "tlength: %d", wanted.tlength);
++ GST_INFO_OBJECT (pulsesrc, "prebuf: %d", wanted.prebuf);
++ GST_INFO_OBJECT (pulsesrc, "minreq: %d", wanted.minreq);
++ GST_INFO_OBJECT (pulsesrc, "fragsize: %d", wanted.fragsize);
+
+- if (pa_stream_connect_record (pulsesrc->stream, pulsesrc->device, &buf_attr,
++ if (pa_stream_connect_record (pulsesrc->stream, pulsesrc->device, &wanted,
+ PA_STREAM_INTERPOLATE_TIMING |
+ PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_NOT_MONOTONOUS |
+ #if HAVE_PULSE_0_9_11
+@@ -998,20 +1003,23 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
}
-+ mute = psink->mute;
+ /* get the actual buffering properties now */
+- buf_attr_ptr = pa_stream_get_buffer_attr (pulsesrc->stream);
++ actual = pa_stream_get_buffer_attr (pulsesrc->stream);
+
+- GST_INFO_OBJECT (pulsesrc, "maxlength: %d", buf_attr_ptr->maxlength);
++ GST_INFO_OBJECT (pulsesrc, "maxlength: %d", actual->maxlength);
+ GST_INFO_OBJECT (pulsesrc, "tlength: %d (wanted: %d)",
+- buf_attr_ptr->tlength, buf_attr.tlength);
+- GST_INFO_OBJECT (pulsesrc, "prebuf: %d", buf_attr_ptr->prebuf);
+- GST_INFO_OBJECT (pulsesrc, "minreq: %d (wanted %d)", buf_attr_ptr->minreq,
+- buf_attr.minreq);
++ actual->tlength, wanted.tlength);
++ GST_INFO_OBJECT (pulsesrc, "prebuf: %d", actual->prebuf);
++ GST_INFO_OBJECT (pulsesrc, "minreq: %d (wanted %d)", actual->minreq,
++ wanted.minreq);
+ GST_INFO_OBJECT (pulsesrc, "fragsize: %d (wanted %d)",
+- buf_attr_ptr->fragsize, buf_attr.fragsize);
++ actual->fragsize, wanted.fragsize);
+
+- /* adjust latency again */
+- spec->segsize = buf_attr_ptr->fragsize;
+- spec->segtotal = buf_attr_ptr->maxlength / spec->segsize;
++ if (actual->fragsize >= wanted.fragsize) {
++ spec->segsize = actual->fragsize;
++ } else {
++ spec->segsize = actual->fragsize * (wanted.fragsize / actual->fragsize);
++ }
++ spec->segtotal = actual->maxlength / spec->segsize;
+
+ pa_threaded_mainloop_unlock (pulsesrc->mainloop);
+
+diff --git a/ext/pulse/pulsesrc.h b/ext/pulse/pulsesrc.h
+index 2358eba..be89434 100644
+--- a/ext/pulse/pulsesrc.h
++++ b/ext/pulse/pulsesrc.h
+@@ -1,3 +1,5 @@
++/*-*- Mode: C; c-basic-offset: 2 -*-*/
+
- unlock:
- if (o)
- pa_operation_unref (o);
+ /*
+ * GStreamer pulseaudio plugin
+ *
+@@ -70,10 +72,10 @@ struct _GstPulseSrc
+ GstPulseMixerCtrl *mixer;
+ GstPulseProbe *probe;
-- mute = psink->mute;
- pa_threaded_mainloop_unlock (psink->mainloop);
+- gboolean corked;
+- gboolean operation_success;
+- gboolean paused;
+- gboolean in_read;
++ gboolean corked:1;
++ gboolean operation_success:1;
++ gboolean paused:1;
++ gboolean in_read:1;
+ };
- return mute;
---
-1.6.3.3
-
+ struct _GstPulseSrcClass
- Previous message (by thread): rpms/colossus/F-12 .cvsignore, 1.7, 1.8 colossus-gen-tarball.sh, 1.1, 1.2 colossus.spec, 1.9, 1.10 import.log, 1.6, 1.7 sources, 1.7, 1.8
- Next message (by thread): rpms/python-paste-script/EL-5 python-paste-script.spec,1.11,1.12
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list