mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
Merge branch 'master' of git://0pointer.de/pulseaudio into dbus-work
Conflicts: src/modules/module-stream-restore.c
This commit is contained in:
commit
0ad2d55cbe
46 changed files with 720 additions and 173 deletions
|
|
@ -833,7 +833,7 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
|
|||
pulsecore/play-memblockq.c pulsecore/play-memblockq.h \
|
||||
pulsecore/play-memchunk.c pulsecore/play-memchunk.h \
|
||||
pulsecore/remap.c pulsecore/remap.h \
|
||||
pulsecore/remap_mmx.c \
|
||||
pulsecore/remap_mmx.c pulsecore/remap_sse.c \
|
||||
pulsecore/resampler.c pulsecore/resampler.h \
|
||||
pulsecore/rtpoll.c pulsecore/rtpoll.h \
|
||||
pulsecore/sample-util.c pulsecore/sample-util.h \
|
||||
|
|
@ -843,6 +843,7 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
|
|||
pulsecore/svolume_mmx.c pulsecore/svolume_sse.c \
|
||||
pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
|
||||
pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
|
||||
pulsecore/sconv_sse.c \
|
||||
pulsecore/sconv.c pulsecore/sconv.h \
|
||||
pulsecore/shared.c pulsecore/shared.h \
|
||||
pulsecore/shm.c pulsecore/shm.h \
|
||||
|
|
@ -1765,7 +1766,7 @@ daemon.conf: daemon/daemon.conf.in Makefile
|
|||
-e 's,@PA_DEFAULT_CONFIG_FILE\@,$(DEFAULT_CONFIG_DIR),g' < $< > $@
|
||||
|
||||
install-exec-hook:
|
||||
chown root $(DESTDIR)$(bindir)/pulseaudio ; true
|
||||
-chown root $(DESTDIR)$(pulselibexecdir)/proximity-helper
|
||||
-chmod u+s $(DESTDIR)$(pulselibexecdir)/proximity-helper
|
||||
ln -sf pacat $(DESTDIR)$(bindir)/parec
|
||||
ln -sf pacat $(DESTDIR)$(bindir)/pamon
|
||||
|
|
|
|||
|
|
@ -662,6 +662,21 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
|||
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
} else if (dbus_message_is_signal(m, "org.bluez.Device", "DisconnectRequested")) {
|
||||
pa_bluetooth_device *d;
|
||||
|
||||
if ((d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) {
|
||||
/* Device will disconnect in 2 sec */
|
||||
d->audio_state = PA_BT_AUDIO_STATE_DISCONNECTED;
|
||||
d->audio_sink_state = PA_BT_AUDIO_STATE_DISCONNECTED;
|
||||
d->audio_source_state = PA_BT_AUDIO_STATE_DISCONNECTED;
|
||||
d->headset_state = PA_BT_AUDIO_STATE_DISCONNECTED;
|
||||
|
||||
run_callback(y, d, FALSE);
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
} else if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
|
||||
const char *name, *old_owner, *new_owner;
|
||||
|
||||
|
|
@ -775,6 +790,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
|
|||
"type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Device',member='DisconnectRequested'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
|
||||
|
|
@ -828,6 +844,7 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
|
|||
"type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Device',member='DisconnectRequested'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
|
||||
"type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ static pa_hook_result_t load_module_for_device(pa_bluetooth_discovery *y, const
|
|||
|
||||
mi = pa_hashmap_get(u->hashmap, d->path);
|
||||
|
||||
pa_log("dead: %d, device_connected: %d, audio_state: %d, audio_source_state: %d", d->dead, d->device_connected, d->audio_state, d->audio_source_state);
|
||||
if (!d->dead &&
|
||||
d->device_connected > 0 && (d->audio_state >= PA_BT_AUDIO_STATE_CONNECTED || d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED)) {
|
||||
|
||||
|
|
|
|||
|
|
@ -844,8 +844,9 @@ static int output_create_sink_input(struct output *o) {
|
|||
pa_sink_input_new_data_set_channel_map(&data, &o->userdata->sink->channel_map);
|
||||
data.module = o->userdata->module;
|
||||
data.resample_method = o->userdata->resample_method;
|
||||
data.flags = PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE|PA_SINK_INPUT_NO_CREATE_ON_SUSPEND;
|
||||
|
||||
pa_sink_input_new(&o->sink_input, o->userdata->core, &data, PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE|PA_SINK_INPUT_NO_CREATE_ON_SUSPEND);
|
||||
pa_sink_input_new(&o->sink_input, o->userdata->core, &data);
|
||||
|
||||
pa_sink_input_new_data_done(&data);
|
||||
|
||||
|
|
|
|||
|
|
@ -812,7 +812,7 @@ int pa__init(pa_module*m) {
|
|||
pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
|
||||
pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
|
||||
|
||||
pa_sink_input_new(&u->sink_input, m->core, &sink_input_data, 0);
|
||||
pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
|
||||
pa_sink_input_new_data_done(&sink_input_data);
|
||||
|
||||
if (!u->sink_input)
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ static void adjust_rates(struct userdata *u) {
|
|||
(double) u->latency_snapshot.source_latency / PA_USEC_PER_MSEC,
|
||||
((double) u->latency_snapshot.sink_latency + buffer_latency + u->latency_snapshot.source_latency) / PA_USEC_PER_MSEC);
|
||||
|
||||
pa_log_info("Should buffer %lu bytes, buffered at minimum %lu bytes",
|
||||
pa_log_info("Should buffer %zu bytes, buffered at minimum %zu bytes",
|
||||
u->latency_snapshot.max_request*2,
|
||||
u->latency_snapshot.min_memblockq_length);
|
||||
|
||||
|
|
@ -676,8 +676,9 @@ int pa__init(pa_module *m) {
|
|||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
|
||||
pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
|
||||
pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
|
||||
sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE;
|
||||
|
||||
pa_sink_input_new(&u->sink_input, m->core, &sink_input_data, PA_SINK_INPUT_VARIABLE_RATE);
|
||||
pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
|
||||
pa_sink_input_new_data_done(&sink_input_data);
|
||||
|
||||
if (!u->sink_input)
|
||||
|
|
@ -709,7 +710,7 @@ int pa__init(pa_module *m) {
|
|||
pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
|
||||
pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
|
||||
|
||||
pa_source_output_new(&u->source_output, m->core, &source_output_data, 0);
|
||||
pa_source_output_new(&u->source_output, m->core, &source_output_data);
|
||||
pa_source_output_new_data_done(&source_output_data);
|
||||
|
||||
if (!u->source_output)
|
||||
|
|
|
|||
|
|
@ -406,8 +406,9 @@ int pa__init(pa_module*m) {
|
|||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
|
||||
pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
|
||||
pa_sink_input_new_data_set_channel_map(&sink_input_data, &stream_map);
|
||||
sink_input_data.flags = (remix ? 0 : PA_SINK_INPUT_NO_REMIX);
|
||||
|
||||
pa_sink_input_new(&u->sink_input, m->core, &sink_input_data, (remix ? 0 : PA_SINK_INPUT_NO_REMIX));
|
||||
pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
|
||||
pa_sink_input_new_data_done(&sink_input_data);
|
||||
|
||||
if (!u->sink_input)
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ int pa__init(pa_module*m) {
|
|||
pa_proplist_setf(data.proplist, "sine.hz", "%u", frequency);
|
||||
pa_sink_input_new_data_set_sample_spec(&data, &ss);
|
||||
|
||||
pa_sink_input_new(&u->sink_input, m->core, &data, 0);
|
||||
pa_sink_input_new(&u->sink_input, m->core, &data);
|
||||
pa_sink_input_new_data_done(&data);
|
||||
|
||||
if (!u->sink_input)
|
||||
|
|
|
|||
|
|
@ -1834,6 +1834,10 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
|
|||
data.data = &entry;
|
||||
data.size = sizeof(entry);
|
||||
|
||||
pa_log_debug("Client %s changes entry %s.",
|
||||
pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)),
|
||||
name);
|
||||
|
||||
if (pa_database_set(u->database, &key, &data, mode == PA_UPDATE_REPLACE) == 0) {
|
||||
#ifdef HAVE_DBUS
|
||||
struct dbus_entry *de;
|
||||
|
|
@ -1846,8 +1850,8 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
|
|||
send_device_updated_signal(de, &entry);
|
||||
|
||||
if ((old->volume_valid != entry.volume_valid)
|
||||
|| (entry.volume_valid
|
||||
&& (!pa_cvolume_equal(&entry.volume, &old->volume) || !pa_channel_map_equal(&entry.channel_map, &old->channel_map))))
|
||||
|| (entry.volume_valid && (!pa_cvolume_equal(&entry.volume, &old->volume)
|
||||
|| !pa_channel_map_equal(&entry.channel_map, &old->channel_map))))
|
||||
send_volume_updated_signal(de, &entry);
|
||||
|
||||
if (!old->muted_valid || (entry.muted != old->muted))
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ static pa_hook_result_t sink_input_fixate_hook_cb(pa_core *c, pa_sink_input_new_
|
|||
pa_assert(data);
|
||||
pa_assert(u);
|
||||
|
||||
if (data->flags & PA_SINK_INPUT_START_CORKED)
|
||||
return PA_HOOK_OK;
|
||||
|
||||
if ((d = pa_hashmap_get(u->device_infos, data->sink)))
|
||||
resume(d);
|
||||
|
||||
|
|
@ -158,6 +161,9 @@ static pa_hook_result_t source_output_fixate_hook_cb(pa_core *c, pa_source_outpu
|
|||
pa_assert(data);
|
||||
pa_assert(u);
|
||||
|
||||
if (data->flags & PA_SOURCE_OUTPUT_START_CORKED)
|
||||
return PA_HOOK_OK;
|
||||
|
||||
if (data->source->monitor_of)
|
||||
d = pa_hashmap_get(u->device_infos, data->source->monitor_of);
|
||||
else
|
||||
|
|
@ -226,11 +232,16 @@ static pa_hook_result_t sink_input_move_start_hook_cb(pa_core *c, pa_sink_input
|
|||
|
||||
static pa_hook_result_t sink_input_move_finish_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) {
|
||||
struct device_info *d;
|
||||
pa_sink_input_state_t state;
|
||||
|
||||
pa_assert(c);
|
||||
pa_sink_input_assert_ref(s);
|
||||
pa_assert(u);
|
||||
|
||||
state = pa_sink_input_get_state(s);
|
||||
if (state != PA_SINK_INPUT_RUNNING && state != PA_SINK_INPUT_DRAINED)
|
||||
return PA_HOOK_OK;
|
||||
|
||||
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
||||
resume(d);
|
||||
|
||||
|
|
@ -265,6 +276,9 @@ static pa_hook_result_t source_output_move_finish_hook_cb(pa_core *c, pa_source_
|
|||
pa_source_output_assert_ref(s);
|
||||
pa_assert(u);
|
||||
|
||||
if (pa_source_output_get_state(s) != PA_SOURCE_OUTPUT_RUNNING)
|
||||
return PA_HOOK_OK;
|
||||
|
||||
if (s->source->monitor_of)
|
||||
d = pa_hashmap_get(u->device_infos, s->source->monitor_of);
|
||||
else
|
||||
|
|
@ -279,6 +293,7 @@ static pa_hook_result_t source_output_move_finish_hook_cb(pa_core *c, pa_source_
|
|||
static pa_hook_result_t sink_input_state_changed_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) {
|
||||
struct device_info *d;
|
||||
pa_sink_input_state_t state;
|
||||
|
||||
pa_assert(c);
|
||||
pa_sink_input_assert_ref(s);
|
||||
pa_assert(u);
|
||||
|
|
@ -292,15 +307,11 @@ static pa_hook_result_t sink_input_state_changed_hook_cb(pa_core *c, pa_sink_inp
|
|||
}
|
||||
|
||||
static pa_hook_result_t source_output_state_changed_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) {
|
||||
pa_source_output_state_t state;
|
||||
|
||||
pa_assert(c);
|
||||
pa_source_output_assert_ref(s);
|
||||
pa_assert(u);
|
||||
|
||||
state = pa_source_output_get_state(s);
|
||||
|
||||
if (state == PA_SOURCE_OUTPUT_RUNNING) {
|
||||
if (pa_source_output_get_state(s) == PA_SOURCE_OUTPUT_RUNNING) {
|
||||
struct device_info *d;
|
||||
|
||||
if (s->source->monitor_of)
|
||||
|
|
@ -387,23 +398,18 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
|
|||
pa_sink *s = PA_SINK(o);
|
||||
pa_sink_state_t state = pa_sink_get_state(s);
|
||||
|
||||
if (pa_sink_check_suspend(s) <= 0) {
|
||||
|
||||
if (pa_sink_check_suspend(s) <= 0)
|
||||
if (PA_SINK_IS_OPENED(state))
|
||||
restart(d);
|
||||
|
||||
}
|
||||
|
||||
} else if (pa_source_isinstance(o)) {
|
||||
pa_source *s = PA_SOURCE(o);
|
||||
pa_source_state_t state = pa_source_get_state(s);
|
||||
|
||||
if (pa_source_check_suspend(s) <= 0) {
|
||||
|
||||
if (pa_source_check_suspend(s) <= 0)
|
||||
if (PA_SOURCE_IS_OPENED(state))
|
||||
restart(d);
|
||||
}
|
||||
}
|
||||
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -501,8 +501,9 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
|
|||
pa_proplist_setf(data.proplist, "rtp.payload", "%u", (unsigned) sdp_info->payload);
|
||||
data.module = u->module;
|
||||
pa_sink_input_new_data_set_sample_spec(&data, &sdp_info->sample_spec);
|
||||
data.flags = PA_SINK_INPUT_VARIABLE_RATE;
|
||||
|
||||
pa_sink_input_new(&s->sink_input, u->module->core, &data, PA_SINK_INPUT_VARIABLE_RATE);
|
||||
pa_sink_input_new(&s->sink_input, u->module->core, &data);
|
||||
pa_sink_input_new_data_done(&data);
|
||||
|
||||
if (!s->sink_input) {
|
||||
|
|
|
|||
|
|
@ -330,8 +330,9 @@ int pa__init(pa_module*m) {
|
|||
data.source = s;
|
||||
pa_source_output_new_data_set_sample_spec(&data, &ss);
|
||||
pa_source_output_new_data_set_channel_map(&data, &cm);
|
||||
data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND;
|
||||
|
||||
pa_source_output_new(&o, m->core, &data, PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND);
|
||||
pa_source_output_new(&o, m->core, &data);
|
||||
pa_source_output_new_data_done(&data);
|
||||
|
||||
if (!o) {
|
||||
|
|
|
|||
|
|
@ -214,8 +214,10 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) {
|
|||
/* End of headers */
|
||||
/* We will have a header left from our looping iteration, so add it in :) */
|
||||
if (c->last_header) {
|
||||
char *tmp = pa_strbuf_tostring_free(c->header_buffer);
|
||||
/* This is not a continuation header so let's dump it into our proplist */
|
||||
pa_headerlist_puts(c->response_headers, c->last_header, pa_strbuf_tostring_free(c->header_buffer));
|
||||
pa_headerlist_puts(c->response_headers, c->last_header, tmp);
|
||||
pa_xfree(tmp);
|
||||
pa_xfree(c->last_header);
|
||||
c->last_header = NULL;
|
||||
c->header_buffer = NULL;
|
||||
|
|
@ -240,9 +242,11 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) {
|
|||
}
|
||||
|
||||
if (c->last_header) {
|
||||
char *tmp = pa_strbuf_tostring_free(c->header_buffer);
|
||||
/* This is not a continuation header so let's dump the full
|
||||
header/value into our proplist */
|
||||
pa_headerlist_puts(c->response_headers, c->last_header, pa_strbuf_tostring_free(c->header_buffer));
|
||||
pa_headerlist_puts(c->response_headers, c->last_header, tmp);
|
||||
pa_xfree(tmp);
|
||||
pa_xfree(c->last_header);
|
||||
c->last_header = NULL;
|
||||
c->header_buffer = NULL;
|
||||
|
|
|
|||
|
|
@ -239,12 +239,9 @@ pa_operation *pa_ext_stream_restore_write(
|
|||
return o;
|
||||
|
||||
fail:
|
||||
if (o) {
|
||||
pa_operation_cancel(o);
|
||||
pa_operation_unref(o);
|
||||
}
|
||||
|
||||
if (t)
|
||||
pa_tagstruct_free(t);
|
||||
|
||||
pa_context_set_error(c, PA_ERR_INVALID);
|
||||
|
|
@ -290,12 +287,9 @@ pa_operation *pa_ext_stream_restore_delete(
|
|||
return o;
|
||||
|
||||
fail:
|
||||
if (o) {
|
||||
pa_operation_cancel(o);
|
||||
pa_operation_unref(o);
|
||||
}
|
||||
|
||||
if (t)
|
||||
pa_tagstruct_free(t);
|
||||
|
||||
pa_context_set_error(c, PA_ERR_INVALID);
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
|
|||
|
||||
pa_assert(p);
|
||||
pa_assert(key);
|
||||
pa_assert(data);
|
||||
pa_assert(data || nbytes == 0);
|
||||
|
||||
if (!property_name_valid(key))
|
||||
return -1;
|
||||
|
|
@ -264,6 +264,7 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
|
|||
pa_xfree(prop->value);
|
||||
|
||||
prop->value = pa_xmalloc(nbytes+1);
|
||||
if (nbytes > 0)
|
||||
memcpy(prop->value, data, nbytes);
|
||||
((char*) prop->value)[nbytes] = 0;
|
||||
prop->nbytes = nbytes;
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ char *pa_sink_list_to_string(pa_core *c) {
|
|||
"\tflags: %s%s%s%s%s%s%s%s\n"
|
||||
"\tstate: %s\n"
|
||||
"\tsuspend cause: %s%s%s%s\n"
|
||||
"\tpriority: %u\n"
|
||||
"\tvolume: %s%s%s\n"
|
||||
"\t balance %0.2f\n"
|
||||
"\tbase volume: %s%s%s\n"
|
||||
|
|
@ -262,6 +263,7 @@ char *pa_sink_list_to_string(pa_core *c) {
|
|||
sink->suspend_cause & PA_SUSPEND_APPLICATION ? "APPLICATION " : "",
|
||||
sink->suspend_cause & PA_SUSPEND_IDLE ? "IDLE " : "",
|
||||
sink->suspend_cause & PA_SUSPEND_SESSION ? "SESSION" : "",
|
||||
sink->priority,
|
||||
pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, FALSE)),
|
||||
sink->flags & PA_SINK_DECIBEL_VOLUME ? "\n\t " : "",
|
||||
sink->flags & PA_SINK_DECIBEL_VOLUME ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), pa_sink_get_volume(sink, FALSE)) : "",
|
||||
|
|
@ -356,6 +358,7 @@ char *pa_source_list_to_string(pa_core *c) {
|
|||
"\tflags: %s%s%s%s%s%s%s\n"
|
||||
"\tstate: %s\n"
|
||||
"\tsuspend cause: %s%s%s%s\n"
|
||||
"\tpriority: %u\n"
|
||||
"\tvolume: %s%s%s\n"
|
||||
"\t balance %0.2f\n"
|
||||
"\tbase volume: %s%s%s\n"
|
||||
|
|
@ -383,6 +386,7 @@ char *pa_source_list_to_string(pa_core *c) {
|
|||
source->suspend_cause & PA_SUSPEND_APPLICATION ? "APPLICATION " : "",
|
||||
source->suspend_cause & PA_SUSPEND_IDLE ? "IDLE " : "",
|
||||
source->suspend_cause & PA_SUSPEND_SESSION ? "SESSION" : "",
|
||||
source->priority,
|
||||
pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source, FALSE)),
|
||||
source->flags & PA_SOURCE_DECIBEL_VOLUME ? "\n\t " : "",
|
||||
source->flags & PA_SOURCE_DECIBEL_VOLUME ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), pa_source_get_volume(source, FALSE)) : "",
|
||||
|
|
|
|||
|
|
@ -1877,17 +1877,17 @@ char *pa_make_path_absolute(const char *p) {
|
|||
static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
|
||||
char *rtp;
|
||||
|
||||
if (pa_is_path_absolute(fn))
|
||||
return pa_xstrdup(fn);
|
||||
|
||||
rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
|
||||
|
||||
if (!rtp)
|
||||
return NULL;
|
||||
|
||||
if (fn) {
|
||||
char *r;
|
||||
|
||||
if (pa_is_path_absolute(fn))
|
||||
return pa_xstrdup(fn);
|
||||
|
||||
if (!rtp)
|
||||
return NULL;
|
||||
|
||||
if (prependmid) {
|
||||
char *mid;
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,11 @@ void pa_cpu_init_x86 (void) {
|
|||
pa_remap_func_init_mmx (flags);
|
||||
}
|
||||
|
||||
if (flags & PA_CPU_X86_SSE)
|
||||
if (flags & PA_CPU_X86_SSE) {
|
||||
pa_volume_func_init_sse (flags);
|
||||
pa_remap_func_init_sse (flags);
|
||||
pa_convert_func_init_sse (flags);
|
||||
}
|
||||
|
||||
#endif /* defined (__i386__) || defined (__amd64__) */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,5 +64,8 @@ void pa_volume_func_init_mmx(pa_cpu_x86_flag_t flags);
|
|||
void pa_volume_func_init_sse(pa_cpu_x86_flag_t flags);
|
||||
|
||||
void pa_remap_func_init_mmx(pa_cpu_x86_flag_t flags);
|
||||
void pa_remap_func_init_sse(pa_cpu_x86_flag_t flags);
|
||||
|
||||
void pa_convert_func_init_sse (pa_cpu_x86_flag_t flags);
|
||||
|
||||
#endif /* foocpux86hfoo */
|
||||
|
|
|
|||
|
|
@ -107,4 +107,7 @@
|
|||
#define PA_LLIST_FOREACH(i,head) \
|
||||
for (i = (head); i; i = i->next)
|
||||
|
||||
#define PA_LLIST_FOREACH_SAFE(i,n,head) \
|
||||
for (i = (head); i && ((n = i->next), 1); i = n)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ static inline size_t PA_PAGE_ALIGN(size_t l) {
|
|||
|
||||
#define PA_ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define PA_DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n)))
|
||||
#else
|
||||
#define PA_DECLARE_ALIGNED(n,t,v) t v
|
||||
#endif
|
||||
|
||||
/* The users of PA_MIN and PA_MAX, PA_CLAMP, PA_ROUND_UP should be
|
||||
* aware that these macros on non-GCC executed code with side effects
|
||||
* twice. It is thus considered misuse to use code with side effects
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ static pa_bool_t is_valid_char(char c) {
|
|||
pa_bool_t pa_namereg_is_valid_name(const char *name) {
|
||||
const char *c;
|
||||
|
||||
pa_assert(name);
|
||||
|
||||
if (*name == 0)
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -70,6 +72,25 @@ pa_bool_t pa_namereg_is_valid_name(const char *name) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
pa_bool_t pa_namereg_is_valid_name_or_wildcard(const char *name, pa_namereg_type_t type) {
|
||||
|
||||
pa_assert(name);
|
||||
|
||||
if (pa_namereg_is_valid_name(name))
|
||||
return TRUE;
|
||||
|
||||
if (type == PA_NAMEREG_SINK &&
|
||||
pa_streq(name, "@DEFAULT_SINK@"))
|
||||
return TRUE;
|
||||
|
||||
if (type == PA_NAMEREG_SOURCE &&
|
||||
(pa_streq(name, "@DEFAULT_SOURCE@") ||
|
||||
pa_streq(name, "@DEFAULT_MONITOR@")))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char* pa_namereg_make_valid_name(const char *name) {
|
||||
const char *a;
|
||||
char *b, *n;
|
||||
|
|
@ -191,7 +212,6 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) {
|
|||
|
||||
if ((s = pa_namereg_get(c, NULL, PA_NAMEREG_SINK)))
|
||||
return s->monitor_source;
|
||||
|
||||
}
|
||||
|
||||
if (!name)
|
||||
|
|
@ -249,7 +269,7 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
|
|||
}
|
||||
|
||||
pa_sink *pa_namereg_get_default_sink(pa_core *c) {
|
||||
pa_sink *s;
|
||||
pa_sink *s, *best = NULL;
|
||||
uint32_t idx;
|
||||
|
||||
pa_assert(c);
|
||||
|
|
@ -257,18 +277,19 @@ pa_sink *pa_namereg_get_default_sink(pa_core *c) {
|
|||
if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
|
||||
return c->default_sink;
|
||||
|
||||
/* FIXME: the selection here should be based priority values on
|
||||
* the sinks */
|
||||
|
||||
PA_IDXSET_FOREACH(s, c->sinks, idx)
|
||||
if (PA_SINK_IS_LINKED(pa_sink_get_state(s)))
|
||||
return pa_namereg_set_default_sink(c, s);
|
||||
if (!best || s->priority > best->priority)
|
||||
best = s;
|
||||
|
||||
if (best)
|
||||
return pa_namereg_set_default_sink(c, best);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pa_source *pa_namereg_get_default_source(pa_core *c) {
|
||||
pa_source *s;
|
||||
pa_source *s, *best = NULL;
|
||||
uint32_t idx;
|
||||
|
||||
pa_assert(c);
|
||||
|
|
@ -279,12 +300,26 @@ pa_source *pa_namereg_get_default_source(pa_core *c) {
|
|||
/* First, try to find one that isn't a monitor */
|
||||
PA_IDXSET_FOREACH(s, c->sources, idx)
|
||||
if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
|
||||
return pa_namereg_set_default_source(c, s);
|
||||
if (!best ||
|
||||
s->priority > best->priority)
|
||||
best = s;
|
||||
|
||||
if (best)
|
||||
return pa_namereg_set_default_source(c, best);
|
||||
|
||||
/* Then, fallback to a monitor */
|
||||
PA_IDXSET_FOREACH(s, c->sources, idx)
|
||||
if (PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
|
||||
return pa_namereg_set_default_source(c, s);
|
||||
if (!best ||
|
||||
s->priority > best->priority ||
|
||||
(s->priority == best->priority &&
|
||||
s->monitor_of &&
|
||||
best->monitor_of &&
|
||||
s->monitor_of->priority > best->monitor_of->priority))
|
||||
best = s;
|
||||
|
||||
if (best)
|
||||
return pa_namereg_set_default_source(c, best);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ pa_sink *pa_namereg_get_default_sink(pa_core *c);
|
|||
pa_source *pa_namereg_get_default_source(pa_core *c);
|
||||
|
||||
pa_bool_t pa_namereg_is_valid_name(const char *name);
|
||||
pa_bool_t pa_namereg_is_valid_name_or_wildcard(const char *name, pa_namereg_type_t type);
|
||||
char* pa_namereg_make_valid_name(const char *name);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ static const char *command_names[PA_COMMAND_MAX] = {
|
|||
/* Supported since protocol v14 (0.9.12) */
|
||||
[PA_COMMAND_EXTENSION] = "EXTENSION",
|
||||
|
||||
|
||||
/* Supported since protocol v15 (0.9.15) */
|
||||
[PA_COMMAND_GET_CARD_INFO] = "GET_CARD_INFO",
|
||||
[PA_COMMAND_GET_CARD_INFO_LIST] = "GET_CARD_INFO_LIST",
|
||||
[PA_COMMAND_SET_CARD_PROFILE] = "SET_CARD_PROFILE",
|
||||
|
|
@ -180,7 +180,11 @@ static const char *command_names[PA_COMMAND_MAX] = {
|
|||
|
||||
/* SERVER->CLIENT */
|
||||
[PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED] = "PLAYBACK_BUFFER_ATTR_CHANGED",
|
||||
[PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = "RECORD_BUFFER_ATTR_CHANGED"
|
||||
[PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = "RECORD_BUFFER_ATTR_CHANGED",
|
||||
|
||||
/* Supported since protocol v16 (0.9.16) */
|
||||
[PA_COMMAND_SET_SINK_PORT] = "SET_SINK_PORT",
|
||||
[PA_COMMAND_SET_SOURCE_PORT] = "SET_SOURCE_PORT"
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -203,10 +207,10 @@ struct pa_pdispatch {
|
|||
const pa_pdispatch_cb_t *callback_table;
|
||||
unsigned n_commands;
|
||||
PA_LLIST_HEAD(struct reply_info, replies);
|
||||
pa_pdispatch_drain_callback drain_callback;
|
||||
pa_pdispatch_drain_cb_t drain_callback;
|
||||
void *drain_userdata;
|
||||
const pa_creds *creds;
|
||||
pa_bool_t use_rtclock:1;
|
||||
pa_bool_t use_rtclock;
|
||||
};
|
||||
|
||||
static void reply_info_free(struct reply_info *r) {
|
||||
|
|
@ -225,19 +229,16 @@ static void reply_info_free(struct reply_info *r) {
|
|||
|
||||
pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, pa_bool_t use_rtclock, const pa_pdispatch_cb_t *table, unsigned entries) {
|
||||
pa_pdispatch *pd;
|
||||
pa_assert(mainloop);
|
||||
|
||||
pa_assert(mainloop);
|
||||
pa_assert((entries && table) || (!entries && !table));
|
||||
|
||||
pd = pa_xnew(pa_pdispatch, 1);
|
||||
pd = pa_xnew0(pa_pdispatch, 1);
|
||||
PA_REFCNT_INIT(pd);
|
||||
pd->mainloop = mainloop;
|
||||
pd->callback_table = table;
|
||||
pd->n_commands = entries;
|
||||
PA_LLIST_HEAD_INIT(struct reply_info, pd->replies);
|
||||
pd->drain_callback = NULL;
|
||||
pd->drain_userdata = NULL;
|
||||
pd->creds = NULL;
|
||||
pd->use_rtclock = use_rtclock;
|
||||
|
||||
return pd;
|
||||
|
|
@ -317,7 +318,7 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds,
|
|||
if (command == PA_COMMAND_ERROR || command == PA_COMMAND_REPLY) {
|
||||
struct reply_info *r;
|
||||
|
||||
for (r = pd->replies; r; r = r->next)
|
||||
PA_LLIST_FOREACH(r, pd->replies)
|
||||
if (r->tag == tag)
|
||||
break;
|
||||
|
||||
|
|
@ -325,9 +326,9 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds,
|
|||
run_action(pd, r, command, ts);
|
||||
|
||||
} else if (pd->callback_table && (command < pd->n_commands) && pd->callback_table[command]) {
|
||||
const pa_pdispatch_cb_t *c = pd->callback_table+command;
|
||||
const pa_pdispatch_cb_t *cb = pd->callback_table+command;
|
||||
|
||||
(*c)(pd, command, tag, ts, userdata);
|
||||
(*cb)(pd, command, tag, ts, userdata);
|
||||
} else {
|
||||
pa_log("Received unsupported command %u", command);
|
||||
goto finish;
|
||||
|
|
@ -375,7 +376,9 @@ void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa
|
|||
r->free_cb = free_cb;
|
||||
r->tag = tag;
|
||||
|
||||
pa_assert_se(r->time_event = pd->mainloop->time_new(pd->mainloop, pa_timeval_rtstore(&tv, pa_rtclock_now() + timeout * PA_USEC_PER_SEC, pd->use_rtclock), timeout_callback, r));
|
||||
pa_assert_se(r->time_event = pd->mainloop->time_new(pd->mainloop,
|
||||
pa_timeval_rtstore(&tv, pa_rtclock_now() + timeout * PA_USEC_PER_SEC, pd->use_rtclock),
|
||||
timeout_callback, r));
|
||||
|
||||
PA_LLIST_PREPEND(struct reply_info, pd->replies, r);
|
||||
}
|
||||
|
|
@ -387,7 +390,7 @@ int pa_pdispatch_is_pending(pa_pdispatch *pd) {
|
|||
return !!pd->replies;
|
||||
}
|
||||
|
||||
void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, void (*cb)(pa_pdispatch *pd, void *userdata), void *userdata) {
|
||||
void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_cb_t cb, void *userdata) {
|
||||
pa_assert(pd);
|
||||
pa_assert(PA_REFCNT_VALUE(pd) >= 1);
|
||||
pa_assert(!cb || pa_pdispatch_is_pending(pd));
|
||||
|
|
@ -402,13 +405,10 @@ void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata) {
|
|||
pa_assert(pd);
|
||||
pa_assert(PA_REFCNT_VALUE(pd) >= 1);
|
||||
|
||||
for (r = pd->replies; r; r = n) {
|
||||
n = r->next;
|
||||
|
||||
PA_LLIST_FOREACH_SAFE(r, n, pd->replies)
|
||||
if (r->userdata == userdata)
|
||||
reply_info_free(r);
|
||||
}
|
||||
}
|
||||
|
||||
void pa_pdispatch_unref(pa_pdispatch *pd) {
|
||||
pa_assert(pd);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
typedef struct pa_pdispatch pa_pdispatch;
|
||||
|
||||
typedef void (*pa_pdispatch_cb_t)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
|
||||
typedef void (*pa_pdispatch_drain_callback)(pa_pdispatch *pd, void *userdata);
|
||||
typedef void (*pa_pdispatch_drain_cb_t)(pa_pdispatch *pd, void *userdata);
|
||||
|
||||
pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *m, pa_bool_t use_rtclock, const pa_pdispatch_cb_t *table, unsigned entries);
|
||||
void pa_pdispatch_unref(pa_pdispatch *pd);
|
||||
|
|
@ -47,7 +47,7 @@ void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa
|
|||
|
||||
int pa_pdispatch_is_pending(pa_pdispatch *pd);
|
||||
|
||||
void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_callback callback, void *userdata);
|
||||
void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_cb_t callback, void *userdata);
|
||||
|
||||
/* Remove all reply slots with the give userdata parameter */
|
||||
void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata);
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ pa_sink_input* pa_memblockq_sink_input_new(
|
|||
pa_sink_input_new_data_set_volume(&data, volume);
|
||||
pa_proplist_update(data.proplist, PA_UPDATE_REPLACE, p);
|
||||
|
||||
pa_sink_input_new(&u->sink_input, sink->core, &data, 0);
|
||||
pa_sink_input_new(&u->sink_input, sink->core, &data);
|
||||
pa_sink_input_new_data_done(&data);
|
||||
|
||||
if (!u->sink_input)
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
|
|||
sdata.sink = sink;
|
||||
pa_sink_input_new_data_set_sample_spec(&sdata, &ss);
|
||||
|
||||
pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata, 0);
|
||||
pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata);
|
||||
pa_sink_input_new_data_done(&sdata);
|
||||
|
||||
CHECK_VALIDITY(c->sink_input, "Failed to create sink input.");
|
||||
|
|
@ -525,7 +525,7 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi
|
|||
sdata.source = source;
|
||||
pa_source_output_new_data_set_sample_spec(&sdata, &ss);
|
||||
|
||||
pa_source_output_new(&c->source_output, c->protocol->core, &sdata, 0);
|
||||
pa_source_output_new(&c->source_output, c->protocol->core, &sdata);
|
||||
pa_source_output_new_data_done(&sdata);
|
||||
|
||||
CHECK_VALIDITY(c->source_output, "Failed to create source output.");
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ static void handle_listen_prefix(struct connection *c, const char *source_name)
|
|||
pa_source_output_new_data_set_sample_spec(&data, &ss);
|
||||
pa_source_output_new_data_set_channel_map(&data, &cm);
|
||||
|
||||
pa_source_output_new(&c->source_output, c->protocol->core, &data, 0);
|
||||
pa_source_output_new(&c->source_output, c->protocol->core, &data);
|
||||
pa_source_output_new_data_done(&data);
|
||||
|
||||
if (!c->source_output) {
|
||||
|
|
|
|||
|
|
@ -648,8 +648,9 @@ static record_stream* record_stream_new(
|
|||
pa_source_output_new_data_set_channel_map(&data, map);
|
||||
if (peak_detect)
|
||||
data.resample_method = PA_RESAMPLER_PEAKS;
|
||||
data.flags = flags;
|
||||
|
||||
*ret = -pa_source_output_new(&source_output, c->protocol->core, &data, flags);
|
||||
*ret = -pa_source_output_new(&source_output, c->protocol->core, &data);
|
||||
|
||||
pa_source_output_new_data_done(&data);
|
||||
|
||||
|
|
@ -1050,8 +1051,9 @@ static playback_stream* playback_stream_new(
|
|||
if (muted_set)
|
||||
pa_sink_input_new_data_set_muted(&data, muted);
|
||||
data.sync_base = ssync ? ssync->sink_input : NULL;
|
||||
data.flags = flags;
|
||||
|
||||
*ret = -pa_sink_input_new(&sink_input, c->protocol->core, &data, flags);
|
||||
*ret = -pa_sink_input_new(&sink_input, c->protocol->core, &data);
|
||||
|
||||
pa_sink_input_new_data_done(&data);
|
||||
|
||||
|
|
@ -1289,7 +1291,8 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
|
|||
|
||||
pa_log_debug("Requesting rewind due to end of underrun.");
|
||||
pa_sink_input_request_rewind(s->sink_input,
|
||||
(size_t) (s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for),
|
||||
(size_t) (s->sink_input->thread_info.underrun_for == (uint64_t) -1 ? 0 :
|
||||
s->sink_input->thread_info.underrun_for),
|
||||
FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
|
|
@ -1865,7 +1868,7 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name_or_wildcard(sink_name, PA_NAMEREG_SINK), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
|
||||
|
|
@ -2114,7 +2117,7 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, !source_name || pa_namereg_is_valid_name(source_name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !source_name || pa_namereg_is_valid_name_or_wildcard(source_name, PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, source_index == PA_INVALID_INDEX || !source_name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !source_name || source_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
|
||||
|
|
@ -2460,7 +2463,7 @@ static void command_lookup(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_LOOKUP_SINK ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
|
||||
|
||||
if (command == PA_COMMAND_LOOKUP_SINK) {
|
||||
pa_sink *sink;
|
||||
|
|
@ -2731,7 +2734,7 @@ static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag
|
|||
return;
|
||||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name_or_wildcard(sink_name, PA_NAMEREG_SINK), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
|
||||
|
|
@ -3105,7 +3108,12 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name ||
|
||||
(command == PA_COMMAND_GET_SINK_INFO &&
|
||||
pa_namereg_is_valid_name_or_wildcard(name, PA_NAMEREG_SINK)) ||
|
||||
(command == PA_COMMAND_GET_SOURCE_INFO &&
|
||||
pa_namereg_is_valid_name_or_wildcard(name, PA_NAMEREG_SOURCE)) ||
|
||||
pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
|
|
@ -3347,7 +3355,7 @@ static void command_set_volume(
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_SET_SINK_VOLUME ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
|
|
@ -3385,10 +3393,10 @@ static void command_set_volume(
|
|||
pa_log_debug("Client %s changes volume of sink %s.", client_name, sink->name);
|
||||
pa_sink_set_volume(sink, &volume, TRUE, TRUE);
|
||||
} else if (source) {
|
||||
pa_log_debug("Client %s changes volume of sink %s.", client_name, source->name);
|
||||
pa_log_debug("Client %s changes volume of source %s.", client_name, source->name);
|
||||
pa_source_set_volume(source, &volume, TRUE);
|
||||
} else if (si) {
|
||||
pa_log_debug("Client %s changes volume of sink %s.",
|
||||
pa_log_debug("Client %s changes volume of sink input %s.",
|
||||
client_name,
|
||||
pa_strnull(pa_proplist_gets(si->proplist, PA_PROP_MEDIA_NAME)));
|
||||
pa_sink_input_set_volume(si, &volume, TRUE, TRUE);
|
||||
|
|
@ -3410,7 +3418,7 @@ static void command_set_mute(
|
|||
pa_sink *sink = NULL;
|
||||
pa_source *source = NULL;
|
||||
pa_sink_input *si = NULL;
|
||||
const char *name = NULL;
|
||||
const char *name = NULL, *client_name;
|
||||
|
||||
pa_native_connection_assert_ref(c);
|
||||
pa_assert(t);
|
||||
|
|
@ -3425,7 +3433,7 @@ static void command_set_mute(
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_SET_SINK_MUTE ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
|
|
@ -3459,12 +3467,20 @@ static void command_set_mute(
|
|||
|
||||
CHECK_VALIDITY(c->pstream, si || sink || source, tag, PA_ERR_NOENTITY);
|
||||
|
||||
if (sink)
|
||||
client_name = pa_strnull(pa_proplist_gets(c->client->proplist, PA_PROP_APPLICATION_PROCESS_BINARY));
|
||||
|
||||
if (sink) {
|
||||
pa_log_debug("Client %s changes mute of sink %s.", client_name, sink->name);
|
||||
pa_sink_set_mute(sink, mute, TRUE);
|
||||
else if (source)
|
||||
} else if (source) {
|
||||
pa_log_debug("Client %s changes mute of source %s.", client_name, source->name);
|
||||
pa_source_set_mute(source, mute, TRUE);
|
||||
else if (si)
|
||||
} else if (si) {
|
||||
pa_log_debug("Client %s changes mute of sink input %s.",
|
||||
client_name,
|
||||
pa_strnull(pa_proplist_gets(si->proplist, PA_PROP_MEDIA_NAME)));
|
||||
pa_sink_input_set_mute(si, mute, TRUE);
|
||||
}
|
||||
|
||||
pa_pstream_send_simple_ack(c->pstream, tag);
|
||||
}
|
||||
|
|
@ -4083,7 +4099,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
|
|||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
|
||||
CHECK_VALIDITY(c->pstream, !name_device || pa_namereg_is_valid_name(name_device), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name_device || pa_namereg_is_valid_name_or_wildcard(name_device, command == PA_COMMAND_MOVE_SINK_INPUT ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || name_device, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx_device == PA_INVALID_INDEX || !name_device, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name_device || idx_device == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
|
|
@ -4147,7 +4163,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name) || *name == 0, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_SUSPEND_SINK ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) || *name == 0, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
|
|
@ -4307,7 +4323,7 @@ static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command,
|
|||
}
|
||||
|
||||
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_SET_SINK_PORT ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
|
||||
CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
|
||||
|
|
@ -4842,3 +4858,9 @@ pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c) {
|
|||
|
||||
return c->pstream;
|
||||
}
|
||||
|
||||
pa_client* pa_native_connection_get_client(pa_native_connection *c) {
|
||||
pa_native_connection_assert_ref(c);
|
||||
|
||||
return c->client;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ typedef struct pa_native_options {
|
|||
char *auth_group;
|
||||
pa_ip_acl *auth_ip_acl;
|
||||
pa_auth_cookie *auth_cookie;
|
||||
|
||||
} pa_native_options;
|
||||
|
||||
typedef enum pa_native_hook {
|
||||
|
|
@ -80,6 +79,7 @@ int pa_native_protocol_install_ext(pa_native_protocol *p, pa_module *m, pa_nativ
|
|||
void pa_native_protocol_remove_ext(pa_native_protocol *p, pa_module *m);
|
||||
|
||||
pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c);
|
||||
pa_client* pa_native_connection_get_client(pa_native_connection *c);
|
||||
|
||||
pa_native_options* pa_native_options_new(void);
|
||||
pa_native_options* pa_native_options_ref(pa_native_options *o);
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
|
|||
pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
|
||||
pa_sink_input_new_data_set_sample_spec(&data, &o->sample_spec);
|
||||
|
||||
pa_sink_input_new(&c->sink_input, p->core, &data, 0);
|
||||
pa_sink_input_new(&c->sink_input, p->core, &data);
|
||||
pa_sink_input_new_data_done(&data);
|
||||
|
||||
if (!c->sink_input) {
|
||||
|
|
@ -593,7 +593,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
|
|||
pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
|
||||
pa_source_output_new_data_set_sample_spec(&data, &o->sample_spec);
|
||||
|
||||
pa_source_output_new(&c->source_output, p->core, &data, 0);
|
||||
pa_source_output_new(&c->source_output, p->core, &data);
|
||||
pa_source_output_new_data_done(&data);
|
||||
|
||||
if (!c->source_output) {
|
||||
|
|
@ -627,7 +627,6 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
|
|||
return;
|
||||
|
||||
fail:
|
||||
if (c)
|
||||
connection_unlink(c);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
" punpckl"#s" %%mm4, %%mm4 \n\t" \
|
||||
" punpckh"#s" %%mm5, %%mm5 \n\t" \
|
||||
" punpckl"#s" %%mm6, %%mm6 \n\t" \
|
||||
" punpckh"#s" %%mm7, %%mm7 \n\t" \
|
||||
" punpckh"#s" %%mm7, %%mm7 \n\t"
|
||||
|
||||
#define STORE_SAMPLES \
|
||||
" movq %%mm0, (%0) \n\t" \
|
||||
|
|
@ -67,7 +67,6 @@
|
|||
|
||||
#define HANDLE_SINGLE(s) \
|
||||
" movd (%1), %%mm0 \n\t" \
|
||||
" movq %%mm0, %%mm1 \n\t" \
|
||||
" punpckl"#s" %%mm0, %%mm0 \n\t" \
|
||||
" movq %%mm0, (%0) \n\t" \
|
||||
" add $4, %1 \n\t" \
|
||||
|
|
|
|||
146
src/pulsecore/remap_sse.c
Normal file
146
src/pulsecore/remap_sse.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
Copyright 2004-2006 Lennart Poettering
|
||||
Copyright 2009 Wim Taymans <wim.taymans@collabora.co.uk.com>
|
||||
|
||||
PulseAudio is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
PulseAudio is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with PulseAudio; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA.
|
||||
***/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <pulse/sample.h>
|
||||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/macro.h>
|
||||
|
||||
#include "cpu-x86.h"
|
||||
#include "remap.h"
|
||||
|
||||
#define LOAD_SAMPLES \
|
||||
" movdqu (%1), %%xmm0 \n\t" \
|
||||
" movdqu 16(%1), %%xmm2 \n\t" \
|
||||
" movdqu 32(%1), %%xmm4 \n\t" \
|
||||
" movdqu 48(%1), %%xmm6 \n\t" \
|
||||
" movdqa %%xmm0, %%xmm1 \n\t" \
|
||||
" movdqa %%xmm2, %%xmm3 \n\t" \
|
||||
" movdqa %%xmm4, %%xmm5 \n\t" \
|
||||
" movdqa %%xmm6, %%xmm7 \n\t"
|
||||
|
||||
#define UNPACK_SAMPLES(s) \
|
||||
" punpckl"#s" %%xmm0, %%xmm0 \n\t" \
|
||||
" punpckh"#s" %%xmm1, %%xmm1 \n\t" \
|
||||
" punpckl"#s" %%xmm2, %%xmm2 \n\t" \
|
||||
" punpckh"#s" %%xmm3, %%xmm3 \n\t" \
|
||||
" punpckl"#s" %%xmm4, %%xmm4 \n\t" \
|
||||
" punpckh"#s" %%xmm5, %%xmm5 \n\t" \
|
||||
" punpckl"#s" %%xmm6, %%xmm6 \n\t" \
|
||||
" punpckh"#s" %%xmm7, %%xmm7 \n\t"
|
||||
|
||||
#define STORE_SAMPLES \
|
||||
" movdqu %%xmm0, (%0) \n\t" \
|
||||
" movdqu %%xmm1, 16(%0) \n\t" \
|
||||
" movdqu %%xmm2, 32(%0) \n\t" \
|
||||
" movdqu %%xmm3, 48(%0) \n\t" \
|
||||
" movdqu %%xmm4, 64(%0) \n\t" \
|
||||
" movdqu %%xmm5, 80(%0) \n\t" \
|
||||
" movdqu %%xmm6, 96(%0) \n\t" \
|
||||
" movdqu %%xmm7, 112(%0) \n\t" \
|
||||
" add $64, %1 \n\t" \
|
||||
" add $128, %0 \n\t"
|
||||
|
||||
#define HANDLE_SINGLE(s) \
|
||||
" movd (%1), %%xmm0 \n\t" \
|
||||
" punpckl"#s" %%xmm0, %%xmm0 \n\t" \
|
||||
" movq %%xmm0, (%0) \n\t" \
|
||||
" add $4, %1 \n\t" \
|
||||
" add $8, %0 \n\t"
|
||||
|
||||
#define MONO_TO_STEREO(s) \
|
||||
" mov %3, %2 \n\t" \
|
||||
" sar $4, %2 \n\t" \
|
||||
" cmp $0, %2 \n\t" \
|
||||
" je 2f \n\t" \
|
||||
"1: \n\t" \
|
||||
LOAD_SAMPLES \
|
||||
UNPACK_SAMPLES(s) \
|
||||
STORE_SAMPLES \
|
||||
" dec %2 \n\t" \
|
||||
" jne 1b \n\t" \
|
||||
"2: \n\t" \
|
||||
" mov %3, %2 \n\t" \
|
||||
" and $15, %2 \n\t" \
|
||||
" je 4f \n\t" \
|
||||
"3: \n\t" \
|
||||
HANDLE_SINGLE(s) \
|
||||
" dec %2 \n\t" \
|
||||
" jne 3b \n\t" \
|
||||
"4: \n\t"
|
||||
|
||||
static void remap_mono_to_stereo_sse (pa_remap_t *m, void *dst, const void *src, unsigned n) {
|
||||
pa_reg_x86 temp;
|
||||
|
||||
switch (*m->format) {
|
||||
case PA_SAMPLE_FLOAT32NE:
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
MONO_TO_STEREO(dq) /* do doubles to quads */
|
||||
: "+r" (dst), "+r" (src), "=&r" (temp)
|
||||
: "r" ((pa_reg_x86)n)
|
||||
: "cc"
|
||||
);
|
||||
break;
|
||||
}
|
||||
case PA_SAMPLE_S16NE:
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
MONO_TO_STEREO(wd) /* do words to doubles */
|
||||
: "+r" (dst), "+r" (src), "=&r" (temp)
|
||||
: "r" ((pa_reg_x86)n)
|
||||
: "cc"
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pa_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
/* set the function that will execute the remapping based on the matrices */
|
||||
static void init_remap_sse (pa_remap_t *m) {
|
||||
unsigned n_oc, n_ic;
|
||||
|
||||
n_oc = m->o_ss->channels;
|
||||
n_ic = m->i_ss->channels;
|
||||
|
||||
/* find some common channel remappings, fall back to full matrix operation. */
|
||||
if (n_ic == 1 && n_oc == 2 &&
|
||||
m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
|
||||
m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_sse;
|
||||
pa_log_info("Using SSE mono to stereo remapping");
|
||||
}
|
||||
}
|
||||
|
||||
void pa_remap_func_init_sse (pa_cpu_x86_flag_t flags) {
|
||||
#if defined (__i386__) || defined (__amd64__)
|
||||
pa_log_info("Initialising SSE optimized remappers.");
|
||||
|
||||
pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_sse);
|
||||
#endif /* defined (__i386__) || defined (__amd64__) */
|
||||
}
|
||||
|
|
@ -299,7 +299,6 @@ pa_resampler* pa_resampler_new(
|
|||
return r;
|
||||
|
||||
fail:
|
||||
if (r)
|
||||
pa_xfree(r);
|
||||
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
|
|||
|
||||
static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
|
||||
unsigned k, channel;
|
||||
float linear[PA_CHANNELS_MAX];
|
||||
float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
|
||||
|
||||
pa_assert(streams);
|
||||
pa_assert(spec);
|
||||
|
|
@ -156,7 +156,7 @@ static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned n
|
|||
|
||||
static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
|
||||
unsigned k, channel;
|
||||
float linear[PA_CHANNELS_MAX];
|
||||
float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
|
||||
|
||||
pa_assert(streams);
|
||||
pa_assert(spec);
|
||||
|
|
|
|||
233
src/pulsecore/sconv_sse.c
Normal file
233
src/pulsecore/sconv_sse.c
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
Copyright 2004-2006 Lennart Poettering
|
||||
Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
|
||||
PulseAudio is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
PulseAudio is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with PulseAudio; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA.
|
||||
***/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pulsecore/g711.h>
|
||||
#include <pulsecore/macro.h>
|
||||
|
||||
#include "endianmacros.h"
|
||||
|
||||
#include "cpu-x86.h"
|
||||
#include "sconv.h"
|
||||
|
||||
#if defined (__i386__) || defined (__amd64__)
|
||||
|
||||
static const PA_DECLARE_ALIGNED (16, float, one[4]) = { 1.0, 1.0, 1.0, 1.0 };
|
||||
static const PA_DECLARE_ALIGNED (16, float, mone[4]) = { -1.0, -1.0, -1.0, -1.0 };
|
||||
static const PA_DECLARE_ALIGNED (16, float, scale[4]) = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
|
||||
|
||||
static void pa_sconv_s16le_from_f32ne_sse(unsigned n, const float *a, int16_t *b) {
|
||||
pa_reg_x86 temp, i;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" movaps %5, %%xmm5 \n\t"
|
||||
" movaps %6, %%xmm6 \n\t"
|
||||
" movaps %7, %%xmm7 \n\t"
|
||||
" xor %0, %0 \n\t"
|
||||
|
||||
" mov %4, %1 \n\t"
|
||||
" sar $3, %1 \n\t" /* 8 floats at a time */
|
||||
" cmp $0, %1 \n\t"
|
||||
" je 2f \n\t"
|
||||
|
||||
"1: \n\t"
|
||||
" movups (%2, %0, 2), %%xmm0 \n\t" /* read 8 floats */
|
||||
" movups 16(%2, %0, 2), %%xmm2 \n\t"
|
||||
" minps %%xmm5, %%xmm0 \n\t" /* clamp to 1.0 */
|
||||
" minps %%xmm5, %%xmm2 \n\t"
|
||||
" maxps %%xmm6, %%xmm0 \n\t" /* clamp to -1.0 */
|
||||
" maxps %%xmm6, %%xmm2 \n\t"
|
||||
" mulps %%xmm7, %%xmm0 \n\t" /* *= 0x7fff */
|
||||
" mulps %%xmm7, %%xmm2 \n\t"
|
||||
|
||||
" cvtps2pi %%xmm0, %%mm0 \n\t" /* low part to int */
|
||||
" cvtps2pi %%xmm2, %%mm2 \n\t"
|
||||
" movhlps %%xmm0, %%xmm0 \n\t" /* bring high part in position */
|
||||
" movhlps %%xmm2, %%xmm2 \n\t"
|
||||
" cvtps2pi %%xmm0, %%mm1 \n\t" /* high part to int */
|
||||
" cvtps2pi %%xmm2, %%mm3 \n\t"
|
||||
|
||||
" packssdw %%mm1, %%mm0 \n\t" /* pack parts */
|
||||
" packssdw %%mm3, %%mm2 \n\t"
|
||||
" movq %%mm0, (%3, %0) \n\t"
|
||||
" movq %%mm2, 8(%3, %0) \n\t"
|
||||
|
||||
" add $16, %0 \n\t"
|
||||
" dec %1 \n\t"
|
||||
" jne 1b \n\t"
|
||||
|
||||
"2: \n\t"
|
||||
" mov %4, %1 \n\t" /* prepare for leftovers */
|
||||
" and $15, %1 \n\t"
|
||||
" je 4f \n\t"
|
||||
|
||||
"3: \n\t"
|
||||
" movss (%2, %0, 2), %%xmm0 \n\t"
|
||||
" minss %%xmm5, %%xmm0 \n\t"
|
||||
" maxss %%xmm6, %%xmm0 \n\t"
|
||||
" mulss %%xmm7, %%xmm0 \n\t"
|
||||
" cvtss2si %%xmm0, %4 \n\t"
|
||||
" movw %w4, (%3, %0) \n\t"
|
||||
" add $2, %0 \n\t"
|
||||
" dec %1 \n\t"
|
||||
" jne 3b \n\t"
|
||||
|
||||
"4: \n\t"
|
||||
" emms \n\t"
|
||||
|
||||
: "=&r" (i), "=&r" (temp)
|
||||
: "r" (a), "r" (b), "r" ((pa_reg_x86)n), "m" (*one), "m" (*mone), "m" (*scale)
|
||||
: "cc", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static void pa_sconv_s16le_from_f32ne_sse2(unsigned n, const float *a, int16_t *b) {
|
||||
pa_reg_x86 temp, i;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" movaps %5, %%xmm5 \n\t"
|
||||
" movaps %6, %%xmm6 \n\t"
|
||||
" movaps %7, %%xmm7 \n\t"
|
||||
" xor %0, %0 \n\t"
|
||||
|
||||
" mov %4, %1 \n\t"
|
||||
" sar $3, %1 \n\t" /* 8 floats at a time */
|
||||
" cmp $0, %1 \n\t"
|
||||
" je 2f \n\t"
|
||||
|
||||
"1: \n\t"
|
||||
" movups (%2, %0, 2), %%xmm0 \n\t" /* read 8 floats */
|
||||
" movups 16(%2, %0, 2), %%xmm2 \n\t"
|
||||
" minps %%xmm5, %%xmm0 \n\t" /* clamp to 1.0 */
|
||||
" minps %%xmm5, %%xmm2 \n\t"
|
||||
" maxps %%xmm6, %%xmm0 \n\t" /* clamp to -1.0 */
|
||||
" maxps %%xmm6, %%xmm2 \n\t"
|
||||
" mulps %%xmm7, %%xmm0 \n\t" /* *= 0x7fff */
|
||||
" mulps %%xmm7, %%xmm2 \n\t"
|
||||
|
||||
" cvtps2dq %%xmm0, %%xmm0 \n\t"
|
||||
" cvtps2dq %%xmm2, %%xmm2 \n\t"
|
||||
|
||||
" packssdw %%xmm2, %%xmm0 \n\t"
|
||||
" movdqu %%xmm0, (%3, %0) \n\t"
|
||||
|
||||
" add $16, %0 \n\t"
|
||||
" dec %1 \n\t"
|
||||
" jne 1b \n\t"
|
||||
|
||||
"2: \n\t"
|
||||
" mov %4, %1 \n\t" /* prepare for leftovers */
|
||||
" and $15, %1 \n\t"
|
||||
" je 4f \n\t"
|
||||
|
||||
"3: \n\t"
|
||||
" movss (%2, %0, 2), %%xmm0 \n\t"
|
||||
" minss %%xmm5, %%xmm0 \n\t"
|
||||
" maxss %%xmm6, %%xmm0 \n\t"
|
||||
" mulss %%xmm7, %%xmm0 \n\t"
|
||||
" cvtss2si %%xmm0, %4 \n\t"
|
||||
" movw %w4, (%3, %0) \n\t"
|
||||
" add $2, %0 \n\t"
|
||||
" dec %1 \n\t"
|
||||
" jne 3b \n\t"
|
||||
|
||||
"4: \n\t"
|
||||
|
||||
: "=&r" (i), "=&r" (temp)
|
||||
: "r" (a), "r" (b), "r" ((pa_reg_x86)n), "m" (*one), "m" (*mone), "m" (*scale)
|
||||
: "cc", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#undef RUN_TEST
|
||||
|
||||
#ifdef RUN_TEST
|
||||
#define SAMPLES 1019
|
||||
#define TIMES 1000
|
||||
|
||||
static void run_test (void) {
|
||||
int16_t samples[SAMPLES];
|
||||
int16_t samples_ref[SAMPLES];
|
||||
float floats[SAMPLES];
|
||||
int i;
|
||||
pa_usec_t start, stop;
|
||||
pa_convert_func_t func;
|
||||
|
||||
printf ("checking SSE %zd\n", sizeof (samples));
|
||||
|
||||
memset (samples_ref, 0, sizeof (samples_ref));
|
||||
memset (samples, 0, sizeof (samples));
|
||||
|
||||
for (i = 0; i < SAMPLES; i++) {
|
||||
floats[i] = (rand()/(RAND_MAX+2.2)) - 1.1;
|
||||
}
|
||||
|
||||
func = pa_get_convert_from_float32ne_function (PA_SAMPLE_S16LE);
|
||||
func (SAMPLES, floats, samples_ref);
|
||||
pa_sconv_s16le_from_f32ne_sse2 (SAMPLES, floats, samples);
|
||||
|
||||
for (i = 0; i < SAMPLES; i++) {
|
||||
if (samples[i] != samples_ref[i]) {
|
||||
printf ("%d: %04x != %04x (%f)\n", i, samples[i], samples_ref[i],
|
||||
floats[i]);
|
||||
}
|
||||
}
|
||||
|
||||
start = pa_rtclock_now();
|
||||
for (i = 0; i < TIMES; i++) {
|
||||
pa_sconv_s16le_from_f32ne_sse2 (SAMPLES, floats, samples);
|
||||
}
|
||||
stop = pa_rtclock_now();
|
||||
pa_log_info("SSE: %llu usec.", (long long unsigned int)(stop - start));
|
||||
|
||||
start = pa_rtclock_now();
|
||||
for (i = 0; i < TIMES; i++) {
|
||||
func (SAMPLES, floats, samples_ref);
|
||||
}
|
||||
stop = pa_rtclock_now();
|
||||
pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
|
||||
}
|
||||
#endif
|
||||
#endif /* defined (__i386__) || defined (__amd64__) */
|
||||
|
||||
|
||||
void pa_convert_func_init_sse (pa_cpu_x86_flag_t flags) {
|
||||
#if defined (__i386__) || defined (__amd64__)
|
||||
pa_log_info("Initialising SSE optimized conversions.");
|
||||
|
||||
#ifdef RUN_TEST
|
||||
run_test ();
|
||||
#endif
|
||||
|
||||
if (flags & PA_CPU_X86_SSE2)
|
||||
pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse2);
|
||||
else
|
||||
pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse);
|
||||
|
||||
#endif /* defined (__i386__) || defined (__amd64__) */
|
||||
}
|
||||
|
|
@ -134,8 +134,7 @@ static void reset_callbacks(pa_sink_input *i) {
|
|||
int pa_sink_input_new(
|
||||
pa_sink_input **_i,
|
||||
pa_core *core,
|
||||
pa_sink_input_new_data *data,
|
||||
pa_sink_input_flags_t flags) {
|
||||
pa_sink_input_new_data *data) {
|
||||
|
||||
pa_sink_input *i;
|
||||
pa_resampler *resampler = NULL;
|
||||
|
|
@ -198,15 +197,15 @@ int pa_sink_input_new(
|
|||
if (!data->muted_is_set)
|
||||
data->muted = FALSE;
|
||||
|
||||
if (flags & PA_SINK_INPUT_FIX_FORMAT)
|
||||
if (data->flags & PA_SINK_INPUT_FIX_FORMAT)
|
||||
data->sample_spec.format = data->sink->sample_spec.format;
|
||||
|
||||
if (flags & PA_SINK_INPUT_FIX_RATE)
|
||||
if (data->flags & PA_SINK_INPUT_FIX_RATE)
|
||||
data->sample_spec.rate = data->sink->sample_spec.rate;
|
||||
|
||||
original_cm = data->channel_map;
|
||||
|
||||
if (flags & PA_SINK_INPUT_FIX_CHANNELS) {
|
||||
if (data->flags & PA_SINK_INPUT_FIX_CHANNELS) {
|
||||
data->sample_spec.channels = data->sink->sample_spec.channels;
|
||||
data->channel_map = data->sink->channel_map;
|
||||
}
|
||||
|
|
@ -225,7 +224,7 @@ int pa_sink_input_new(
|
|||
if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
|
||||
return r;
|
||||
|
||||
if ((flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
|
||||
if ((data->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
|
||||
pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
|
||||
pa_log_warn("Failed to create sink input: sink is suspended.");
|
||||
return -PA_ERR_BADSTATE;
|
||||
|
|
@ -236,7 +235,7 @@ int pa_sink_input_new(
|
|||
return -PA_ERR_TOOLARGE;
|
||||
}
|
||||
|
||||
if ((flags & PA_SINK_INPUT_VARIABLE_RATE) ||
|
||||
if ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
|
||||
!pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
|
||||
!pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
|
||||
|
||||
|
|
@ -245,9 +244,9 @@ int pa_sink_input_new(
|
|||
&data->sample_spec, &data->channel_map,
|
||||
&data->sink->sample_spec, &data->sink->channel_map,
|
||||
data->resample_method,
|
||||
((flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
|
||||
((flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
|
||||
(core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
|
||||
((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
|
||||
((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
|
||||
(core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
|
||||
(core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
|
||||
pa_log_warn("Unsupported resampling operation.");
|
||||
return -PA_ERR_NOTSUPPORTED;
|
||||
|
|
@ -260,7 +259,7 @@ int pa_sink_input_new(
|
|||
|
||||
i->core = core;
|
||||
i->state = PA_SINK_INPUT_INIT;
|
||||
i->flags = flags;
|
||||
i->flags = data->flags;
|
||||
i->proplist = pa_proplist_copy(data->proplist);
|
||||
i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
|
||||
i->module = data->module;
|
||||
|
|
@ -1472,7 +1471,13 @@ pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
|
|||
}
|
||||
|
||||
/* Called from IO context */
|
||||
void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sample spec */, pa_bool_t rewrite, pa_bool_t flush, pa_bool_t dont_rewind_render) {
|
||||
void pa_sink_input_request_rewind(
|
||||
pa_sink_input *i,
|
||||
size_t nbytes /* in our sample spec */,
|
||||
pa_bool_t rewrite,
|
||||
pa_bool_t flush,
|
||||
pa_bool_t dont_rewind_render) {
|
||||
|
||||
size_t lbq;
|
||||
|
||||
/* If 'rewrite' is TRUE the sink is rewound as far as requested
|
||||
|
|
@ -1487,19 +1492,20 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sam
|
|||
* dont_rewind_render is TRUE then the render memblockq is not
|
||||
* rewound. */
|
||||
|
||||
/* nbytes = 0 means maximum rewind request */
|
||||
|
||||
pa_sink_input_assert_ref(i);
|
||||
pa_sink_input_assert_io_context(i);
|
||||
|
||||
nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
|
||||
|
||||
/* pa_log_debug("request rewrite %lu", (unsigned long) nbytes); */
|
||||
pa_assert(rewrite || flush);
|
||||
pa_assert(!dont_rewind_render || !rewrite);
|
||||
|
||||
/* We don't take rewind requests while we are corked */
|
||||
if (i->thread_info.state == PA_SINK_INPUT_CORKED)
|
||||
return;
|
||||
|
||||
pa_assert(rewrite || flush);
|
||||
pa_assert(!dont_rewind_render || !rewrite);
|
||||
nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
|
||||
|
||||
/* pa_log_debug("request rewrite %zu", nbytes); */
|
||||
|
||||
/* Calculate how much we can rewind locally without having to
|
||||
* touch the sink */
|
||||
|
|
@ -1519,6 +1525,7 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes /* in our sam
|
|||
nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
|
||||
}
|
||||
|
||||
/* Remember how much we actually want to rewrite */
|
||||
if (i->thread_info.rewrite_nbytes != (size_t) -1) {
|
||||
if (rewrite) {
|
||||
/* Make sure to not overwrite over underruns */
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ struct pa_sink_input {
|
|||
|
||||
pa_bool_t attached:1; /* True only between ->attach() and ->detach() calls */
|
||||
|
||||
/* 0: rewrite nothing, (size_t) -1: rewrite everything, otherwise how many bytes to rewrite */
|
||||
/* rewrite_nbytes: 0: rewrite nothing, (size_t) -1: rewrite everything, otherwise how many bytes to rewrite */
|
||||
pa_bool_t rewrite_flush:1, dont_rewind_render:1;
|
||||
size_t rewrite_nbytes;
|
||||
uint64_t underrun_for, playing_for;
|
||||
|
|
@ -256,6 +256,8 @@ typedef struct pa_sink_input_send_event_hook_data {
|
|||
} pa_sink_input_send_event_hook_data;
|
||||
|
||||
typedef struct pa_sink_input_new_data {
|
||||
pa_sink_input_flags_t flags;
|
||||
|
||||
pa_proplist *proplist;
|
||||
|
||||
const char *driver;
|
||||
|
|
@ -298,8 +300,7 @@ void pa_sink_input_new_data_done(pa_sink_input_new_data *data);
|
|||
int pa_sink_input_new(
|
||||
pa_sink_input **i,
|
||||
pa_core *core,
|
||||
pa_sink_input_new_data *data,
|
||||
pa_sink_input_flags_t flags);
|
||||
pa_sink_input_new_data *data);
|
||||
|
||||
void pa_sink_input_put(pa_sink_input *i);
|
||||
void pa_sink_input_unlink(pa_sink_input* i);
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@ pa_sink* pa_sink_new(
|
|||
s->core = core;
|
||||
s->state = PA_SINK_INIT;
|
||||
s->flags = flags;
|
||||
s->priority = 0;
|
||||
s->suspend_cause = 0;
|
||||
s->name = pa_xstrdup(name);
|
||||
s->proplist = pa_proplist_copy(data->proplist);
|
||||
|
|
@ -243,6 +244,8 @@ pa_sink* pa_sink_new(
|
|||
s->module = data->module;
|
||||
s->card = data->card;
|
||||
|
||||
s->priority = pa_device_init_priority(s->proplist);
|
||||
|
||||
s->sample_spec = data->sample_spec;
|
||||
s->channel_map = data->channel_map;
|
||||
|
||||
|
|
@ -2695,3 +2698,48 @@ pa_bool_t pa_device_init_intended_roles(pa_proplist *p) {
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unsigned pa_device_init_priority(pa_proplist *p) {
|
||||
const char *s;
|
||||
unsigned priority = 0;
|
||||
|
||||
pa_assert(p);
|
||||
|
||||
if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS))) {
|
||||
|
||||
if (pa_streq(s, "sound"))
|
||||
priority += 9000;
|
||||
else if (!pa_streq(s, "modem"))
|
||||
priority += 1000;
|
||||
}
|
||||
|
||||
if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
|
||||
|
||||
if (pa_streq(s, "internal"))
|
||||
priority += 900;
|
||||
else if (pa_streq(s, "speaker"))
|
||||
priority += 500;
|
||||
else if (pa_streq(s, "headphone"))
|
||||
priority += 400;
|
||||
}
|
||||
|
||||
if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_BUS))) {
|
||||
|
||||
if (pa_streq(s, "pci"))
|
||||
priority += 50;
|
||||
else if (pa_streq(s, "usb"))
|
||||
priority += 40;
|
||||
else if (pa_streq(s, "bluetooth"))
|
||||
priority += 30;
|
||||
}
|
||||
|
||||
if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
|
||||
|
||||
if (pa_startswith(s, "analog-"))
|
||||
priority += 9;
|
||||
else if (pa_startswith(s, "iec958-"))
|
||||
priority += 8;
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ struct pa_sink {
|
|||
pa_hashmap *ports;
|
||||
pa_device_port *active_port;
|
||||
|
||||
unsigned priority;
|
||||
|
||||
/* Called when the main loop requests a state change. Called from
|
||||
* main loop context. If returns -1 the state change will be
|
||||
* inhibited */
|
||||
|
|
@ -288,6 +290,7 @@ void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t valu
|
|||
pa_bool_t pa_device_init_description(pa_proplist *p);
|
||||
pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink);
|
||||
pa_bool_t pa_device_init_intended_roles(pa_proplist *p);
|
||||
unsigned pa_device_init_priority(pa_proplist *p);
|
||||
|
||||
/**** May be called by everyone, from main context */
|
||||
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ int pa_play_file(
|
|||
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_FILENAME, fname);
|
||||
pa_sndfile_init_proplist(u->sndfile, data.proplist);
|
||||
|
||||
pa_sink_input_new(&u->sink_input, sink->core, &data, 0);
|
||||
pa_sink_input_new(&u->sink_input, sink->core, &data);
|
||||
pa_sink_input_new_data_done(&data);
|
||||
|
||||
if (!u->sink_input)
|
||||
|
|
@ -334,7 +334,6 @@ int pa_play_file(
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
if (u)
|
||||
file_stream_unref(u);
|
||||
|
||||
if (fd >= 0)
|
||||
|
|
|
|||
|
|
@ -101,8 +101,7 @@ static void reset_callbacks(pa_source_output *o) {
|
|||
int pa_source_output_new(
|
||||
pa_source_output**_o,
|
||||
pa_core *core,
|
||||
pa_source_output_new_data *data,
|
||||
pa_source_output_flags_t flags) {
|
||||
pa_source_output_new_data *data) {
|
||||
|
||||
pa_source_output *o;
|
||||
pa_resampler *resampler = NULL;
|
||||
|
|
@ -146,13 +145,13 @@ int pa_source_output_new(
|
|||
pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
|
||||
pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
|
||||
|
||||
if (flags & PA_SOURCE_OUTPUT_FIX_FORMAT)
|
||||
if (data->flags & PA_SOURCE_OUTPUT_FIX_FORMAT)
|
||||
data->sample_spec.format = data->source->sample_spec.format;
|
||||
|
||||
if (flags & PA_SOURCE_OUTPUT_FIX_RATE)
|
||||
if (data->flags & PA_SOURCE_OUTPUT_FIX_RATE)
|
||||
data->sample_spec.rate = data->source->sample_spec.rate;
|
||||
|
||||
if (flags & PA_SOURCE_OUTPUT_FIX_CHANNELS) {
|
||||
if (data->flags & PA_SOURCE_OUTPUT_FIX_CHANNELS) {
|
||||
data->sample_spec.channels = data->source->sample_spec.channels;
|
||||
data->channel_map = data->source->channel_map;
|
||||
}
|
||||
|
|
@ -168,7 +167,7 @@ int pa_source_output_new(
|
|||
if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], data)) < 0)
|
||||
return r;
|
||||
|
||||
if ((flags & PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND) &&
|
||||
if ((data->flags & PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND) &&
|
||||
pa_source_get_state(data->source) == PA_SOURCE_SUSPENDED) {
|
||||
pa_log("Failed to create source output: source is suspended.");
|
||||
return -PA_ERR_BADSTATE;
|
||||
|
|
@ -179,7 +178,7 @@ int pa_source_output_new(
|
|||
return -PA_ERR_TOOLARGE;
|
||||
}
|
||||
|
||||
if ((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ||
|
||||
if ((data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ||
|
||||
!pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec) ||
|
||||
!pa_channel_map_equal(&data->channel_map, &data->source->channel_map)) {
|
||||
|
||||
|
|
@ -188,9 +187,9 @@ int pa_source_output_new(
|
|||
&data->source->sample_spec, &data->source->channel_map,
|
||||
&data->sample_spec, &data->channel_map,
|
||||
data->resample_method,
|
||||
((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
|
||||
((flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
|
||||
(core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
|
||||
((data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
|
||||
((data->flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
|
||||
(core->disable_remixing || (data->flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
|
||||
(core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
|
||||
pa_log_warn("Unsupported resampling operation.");
|
||||
return -PA_ERR_NOTSUPPORTED;
|
||||
|
|
@ -203,7 +202,7 @@ int pa_source_output_new(
|
|||
|
||||
o->core = core;
|
||||
o->state = PA_SOURCE_OUTPUT_INIT;
|
||||
o->flags = flags;
|
||||
o->flags = data->flags;
|
||||
o->proplist = pa_proplist_copy(data->proplist);
|
||||
o->driver = pa_xstrdup(pa_path_get_filename(data->driver));
|
||||
o->module = data->module;
|
||||
|
|
|
|||
|
|
@ -201,6 +201,8 @@ typedef struct pa_source_output_send_event_hook_data {
|
|||
} pa_source_output_send_event_hook_data;
|
||||
|
||||
typedef struct pa_source_output_new_data {
|
||||
pa_source_output_flags_t flags;
|
||||
|
||||
pa_proplist *proplist;
|
||||
pa_sink_input *direct_on_input;
|
||||
|
||||
|
|
@ -231,8 +233,7 @@ void pa_source_output_new_data_done(pa_source_output_new_data *data);
|
|||
int pa_source_output_new(
|
||||
pa_source_output**o,
|
||||
pa_core *core,
|
||||
pa_source_output_new_data *data,
|
||||
pa_source_output_flags_t flags);
|
||||
pa_source_output_new_data *data);
|
||||
|
||||
void pa_source_output_put(pa_source_output *o);
|
||||
void pa_source_output_unlink(pa_source_output*o);
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ pa_source* pa_source_new(
|
|||
s->core = core;
|
||||
s->state = PA_SOURCE_INIT;
|
||||
s->flags = flags;
|
||||
s->priority = 0;
|
||||
s->suspend_cause = 0;
|
||||
s->name = pa_xstrdup(name);
|
||||
s->proplist = pa_proplist_copy(data->proplist);
|
||||
|
|
@ -212,6 +213,8 @@ pa_source* pa_source_new(
|
|||
s->module = data->module;
|
||||
s->card = data->card;
|
||||
|
||||
s->priority = pa_device_init_priority(s->proplist);
|
||||
|
||||
s->sample_spec = data->sample_spec;
|
||||
s->channel_map = data->channel_map;
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ struct pa_source {
|
|||
pa_hashmap *ports;
|
||||
pa_device_port *active_port;
|
||||
|
||||
unsigned priority;
|
||||
|
||||
/* Called when the main loop requests a state change. Called from
|
||||
* main loop context. If returns -1 the state change will be
|
||||
* inhibited */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue