mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
implement PA_STREAM_FAIL_ON_SUSPEND logic
This commit is contained in:
parent
c61ad2a706
commit
e47d03dea4
10 changed files with 59 additions and 24 deletions
|
|
@ -237,12 +237,17 @@ typedef enum pa_stream_flags {
|
|||
* 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 */
|
||||
|
|
@ -268,6 +273,7 @@ typedef enum pa_stream_flags {
|
|||
#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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -891,7 +891,8 @@ static int create_stream(
|
|||
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);
|
||||
|
|
@ -1017,6 +1018,7 @@ static int create_stream(
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ char *pa_source_output_list_to_string(pa_core *c) {
|
|||
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"
|
||||
|
|
@ -439,6 +439,8 @@ char *pa_source_output_list_to_string(pa_core *c) {
|
|||
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,
|
||||
|
|
@ -498,7 +500,7 @@ char *pa_sink_input_list_to_string(pa_core *c) {
|
|||
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"
|
||||
|
|
@ -520,6 +522,8 @@ char *pa_sink_input_list_to_string(pa_core *c) {
|
|||
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)),
|
||||
|
|
|
|||
|
|
@ -1691,8 +1691,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
|
|||
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;
|
||||
|
|
@ -1775,7 +1775,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
|
|||
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;
|
||||
|
|
@ -1814,7 +1815,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
|
|||
(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 */
|
||||
|
|
@ -1942,7 +1944,8 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
|
|||
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;
|
||||
|
|
@ -2016,7 +2019,8 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
|
|||
|
||||
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;
|
||||
|
|
@ -2064,7 +2068,8 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
|
|||
(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);
|
||||
|
|
|
|||
|
|
@ -144,9 +144,13 @@ pa_sink_input* pa_sink_input_new(
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ typedef enum pa_sink_input_flags {
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -305,6 +305,11 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
|
|||
|
||||
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;
|
||||
|
|
@ -312,15 +317,13 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
|
|||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,10 +118,13 @@ pa_source_output* pa_source_output_new(
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ typedef enum pa_source_output_flags {
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -267,6 +267,11 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {
|
|||
|
||||
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;
|
||||
|
|
@ -274,12 +279,13 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {
|
|||
/* 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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue