diff --git a/pipewire-alsa b/pipewire-alsa index d81bbae7e..dddaaf4db 160000 --- a/pipewire-alsa +++ b/pipewire-alsa @@ -1 +1 @@ -Subproject commit d81bbae7ea2cb07abe85636bd52ab19b06b20dee +Subproject commit dddaaf4db427cb5b9bc5cc273bff00bfdb75d7c7 diff --git a/pipewire-jack b/pipewire-jack index 48f28f7b6..2d6f9950a 160000 --- a/pipewire-jack +++ b/pipewire-jack @@ -1 +1 @@ -Subproject commit 48f28f7b63658832f348b65511906eceb329b1ba +Subproject commit 2d6f9950a5e036f908953727e61e3b3fb02eacf0 diff --git a/pipewire-pulseaudio b/pipewire-pulseaudio index 5e2b740ee..69ad904b6 160000 --- a/pipewire-pulseaudio +++ b/pipewire-pulseaudio @@ -1 +1 @@ -Subproject commit 5e2b740ee0ffc276911ef9217237dbb47da8be6f +Subproject commit 69ad904b63954257da772af1bea8deea27fca369 diff --git a/spa/plugins/alsa/alsa-monitor.c b/spa/plugins/alsa/alsa-monitor.c index 2715199ad..1f6c2dab1 100644 --- a/spa/plugins/alsa/alsa-monitor.c +++ b/spa/plugins/alsa/alsa-monitor.c @@ -101,10 +101,90 @@ static const char *path_get_card_id(const char *path) return e + 5; } +static int dehex(char x) +{ + if (x >= '0' && x <= '9') + return x - '0'; + if (x >= 'A' && x <= 'F') + return x - 'A' + 10; + if (x >= 'a' && x <= 'f') + return x - 'a' + 10; + return -1; +} + +static void unescape(const char *src, char *dst) +{ + const char *s; + char *d; + int h1, h2; + enum { TEXT, BACKSLASH, EX, FIRST } state = TEXT; + + for (s = src, d = dst; *s; s++) { + switch (state) { + case TEXT: + if (*s == '\\') + state = BACKSLASH; + else + *(d++) = *s; + break; + + case BACKSLASH: + if (*s == 'x') + state = EX; + else { + *(d++) = '\\'; + *(d++) = *s; + state = TEXT; + } + break; + + case EX: + h1 = dehex(*s); + if (h1 < 0) { + *(d++) = '\\'; + *(d++) = 'x'; + *(d++) = *s; + state = TEXT; + } else + state = FIRST; + break; + + case FIRST: + h2 = dehex(*s); + if (h2 < 0) { + *(d++) = '\\'; + *(d++) = 'x'; + *(d++) = *(s-1); + *(d++) = *s; + } else + *(d++) = (char) (h1 << 4) | h2; + state = TEXT; + break; + } + } + switch (state) { + case TEXT: + break; + case BACKSLASH: + *(d++) = '\\'; + break; + case EX: + *(d++) = '\\'; + *(d++) = 'x'; + break; + case FIRST: + *(d++) = '\\'; + *(d++) = 'x'; + *(d++) = *(s-1); + break; + } + *d = 0; +} + static int emit_object_info(struct impl *this, uint32_t id, struct udev_device *dev) { struct spa_monitor_object_info info; - const char *str, *name; + const char *str; char path[32]; struct spa_dict_item items[20]; uint32_t n_items = 0; @@ -117,17 +197,8 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device * SPA_MONITOR_OBJECT_CHANGE_MASK_PROPS; info.flags = 0; - name = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE"); - if (!(name && *name)) { - name = udev_device_get_property_value(dev, "ID_MODEL_ENC"); - if (!(name && *name)) { - name = udev_device_get_property_value(dev, "ID_MODEL"); - } - } - if (!(name && *name)) - name = "Unknown"; - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_MONITOR_API, "udev"); + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "alsa"); if ((str = path_get_card_id(udev_device_get_property_value(dev, "DEVPATH"))) == NULL) return 0; @@ -135,7 +206,9 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device * snprintf(path, sizeof(path), "hw:%d", atoi(str)); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_PATH, path); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_CARD, str); - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_NAME, name); + + if ((str = udev_device_get_property_value(dev, "PULSE_NAME")) && *str) + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_NAME, str); if ((str = udev_device_get_property_value(dev, "SOUND_CLASS")) && *str) items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_CLASS, str); @@ -169,6 +242,10 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device * str = udev_device_get_property_value(dev, "ID_VENDOR_ENC"); if (!(str && *str)) { str = udev_device_get_property_value(dev, "ID_VENDOR"); + } else { + char *t = alloca(strlen(str) + 1); + unescape(str, t); + str = t; } } if (str && *str) { @@ -177,7 +254,19 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device * if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) { items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_ID, str); } - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_NAME, name); + str = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE"); + if (!(str && *str)) { + str = udev_device_get_property_value(dev, "ID_MODEL_ENC"); + if (!(str && *str)) { + str = udev_device_get_property_value(dev, "ID_MODEL"); + } else { + char *t = alloca(strlen(str) + 1); + unescape(str, t); + str = t; + } + } + if (str && *str) + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_NAME, str); if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) { items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_SERIAL, str); diff --git a/spa/plugins/audioconvert/audioadapter.c b/spa/plugins/audioconvert/audioadapter.c index 940b3284e..6df4f5a14 100644 --- a/spa/plugins/audioconvert/audioadapter.c +++ b/spa/plugins/audioconvert/audioadapter.c @@ -99,6 +99,8 @@ static int impl_node_enum_params(void *object, int seq, next: result.index = result.next; + spa_log_debug(this->log, NAME" %p: %d id:%u", this, seq, id); + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -190,7 +192,6 @@ static void emit_node_info(struct impl *this, bool full) if (this->info.change_mask) { struct spa_dict_item items[1]; - this->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS; items[0] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_DRIVER, this->driver ? "1" : "0"); this->info.props = &SPA_DICT_INIT(items, 1); @@ -228,10 +229,6 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, if (this->target != this->slave) { if ((res = spa_node_set_param(this->target, id, flags, param)) < 0) return res; - - this->info.change_mask = SPA_NODE_CHANGE_MASK_PARAMS; - this->params[2].flags ^= SPA_PARAM_INFO_SERIAL; - emit_node_info(this, false); } break; default: @@ -366,8 +363,10 @@ static void slave_info(void *data, const struct spa_node_info *info) "Input" : "Output"); if (info->props) { - if ((str = spa_dict_lookup(info->props, SPA_KEY_NODE_DRIVER)) != NULL) + if ((str = spa_dict_lookup(info->props, SPA_KEY_NODE_DRIVER)) != NULL) { this->driver = strcmp(str, "true") == 0 || atoi(str) == 1; + this->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS; + } } } diff --git a/spa/plugins/audioconvert/channelmix-ops-c.c b/spa/plugins/audioconvert/channelmix-ops-c.c index 522196158..5b1a91a5f 100644 --- a/spa/plugins/audioconvert/channelmix-ops-c.c +++ b/spa/plugins/audioconvert/channelmix-ops-c.c @@ -31,7 +31,8 @@ channelmix_copy_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRICT ds uint32_t i, n; float **d = (float **)dst; const float **s = (const float **)src; - float v = mix->volume; + const float *m = mix->matrix; + const float v = mix->volume; if (v <= VOLUME_MIN) { for (i = 0; i < n_dst; i++) @@ -42,9 +43,12 @@ channelmix_copy_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRICT ds spa_memcpy(d[i], s[i], n_samples * sizeof(float)); } else { - for (i = 0; i < n_dst; i++) + for (i = 0; i < n_dst; i++) { + const float vol = m[i * n_src + i]; for (n = 0; n < n_samples; n++) - d[i][n] = s[i][n] * v; + d[i][n] = s[i][n] * vol; + } + } } @@ -58,14 +62,13 @@ channelmix_f32_n_m_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRICT float **d = (float **) dst; const float **s = (const float **) src; const float *m = mix->matrix; - float v = mix->volume; for (n = 0; n < n_samples; n++) { for (i = 0; i < n_dst; i++) { float sum = 0.0f; for (j = 0; j < n_src; j++) sum += s[j][n] * m[i * n_src + j]; - d[i][n] = sum * v; + d[i][n] = sum; } } } diff --git a/spa/plugins/audioconvert/channelmix-ops-sse.c b/spa/plugins/audioconvert/channelmix-ops-sse.c index 78e53e298..dbd506b05 100644 --- a/spa/plugins/audioconvert/channelmix-ops-sse.c +++ b/spa/plugins/audioconvert/channelmix-ops-sse.c @@ -32,8 +32,8 @@ void channelmix_copy_sse(struct channelmix *mix, uint32_t n_dst, void * SPA_REST uint32_t i, n, unrolled; float **d = (float **)dst; const float **s = (const float **)src; + float *m = mix->matrix; float v = mix->volume; - const __m128 vol = _mm_set1_ps(v); if (v <= VOLUME_MIN) { for (i = 0; i < n_dst; i++) @@ -48,6 +48,7 @@ void channelmix_copy_sse(struct channelmix *mix, uint32_t n_dst, void * SPA_REST float *di = d[i]; const float *si = s[i]; __m128 t[4]; + const __m128 vol = _mm_set1_ps(m[i * n_src + i]); if (SPA_IS_ALIGNED(di, 16) && SPA_IS_ALIGNED(si, 16)) diff --git a/spa/plugins/audioconvert/channelmix-ops.c b/spa/plugins/audioconvert/channelmix-ops.c index 8ad3b1890..170a1856d 100644 --- a/spa/plugins/audioconvert/channelmix-ops.c +++ b/spa/plugins/audioconvert/channelmix-ops.c @@ -159,9 +159,7 @@ static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uin static int make_matrix(struct channelmix *mix) { float matrix[NUM_CHAN][NUM_CHAN] = {{ 0.0f }}; - uint32_t src_chan = mix->src_chan; uint64_t src_mask = mix->src_mask; - uint32_t dst_chan = mix->dst_chan; uint64_t dst_mask = mix->dst_mask; uint64_t unassigned; uint32_t i, j, matrix_encoding = MATRIX_NORMAL, c; @@ -335,11 +333,46 @@ static int make_matrix(struct channelmix *mix) for (j = 0; j < NUM_CHAN; j++) { if ((src_mask & (1UL << (j + 2))) == 0) continue; - mix->matrix[c++] = matrix[i][j]; + mix->matrix_orig[c++] = matrix[i][j]; sum += fabs(matrix[i][j]); } max = SPA_MAX(max, sum); } + return 0; +} + +static void impl_channelmix_set_volume(struct channelmix *mix, float volume, bool mute, + uint32_t n_channel_volumes, float *channel_volumes) +{ + float volumes[SPA_AUDIO_MAX_CHANNELS]; + float vol = mute ? 0.0f : volume, sum; + uint32_t i, j; + uint32_t src_chan = mix->src_chan; + uint32_t dst_chan = mix->dst_chan; + + /** apply global volume to channels */ + sum = 0.0; + for (i = 0; i < n_channel_volumes; i++) { + volumes[i] = channel_volumes[i] * vol; + sum += volumes[i]; + } + mix->volume = sum / n_channel_volumes; + + if (n_channel_volumes == src_chan) { + for (i = 0; i < dst_chan; i++) { + for (j = 0; j < src_chan; j++) { + float v = mix->matrix_orig[i * src_chan + j]; + mix->matrix[i * src_chan + j] = v * volumes[j]; + } + } + } else if (n_channel_volumes == dst_chan) { + for (i = 0; i < dst_chan; i++) { + for (j = 0; j < src_chan; j++) { + float v = mix->matrix_orig[i * src_chan + j]; + mix->matrix[i * src_chan + j] = v * volumes[i]; + } + } + } mix->is_identity = dst_chan == src_chan; for (i = 0; i < dst_chan; i++) { @@ -351,7 +384,7 @@ static int make_matrix(struct channelmix *mix) mix->is_identity = false; } } - return 0; + spa_log_debug(mix->log, "vol:%f, identity:%d", mix->volume, mix->is_identity); } static void impl_channelmix_free(struct channelmix *mix) @@ -370,6 +403,7 @@ int channelmix_init(struct channelmix *mix) mix->free = impl_channelmix_free; mix->process = info->process; + mix->set_volume = impl_channelmix_set_volume; mix->cpu_flags = info->cpu_flags; return make_matrix(mix); } diff --git a/spa/plugins/audioconvert/channelmix-ops.h b/spa/plugins/audioconvert/channelmix-ops.h index 48b191b58..bd5568fed 100644 --- a/spa/plugins/audioconvert/channelmix-ops.h +++ b/spa/plugins/audioconvert/channelmix-ops.h @@ -26,12 +26,11 @@ #include #include +#include #define VOLUME_MIN 0.0f #define VOLUME_NORM 1.0f -#define MAX_CHANNELS 64 - #define _M(ch) (1UL << SPA_AUDIO_CHANNEL_ ## ch) #define MASK_MONO _M(FC)|_M(MONO)|_M(UNKNOWN) #define MASK_STEREO _M(FL)|_M(FR)|_M(UNKNOWN) @@ -52,10 +51,14 @@ struct channelmix { unsigned int is_identity:1; float volume; - float matrix[MAX_CHANNELS * MAX_CHANNELS]; + float matrix_orig[SPA_AUDIO_MAX_CHANNELS * SPA_AUDIO_MAX_CHANNELS]; + + float matrix[SPA_AUDIO_MAX_CHANNELS * SPA_AUDIO_MAX_CHANNELS]; void (*process) (struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRICT dst[n_dst], uint32_t n_src, const void * SPA_RESTRICT src[n_src], uint32_t n_samples); + void (*set_volume) (struct channelmix *mix, float volume, bool mute, + uint32_t n_channel_volumes, float *channel_volumes); void (*free) (struct channelmix *mix); void *data; @@ -64,6 +67,7 @@ struct channelmix { int channelmix_init(struct channelmix *mix); #define channelmix_process(mix,...) (mix)->process(mix, __VA_ARGS__) +#define channelmix_set_volume(mix,...) (mix)->set_volume(mix, __VA_ARGS__) #define channelmix_free(mix) (mix)->free(mix) #define DEFINE_FUNCTION(name,arch) \ diff --git a/spa/plugins/audioconvert/channelmix.c b/spa/plugins/audioconvert/channelmix.c index 1c1bf69ad..350ad754d 100644 --- a/spa/plugins/audioconvert/channelmix.c +++ b/spa/plugins/audioconvert/channelmix.c @@ -39,6 +39,8 @@ #include #include +#include "channelmix-ops.h" + #define NAME "channelmix" #define DEFAULT_RATE 44100 @@ -55,12 +57,18 @@ struct impl; struct props { float volume; bool mute; + uint32_t n_channel_volumes; + float channel_volumes[SPA_AUDIO_MAX_CHANNELS]; }; static void props_reset(struct props *props) { + uint32_t i; props->mute = DEFAULT_MUTE; props->volume = DEFAULT_VOLUME; + props->n_channel_volumes = 0; + for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + props->channel_volumes[i] = 1.0; } struct buffer { @@ -96,8 +104,6 @@ struct port { struct spa_list queue; }; -#include "channelmix-ops.h" - struct impl { struct spa_handle handle; struct spa_node node; @@ -228,11 +234,17 @@ static int setup_convert(struct impl *this, this->mix.dst_mask = dst_mask; this->mix.cpu_flags = this->cpu_flags; this->mix.log = this->log; - this->mix.volume = this->props.mute ? 0.0f : this->props.volume; if ((res = channelmix_init(&this->mix)) < 0) return res; + this->props.n_channel_volumes = SPA_MAX(src_chan, dst_chan); + + channelmix_set_volume(&this->mix, this->props.volume, this->props.mute, + this->props.n_channel_volumes, this->props.channel_volumes); + + emit_params_changed(this); + spa_log_info(this->log, NAME " %p: got channelmix features %08x:%08x %d", this, this->cpu_flags, this->mix.cpu_flags, this->mix.is_identity); @@ -283,6 +295,13 @@ static int impl_node_enum_params(void *object, int seq, SPA_PROP_INFO_name, SPA_POD_String("Mute"), SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool(p->mute)); break; + case 2: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_PropInfo, id, + SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_channelVolumes), + SPA_PROP_INFO_name, SPA_POD_String("Channel Volumes"), + SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(p->volume, 0.0, 10.0)); + break; default: return 0; } @@ -296,8 +315,12 @@ static int impl_node_enum_params(void *object, int seq, case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, - SPA_PROP_volume, SPA_POD_Float(p->volume), - SPA_PROP_mute, SPA_POD_Bool(p->mute)); + SPA_PROP_volume, SPA_POD_Float(p->volume), + SPA_PROP_mute, SPA_POD_Bool(p->mute), + SPA_PROP_channelVolumes, SPA_POD_Array(sizeof(float), + SPA_TYPE_Float, + p->n_channel_volumes, + p->channel_volumes)); break; default: return 0; @@ -336,13 +359,19 @@ static int apply_props(struct impl *this, const struct spa_pod *param) if (spa_pod_get_bool(&prop->value, &p->mute) == 0) changed++; break; + case SPA_PROP_channelVolumes: + if (spa_pod_copy_array(&prop->value, SPA_TYPE_Float, + p->channel_volumes, SPA_AUDIO_MAX_CHANNELS) > 0) + changed++; + break; default: break; } } - if (changed) - this->mix.volume = p->mute ? 0.0f : p->volume; - + if (changed && this->mix.set_volume) { + channelmix_set_volume(&this->mix, p->volume, p->mute, + p->n_channel_volumes, p->channel_volumes); + } return changed; } diff --git a/spa/plugins/audioconvert/splitter.c b/spa/plugins/audioconvert/splitter.c index dba2d4e80..f4c5380ae 100644 --- a/spa/plugins/audioconvert/splitter.c +++ b/spa/plugins/audioconvert/splitter.c @@ -334,7 +334,6 @@ impl_node_add_listener(void *object, spa_return_val_if_fail(this != NULL, -EINVAL); - spa_log_debug(this->log, NAME " %p: listener %p", this, listener); spa_hook_list_isolate(&this->hooks, &save, listener, events, data); emit_node_info(this, true); diff --git a/spa/plugins/v4l2/v4l2-monitor.c b/spa/plugins/v4l2/v4l2-monitor.c index 15a39fd83..b4eb2172b 100644 --- a/spa/plugins/v4l2/v4l2-monitor.c +++ b/spa/plugins/v4l2/v4l2-monitor.c @@ -90,10 +90,90 @@ static uint32_t get_device_id(struct impl *this, struct udev_device *dev) return atoi(str + 6); } +static int dehex(char x) +{ + if (x >= '0' && x <= '9') + return x - '0'; + if (x >= 'A' && x <= 'F') + return x - 'A' + 10; + if (x >= 'a' && x <= 'f') + return x - 'a' + 10; + return -1; +} + +static void unescape(const char *src, char *dst) +{ + const char *s; + char *d; + int h1, h2; + enum { TEXT, BACKSLASH, EX, FIRST } state = TEXT; + + for (s = src, d = dst; *s; s++) { + switch (state) { + case TEXT: + if (*s == '\\') + state = BACKSLASH; + else + *(d++) = *s; + break; + + case BACKSLASH: + if (*s == 'x') + state = EX; + else { + *(d++) = '\\'; + *(d++) = *s; + state = TEXT; + } + break; + + case EX: + h1 = dehex(*s); + if (h1 < 0) { + *(d++) = '\\'; + *(d++) = 'x'; + *(d++) = *s; + state = TEXT; + } else + state = FIRST; + break; + + case FIRST: + h2 = dehex(*s); + if (h2 < 0) { + *(d++) = '\\'; + *(d++) = 'x'; + *(d++) = *(s-1); + *(d++) = *s; + } else + *(d++) = (char) (h1 << 4) | h2; + state = TEXT; + break; + } + } + switch (state) { + case TEXT: + break; + case BACKSLASH: + *(d++) = '\\'; + break; + case EX: + *(d++) = '\\'; + *(d++) = 'x'; + break; + case FIRST: + *(d++) = '\\'; + *(d++) = 'x'; + *(d++) = *(s-1); + break; + } + *d = 0; +} + static int emit_object_info(struct impl *this, uint32_t id, struct udev_device *dev) { struct spa_monitor_object_info info; - const char *str, *name; + const char *str; struct spa_dict_item items[20]; uint32_t n_items = 0; @@ -105,22 +185,9 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device * SPA_MONITOR_OBJECT_CHANGE_MASK_PROPS; info.flags = 0; - name = udev_device_get_property_value(dev, "ID_V4L_PRODUCT"); - if (!(name && *name)) { - name = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE"); - if (!(name && *name)) { - name = udev_device_get_property_value(dev, "ID_MODEL_ENC"); - if (!(name && *name)) { - name = udev_device_get_property_value(dev, "ID_MODEL"); - } - } - } - if (!(name && *name)) - name = "Unknown"; - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_MONITOR_API,"udev"); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "v4l2"); - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_NAME, name); + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_V4L2_PATH, udev_device_get_devnode(dev)); if ((str = udev_device_get_property_value(dev, "USEC_INITIALIZED")) && *str) @@ -152,6 +219,10 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device * str = udev_device_get_property_value(dev, "ID_VENDOR_ENC"); if (!(str && *str)) { str = udev_device_get_property_value(dev, "ID_VENDOR"); + } else { + char *t = alloca(strlen(str) + 1); + unescape(str, t); + str = t; } } if (str && *str) { @@ -160,7 +231,24 @@ static int emit_object_info(struct impl *this, uint32_t id, struct udev_device * if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) { items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_ID, str); } - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_NAME, name); + + str = udev_device_get_property_value(dev, "ID_V4L_PRODUCT"); + if (!(str && *str)) { + str = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE"); + if (!(str && *str)) { + str = udev_device_get_property_value(dev, "ID_MODEL_ENC"); + if (!(str && *str)) { + str = udev_device_get_property_value(dev, "ID_MODEL"); + } else { + char *t = alloca(strlen(str) + 1); + unescape(str, t); + str = t; + } + } + } + if (str && *str) + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_NAME, str); + if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) { items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_SERIAL, str); } diff --git a/src/examples/alsa-monitor.c b/src/examples/alsa-monitor.c index c67964fa1..16a83843a 100644 --- a/src/examples/alsa-monitor.c +++ b/src/examples/alsa-monitor.c @@ -109,17 +109,27 @@ static struct alsa_node *alsa_create_node(struct alsa_object *obj, uint32_t id, goto exit; } - node->props = pw_properties_copy(obj->props); - pw_properties_update(node->props, info->props); + node->props = pw_properties_new_dict(info->props); str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NICK); + if (str) + pw_properties_set(node->props, PW_KEY_NODE_NICK, str); + + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NAME); if (str == NULL) - str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NAME); + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NICK); if (str == NULL) str = pw_properties_get(obj->props, SPA_KEY_DEVICE_ALIAS); if (str == NULL) str = "alsa-device"; - pw_properties_set(node->props, PW_KEY_NODE_NAME, str); + + pw_properties_setf(node->props, PW_KEY_NODE_NAME, "%s.%s", info->factory_name, str); + + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_DESCRIPTION); + if (str == NULL) + str = "alsa-device"; + pw_properties_set(node->props, PW_KEY_NODE_DESCRIPTION, str); + pw_properties_set(node->props, "factory.name", info->factory_name); node->monitor = monitor; @@ -209,6 +219,83 @@ static void alsa_update_object(struct monitor *monitor, struct alsa_object *obj, pw_properties_update(obj->props, info->props); } +static int update_device_props(struct alsa_object *obj) +{ + struct pw_properties *p = obj->props; + const char *s, *d; + char temp[32]; + + if ((s = pw_properties_get(p, SPA_KEY_DEVICE_NAME)) == NULL) { + if ((s = pw_properties_get(p, SPA_KEY_DEVICE_ID)) == NULL) { + if ((s = pw_properties_get(p, SPA_KEY_DEVICE_BUS_PATH)) == NULL) { + snprintf(temp, sizeof(temp), "%d", obj->id); + s = temp; + } + } + } + pw_properties_setf(p, PW_KEY_DEVICE_NAME, "alsa_card.%s", s); + + if (pw_properties_get(p, PW_KEY_DEVICE_DESCRIPTION) == NULL) { + d = NULL; + + if ((s = pw_properties_get(p, PW_KEY_DEVICE_FORM_FACTOR))) + if (strcmp(s, "internal") == 0) + d = "Built-in Audio"; + if (!d) + if ((s = pw_properties_get(p, PW_KEY_DEVICE_CLASS))) + if (strcmp(s, "modem") == 0) + d = "Modem"; + if (!d) + d = pw_properties_get(p, PW_KEY_DEVICE_PRODUCT_NAME); + + if (!d) + d = "Unknown device"; + + pw_properties_set(p, PW_KEY_DEVICE_DESCRIPTION, d); + } + + if (pw_properties_get(p, PW_KEY_DEVICE_ICON_NAME) == NULL) { + d = NULL; + + if ((s = pw_properties_get(p, PW_KEY_DEVICE_FORM_FACTOR))) { + if (strcmp(s, "microphone") == 0) + d = "audio-input-microphone"; + else if (strcmp(s, "webcam") == 0) + d = "camera-web"; + else if (strcmp(s, "computer") == 0) + d = "computer"; + else if (strcmp(s, "handset") == 0) + d = "phone"; + else if (strcmp(s, "portable") == 0) + d = "multimedia-player"; + else if (strcmp(s, "tv") == 0) + d = "video-display"; + else if (strcmp(s, "headset") == 0) + d = "audio-headset"; + else if (strcmp(s, "headphone") == 0) + d = "audio-headphones"; + else if (strcmp(s, "speaker") == 0) + d = "audio-speakers"; + else if (strcmp(s, "hands-free") == 0) + d = "audio-handsfree"; + } + if (!d) + if ((s = pw_properties_get(p, PW_KEY_DEVICE_CLASS))) + if (strcmp(s, "modem") == 0) + d = "modem"; + + if (!d) + d = "audio-card"; + + s = pw_properties_get(p, PW_KEY_DEVICE_BUS); + + pw_properties_setf(p, PW_KEY_DEVICE_ICON_NAME, + "%s-analog%s%s", d, s ? "-" : "", s); + } + return 1; +} + + static struct alsa_object *alsa_create_object(struct monitor *monitor, uint32_t id, const struct spa_monitor_object_info *info) { @@ -251,6 +338,8 @@ static struct alsa_object *alsa_create_object(struct monitor *monitor, uint32_t obj->handle = handle; obj->device = iface; obj->props = pw_properties_new_dict(info->props); + update_device_props(obj); + obj->proxy = pw_remote_export(impl->remote, info->type, obj->props, obj->device, 0); if (obj->proxy == NULL) { diff --git a/src/examples/bluez-monitor.c b/src/examples/bluez-monitor.c index 75a35ea4a..1ae5ffe0f 100644 --- a/src/examples/bluez-monitor.c +++ b/src/examples/bluez-monitor.c @@ -109,17 +109,20 @@ static struct bluez5_node *bluez5_create_node(struct bluez5_object *obj, uint32_ goto exit; } - node->props = pw_properties_copy(obj->props); - pw_properties_update(node->props, info->props); + node->props = pw_properties_new_dict(info->props); - str = pw_properties_get(obj->props, PW_KEY_DEVICE_NICK); + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_DESCRIPTION); if (str == NULL) str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NAME); + if (str == NULL) + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NICK); if (str == NULL) str = pw_properties_get(obj->props, SPA_KEY_DEVICE_ALIAS); if (str == NULL) str = "bluetooth-device"; - pw_properties_set(node->props, PW_KEY_NODE_NAME, str); + + pw_properties_setf(node->props, PW_KEY_NODE_NAME, "%s.%s", info->factory_name, str); + pw_properties_set(node->props, PW_KEY_NODE_DESCRIPTION, str); pw_properties_setf(node->props, "factory.name", info->factory_name); node->monitor = monitor; diff --git a/src/examples/local-v4l2.c b/src/examples/local-v4l2.c index e020c8725..a4ae9b46b 100644 --- a/src/examples/local-v4l2.c +++ b/src/examples/local-v4l2.c @@ -339,7 +339,7 @@ static int make_nodes(struct data *data) struct pw_factory *factory; struct pw_properties *props; - data->node = pw_node_new(data->core, "SDL-sink", NULL, 0); + data->node = pw_node_new(data->core, NULL, 0); data->impl_node.iface = SPA_INTERFACE_INIT( SPA_TYPE_INTERFACE_Node, SPA_VERSION_NODE, diff --git a/src/examples/v4l2-monitor.c b/src/examples/v4l2-monitor.c index 55339e5ab..08f6e5888 100644 --- a/src/examples/v4l2-monitor.c +++ b/src/examples/v4l2-monitor.c @@ -108,17 +108,22 @@ static struct v4l2_node *v4l2_create_node(struct v4l2_object *obj, uint32_t id, goto exit; } - node->props = pw_properties_copy(obj->props); - pw_properties_update(node->props, info->props); + node->props = pw_properties_new_dict(info->props); - str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NICK); + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NAME); if (str == NULL) - str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NAME); + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_NICK); if (str == NULL) str = pw_properties_get(obj->props, SPA_KEY_DEVICE_ALIAS); if (str == NULL) str = "v4l2-device"; - pw_properties_set(node->props, PW_KEY_NODE_NAME, str); + pw_properties_setf(node->props, PW_KEY_NODE_NAME, "%s.%s", info->factory_name, str); + + str = pw_properties_get(obj->props, SPA_KEY_DEVICE_DESCRIPTION); + if (str == NULL) + str = "v4l2-device"; + pw_properties_set(node->props, PW_KEY_NODE_DESCRIPTION, str); + pw_properties_set(node->props, "factory.name", info->factory_name); node->monitor = monitor; @@ -208,6 +213,32 @@ static void v4l2_update_object(struct monitor *monitor, struct v4l2_object *obj, pw_properties_update(obj->props, info->props); } +static int v4l2_update_device_props(struct v4l2_object *obj) +{ + struct pw_properties *p = obj->props; + const char *s, *d; + char temp[32]; + + if ((s = pw_properties_get(p, SPA_KEY_DEVICE_NAME)) == NULL) { + if ((s = pw_properties_get(p, SPA_KEY_DEVICE_ID)) == NULL) { + if ((s = pw_properties_get(p, SPA_KEY_DEVICE_BUS_PATH)) == NULL) { + snprintf(temp, sizeof(temp), "%d", obj->id); + s = temp; + } + } + } + pw_properties_setf(p, PW_KEY_DEVICE_NAME, "v4l2_device.%s", s); + + if (pw_properties_get(p, PW_KEY_DEVICE_DESCRIPTION) == NULL) { + d = pw_properties_get(p, PW_KEY_DEVICE_PRODUCT_NAME); + if (!d) + d = "Unknown device"; + + pw_properties_set(p, PW_KEY_DEVICE_DESCRIPTION, d); + } + return 0; +} + static struct v4l2_object *v4l2_create_object(struct monitor *monitor, uint32_t id, const struct spa_monitor_object_info *info) { @@ -250,6 +281,8 @@ static struct v4l2_object *v4l2_create_object(struct monitor *monitor, uint32_t obj->handle = handle; obj->device = iface; obj->props = pw_properties_new_dict(info->props); + v4l2_update_device_props(obj); + obj->proxy = pw_remote_export(impl->remote, info->type, obj->props, obj->device, 0); if (obj->proxy == NULL) { diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index 899479cd3..70446854b 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -215,7 +215,7 @@ static GstDevice * new_node (GstPipeWireDeviceProvider *self, struct node_data *data) { GstStructure *props; - const gchar *klass = NULL; + const gchar *klass = NULL, *name = NULL; GstPipeWireDeviceType type; const struct pw_node_info *info = data->info; const gchar *element = NULL; @@ -242,8 +242,12 @@ new_node (GstPipeWireDeviceProvider *self, struct node_data *data) if (klass == NULL) klass = "unknown/unknown"; + name = spa_dict_lookup (info->props, PW_KEY_NODE_DESCRIPTION); + if (name == NULL) + name = "unknown"; + gstdev = g_object_new (GST_TYPE_PIPEWIRE_DEVICE, - "display-name", info->name, "caps", data->caps, "device-class", klass, + "display-name", name, "caps", data->caps, "device-class", klass, "id", data->id, "properties", props, NULL); gstdev->id = data->id; diff --git a/src/modules/module-adapter.c b/src/modules/module-adapter.c index ce68aef71..d46cd9b19 100644 --- a/src/modules/module-adapter.c +++ b/src/modules/module-adapter.c @@ -134,7 +134,6 @@ static void *create_object(void *_data, NULL, pw_factory_get_global(d->this), factory_name, - "slave-node", PW_SPA_NODE_FLAG_ACTIVATE | PW_SPA_NODE_FLAG_NO_REGISTER, pw_properties_copy(properties), 0); diff --git a/src/modules/module-adapter/adapter.c b/src/modules/module-adapter/adapter.c index fc1fd9e25..eab1ecf32 100644 --- a/src/modules/module-adapter/adapter.c +++ b/src/modules/module-adapter/adapter.c @@ -322,7 +322,7 @@ struct pw_node *pw_adapter_new(struct pw_core *core, { struct pw_node *node; struct node *n; - const char *name, *str, *factory_name; + const char *str, *factory_name; const struct pw_node_info *info; enum pw_direction direction; int res; @@ -349,9 +349,6 @@ struct pw_node *pw_adapter_new(struct pw_core *core, goto error; } - if ((name = pw_properties_get(props, PW_KEY_NODE_NAME)) == NULL) - name = NAME; - if ((str = pw_properties_get(props, PW_KEY_NODE_ID)) != NULL) pw_properties_set(props, PW_KEY_NODE_SESSION, str); @@ -389,7 +386,6 @@ struct pw_node *pw_adapter_new(struct pw_core *core, node = pw_spa_node_load(core, NULL, NULL, factory_name, - name, PW_SPA_NODE_FLAG_ACTIVATE | PW_SPA_NODE_FLAG_NO_REGISTER, pw_properties_copy(props), sizeof(struct node) + user_data_size); diff --git a/src/modules/module-client-device/resource-device.c b/src/modules/module-client-device/resource-device.c index 907dba84b..0c482ba65 100644 --- a/src/modules/module-client-device/resource-device.c +++ b/src/modules/module-client-device/resource-device.c @@ -110,12 +110,8 @@ struct pw_device *pw_client_device_new(struct pw_resource *resource, struct pw_device *device; struct pw_client *client = pw_resource_get_client(resource); struct pw_core *core = pw_client_get_core(client); - const char *name; - if ((name = pw_properties_get(properties, PW_KEY_DEVICE_NAME)) == NULL) - name = "client-device"; - - device = pw_device_new(core, name, properties, sizeof(struct impl)); + device = pw_device_new(core, properties, sizeof(struct impl)); if (device == NULL) return NULL; diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 417a290b0..7a25e00d5 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -1607,7 +1607,6 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, struct pw_core *core = pw_client_get_core(client); const struct spa_support *support; uint32_t n_support; - const char *name; int res; impl = calloc(1, sizeof(struct impl)); @@ -1631,15 +1630,11 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, pw_map_init(&impl->io_map, 64, 64); - if ((name = pw_properties_get(properties, PW_KEY_NODE_NAME)) == NULL) - name = NAME; - this->resource = resource; this->parent = parent; this->node = pw_spa_node_new(core, client, parent, - name, PW_SPA_NODE_FLAG_ASYNC | (do_register ? 0 : PW_SPA_NODE_FLAG_NO_REGISTER), (struct spa_node *)&impl->node.node, diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index 75210d906..ec522b0a0 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -939,10 +939,11 @@ static void node_free(void *data) static void node_info_changed(void *data, const struct pw_node_info *info) { struct node_data *d = data; - uint32_t change_mask = 0; + uint32_t change_mask; pw_log_debug("info changed %p", d); + change_mask = 0; if (info->change_mask & PW_NODE_CHANGE_MASK_PROPS) change_mask |= PW_CLIENT_NODE_UPDATE_INFO; if (info->change_mask & PW_NODE_CHANGE_MASK_PARAMS) { @@ -1134,7 +1135,7 @@ struct pw_proxy *pw_remote_spa_node_export(struct pw_remote *remote, { struct pw_node *node; - node = pw_node_new(pw_remote_get_core(remote), NULL, props, 0); + node = pw_node_new(pw_remote_get_core(remote), props, 0); if (node == NULL) return NULL; diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 818e32703..4f874da06 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -251,12 +251,12 @@ static int core_event_demarshal_info(void *object, const struct pw_protocol_nati return -EINVAL; if (spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), - SPA_POD_Long(&info.change_mask), + SPA_POD_Int(&info.cookie), SPA_POD_String(&info.user_name), SPA_POD_String(&info.host_name), SPA_POD_String(&info.version), SPA_POD_String(&info.name), - SPA_POD_Int(&info.cookie), NULL) < 0) + SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; if (spa_pod_parser_push_struct(&prs, &f[1]) < 0) @@ -380,12 +380,12 @@ static void core_event_marshal_info(void *object, const struct pw_core_info *inf spa_pod_builder_push_struct(b, &f); spa_pod_builder_add(b, SPA_POD_Int(info->id), - SPA_POD_Long(info->change_mask), + SPA_POD_Int(info->cookie), SPA_POD_String(info->user_name), SPA_POD_String(info->host_name), SPA_POD_String(info->version), SPA_POD_String(info->name), - SPA_POD_Int(info->cookie), + SPA_POD_Long(info->change_mask), NULL); push_dict(b, info->props); spa_pod_builder_pop(b, &f); @@ -719,10 +719,10 @@ static void module_marshal_info(void *object, const struct pw_module_info *info) spa_pod_builder_push_struct(b, &f); spa_pod_builder_add(b, SPA_POD_Int(info->id), - SPA_POD_Long(info->change_mask), SPA_POD_String(info->name), SPA_POD_String(info->filename), SPA_POD_String(info->args), + SPA_POD_Long(info->change_mask), NULL); push_dict(b, info->props); spa_pod_builder_pop(b, &f); @@ -742,10 +742,10 @@ static int module_demarshal_info(void *object, const struct pw_protocol_native_m if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), - SPA_POD_Long(&info.change_mask), SPA_POD_String(&info.name), SPA_POD_String(&info.filename), - SPA_POD_String(&info.args), NULL) < 0) + SPA_POD_String(&info.args), + SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || @@ -782,7 +782,6 @@ static void device_marshal_info(void *object, const struct pw_device_info *info) spa_pod_builder_push_struct(b, &f); spa_pod_builder_add(b, SPA_POD_Int(info->id), - SPA_POD_String(info->name), SPA_POD_Long(info->change_mask), NULL); push_dict(b, info->props); @@ -805,7 +804,6 @@ static int device_demarshal_info(void *object, const struct pw_protocol_native_m if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), - SPA_POD_String(&info.name), SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; @@ -969,10 +967,10 @@ static void factory_marshal_info(void *object, const struct pw_factory_info *inf spa_pod_builder_push_struct(b, &f); spa_pod_builder_add(b, SPA_POD_Int(info->id), - SPA_POD_Long(info->change_mask), SPA_POD_String(info->name), SPA_POD_Id(info->type), SPA_POD_Int(info->version), + SPA_POD_Long(info->change_mask), NULL); push_dict(b, info->props); spa_pod_builder_pop(b, &f); @@ -992,10 +990,10 @@ static int factory_demarshal_info(void *object, const struct pw_protocol_native_ if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), - SPA_POD_Long(&info.change_mask), SPA_POD_String(&info.name), SPA_POD_Id(&info.type), - SPA_POD_Int(&info.version), NULL) < 0) + SPA_POD_Int(&info.version), + SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || @@ -1032,11 +1030,10 @@ static void node_marshal_info(void *object, const struct pw_node_info *info) spa_pod_builder_push_struct(b, &f); spa_pod_builder_add(b, SPA_POD_Int(info->id), - SPA_POD_Long(info->change_mask), - SPA_POD_String(info->name), SPA_POD_Int(info->max_input_ports), - SPA_POD_Int(info->n_input_ports), SPA_POD_Int(info->max_output_ports), + SPA_POD_Long(info->change_mask), + SPA_POD_Int(info->n_input_ports), SPA_POD_Int(info->n_output_ports), SPA_POD_Id(info->state), SPA_POD_String(info->error), @@ -1061,11 +1058,10 @@ static int node_demarshal_info(void *object, const struct pw_protocol_native_mes if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), - SPA_POD_Long(&info.change_mask), - SPA_POD_String(&info.name), SPA_POD_Int(&info.max_input_ports), - SPA_POD_Int(&info.n_input_ports), SPA_POD_Int(&info.max_output_ports), + SPA_POD_Long(&info.change_mask), + SPA_POD_Int(&info.n_input_ports), SPA_POD_Int(&info.n_output_ports), SPA_POD_Id(&info.state), SPA_POD_String(&info.error), NULL) < 0) @@ -1734,11 +1730,11 @@ static void link_marshal_info(void *object, const struct pw_link_info *info) spa_pod_builder_push_struct(b, &f); spa_pod_builder_add(b, SPA_POD_Int(info->id), - SPA_POD_Long(info->change_mask), SPA_POD_Int(info->output_node_id), SPA_POD_Int(info->output_port_id), SPA_POD_Int(info->input_node_id), SPA_POD_Int(info->input_port_id), + SPA_POD_Long(info->change_mask), SPA_POD_Int(info->state), SPA_POD_String(info->error), SPA_POD_Pod(info->format), @@ -1761,11 +1757,11 @@ static int link_demarshal_info(void *object, const struct pw_protocol_native_mes if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&info.id), - SPA_POD_Long(&info.change_mask), SPA_POD_Int(&info.output_node_id), SPA_POD_Int(&info.output_port_id), SPA_POD_Int(&info.input_node_id), SPA_POD_Int(&info.input_port_id), + SPA_POD_Long(&info.change_mask), SPA_POD_Int(&info.state), SPA_POD_String(&info.error), SPA_POD_Pod(&info.format), NULL) < 0) diff --git a/src/modules/spa/module-device-factory.c b/src/modules/spa/module-device-factory.c index 257009636..148b41f12 100644 --- a/src/modules/spa/module-device-factory.c +++ b/src/modules/spa/module-device-factory.c @@ -81,7 +81,7 @@ static void *create_object(void *_data, struct factory_data *data = _data; struct pw_core *core = data->core; struct pw_device *device; - const char *factory_name, *name; + const char *factory_name; struct device_data *nd; int res; @@ -92,15 +92,10 @@ static void *create_object(void *_data, if (factory_name == NULL) goto error_properties; - name = pw_properties_get(properties, PW_KEY_DEVICE_NAME); - if (name == NULL) - name = "spa-device"; - device = pw_spa_device_load(core, NULL, pw_factory_get_global(data->this), factory_name, - name, 0, properties, sizeof(struct device_data)); diff --git a/src/modules/spa/module-device.c b/src/modules/spa/module-device.c index 47baf02f2..e7f04c9b6 100644 --- a/src/modules/spa/module-device.c +++ b/src/modules/spa/module-device.c @@ -38,7 +38,7 @@ #include "spa-monitor.h" #include "spa-device.h" -#define MODULE_USAGE " [key=value ...]" +#define MODULE_USAGE " [key=value ...]" static const struct spa_dict_item module_props[] = { { PW_KEY_MODULE_AUTHOR, "Wim Taymans " }, @@ -82,12 +82,12 @@ int pipewire__module_init(struct pw_module *module, const char *args) if (args == NULL) goto error_arguments; - argv = pw_split_strv(args, " \t", 3, &n_tokens); - if (n_tokens < 2) + argv = pw_split_strv(args, " \t", 2, &n_tokens); + if (n_tokens < 1) goto error_arguments; - if (n_tokens == 3) { - props = pw_properties_new_string(argv[2]); + if (n_tokens == 2) { + props = pw_properties_new_string(argv[1]); if (props == NULL) { res = -errno; goto error_exit_cleanup; @@ -97,7 +97,7 @@ int pipewire__module_init(struct pw_module *module, const char *args) device = pw_spa_device_load(core, NULL, pw_module_get_global(module), - argv[0], argv[1], + argv[0], 0, props, sizeof(struct device_data)); diff --git a/src/modules/spa/module-node-factory.c b/src/modules/spa/module-node-factory.c index 574edb225..c6d8b8bbc 100644 --- a/src/modules/spa/module-node-factory.c +++ b/src/modules/spa/module-node-factory.c @@ -99,7 +99,7 @@ static void *create_object(void *_data, struct factory_data *data = _data; struct pw_core *core = data->core; struct pw_node *node; - const char *factory_name, *name; + const char *factory_name; struct node_data *nd; int res; @@ -110,15 +110,10 @@ static void *create_object(void *_data, if (factory_name == NULL) goto error_properties; - name = pw_properties_get(properties, PW_KEY_NODE_NAME); - if (name == NULL) - name = "spa-node"; - node = pw_spa_node_load(core, NULL, pw_factory_get_global(data->this), factory_name, - name, PW_SPA_NODE_FLAG_ACTIVATE, properties, sizeof(struct node_data)); diff --git a/src/modules/spa/module-node.c b/src/modules/spa/module-node.c index 707d3cd77..ff102650c 100644 --- a/src/modules/spa/module-node.c +++ b/src/modules/spa/module-node.c @@ -40,7 +40,7 @@ #include "spa-monitor.h" #include "spa-node.h" -#define MODULE_USAGE " [key=value ...]" +#define MODULE_USAGE " [key=value ...]" static const struct spa_dict_item module_props[] = { { PW_KEY_MODULE_AUTHOR, "Wim Taymans " }, @@ -82,12 +82,12 @@ int pipewire__module_init(struct pw_module *module, const char *args) if (args == NULL) goto error_arguments; - argv = pw_split_strv(args, " \t", 3, &n_tokens); - if (n_tokens < 2) + argv = pw_split_strv(args, " \t", 2, &n_tokens); + if (n_tokens < 1) goto error_arguments; - if (n_tokens == 3) { - props = pw_properties_new_string(argv[2]); + if (n_tokens == 2) { + props = pw_properties_new_string(argv[1]); if (props == NULL) { res = -errno; goto error_exit_cleanup; @@ -97,7 +97,7 @@ int pipewire__module_init(struct pw_module *module, const char *args) node = pw_spa_node_load(core, NULL, pw_module_get_global(module), - argv[0], argv[1], + argv[0], PW_SPA_NODE_FLAG_ACTIVATE, props, sizeof(struct node_data)); diff --git a/src/modules/spa/spa-device.c b/src/modules/spa/spa-device.c index ac6d033b2..d4e004882 100644 --- a/src/modules/spa/spa-device.c +++ b/src/modules/spa/spa-device.c @@ -79,7 +79,6 @@ struct pw_device * pw_spa_device_new(struct pw_core *core, struct pw_client *owner, struct pw_global *parent, - const char *name, enum pw_spa_device_flags flags, struct spa_device *device, struct spa_handle *handle, @@ -90,7 +89,7 @@ pw_spa_device_new(struct pw_core *core, struct impl *impl; int res; - this = pw_device_new(core, name, properties, sizeof(struct impl) + user_data_size); + this = pw_device_new(core, properties, sizeof(struct impl) + user_data_size); if (this == NULL) return NULL; @@ -130,7 +129,6 @@ struct pw_device *pw_spa_device_load(struct pw_core *core, struct pw_client *owner, struct pw_global *parent, const char *factory_name, - const char *name, enum pw_spa_device_flags flags, struct pw_properties *properties, size_t user_data_size) @@ -148,7 +146,7 @@ struct pw_device *pw_spa_device_load(struct pw_core *core, if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Device, &iface)) < 0) goto error_interface; - this = pw_spa_device_new(core, owner, parent, name, flags, + this = pw_spa_device_new(core, owner, parent, flags, iface, handle, properties, user_data_size); if (this == NULL) goto error_device; diff --git a/src/modules/spa/spa-device.h b/src/modules/spa/spa-device.h index 90508f258..4a34c0f7a 100644 --- a/src/modules/spa/spa-device.h +++ b/src/modules/spa/spa-device.h @@ -43,7 +43,6 @@ struct pw_device * pw_spa_device_new(struct pw_core *core, struct pw_client *owner, /**< optional owner */ struct pw_global *parent, /**< optional parent */ - const char *name, enum pw_spa_device_flags flags, struct spa_device *device, struct spa_handle *handle, @@ -55,7 +54,6 @@ pw_spa_device_load(struct pw_core *core, struct pw_client *owner, /**< optional owner */ struct pw_global *parent, /**< optional parent */ const char *factory_name, - const char *name, enum pw_spa_device_flags flags, struct pw_properties *properties, size_t user_data_size); diff --git a/src/modules/spa/spa-monitor.c b/src/modules/spa/spa-monitor.c index 3f1df6078..03880c7b2 100644 --- a/src/modules/spa/spa-monitor.c +++ b/src/modules/spa/spa-monitor.c @@ -139,7 +139,7 @@ static struct monitor_object *add_object(struct pw_spa_monitor *this, uint32_t i case SPA_TYPE_INTERFACE_Device: { struct pw_device *device; - device = pw_spa_device_new(core, NULL, impl->parent, name, + device = pw_spa_device_new(core, NULL, impl->parent, 0, iface, handle, props, 0); pw_device_add_listener(device, &obj->object_listener, &device_events, obj); diff --git a/src/modules/spa/spa-node.c b/src/modules/spa/spa-node.c index 7256abfef..d1babaaaf 100644 --- a/src/modules/spa/spa-node.c +++ b/src/modules/spa/spa-node.c @@ -112,7 +112,6 @@ struct pw_node * pw_spa_node_new(struct pw_core *core, struct pw_client *owner, struct pw_global *parent, - const char *name, enum pw_spa_node_flags flags, struct spa_node *node, struct spa_handle *handle, @@ -123,7 +122,7 @@ pw_spa_node_new(struct pw_core *core, struct impl *impl; int res; - this = pw_node_new(core, name, properties, sizeof(struct impl) + user_data_size); + this = pw_node_new(core, properties, sizeof(struct impl) + user_data_size); if (this == NULL) { res = -errno; goto error_exit; @@ -246,7 +245,6 @@ struct pw_node *pw_spa_node_load(struct pw_core *core, struct pw_client *owner, struct pw_global *parent, const char *factory_name, - const char *name, enum pw_spa_node_flags flags, struct pw_properties *properties, size_t user_data_size) @@ -281,7 +279,7 @@ struct pw_node *pw_spa_node_load(struct pw_core *core, } } - this = pw_spa_node_new(core, owner, parent, name, flags, + this = pw_spa_node_new(core, owner, parent, flags, spa_node, handle, properties, user_data_size); if (this == NULL) { res = -errno; diff --git a/src/modules/spa/spa-node.h b/src/modules/spa/spa-node.h index 70eb85475..ecc290aa0 100644 --- a/src/modules/spa/spa-node.h +++ b/src/modules/spa/spa-node.h @@ -44,7 +44,6 @@ struct pw_node * pw_spa_node_new(struct pw_core *core, struct pw_client *owner, /**< optional owner */ struct pw_global *parent, /**< optional parent */ - const char *name, enum pw_spa_node_flags flags, struct spa_node *node, struct spa_handle *handle, @@ -56,7 +55,6 @@ pw_spa_node_load(struct pw_core *core, struct pw_client *owner, /**< optional owner */ struct pw_global *parent, /**< optional parent */ const char *factory_name, - const char *name, enum pw_spa_node_flags flags, struct pw_properties *properties, size_t user_data_size); diff --git a/src/pipewire/core.c b/src/pipewire/core.c index 7d6d91a0d..8c67c6f27 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -1061,7 +1061,7 @@ static int collect_nodes(struct pw_node *driver) spa_list_init(&t->slave_link); } - pw_log_info("driver %p: '%s'", driver, driver->info.name); + pw_log_info("driver %p: '%s'", driver, driver->name); spa_list_init(&queue); spa_list_append(&queue, &driver->sort_link); @@ -1113,7 +1113,7 @@ int pw_core_recalc_graph(struct pw_core *core) spa_list_for_each(n, &core->node_list, link) { if (!n->visited) { pw_log_info(NAME" %p: unassigned node %p: '%s' %d", core, - n, n->info.name, n->active); + n, n->name, n->active); pw_node_set_driver(n, NULL); } n->visited = false; @@ -1123,10 +1123,10 @@ int pw_core_recalc_graph(struct pw_core *core) if (!n->master) continue; pw_log_info(NAME" %p: master %p quantum:%d '%s'", core, n, - n->rt.position ? n->rt.position->size : 0, n->info.name); + n->rt.position ? n->rt.position->size : 0, n->name); spa_list_for_each(s, &n->slave_list, slave_link) pw_log_info(NAME" %p: slave %p: active:%d '%s'", - core, s, s->active, s->info.name); + core, s, s->active, s->name); } return 0; } diff --git a/src/pipewire/device.c b/src/pipewire/device.c index cf4aa445d..b9c5151a2 100644 --- a/src/pipewire/device.c +++ b/src/pipewire/device.c @@ -73,9 +73,19 @@ struct node_data { struct spa_hook node_listener; }; +static void check_properties(struct pw_device *device) +{ + const char *str; + + if ((str = pw_properties_get(device->properties, PW_KEY_DEVICE_NAME))) { + free(device->name); + device->name = strdup(str); + pw_log_info(NAME" %p: name '%s'", device, device->name); + } +} + SPA_EXPORT struct pw_device *pw_device_new(struct pw_core *core, - const char *name, struct pw_properties *properties, size_t user_data_size) { @@ -90,6 +100,7 @@ struct pw_device *pw_device_new(struct pw_core *core, } this = &impl->this; + pw_log_debug(NAME" %p: new", this); if (properties == NULL) properties = pw_properties_new(NULL, NULL); @@ -101,7 +112,6 @@ struct pw_device *pw_device_new(struct pw_core *core, this->core = core; this->properties = properties; - this->info.name = strdup(name); this->info.props = &properties->dict; this->info.params = this->params; spa_hook_list_init(&this->listener_list); @@ -111,7 +121,7 @@ struct pw_device *pw_device_new(struct pw_core *core, if (user_data_size > 0) this->user_data = SPA_MEMBER(this, sizeof(struct impl), void); - pw_log_debug(NAME" %p: new %s", this, name); + check_properties(this); return this; @@ -145,7 +155,6 @@ void pw_device_destroy(struct pw_device *device) pw_log_debug(NAME" %p: free", device); pw_device_emit_free(device); - free((char *)device->info.name); pw_properties_free(device->properties); free(device); @@ -507,7 +516,6 @@ static void device_add(struct pw_device *device, uint32_t id, pw_properties_update(props, info->props); node = pw_node_new(core, - device->info.name, props, sizeof(struct node_data)); diff --git a/src/pipewire/device.h b/src/pipewire/device.h index fe95a5e37..c7fad1cea 100644 --- a/src/pipewire/device.h +++ b/src/pipewire/device.h @@ -64,7 +64,6 @@ struct pw_device_events { }; struct pw_device *pw_device_new(struct pw_core *core, - const char *name, struct pw_properties *properties, size_t user_data_size); diff --git a/src/pipewire/introspect.c b/src/pipewire/introspect.c index 9e9403704..aa246a2f5 100644 --- a/src/pipewire/introspect.c +++ b/src/pipewire/introspect.c @@ -132,27 +132,16 @@ struct pw_core_info *pw_core_info_update(struct pw_core_info *info, info = calloc(1, sizeof(struct pw_core_info)); if (info == NULL) return NULL; - } - info->id = update->id; - info->cookie = update->cookie; - info->change_mask = update->change_mask; - if (update->change_mask & PW_CORE_CHANGE_MASK_USER_NAME) { - free((void *) info->user_name); + info->id = update->id; + info->cookie = update->cookie; info->user_name = update->user_name ? strdup(update->user_name) : NULL; - } - if (update->change_mask & PW_CORE_CHANGE_MASK_HOST_NAME) { - free((void *) info->host_name); info->host_name = update->host_name ? strdup(update->host_name) : NULL; - } - if (update->change_mask & PW_CORE_CHANGE_MASK_VERSION) { - free((void *) info->version); info->version = update->version ? strdup(update->version) : NULL; - } - if (update->change_mask & PW_CORE_CHANGE_MASK_NAME) { - free((void *) info->name); info->name = update->name ? strdup(update->name) : NULL; } + info->change_mask = update->change_mask; + if (update->change_mask & PW_CORE_CHANGE_MASK_PROPS) { if (info->props) pw_spa_dict_destroy(info->props); @@ -184,20 +173,17 @@ struct pw_node_info *pw_node_info_update(struct pw_node_info *info, info = calloc(1, sizeof(struct pw_node_info)); if (info == NULL) return NULL; + + info->id = update->id; + info->max_input_ports = update->max_input_ports; + info->max_output_ports = update->max_output_ports; } - info->id = update->id; info->change_mask = update->change_mask; - if (update->change_mask & PW_NODE_CHANGE_MASK_NAME) { - free((void *) info->name); - info->name = update->name ? strdup(update->name) : NULL; - } if (update->change_mask & PW_NODE_CHANGE_MASK_INPUT_PORTS) { - info->max_input_ports = update->max_input_ports; info->n_input_ports = update->n_input_ports; } if (update->change_mask & PW_NODE_CHANGE_MASK_OUTPUT_PORTS) { - info->max_output_ports = update->max_output_ports; info->n_output_ports = update->n_output_ports; } @@ -229,7 +215,6 @@ SPA_EXPORT void pw_node_info_free(struct pw_node_info *info) { - free((void *) info->name); free((void *) info->error); if (info->props) pw_spa_dict_destroy(info->props); @@ -249,9 +234,10 @@ struct pw_port_info *pw_port_info_update(struct pw_port_info *info, info = calloc(1, sizeof(struct pw_port_info)); if (info == NULL) return NULL; + + info->id = update->id; + info->direction = update->direction; } - info->id = update->id; - info->direction = update->direction; info->change_mask = update->change_mask; if (update->change_mask & PW_PORT_CHANGE_MASK_PROPS) { @@ -294,12 +280,12 @@ struct pw_factory_info *pw_factory_info_update(struct pw_factory_info *info, info = calloc(1, sizeof(struct pw_factory_info)); if (info == NULL) return NULL; + + info->id = update->id; + info->name = update->name ? strdup(update->name) : NULL; + info->type = update->type; + info->version = update->version; } - info->id = update->id; - free((void *) info->name); - info->name = update->name ? strdup(update->name) : NULL; - info->type = update->type; - info->version = update->version; info->change_mask = update->change_mask; if (update->change_mask & PW_FACTORY_CHANGE_MASK_PROPS) { @@ -330,22 +316,14 @@ struct pw_module_info *pw_module_info_update(struct pw_module_info *info, info = calloc(1, sizeof(struct pw_module_info)); if (info == NULL) return NULL; - } - info->id = update->id; - info->change_mask = update->change_mask; - if (update->change_mask & PW_MODULE_CHANGE_MASK_NAME) { - free((void *) info->name); + info->id = update->id; info->name = update->name ? strdup(update->name) : NULL; - } - if (update->change_mask & PW_MODULE_CHANGE_MASK_FILENAME) { - free((void *) info->filename); info->filename = update->filename ? strdup(update->filename) : NULL; - } - if (update->change_mask & PW_MODULE_CHANGE_MASK_ARGS) { - free((void *) info->args); info->args = update->args ? strdup(update->args) : NULL; } + info->change_mask = update->change_mask; + if (update->change_mask & PW_MODULE_CHANGE_MASK_PROPS) { if (info->props) pw_spa_dict_destroy(info->props); @@ -365,7 +343,6 @@ void pw_module_info_free(struct pw_module_info *info) free(info); } - SPA_EXPORT struct pw_device_info *pw_device_info_update(struct pw_device_info *info, const struct pw_device_info *update) @@ -377,10 +354,9 @@ struct pw_device_info *pw_device_info_update(struct pw_device_info *info, info = calloc(1, sizeof(struct pw_device_info)); if (info == NULL) return NULL; + + info->id = update->id; } - info->id = update->id; - free((void *) info->name); - info->name = update->name ? strdup(update->name) : NULL; info->change_mask = update->change_mask; if (update->change_mask & PW_DEVICE_CHANGE_MASK_PROPS) { @@ -405,7 +381,6 @@ struct pw_device_info *pw_device_info_update(struct pw_device_info *info, SPA_EXPORT void pw_device_info_free(struct pw_device_info *info) { - free((void *) info->name); if (info->props) pw_spa_dict_destroy(info->props); free((void *) info->params); @@ -423,8 +398,9 @@ struct pw_client_info *pw_client_info_update(struct pw_client_info *info, info = calloc(1, sizeof(struct pw_client_info)); if (info == NULL) return NULL; + + info->id = update->id; } - info->id = update->id; info->change_mask = update->change_mask; if (update->change_mask & PW_CLIENT_CHANGE_MASK_PROPS) { @@ -454,18 +430,16 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info, info = calloc(1, sizeof(struct pw_link_info)); if (info == NULL) return NULL; - } - info->id = update->id; - info->change_mask = update->change_mask; - if (update->change_mask & PW_LINK_CHANGE_MASK_OUTPUT) { + info->id = update->id; info->output_node_id = update->output_node_id; info->output_port_id = update->output_port_id; - } - if (update->change_mask & PW_LINK_CHANGE_MASK_INPUT) { info->input_node_id = update->input_node_id; info->input_port_id = update->input_port_id; } + + info->change_mask = update->change_mask; + if (update->change_mask & PW_LINK_CHANGE_MASK_STATE) { info->state = update->state; free((void *) info->error); diff --git a/src/pipewire/introspect.h b/src/pipewire/introspect.h index 1f582f252..6f3554076 100644 --- a/src/pipewire/introspect.h +++ b/src/pipewire/introspect.h @@ -80,17 +80,13 @@ const char * pw_link_state_as_string(enum pw_link_state state); struct pw_core_info { uint32_t id; /**< id of the global */ uint32_t cookie; /**< a random cookie for identifying this instance of PipeWire */ -#define PW_CORE_CHANGE_MASK_USER_NAME (1 << 0) -#define PW_CORE_CHANGE_MASK_HOST_NAME (1 << 1) -#define PW_CORE_CHANGE_MASK_VERSION (1 << 2) -#define PW_CORE_CHANGE_MASK_NAME (1 << 3) -#define PW_CORE_CHANGE_MASK_PROPS (1 << 4) -#define PW_CORE_CHANGE_MASK_ALL (~0) - uint64_t change_mask; /**< bitfield of changed fields since last call */ const char *user_name; /**< name of the user that started the core */ const char *host_name; /**< name of the machine the core is running on */ const char *version; /**< version of the core */ const char *name; /**< name of the core */ +#define PW_CORE_CHANGE_MASK_PROPS (1 << 0) +#define PW_CORE_CHANGE_MASK_ALL ((1 << 1)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ struct spa_dict *props; /**< extra properties */ }; @@ -105,14 +101,12 @@ void pw_core_info_free(struct pw_core_info *info); /** The module information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_module_info { uint32_t id; /**< id of the global */ -#define PW_MODULE_CHANGE_MASK_NAME (1 << 0) -#define PW_MODULE_CHANGE_MASK_FILENAME (1 << 1) -#define PW_MODULE_CHANGE_MASK_ARGS (1 << 2) -#define PW_MODULE_CHANGE_MASK_PROPS (1 << 3) - uint64_t change_mask; /**< bitfield of changed fields since last call */ const char *name; /**< name of the module */ const char *filename; /**< filename of the module */ const char *args; /**< arguments passed to the module */ +#define PW_MODULE_CHANGE_MASK_PROPS (1 << 0) +#define PW_MODULE_CHANGE_MASK_ALL ((1 << 1)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ struct spa_dict *props; /**< extra properties */ }; @@ -128,10 +122,9 @@ void pw_module_info_free(struct pw_module_info *info); /** The device information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_device_info { uint32_t id; /**< id of the global */ - const char *name; /**< name the device */ -#define PW_DEVICE_CHANGE_MASK_PROPS (1 << 0) -#define PW_DEVICE_CHANGE_MASK_PARAMS (1 << 1) -#define PW_DEVICE_CHANGE_MASK_ALL ((1 << 2)-1) +#define PW_DEVICE_CHANGE_MASK_PROPS (1 << 0) +#define PW_DEVICE_CHANGE_MASK_PARAMS (1 << 1) +#define PW_DEVICE_CHANGE_MASK_ALL ((1 << 2)-1) uint64_t change_mask; /**< bitfield of changed fields since last call */ struct spa_dict *props; /**< extra properties */ struct spa_param_info *params; /**< parameters */ @@ -148,10 +141,11 @@ void pw_device_info_free(struct pw_device_info *info); /** The client information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_client_info { - uint32_t id; /**< id of the global */ -#define PW_CLIENT_CHANGE_MASK_PROPS (1 << 0) - uint64_t change_mask; /**< bitfield of changed fields since last call */ - struct spa_dict *props; /**< extra properties */ + uint32_t id; /**< id of the global */ +#define PW_CLIENT_CHANGE_MASK_PROPS (1 << 0) +#define PW_CLIENT_CHANGE_MASK_ALL ((1 << 1)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + struct spa_dict *props; /**< extra properties */ }; /** Update and existing \ref pw_client_info with \a update \memberof pw_introspect */ @@ -166,18 +160,16 @@ void pw_client_info_free(struct pw_client_info *info); /** The node information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_node_info { uint32_t id; /**< id of the global */ -#define PW_NODE_CHANGE_MASK_NAME (1 << 0) -#define PW_NODE_CHANGE_MASK_INPUT_PORTS (1 << 1) -#define PW_NODE_CHANGE_MASK_OUTPUT_PORTS (1 << 2) -#define PW_NODE_CHANGE_MASK_STATE (1 << 3) -#define PW_NODE_CHANGE_MASK_PROPS (1 << 4) -#define PW_NODE_CHANGE_MASK_PARAMS (1 << 5) -#define PW_NODE_CHANGE_MASK_ALL ((1 << 6)-1) - uint64_t change_mask; /**< bitfield of changed fields since last call */ - const char *name; /**< name the node, suitable for display */ uint32_t max_input_ports; /**< maximum number of inputs */ - uint32_t n_input_ports; /**< number of inputs */ uint32_t max_output_ports; /**< maximum number of outputs */ +#define PW_NODE_CHANGE_MASK_INPUT_PORTS (1 << 0) +#define PW_NODE_CHANGE_MASK_OUTPUT_PORTS (1 << 1) +#define PW_NODE_CHANGE_MASK_STATE (1 << 2) +#define PW_NODE_CHANGE_MASK_PROPS (1 << 3) +#define PW_NODE_CHANGE_MASK_PARAMS (1 << 4) +#define PW_NODE_CHANGE_MASK_ALL ((1 << 5)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ + uint32_t n_input_ports; /**< number of inputs */ uint32_t n_output_ports; /**< number of outputs */ enum pw_node_state state; /**< the current state of the node */ const char *error; /**< an error reason if \a state is error */ @@ -219,6 +211,7 @@ struct pw_factory_info { uint32_t type; /**< type of the objects created by this factory */ uint32_t version; /**< version of the objects */ #define PW_FACTORY_CHANGE_MASK_PROPS (1 << 0) +#define PW_FACTORY_CHANGE_MASK_ALL ((1 << 1)-1) uint64_t change_mask; /**< bitfield of changed fields since last call */ struct spa_dict *props; /**< the properties of the factory */ }; @@ -233,16 +226,15 @@ pw_factory_info_free(struct pw_factory_info *info); /** The link information. Extra information can be added in later versions \memberof pw_introspect */ struct pw_link_info { uint32_t id; /**< id of the global */ -#define PW_LINK_CHANGE_MASK_OUTPUT (1 << 0) -#define PW_LINK_CHANGE_MASK_INPUT (1 << 1) -#define PW_LINK_CHANGE_MASK_STATE (1 << 2) -#define PW_LINK_CHANGE_MASK_FORMAT (1 << 3) -#define PW_LINK_CHANGE_MASK_PROPS (1 << 4) - uint64_t change_mask; /**< bitfield of changed fields since last call */ uint32_t output_node_id; /**< server side output node id */ uint32_t output_port_id; /**< output port id */ uint32_t input_node_id; /**< server side input node id */ uint32_t input_port_id; /**< input port id */ +#define PW_LINK_CHANGE_MASK_STATE (1 << 0) +#define PW_LINK_CHANGE_MASK_FORMAT (1 << 1) +#define PW_LINK_CHANGE_MASK_PROPS (1 << 2) +#define PW_LINK_CHANGE_MASK_ALL ((1 << 3)-1) + uint64_t change_mask; /**< bitfield of changed fields since last call */ enum pw_link_state state; /**< the current state of the link */ const char *error; /**< an error reason if \a state is error */ struct spa_pod *format; /**< format over link */ diff --git a/src/pipewire/node.c b/src/pipewire/node.c index 6b12abb51..523fd144e 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -357,7 +357,7 @@ static void node_unbind_func(void *data) static void clear_info(struct pw_node *this) { - free((char*)this->info.name); + free(this->name); free((char*)this->info.error); } @@ -562,11 +562,16 @@ int pw_node_register(struct pw_node *this, if (properties == NULL) return -errno; + if ((str = pw_properties_get(this->properties, PW_KEY_NODE_DESCRIPTION)) != NULL) + pw_properties_set(properties, PW_KEY_NODE_DESCRIPTION, str); + if ((str = pw_properties_get(this->properties, PW_KEY_NODE_NAME)) != NULL) + pw_properties_set(properties, PW_KEY_NODE_NAME, str); + if ((str = pw_properties_get(this->properties, PW_KEY_NODE_NICK)) != NULL) + pw_properties_set(properties, PW_KEY_NODE_NICK, str); if ((str = pw_properties_get(this->properties, PW_KEY_MEDIA_CLASS)) != NULL) pw_properties_set(properties, PW_KEY_MEDIA_CLASS, str); if ((str = pw_properties_get(this->properties, PW_KEY_MEDIA_ROLE)) != NULL) pw_properties_set(properties, PW_KEY_MEDIA_ROLE, str); - pw_properties_set(properties, PW_KEY_NODE_NAME, this->info.name); if ((str = pw_properties_get(this->properties, PW_KEY_NODE_SESSION)) != NULL) pw_properties_set(properties, PW_KEY_NODE_SESSION, str); @@ -689,6 +694,12 @@ static void check_properties(struct pw_node *node) const char *str; bool driver; + if ((str = pw_properties_get(node->properties, PW_KEY_NODE_NAME))) { + free(node->name); + node->name = strdup(str); + pw_log_info(NAME" %p: name '%s'", node, node->name); + } + if ((str = pw_properties_get(node->properties, PW_KEY_NODE_PAUSE_ON_IDLE))) impl->pause_on_idle = pw_properties_parse_bool(str); else @@ -733,7 +744,7 @@ static void dump_states(struct pw_node *driver) continue; pw_log_warn(NAME" %p (%s): pending:%d/%d s:%"PRIu64" a:%"PRIu64" f:%"PRIu64 " waiting:%"PRIu64" process:%"PRIu64" status:%d", - t->node, t->node->info.name, + t->node, t->node->name, a->state[0].pending, a->state[0].required, a->signal_time, a->awake_time, @@ -841,7 +852,6 @@ static void node_on_fd_events(struct spa_source *source) SPA_EXPORT struct pw_node *pw_node_new(struct pw_core *core, - const char *name, struct pw_properties *properties, size_t user_data_size) { @@ -849,7 +859,6 @@ struct pw_node *pw_node_new(struct pw_core *core, struct pw_node *this; size_t size; struct spa_system *data_system = core->data_system; - char *n = NULL; int res; impl = calloc(1, sizeof(struct impl) + user_data_size); @@ -858,14 +867,8 @@ struct pw_node *pw_node_new(struct pw_core *core, goto error_exit; } - if (name == NULL) - asprintf(&n, "node"); - else - n = strdup(name); - this = &impl->this; this->core = core; - pw_log_debug(NAME" %p: new \"%s\"", this, n); if (user_data_size > 0) this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void); @@ -877,6 +880,8 @@ struct pw_node *pw_node_new(struct pw_core *core, goto error_clean; } + pw_log_debug(NAME" %p: new", this); + this->properties = properties; if ((res = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK)) < 0) @@ -907,8 +912,6 @@ struct pw_node *pw_node_new(struct pw_core *core, goto error_clean; } - this->info.name = n; - this->data_loop = core->data_loop; spa_list_init(&this->slave_list); @@ -951,8 +954,6 @@ error_clean: pw_memblock_unref(this->activation); if (this->source.fd != -1) spa_system_close(this->core->data_system, this->source.fd); - if (n) - free(n); free(impl); error_exit: if (properties) @@ -1040,6 +1041,11 @@ static void node_info(void *data, const struct spa_node_info *info) node->info.n_params = SPA_MIN(info->n_params, SPA_N_ELEMENTS(node->params)); for (i = 0; i < node->info.n_params; i++) { + pw_log_debug(NAME" %p: param %d id:%d (%s) %08x:%08x", node, i, + info->params[i].id, + spa_debug_type_find_name(spa_type_param, info->params[i].id), + node->info.params[i].flags, info->params[i].flags); + if (node->info.params[i].flags == info->params[i].flags) continue; diff --git a/src/pipewire/node.h b/src/pipewire/node.h index 0f1a4c0b6..e3005329d 100644 --- a/src/pipewire/node.h +++ b/src/pipewire/node.h @@ -102,7 +102,6 @@ struct pw_node_events { /** Create a new node \memberof pw_node */ struct pw_node * pw_node_new(struct pw_core *core, /**< the core */ - const char *name, /**< node name */ struct pw_properties *properties, /**< extra properties */ size_t user_data_size /**< user data size */); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 1c1dcb6fe..73cb809c8 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -301,6 +301,8 @@ struct pw_device { struct pw_device_info info; /**< introspectable device info */ struct spa_param_info params[MAX_PARAMS]; + char *name; /**< device name for debug */ + struct spa_device *device; /**< device implementation */ struct spa_hook listener; struct spa_hook_list listener_list; @@ -395,6 +397,8 @@ struct pw_node { struct pw_node_info info; /**< introspectable node info */ struct spa_param_info params[MAX_PARAMS]; + char *name; /** for debug */ + uint32_t spa_flags; unsigned int registered:1; @@ -701,7 +705,7 @@ struct pw_remote { #define pw_stream_emit_remove_buffer(s,b) pw_stream_emit(s, remove_buffer, 0, b) #define pw_stream_emit_process(s) pw_stream_emit(s, process, 0) #define pw_stream_emit_drained(s) pw_stream_emit(s, drained,0) -#define pw_stream_emit_control_changed(s,i,v) pw_stream_emit(s, control_changed, 0, i, v) +#define pw_stream_emit_control_info(s,i,c) pw_stream_emit(s, control_info, 0, i, c) struct pw_stream { diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index e96925c76..98afe93f7 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -88,6 +88,7 @@ struct control { struct pw_stream_control control; struct spa_pod *info; unsigned int emitted:1; + float values[64]; }; #define DEFAULT_VOLUME 1.0 @@ -461,6 +462,10 @@ static int impl_port_enum_params(void *object, int seq, result.id = id; result.next = start; + pw_log_debug(NAME" %p: param id %d (%s) start:%d num:%d", d, id, + spa_debug_type_find_name(spa_type_param, id), + start, num); + spa_list_for_each(p, &d->param_list, link) { struct spa_pod *param; @@ -519,6 +524,8 @@ static int port_set_format(void *object, if (stream->state == PW_STREAM_STATE_ERROR) return -EIO; + impl->params[3].flags |= SPA_PARAM_INFO_READ; + impl->params[3].flags ^= SPA_PARAM_INFO_SERIAL; emit_port_info(impl); stream_set_state(stream, @@ -864,6 +871,8 @@ static void node_event_param(void *object, int seq, { struct pw_stream *stream = object; + pw_log_debug(NAME" %p: param %d", stream, id); + switch (id) { case SPA_PARAM_PropInfo: { @@ -875,6 +884,9 @@ static void node_event_param(void *object, int seq, c = calloc(1, sizeof(*c) + SPA_POD_SIZE(param)); c->info = SPA_MEMBER(c, sizeof(*c), struct spa_pod); memcpy(c->info, param, SPA_POD_SIZE(param)); + c->control.n_values = 0; + c->control.max_values = 0; + c->control.values = c->values; spa_list_append(&stream->controls, &c->link); if (spa_pod_parse_object(c->info, @@ -902,12 +914,16 @@ static void node_event_param(void *object, int seq, case SPA_CHOICE_None: if (n_vals < 1) return; - c->control.value = c->control.def = c->control.min = c->control.max = vals[0]; + c->control.n_values = 1; + c->control.max_values = 1; + c->control.values[0] = c->control.def = c->control.min = c->control.max = vals[0]; break; case SPA_CHOICE_Range: if (n_vals < 3) return; - c->control.value = vals[0]; + c->control.n_values = 1; + c->control.max_values = 1; + c->control.values[0] = vals[0]; c->control.def = vals[0]; c->control.min = vals[1]; c->control.max = vals[2]; @@ -930,6 +946,8 @@ static void node_event_param(void *object, int seq, float f; bool b; } value; + float *values; + uint32_t i, n_values; SPA_POD_OBJECT_FOREACH(obj, prop) { struct control *c; @@ -938,21 +956,34 @@ static void node_event_param(void *object, int seq, if (c == NULL) continue; - if (spa_pod_get_float(&prop->value, &value.f) == 0) - ; - else if (spa_pod_get_bool(&prop->value, &value.b) == 0) + if (spa_pod_get_float(&prop->value, &value.f) == 0) { + n_values = 1; + values = &value.f; + } else if (spa_pod_get_bool(&prop->value, &value.b) == 0) { value.f = value.b ? 1.0 : 0.0; - else + n_values = 1; + values = &value.f; + } else if ((values = spa_pod_get_array(&prop->value, &n_values))) { + if (!spa_pod_is_float(SPA_POD_ARRAY_CHILD(&prop->value))) + continue; + } else continue; - if (c->control.value == value.f && c->emitted) + + if (c->emitted && c->control.n_values == n_values && + memcmp(c->control.values, values, sizeof(float) * n_values) == 0) continue; - c->control.value = value.f; + memcpy(c->control.values, values, sizeof(float) * n_values); + c->control.n_values = n_values; c->emitted = true; - pw_log_debug(NAME" %p: control %d (%s) changed %f", stream, - prop->key, c->control.name, value.f); - pw_stream_emit_control_changed(stream, prop->key, value.f); + + pw_log_debug(NAME" %p: control %d (%s) changed %d:", stream, + prop->key, c->control.name, n_values); + for (i = 0; i < n_values; i++) + pw_log_debug(NAME" %p: value %d %f", stream, i, values[i]); + + pw_stream_emit_control_info(stream, prop->key, &c->control); } break; } @@ -984,8 +1015,7 @@ static int handle_connect(struct pw_stream *stream) pw_properties_set(props, "resample.peaks", "1"); } - slave = pw_node_new(impl->core, stream->name, - pw_properties_copy(props), 0); + slave = pw_node_new(impl->core, pw_properties_copy(props), 0); if (slave == NULL) { res = -errno; goto error_node; @@ -1470,7 +1500,7 @@ void pw_stream_finish_format(struct pw_stream *stream, } SPA_EXPORT -int pw_stream_set_control(struct pw_stream *stream, uint32_t id, float value, ...) +int pw_stream_set_control(struct pw_stream *stream, uint32_t id, uint32_t n_values, float *values, ...) { va_list varargs; char buf[1024]; @@ -1479,9 +1509,9 @@ int pw_stream_set_control(struct pw_stream *stream, uint32_t id, float value, .. struct spa_pod *pod; struct control *c; - pw_log_debug(NAME" %p: set control %d %f", stream, id, value); + pw_log_debug(NAME" %p: set control %d %d %f", stream, id, n_values, values[0]); - va_start(varargs, value); + va_start(varargs, values); spa_pod_builder_push_object(&b, &f[0], SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); while (1) { @@ -1489,10 +1519,15 @@ int pw_stream_set_control(struct pw_stream *stream, uint32_t id, float value, .. spa_pod_builder_prop(&b, id, 0); switch (c->type) { case SPA_TYPE_Float: - spa_pod_builder_float(&b, value); + if (n_values == 1) + spa_pod_builder_float(&b, values[0]); + else + spa_pod_builder_array(&b, + sizeof(float), SPA_TYPE_Float, + n_values, values); break; case SPA_TYPE_Bool: - spa_pod_builder_bool(&b, value < 0.5 ? false : true); + spa_pod_builder_bool(&b, values[0] < 0.5 ? false : true); break; default: spa_pod_builder_none(&b); @@ -1501,7 +1536,8 @@ int pw_stream_set_control(struct pw_stream *stream, uint32_t id, float value, .. } if ((id = va_arg(varargs, uint32_t)) == 0) break; - value = va_arg(varargs, double); + n_values = va_arg(varargs, uint32_t); + values = va_arg(varargs, float *); } pod = spa_pod_builder_pop(&b, &f[0]); diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h index 63215be3e..ca52a132b 100644 --- a/src/pipewire/stream.h +++ b/src/pipewire/stream.h @@ -179,12 +179,14 @@ struct pw_buffer { }; struct pw_stream_control { - const char *name; - uint32_t flags; - float value; - float def; - float min; - float max; + const char *name; /**< name of the control */ + uint32_t flags; /**< extra flags (unused) */ + float def; /**< default value */ + float min; /**< min value */ + float max; /**< max value */ + float *values; /**< array of values */ + uint32_t n_values; /**< number of values in array */ + uint32_t max_values; /**< max values that can be set on this control */ }; /** Events for a stream. These events are always called from the mainloop @@ -199,7 +201,7 @@ struct pw_stream_events { enum pw_stream_state state, const char *error); /** Notify information about a control. */ - void (*control_changed) (void *data, uint32_t id, float value); + void (*control_info) (void *data, uint32_t id, struct pw_stream_control *control); /** when the format changed. The listener should call * pw_stream_finish_format() from within this callback or later to complete @@ -251,12 +253,12 @@ enum pw_stream_flags { * \return a newly allocated \ref pw_stream */ struct pw_stream * pw_stream_new(struct pw_remote *remote, /**< a \ref pw_remote */ - const char *name, /**< a stream name */ + const char *name, /**< a stream media name */ struct pw_properties *props /**< stream properties, ownership is taken */); struct pw_stream * pw_stream_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use */ - const char *name, /**< a stream name */ + const char *name, /**< a stream media name */ struct pw_properties *props,/**< stream properties, ownership is taken */ const struct pw_stream_events *events, /**< stream events */ void *data /**< data passed to events */); @@ -320,10 +322,7 @@ pw_stream_finish_format(struct pw_stream *stream, /**< a \ref pw_stream */ /** Set control values */ -int pw_stream_set_control(struct pw_stream *stream, uint32_t id, float value, ...); - -/** Get control information */ -const struct pw_stream_control * pw_stream_get_control(struct pw_stream *stream, uint32_t id); +int pw_stream_set_control(struct pw_stream *stream, uint32_t id, uint32_t n_values, float *values, ...); /** A time structure \memberof pw_stream */ struct pw_time { diff --git a/src/tests/test-stream.c b/src/tests/test-stream.c index ba183e576..f5192f06f 100644 --- a/src/tests/test-stream.c +++ b/src/tests/test-stream.c @@ -40,7 +40,7 @@ static void test_abi(void) void (*destroy) (void *data); void (*state_changed) (void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error); - void (*control_changed) (void *data, uint32_t id, float value); + void (*control_info) (void *data, uint32_t id, struct pw_stream_control *control); void (*format_changed) (void *data, const struct spa_pod *format); void (*add_buffer) (void *data, struct pw_buffer *buffer); void (*remove_buffer) (void *data, struct pw_buffer *buffer); @@ -50,7 +50,7 @@ static void test_abi(void) TEST_FUNC(ev, test, destroy); TEST_FUNC(ev, test, state_changed); - TEST_FUNC(ev, test, control_changed); + TEST_FUNC(ev, test, control_info); TEST_FUNC(ev, test, format_changed); TEST_FUNC(ev, test, add_buffer); TEST_FUNC(ev, test, remove_buffer); diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index 61eb06385..5092d7938 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -517,7 +517,7 @@ static bool do_switch_remote(struct data *data, const char *cmd, char *args, cha return false; } -#define MARK_CHANGE(f) ((((info)->change_mask & (1 << (f)))) ? '*' : ' ') +#define MARK_CHANGE(f) ((((info)->change_mask & (f))) ? '*' : ' ') static void info_global(struct proxy_data *pd) { @@ -531,7 +531,9 @@ static void info_global(struct proxy_data *pd) fprintf(stdout, "\tpermissions: %c%c%c\n", global->permissions & PW_PERM_R ? 'r' : '-', global->permissions & PW_PERM_W ? 'w' : '-', global->permissions & PW_PERM_X ? 'x' : '-'); - fprintf(stdout, "\ttype: %s/%d\n", spa_debug_type_find_name(pw_type_info(), global->type), pd->global->version); + fprintf(stdout, "\ttype: %s/%d\n", + spa_debug_type_find_name(pw_type_info(), global->type), + pd->global->version); } static void info_core(struct proxy_data *pd) @@ -539,12 +541,12 @@ static void info_core(struct proxy_data *pd) struct pw_core_info *info = pd->info; info_global(pd); - fprintf(stdout, "%c\tuser-name: \"%s\"\n", MARK_CHANGE(0), info->user_name); - fprintf(stdout, "%c\thost-name: \"%s\"\n", MARK_CHANGE(1), info->host_name); - fprintf(stdout, "%c\tversion: \"%s\"\n", MARK_CHANGE(2), info->version); - fprintf(stdout, "%c\tname: \"%s\"\n", MARK_CHANGE(3), info->name); - fprintf(stdout, "%c\tcookie: %u\n", MARK_CHANGE(4), info->cookie); - print_properties(info->props, MARK_CHANGE(5), true); + fprintf(stdout, "\tcookie: %u\n", info->cookie); + fprintf(stdout, "\tuser-name: \"%s\"\n", info->user_name); + fprintf(stdout, "\thost-name: \"%s\"\n", info->host_name); + fprintf(stdout, "\tversion: \"%s\"\n", info->version); + fprintf(stdout, "\tname: \"%s\"\n", info->name); + print_properties(info->props, MARK_CHANGE(PW_CORE_CHANGE_MASK_PROPS), true); info->change_mask = 0; } @@ -553,10 +555,10 @@ static void info_module(struct proxy_data *pd) struct pw_module_info *info = pd->info; info_global(pd); - fprintf(stdout, "%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); - fprintf(stdout, "%c\tfilename: \"%s\"\n", MARK_CHANGE(1), info->filename); - fprintf(stdout, "%c\targs: \"%s\"\n", MARK_CHANGE(2), info->args); - print_properties(info->props, MARK_CHANGE(3), true); + fprintf(stdout, "\tname: \"%s\"\n", info->name); + fprintf(stdout, "\tfilename: \"%s\"\n", info->filename); + fprintf(stdout, "\targs: \"%s\"\n", info->args); + print_properties(info->props, MARK_CHANGE(PW_MODULE_CHANGE_MASK_PROPS), true); info->change_mask = 0; } @@ -565,18 +567,18 @@ static void info_node(struct proxy_data *pd) struct pw_node_info *info = pd->info; info_global(pd); - fprintf(stdout, "%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); - fprintf(stdout, "%c\tinput ports: %u/%u\n", MARK_CHANGE(1), + fprintf(stdout, "%c\tinput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_INPUT_PORTS), info->n_input_ports, info->max_input_ports); - fprintf(stdout, "%c\toutput ports: %u/%u\n", MARK_CHANGE(2), + fprintf(stdout, "%c\toutput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_OUTPUT_PORTS), info->n_output_ports, info->max_output_ports); - fprintf(stdout, "%c\tstate: \"%s\"", MARK_CHANGE(3), pw_node_state_as_string(info->state)); + fprintf(stdout, "%c\tstate: \"%s\"", MARK_CHANGE(PW_NODE_CHANGE_MASK_STATE), + pw_node_state_as_string(info->state)); if (info->state == PW_NODE_STATE_ERROR && info->error) fprintf(stdout, " \"%s\"\n", info->error); else fprintf(stdout, "\n"); - print_properties(info->props, MARK_CHANGE(4), true); - print_params(info->params, info->n_params, MARK_CHANGE(5), true); + print_properties(info->props, MARK_CHANGE(PW_NODE_CHANGE_MASK_PROPS), true); + print_params(info->params, info->n_params, MARK_CHANGE(PW_NODE_CHANGE_MASK_PARAMS), true); info->change_mask = 0; } @@ -585,8 +587,9 @@ static void info_port(struct proxy_data *pd) struct pw_port_info *info = pd->info; info_global(pd); - print_properties(info->props, MARK_CHANGE(0), true); - print_params(info->params, info->n_params, MARK_CHANGE(1), true); + fprintf(stdout, "\tdirection: \"%s\"\n", pw_direction_as_string(info->direction)); + print_properties(info->props, MARK_CHANGE(PW_PORT_CHANGE_MASK_PROPS), true); + print_params(info->params, info->n_params, MARK_CHANGE(PW_PORT_CHANGE_MASK_PARAMS), true); info->change_mask = 0; } @@ -596,8 +599,9 @@ static void info_factory(struct proxy_data *pd) info_global(pd); fprintf(stdout, "\tname: \"%s\"\n", info->name); - fprintf(stdout, "\tobject-type: %s/%d\n", spa_debug_type_find_name(pw_type_info(), info->type), info->version); - print_properties(info->props, MARK_CHANGE(0), true); + fprintf(stdout, "\tobject-type: %s/%d\n", + spa_debug_type_find_name(pw_type_info(), info->type), info->version); + print_properties(info->props, MARK_CHANGE(PW_FACTORY_CHANGE_MASK_PROPS), true); info->change_mask = 0; } @@ -606,7 +610,7 @@ static void info_client(struct proxy_data *pd) struct pw_client_info *info = pd->info; info_global(pd); - print_properties(info->props, MARK_CHANGE(0), true); + print_properties(info->props, MARK_CHANGE(PW_CLIENT_CHANGE_MASK_PROPS), true); info->change_mask = 0; } @@ -615,16 +619,23 @@ static void info_link(struct proxy_data *pd) struct pw_link_info *info = pd->info; info_global(pd); - fprintf(stdout, "%c\toutput-node-id: %u\n", MARK_CHANGE(0), info->output_node_id); - fprintf(stdout, "%c\toutput-port-id: %u\n", MARK_CHANGE(0), info->output_port_id); - fprintf(stdout, "%c\tinput-node-id: %u\n", MARK_CHANGE(1), info->input_node_id); - fprintf(stdout, "%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id); - fprintf(stdout, "%c\tformat:\n", MARK_CHANGE(2)); + fprintf(stdout, "\toutput-node-id: %u\n", info->output_node_id); + fprintf(stdout, "\toutput-port-id: %u\n", info->output_port_id); + fprintf(stdout, "\tinput-node-id: %u\n", info->input_node_id); + fprintf(stdout, "\tinput-port-id: %u\n", info->input_port_id); + + fprintf(stdout, "%c\tstate: \"%s\"", MARK_CHANGE(PW_LINK_CHANGE_MASK_STATE), + pw_link_state_as_string(info->state)); + if (info->state == PW_LINK_STATE_ERROR && info->error) + printf(" \"%s\"\n", info->error); + else + printf("\n"); + fprintf(stdout, "%c\tformat:\n", MARK_CHANGE(PW_LINK_CHANGE_MASK_FORMAT)); if (info->format) spa_debug_format(2, NULL, info->format); else fprintf(stdout, "\t\tnone\n"); - print_properties(info->props, MARK_CHANGE(3), true); + print_properties(info->props, MARK_CHANGE(PW_LINK_CHANGE_MASK_PROPS), true); info->change_mask = 0; } @@ -633,9 +644,8 @@ static void info_device(struct proxy_data *pd) struct pw_device_info *info = pd->info; info_global(pd); - fprintf(stdout, "\tname: \"%s\"\n", info->name); - print_properties(info->props, MARK_CHANGE(0), true); - print_params(info->params, info->n_params, MARK_CHANGE(1), true); + print_properties(info->props, MARK_CHANGE(PW_DEVICE_CHANGE_MASK_PROPS), true); + print_params(info->params, info->n_params, MARK_CHANGE(PW_DEVICE_CHANGE_MASK_PARAMS), true); info->change_mask = 0; } diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 8fe21cdad..9bb3aa3be 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -188,20 +188,20 @@ static void print_properties(const struct spa_dict *props, char mark) } } -#define MARK_CHANGE(f) ((print_mark && ((info)->change_mask & (1 << (f)))) ? '*' : ' ') +#define MARK_CHANGE(f) ((print_mark && ((info)->change_mask & (f))) ? '*' : ' ') static void on_core_info(void *data, const struct pw_core_info *info) { - bool print_all = true, print_mark = false; + bool print_all = true, print_mark = true; printf("\ttype: %s\n", spa_debug_type_find_name(pw_type_info(), PW_TYPE_INTERFACE_Core)); printf("\tcookie: %u\n", info->cookie); + printf("\tuser-name: \"%s\"\n", info->user_name); + printf("\thost-name: \"%s\"\n", info->host_name); + printf("\tversion: \"%s\"\n", info->version); + printf("\tname: \"%s\"\n", info->name); if (print_all) { - printf("%c\tuser-name: \"%s\"\n", MARK_CHANGE(0), info->user_name); - printf("%c\thost-name: \"%s\"\n", MARK_CHANGE(1), info->host_name); - printf("%c\tversion: \"%s\"\n", MARK_CHANGE(2), info->version); - printf("%c\tname: \"%s\"\n", MARK_CHANGE(3), info->name); - print_properties(info->props, MARK_CHANGE(4)); + print_properties(info->props, MARK_CHANGE(PW_CORE_CHANGE_MASK_PROPS)); } } @@ -229,11 +229,11 @@ static void module_event_info(void *object, const struct pw_module_info *info) data->permissions & PW_PERM_X ? 'x' : '-'); printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), data->type), data->version); + printf("\tname: \"%s\"\n", info->name); + printf("\tfilename: \"%s\"\n", info->filename); + printf("\targs: \"%s\"\n", info->args); if (print_all) { - printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); - printf("%c\tfilename: \"%s\"\n", MARK_CHANGE(1), info->filename); - printf("%c\targs: \"%s\"\n", MARK_CHANGE(2), info->args); - print_properties(info->props, MARK_CHANGE(3)); + print_properties(info->props, MARK_CHANGE(PW_MODULE_CHANGE_MASK_PROPS)); } } @@ -266,20 +266,18 @@ static void print_node(struct proxy_data *data) printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), data->type), data->version); if (print_all) { - printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); - print_params(data, MARK_CHANGE(5)); - printf("%c\tinput ports: %u/%u\n", MARK_CHANGE(1), + print_params(data, MARK_CHANGE(PW_NODE_CHANGE_MASK_PARAMS)); + printf("%c\tinput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_INPUT_PORTS), info->n_input_ports, info->max_input_ports); - printf("%c\toutput ports: %u/%u\n", MARK_CHANGE(2), + printf("%c\toutput ports: %u/%u\n", MARK_CHANGE(PW_NODE_CHANGE_MASK_OUTPUT_PORTS), info->n_output_ports, info->max_output_ports); - printf("%c\tstate: \"%s\"", MARK_CHANGE(3), pw_node_state_as_string(info->state)); + printf("%c\tstate: \"%s\"", MARK_CHANGE(PW_NODE_CHANGE_MASK_STATE), + pw_node_state_as_string(info->state)); if (info->state == PW_NODE_STATE_ERROR && info->error) printf(" \"%s\"\n", info->error); else printf("\n"); - print_properties(info->props, MARK_CHANGE(4)); - - + print_properties(info->props, MARK_CHANGE(PW_NODE_CHANGE_MASK_PROPS)); } } @@ -336,16 +334,16 @@ static void print_port(struct proxy_data *data) data->permissions & PW_PERM_X ? 'x' : '-'); printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), data->type), data->version); + + printf("\tdirection: \"%s\"\n", pw_direction_as_string(info->direction)); if (print_all) { - printf(" \tdirection: \"%s\"\n", pw_direction_as_string(info->direction)); - print_params(data, MARK_CHANGE(1)); - print_properties(info->props, MARK_CHANGE(0)); + print_params(data, MARK_CHANGE(PW_PORT_CHANGE_MASK_PARAMS)); + print_properties(info->props, MARK_CHANGE(PW_PORT_CHANGE_MASK_PROPS)); } } static void port_event_info(void *object, const struct pw_port_info *info) { - struct proxy_data *data = object; struct pw_port_info *old = data->info; uint32_t i; @@ -398,10 +396,11 @@ static void factory_event_info(void *object, const struct pw_factory_info *info) data->permissions & PW_PERM_X ? 'x' : '-'); printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), data->type), data->version); + printf("\tname: \"%s\"\n", info->name); printf("\tobject-type: %s/%d\n", spa_debug_type_find_name(pw_type_info(), info->type), info->version); if (print_all) { - print_properties(info->props, MARK_CHANGE(0)); + print_properties(info->props, MARK_CHANGE(PW_FACTORY_CHANGE_MASK_PROPS)); } } @@ -434,8 +433,9 @@ static void client_event_info(void *object, const struct pw_client_info *info) data->permissions & PW_PERM_X ? 'x' : '-'); printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), data->type), data->version); + if (print_all) { - print_properties(info->props, MARK_CHANGE(0)); + print_properties(info->props, MARK_CHANGE(PW_CLIENT_CHANGE_MASK_PROPS)); } } @@ -468,22 +468,24 @@ static void link_event_info(void *object, const struct pw_link_info *info) data->permissions & PW_PERM_X ? 'x' : '-'); printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), data->type), data->version); + + printf("\toutput-node-id: %u\n", info->output_node_id); + printf("\toutput-port-id: %u\n", info->output_port_id); + printf("\tinput-node-id: %u\n", info->input_node_id); + printf("\tinput-port-id: %u\n", info->input_port_id); if (print_all) { - printf("%c\toutput-node-id: %u\n", MARK_CHANGE(0), info->output_node_id); - printf("%c\toutput-port-id: %u\n", MARK_CHANGE(0), info->output_port_id); - printf("%c\tinput-node-id: %u\n", MARK_CHANGE(1), info->input_node_id); - printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id); - printf("%c\tstate: \"%s\"", MARK_CHANGE(2), pw_link_state_as_string(info->state)); + printf("%c\tstate: \"%s\"", MARK_CHANGE(PW_LINK_CHANGE_MASK_STATE), + pw_link_state_as_string(info->state)); if (info->state == PW_LINK_STATE_ERROR && info->error) printf(" \"%s\"\n", info->error); else printf("\n"); - printf("%c\tformat:\n", MARK_CHANGE(3)); + printf("%c\tformat:\n", MARK_CHANGE(PW_LINK_CHANGE_MASK_FORMAT)); if (info->format) spa_debug_format(2, NULL, info->format); else printf("\t\tnone\n"); - print_properties(info->props, MARK_CHANGE(4)); + print_properties(info->props, MARK_CHANGE(PW_LINK_CHANGE_MASK_PROPS)); } } @@ -515,9 +517,10 @@ static void print_device(struct proxy_data *data) data->permissions & PW_PERM_X ? 'x' : '-'); printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), data->type), data->version); + if (print_all) { - print_params(data, MARK_CHANGE(1)); - print_properties(info->props, MARK_CHANGE(0)); + print_params(data, MARK_CHANGE(PW_DEVICE_CHANGE_MASK_PARAMS)); + print_properties(info->props, MARK_CHANGE(PW_DEVICE_CHANGE_MASK_PROPS)); } }