* checked whether the device this stream is connected to should
* auto-suspend. \since 0.9.15 */
- PA_STREAM_START_UNMUTED = 0x10000U
+ PA_STREAM_START_UNMUTED = 0x10000U,
/**< Create in unmuted state. If neither PA_STREAM_START_UNMUTED
* nor PA_STREAM_START_MUTED it is left to the server to decide
* whether to create the stream in muted or in unmuted
* state. \since 0.9.15 */
+ PA_STREAM_FAIL_ON_SUSPEND = 0x20000U
+ /**< If the sink/source this stream is connected to is suspended
+ * during the creation of this stream, cause it to fail. If the
+ * sink/source is being suspended during creation of this stream,
+ * make sure this stream is terminated. \since 0.9.15 */
} pa_stream_flags_t;
/** \cond fulldocs */
#define PA_STREAM_EARLY_REQUESTS PA_STREAM_EARLY_REQUESTS
#define PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
#define PA_STREAM_START_UNMUTED PA_STREAM_START_UNMUTED
+#define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND
/** \endcond */
PA_STREAM_ADJUST_LATENCY|
PA_STREAM_EARLY_REQUESTS|
PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND|
- PA_STREAM_START_UNMUTED)), PA_ERR_INVALID);
+ PA_STREAM_START_UNMUTED|
+ PA_STREAM_FAIL_ON_SUSPEND)), PA_ERR_INVALID);
PA_CHECK_VALIDITY(s->context, s->context->version >= 12 || !(flags & PA_STREAM_VARIABLE_RATE), PA_ERR_NOTSUPPORTED);
PA_CHECK_VALIDITY(s->context, s->context->version >= 13 || !(flags & PA_STREAM_PEAK_DETECT), PA_ERR_NOTSUPPORTED);
pa_tagstruct_put_boolean(t, flags & (PA_STREAM_START_MUTED|PA_STREAM_START_UNMUTED));
pa_tagstruct_put_boolean(t, flags & PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND);
+ pa_tagstruct_put_boolean(t, flags & PA_STREAM_FAIL_ON_SUSPEND);
}
pa_pstream_send_tagstruct(s->context->pstream, t);
s,
" index: %u\n"
"\tdriver: <%s>\n"
- "\tflags: %s%s%s%s%s%s%s%s\n"
+ "\tflags: %s%s%s%s%s%s%s%s%s%s\n"
"\tstate: %s\n"
"\tsource: %u <%s>\n"
"\tcurrent latency: %0.2f ms\n"
o->flags & PA_SOURCE_OUTPUT_FIX_FORMAT ? "FIX_FORMAT " : "",
o->flags & PA_SOURCE_OUTPUT_FIX_RATE ? "FIX_RATE " : "",
o->flags & PA_SOURCE_OUTPUT_FIX_CHANNELS ? "FIX_CHANNELS " : "",
+ o->flags & PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND ? "DONT_INHIBIT_AUTO_SUSPEND " : "",
+ o->flags & PA_SOURCE_OUTPUT_FAIL_ON_SUSPEND ? "FAIL_ON_SUSPEND " : "",
state_table[pa_source_output_get_state(o)],
o->source->index, o->source->name,
(double) pa_source_output_get_latency(o, NULL) / PA_USEC_PER_MSEC,
s,
" index: %u\n"
"\tdriver: <%s>\n"
- "\tflags: %s%s%s%s%s%s%s%s\n"
+ "\tflags: %s%s%s%s%s%s%s%s%s%s\n"
"\tstate: %s\n"
"\tsink: %u <%s>\n"
"\tvolume: %s\n"
i->flags & PA_SINK_INPUT_FIX_FORMAT ? "FIX_FORMAT " : "",
i->flags & PA_SINK_INPUT_FIX_RATE ? "FIX_RATE " : "",
i->flags & PA_SINK_INPUT_FIX_CHANNELS ? "FIX_CHANNELS " : "",
+ i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND ? "DONT_INHIBIT_AUTO_SUSPEND " : "",
+ i->flags & PA_SINK_INPUT_FAIL_ON_SUSPEND ? "FAIL_ON_SUSPEND " : "",
state_table[pa_sink_input_get_state(i)],
i->sink->index, i->sink->name,
pa_cvolume_snprint(cv, sizeof(cv), pa_sink_input_get_volume(i)),
adjust_latency = FALSE,
early_requests = FALSE,
dont_inhibit_auto_suspend = FALSE,
- muted_set = FALSE;
-
+ muted_set = FALSE,
+ fail_on_suspend = FALSE;
pa_sink_input_flags_t flags = 0;
pa_proplist *p;
pa_bool_t volume_set = TRUE;
if (c->version >= 15) {
if (pa_tagstruct_get_boolean(t, &muted_set) < 0 ||
- pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0) {
+ pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0 ||
+ pa_tagstruct_get_boolean(t, &fail_on_suspend) < 0) {
protocol_error(c);
pa_proplist_free(p);
return;
(fix_channels ? PA_SINK_INPUT_FIX_CHANNELS : 0) |
(no_move ? PA_SINK_INPUT_DONT_MOVE : 0) |
(variable_rate ? PA_SINK_INPUT_VARIABLE_RATE : 0) |
- (dont_inhibit_auto_suspend ? PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND : 0);
+ (dont_inhibit_auto_suspend ? PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND : 0) |
+ (fail_on_suspend ? PA_SINK_INPUT_FAIL_ON_SUSPEND : 0);
/* Only since protocol version 15 there's a seperate muted_set
* flag. For older versions we synthesize it here */
adjust_latency = FALSE,
peak_detect = FALSE,
early_requests = FALSE,
- dont_inhibit_auto_suspend = FALSE;
+ dont_inhibit_auto_suspend = FALSE,
+ fail_on_suspend = FALSE;
pa_source_output_flags_t flags = 0;
pa_proplist *p;
uint32_t direct_on_input_idx = PA_INVALID_INDEX;
if (c->version >= 15) {
- if (pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0) {
+ if (pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0 ||
+ pa_tagstruct_get_boolean(t, &fail_on_suspend) < 0) {
protocol_error(c);
pa_proplist_free(p);
return;
(fix_channels ? PA_SOURCE_OUTPUT_FIX_CHANNELS : 0) |
(no_move ? PA_SOURCE_OUTPUT_DONT_MOVE : 0) |
(variable_rate ? PA_SOURCE_OUTPUT_VARIABLE_RATE : 0) |
- (dont_inhibit_auto_suspend ? PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND : 0);
+ (dont_inhibit_auto_suspend ? PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND : 0) |
+ (fail_on_suspend ? PA_SOURCE_OUTPUT_FAIL_ON_SUSPEND : 0);
s = record_stream_new(c, source, &ss, &map, peak_detect, &maxlength, &fragment_size, flags, p, adjust_latency, direct_on_input, early_requests);
pa_proplist_free(p);
}
pa_return_null_if_fail(data->sink);
- pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_UNLINKED);
+ pa_return_null_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)));
pa_return_null_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED));
+ if ((flags & PA_SINK_INPUT_FAIL_ON_SUSPEND) &&
+ pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED)
+ return NULL;
+
if (!data->sample_spec_is_set)
data->sample_spec = data->sink->sample_spec;
PA_SINK_INPUT_FIX_RATE = 64,
PA_SINK_INPUT_FIX_CHANNELS = 128,
PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
+ PA_SINK_INPUT_FAIL_ON_SUSPEND = 512
} pa_sink_input_flags_t;
struct pa_sink_input {
s->state = state;
+ if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the apropriate events */
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+ }
+
if (suspend_change) {
pa_sink_input *i;
uint32_t idx;
/* We're suspending or resuming, tell everyone about it */
for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx)))
- if (i->suspend)
+ if (s->state == PA_SINK_SUSPENDED &&
+ (i->flags & PA_SINK_INPUT_FAIL_ON_SUSPEND))
+ pa_sink_input_kill(i);
+ else if (i->suspend)
i->suspend(i, state == PA_SINK_SUSPENDED);
}
- if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the apropriate events */
- pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
- pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
- }
-
return 0;
}
}
pa_return_null_if_fail(data->source);
- pa_return_null_if_fail(pa_source_get_state(data->source) != PA_SOURCE_UNLINKED);
-
+ pa_return_null_if_fail(PA_SOURCE_IS_LINKED(pa_source_get_state(data->source)));
pa_return_null_if_fail(!data->direct_on_input || data->direct_on_input->sink == data->source->monitor_of);
+ if ((flags & PA_SOURCE_OUTPUT_FAIL_ON_SUSPEND) &&
+ pa_source_get_state(data->source) == PA_SOURCE_SUSPENDED)
+ return NULL;
+
if (!data->sample_spec_is_set)
data->sample_spec = data->source->sample_spec;
PA_SOURCE_OUTPUT_FIX_FORMAT = 32,
PA_SOURCE_OUTPUT_FIX_RATE = 64,
PA_SOURCE_OUTPUT_FIX_CHANNELS = 128,
- PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND = 256
+ PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
+ PA_SOURCE_OUTPUT_FAIL_ON_SUSPEND = 512
} pa_source_output_flags_t;
struct pa_source_output {
s->state = state;
+ if (state != PA_SOURCE_UNLINKED) { /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s);
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+ }
+
if (suspend_change) {
pa_source_output *o;
uint32_t idx;
/* We're suspending or resuming, tell everyone about it */
for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx)))
- if (o->suspend)
+ if (s->state == PA_SOURCE_SUSPENDED &&
+ (o->flags & PA_SOURCE_OUTPUT_FAIL_ON_SUSPEND))
+ pa_source_output_kill(o);
+ else if (o->suspend)
o->suspend(o, state == PA_SOURCE_SUSPENDED);
}
- if (state != PA_SOURCE_UNLINKED) /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */
- pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s);
return 0;
}