summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-09-23 22:29:31 +0000
committerLennart Poettering <lennart@poettering.net>2007-09-23 22:29:31 +0000
commitc7bce9fd5aba9125fb030fb3c61fa6140a743396 (patch)
tree56f5161e2c5ffd658842208226e673a1f0873e36
parent16866cadb266001268b20a90839fb0be2770b24a (diff)
ignore old volume/mute change notifications when we change the volume
git-svn-id: file:///home/lennart/svn/public/gst-pulse/trunk@66 bb39ca4e-bce3-0310-b5d4-eea78a553289
-rw-r--r--src/pulsemixerctrl.c122
-rw-r--r--src/pulsemixerctrl.h9
2 files changed, 88 insertions, 43 deletions
diff --git a/src/pulsemixerctrl.c b/src/pulsemixerctrl.c
index 883331f..df29a48 100644
--- a/src/pulsemixerctrl.c
+++ b/src/pulsemixerctrl.c
@@ -53,10 +53,21 @@ static void gst_pulsemixer_ctrl_context_state_cb(pa_context *context, void *user
}
static void gst_pulsemixer_ctrl_sink_info_cb(pa_context *context, const pa_sink_info *i, int eol, void *userdata) {
- GstPulseMixerCtrl *c = (GstPulseMixerCtrl*) userdata;
+ GstPulseMixerCtrl *c = userdata;
/* Called from the background thread! */
+
+ if (c->outstandig_queries > 0)
+ c->outstandig_queries--;
+ if (c->ignore_queries > 0 || c->time_event) {
+
+ if (c->ignore_queries > 0)
+ c->ignore_queries--;
+
+ return;
+ }
+
if (!i && eol < 0) {
c->operation_success = 0;
pa_threaded_mainloop_signal(c->mainloop, 0);
@@ -76,7 +87,6 @@ static void gst_pulsemixer_ctrl_sink_info_cb(pa_context *context, const pa_sink_
c->muted = i->mute;
c->type = GST_PULSEMIXER_SINK;
-
if (c->track)
c->track->flags = (c->track->flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0);
@@ -85,10 +95,21 @@ static void gst_pulsemixer_ctrl_sink_info_cb(pa_context *context, const pa_sink_
}
static void gst_pulsemixer_ctrl_source_info_cb(pa_context *context, const pa_source_info *i, int eol, void *userdata) {
- GstPulseMixerCtrl *c = (GstPulseMixerCtrl*) userdata;
+ GstPulseMixerCtrl *c = userdata;
/* Called from the background thread! */
+ if (c->outstandig_queries > 0)
+ c->outstandig_queries--;
+
+ if (c->ignore_queries > 0 || c->time_event) {
+
+ if (c->ignore_queries > 0)
+ c->ignore_queries--;
+
+ return;
+ }
+
if (!i && eol < 0) {
c->operation_success = 0;
pa_threaded_mainloop_signal(c->mainloop, 0);
@@ -138,6 +159,8 @@ static void gst_pulsemixer_ctrl_subscribe_cb(pa_context *context, pa_subscriptio
}
pa_operation_unref(o);
+
+ c->outstandig_queries++;
}
static void gst_pulsemixer_ctrl_success_cb(pa_context *context, int success, void *userdata) {
@@ -315,6 +338,7 @@ GstPulseMixerCtrl* gst_pulsemixer_ctrl_new(const gchar *server, const gchar *dev
c->mainloop = NULL;
c->context = NULL;
c->track = NULL;
+ c->ignore_queries = c->outstandig_queries = 0;
pa_cvolume_mute(&c->volume, PA_CHANNELS_MAX);
pa_channel_map_init(&c->channel_map);
@@ -325,6 +349,7 @@ GstPulseMixerCtrl* gst_pulsemixer_ctrl_new(const gchar *server, const gchar *dev
c->description = NULL;
c->time_event = NULL;
+ c->update_volume = c->update_mute = FALSE;
if (!(gst_pulsemixer_ctrl_open(c))) {
gst_pulsemixer_ctrl_free(c);
@@ -355,22 +380,59 @@ const GList* gst_pulsemixer_ctrl_list_tracks(GstPulseMixerCtrl *c) {
static void gst_pulsemixer_ctrl_timeout_event(pa_mainloop_api *a, pa_time_event *e, const struct timeval *tv, void *userdata) {
pa_operation *o;
GstPulseMixerCtrl *c = GST_PULSEMIXER_CTRL(userdata);
-
- if (c->type == GST_PULSEMIXER_SINK)
- o = pa_context_set_sink_volume_by_index(c->context, c->index, &c->volume, NULL, NULL);
- else
- o = pa_context_set_source_volume_by_index(c->context, c->index, &c->volume, NULL, NULL);
-
- if (!(o))
- GST_WARNING("Failed to set device volume: %s", pa_strerror(pa_context_errno(c->context)));
- else
- pa_operation_unref(o);
+ if (c->update_volume) {
+ if (c->type == GST_PULSEMIXER_SINK)
+ o = pa_context_set_sink_volume_by_index(c->context, c->index, &c->volume, NULL, NULL);
+ else
+ o = pa_context_set_source_volume_by_index(c->context, c->index, &c->volume, NULL, NULL);
+
+ if (!o)
+ GST_WARNING("Failed to set device volume: %s", pa_strerror(pa_context_errno(c->context)));
+ else
+ pa_operation_unref(o);
+
+ c->update_volume = FALSE;
+ }
+
+ if (c->update_mute) {
+ if (c->type == GST_PULSEMIXER_SINK)
+ 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, NULL, NULL);
+
+ if (!o)
+ GST_WARNING("Failed to set device mute: %s", pa_strerror(pa_context_errno(c->context)));
+ else
+ pa_operation_unref(o);
+
+ c->update_mute = FALSE;
+ }
+
+ /* Make sure that all outstanding queries are being ignored */
+ c->ignore_queries = c->outstandig_queries;
+
g_assert(e == c->time_event);
a->time_free(e);
c->time_event = NULL;
}
+#define UPDATE_DELAY 50000
+
+static void restart_time_event(GstPulseMixerCtrl *c) {
+ g_assert(c);
+
+ if (c->time_event)
+ return;
+
+ /* Updating the volume too often will cause a lot of traffic
+ * when accessing a networked server. Therefore we make sure
+ * to update the volume only once every 50ms */
+ struct timeval tv;
+ pa_mainloop_api *api = pa_threaded_mainloop_get_api(c->mainloop);
+ c->time_event = api->time_new(api, pa_timeval_add(pa_gettimeofday(&tv), UPDATE_DELAY), gst_pulsemixer_ctrl_timeout_event, c);
+}
+
void gst_pulsemixer_ctrl_set_volume(GstPulseMixerCtrl *c, GstMixerTrack *track, gint *volumes) {
pa_cvolume v;
int i;
@@ -386,16 +448,10 @@ void gst_pulsemixer_ctrl_set_volume(GstPulseMixerCtrl *c, GstMixerTrack *track,
v.channels = c->channel_map.channels;
c->volume = v;
+ c->update_volume = TRUE;
+
+ restart_time_event(c);
- if (!c->time_event) {
- /* Updating the volume too often will cause a lot of traffic
- * when accessing a networked server. Therefore we make sure
- * to update the volume only once every 100ms */
- struct timeval tv;
- pa_mainloop_api *api = pa_threaded_mainloop_get_api(c->mainloop);
- c->time_event = api->time_new(api, pa_timeval_add(pa_gettimeofday(&tv), 100000), gst_pulsemixer_ctrl_timeout_event, c);
- }
-
pa_threaded_mainloop_unlock(c->mainloop);
}
@@ -419,34 +475,18 @@ void gst_pulsemixer_ctrl_set_record(GstPulseMixerCtrl *c, GstMixerTrack *track,
}
void gst_pulsemixer_ctrl_set_mute(GstPulseMixerCtrl *c, GstMixerTrack *track, gboolean mute) {
- pa_operation *o = NULL;
-
g_assert(c);
g_assert(track == c->track);
pa_threaded_mainloop_lock(c->mainloop);
- if (c->type == GST_PULSEMIXER_SINK)
- o = pa_context_set_sink_mute_by_index(c->context, c->index, !!mute, NULL, NULL);
- else
- o = pa_context_set_source_mute_by_index(c->context, c->index, !!mute, NULL, NULL);
-
- if (!(o)) {
- GST_WARNING("Failed to set device mute status: %s", pa_strerror(pa_context_errno(c->context)));
- goto unlock_and_fail;
- }
-
- c->muted = mute;
+ c->muted = !!mute;
+ c->update_mute = TRUE;
if (c->track)
c->track->flags = (c->track->flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0);
- /* We're not interested in the return code of this operation */
-
-unlock_and_fail:
+ restart_time_event(c);
- if (o)
- pa_operation_unref(o);
-
pa_threaded_mainloop_unlock(c->mainloop);
}
diff --git a/src/pulsemixerctrl.h b/src/pulsemixerctrl.h
index 378898d..40b4213 100644
--- a/src/pulsemixerctrl.h
+++ b/src/pulsemixerctrl.h
@@ -38,8 +38,8 @@ typedef struct _GstPulseMixerCtrl GstPulseMixerCtrl;
typedef enum {
GST_PULSEMIXER_UNKNOWN,
GST_PULSEMIXER_SINK,
- GST_PULSEMIXER_SOURCE }
-GstPulseMixerType;
+ GST_PULSEMIXER_SOURCE
+} GstPulseMixerType;
struct _GstPulseMixerCtrl {
GList *tracklist;
@@ -60,6 +60,11 @@ struct _GstPulseMixerCtrl {
GstMixerTrack *track;
pa_time_event *time_event;
+
+ int outstandig_queries;
+ int ignore_queries;
+
+ gboolean update_volume, update_mute;
};
GstPulseMixerCtrl* gst_pulsemixer_ctrl_new(const gchar *server, const gchar *device, GstPulseMixerType type);