From c7bce9fd5aba9125fb030fb3c61fa6140a743396 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 23 Sep 2007 22:29:31 +0000 Subject: 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 --- src/pulsemixerctrl.c | 122 ++++++++++++++++++++++++++++++++++----------------- src/pulsemixerctrl.h | 9 +++- 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); -- cgit