o->rtpoll_item = NULL;
if (o->userdata->master == o)
- pa_sink_detach_from_thread(o->userdata->sink);
+ pa_sink_detach_within_thread(o->userdata->sink);
}
/* Called from main context */
return i;
}
+static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
+ pa_assert(i);
+
+ if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
+ pa_assert_se(i->sink->n_corked -- >= 1);
+ else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
+ i->sink->n_corked++;
+}
+
static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
pa_sink_input *ssync;
pa_assert(i);
if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0)
return -1;
+ update_n_corked(i, state);
i->state = state;
- for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
+
+ for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
+ update_n_corked(ssync, state);
ssync->state = state;
- for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
+ }
+ for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
+ update_n_corked(ssync, state);
ssync->state = state;
+ }
return 0;
}
s->channel_map = *map;
s->inputs = pa_idxset_new(NULL, NULL);
+ s->n_corked = 0;
pa_cvolume_reset(&s->volume, spec->channels);
s->muted = 0;
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
}
+unsigned pa_sink_linked_by(pa_sink *s) {
+ unsigned ret;
+
+ pa_sink_assert_ref(s);
+ pa_assert(PA_SINK_LINKED(s->state));
+
+ ret = pa_idxset_size(s->inputs);
+
+ if (s->monitor_source)
+ ret += pa_source_used_by(s->monitor_source);
+
+ return ret;
+}
+
unsigned pa_sink_used_by(pa_sink *s) {
unsigned ret;
ret = pa_idxset_size(s->inputs);
+ pa_assert(ret >= s->n_corked);
+
+ ret -= s->n_corked;
+
if (s->monitor_source)
ret += pa_source_used_by(s->monitor_source);
pa_channel_map channel_map;
pa_idxset *inputs;
- pa_source *monitor_source;
+ unsigned n_corked;
+ pa_source *monitor_source;
pa_cvolume volume;
int muted;
void pa_sink_set_mute(pa_sink *sink, int mute);
int pa_sink_get_mute(pa_sink *sink);
-unsigned pa_sink_used_by(pa_sink *s);
+unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */
+unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */
#define pa_sink_get_state(s) ((s)->state)
/* To be called exclusively by the sink driver, from IO context */
if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0)
return -1;
+ if (o->state == PA_SOURCE_OUTPUT_CORKED && state != PA_SOURCE_OUTPUT_CORKED)
+ pa_assert_se(o->source->n_corked -- >= 1);
+ else if (o->state != PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_CORKED)
+ o->source->n_corked++;
+
o->state = state;
+
return 0;
}
s->channel_map = *map;
s->outputs = pa_idxset_new(NULL, NULL);
+ s->n_corked = 0;
s->monitor_of = NULL;
pa_cvolume_reset(&s->volume, spec->channels);
s->rtpoll = p;
}
-unsigned pa_source_used_by(pa_source *s) {
+unsigned pa_source_linked_by(pa_source *s) {
pa_source_assert_ref(s);
pa_assert(PA_SOURCE_LINKED(s->state));
return pa_idxset_size(s->outputs);
}
+unsigned pa_source_used_by(pa_source *s) {
+ unsigned ret;
+
+ pa_source_assert_ref(s);
+ pa_assert(PA_SOURCE_LINKED(s->state));
+
+ ret = pa_idxset_size(s->outputs);
+ pa_assert(ret >= s->n_corked);
+
+ return ret - s->n_corked;
+}
+
int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
pa_source *s = PA_SOURCE(object);
pa_source_assert_ref(s);
pa_channel_map channel_map;
pa_idxset *outputs;
+ unsigned n_corked;
pa_sink *monitor_of; /* may be NULL */
pa_cvolume volume;
void pa_source_set_mute(pa_source *source, int mute);
int pa_source_get_mute(pa_source *source);
-unsigned pa_source_used_by(pa_source *s);
+unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */
+unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */
#define pa_source_get_state(s) ((pa_source_state_t) (s)->state)
/* To be called exclusively by the source driver, from IO context */