diff options
Diffstat (limited to 'src/pulsecore/source.c')
-rw-r--r-- | src/pulsecore/source.c | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 21902509..53697c57 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -180,6 +180,7 @@ pa_source* pa_source_new( s->core = core; s->state = PA_SOURCE_INIT; s->flags = flags; + s->suspend_cause = 0; s->name = pa_xstrdup(name); s->proplist = pa_proplist_copy(data->proplist); s->driver = pa_xstrdup(pa_path_get_filename(data->driver)); @@ -308,20 +309,19 @@ void pa_source_put(pa_source *s) { pa_assert(s->rtpoll); pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency); - if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL)) { - s->flags |= PA_SOURCE_DECIBEL_VOLUME; + /* Generally, flags should be initialized via pa_source_new(). As + * a special exception we allow volume related flags to be set + * between _new() and _put(). */ - s->thread_info.soft_volume = s->soft_volume; - s->thread_info.soft_muted = s->muted; - } + if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL)) + s->flags |= PA_SOURCE_DECIBEL_VOLUME; - if (s->flags & PA_SOURCE_DECIBEL_VOLUME) - s->n_volume_steps = PA_VOLUME_NORM+1; + s->thread_info.soft_volume = s->soft_volume; + s->thread_info.soft_muted = s->muted; - if (s->flags & PA_SOURCE_DYNAMIC_LATENCY) - s->fixed_latency = 0; - else if (s->fixed_latency <= 0) - s->fixed_latency = DEFAULT_FIXED_LATENCY; + pa_assert((s->flags & PA_SOURCE_HW_VOLUME_CTRL) || (s->base_volume == PA_VOLUME_NORM && s->flags & PA_SOURCE_DECIBEL_VOLUME)); + pa_assert(!(s->flags & PA_SOURCE_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1); + pa_assert(!(s->flags & PA_SOURCE_DYNAMIC_LATENCY) == (s->fixed_latency != 0)); pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0); @@ -428,14 +428,25 @@ int pa_source_update_status(pa_source*s) { } /* Called from main context */ -int pa_source_suspend(pa_source *s, pa_bool_t suspend) { +int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause) { pa_source_assert_ref(s); pa_assert(PA_SOURCE_IS_LINKED(s->state)); + pa_assert(cause != 0); if (s->monitor_of) return -PA_ERR_NOTSUPPORTED; if (suspend) + s->suspend_cause |= cause; + else + s->suspend_cause &= ~cause; + + if ((pa_source_get_state(s) == PA_SOURCE_SUSPENDED) == !!s->suspend_cause) + return 0; + + pa_log_debug("Suspend cause of source %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming"); + + if (suspend) return source_set_state(s, PA_SOURCE_SUSPENDED); else return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE); @@ -757,8 +768,12 @@ pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) { pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0); - if (old_muted != s->muted) + if (old_muted != s->muted) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + + /* Make sure the soft mute status stays in sync */ + pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0); + } } return s->muted; @@ -1033,12 +1048,13 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ } /* Called from main thread */ -int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) { +int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) { uint32_t idx; pa_source *source; int ret = 0; pa_core_assert_ref(c); + pa_assert(cause != 0); for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) { int r; @@ -1046,7 +1062,7 @@ int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) { if (source->monitor_of) continue; - if ((r = pa_source_suspend(source, suspend)) < 0) + if ((r = pa_source_suspend(source, suspend, cause)) < 0) ret = r; } @@ -1118,8 +1134,11 @@ pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) { if (result != (pa_usec_t) -1) result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency); - s->thread_info.requested_latency = result; - s->thread_info.requested_latency_valid = TRUE; + if (PA_SOURCE_IS_LINKED(s->thread_info.state)) { + /* Only cache this if we are fully set up */ + s->thread_info.requested_latency = result; + s->thread_info.requested_latency_valid = TRUE; + } return result; } @@ -1276,6 +1295,21 @@ void pa_source_set_latency_range_within_thread(pa_source *s, pa_usec_t min_laten pa_source_invalidate_requested_latency(s); } +/* Called from main thread, before the source is put */ +void pa_source_set_fixed_latency(pa_source *s, pa_usec_t latency) { + pa_source_assert_ref(s); + + pa_assert(pa_source_get_state(s) == PA_SOURCE_INIT); + + if (latency < ABSOLUTE_MIN_LATENCY) + latency = ABSOLUTE_MIN_LATENCY; + + if (latency > ABSOLUTE_MAX_LATENCY) + latency = ABSOLUTE_MAX_LATENCY; + + s->fixed_latency = latency; +} + /* Called from main thread */ size_t pa_source_get_max_rewind(pa_source *s) { size_t r; |