From 439a0b003b4343b6a3ab3205c0f0e309a0312b74 Mon Sep 17 00:00:00 2001 From: Christian Glombek Date: Jan 25 2023 21:48:39 +0000 Subject: WIP --- diff --git a/0001-WIP-Dedupe-RAOP-sink-discovery.patch b/0001-WIP-Dedupe-RAOP-sink-discovery.patch new file mode 100644 index 0000000..3971caa --- /dev/null +++ b/0001-WIP-Dedupe-RAOP-sink-discovery.patch @@ -0,0 +1,249 @@ +From 3fef621c409ebf9a04f1ed8a713adb2b16e3a451 Mon Sep 17 00:00:00 2001 +From: Christian Glombek +Date: Wed, 25 Jan 2023 22:47:05 +0100 +Subject: [PATCH] WIP: Dedupe RAOP sink discovery + +--- + src/modules/module-raop-discover.c | 124 ++++++++++++++++++++++++----- + 1 file changed, 104 insertions(+), 20 deletions(-) + +diff --git a/src/modules/module-raop-discover.c b/src/modules/module-raop-discover.c +index 0c6201177..5696baedd 100644 +--- a/src/modules/module-raop-discover.c ++++ b/src/modules/module-raop-discover.c +@@ -104,9 +104,19 @@ struct impl { + struct spa_list tunnel_list; + }; + +-struct tunnel_info { ++struct profile_info { + AvahiIfIndex interface; + AvahiProtocol protocol; ++}; ++ ++#define PROFILE_INFO(...) ((struct profile_info){ __VA_ARGS__ }) ++ ++struct profile { ++ struct spa_list link; ++ struct profile_info info; ++}; ++ ++struct tunnel_info { + const char *name; + const char *type; + const char *domain; +@@ -117,6 +127,7 @@ struct tunnel_info { + struct tunnel { + struct spa_list link; + struct tunnel_info info; ++ struct spa_list profile_list; + struct pw_impl_module *module; + struct spa_hook module_listener; + }; +@@ -128,11 +139,11 @@ static struct tunnel *make_tunnel(struct impl *impl, const struct tunnel_info *i + struct tunnel *t; + + t = calloc(1, sizeof(*t)); +- if (t == NULL) ++ if (t == NULL) { ++ pw_log_error("can't create raop tunnel info"); + return NULL; ++ }; + +- t->info.interface = info->interface; +- t->info.protocol = info->protocol; + t->info.name = strdup(info->name); + t->info.type = strdup(info->type); + t->info.domain = strdup(info->domain); +@@ -141,14 +152,29 @@ static struct tunnel *make_tunnel(struct impl *impl, const struct tunnel_info *i + return t; + } + ++static void *add_profile(struct tunnel *t, const struct profile_info *info) ++{ ++ struct profile *p; ++ ++ p = calloc(1, sizeof(*p)); ++ if (p == NULL) { ++ pw_log_error("can't create raop profile"); ++ return; ++ }; ++ ++ p->info.interface = info->interface; ++ p->info.protocol = info->protocol; ++ spa_list_append(&t->profile_list, &p->link); ++ ++ return; ++} ++ + static struct tunnel *find_tunnel(struct impl *impl, const struct tunnel_info *info) + { + struct tunnel *t; + spa_list_for_each(t, &impl->tunnel_list, link) { +- if (t->info.interface == info->interface && +- t->info.protocol == info->protocol && +- spa_streq(t->info.name, info->name) && +- spa_streq(t->info.type, info->type) && ++ if (spa_streq(t->info.name, info->name) && ++ spa_streq(t->info.type, info->type) && + spa_streq(t->info.domain, info->domain)) + return t; + } +@@ -270,12 +296,17 @@ static void pw_properties_from_avahi_string(const char *key, const char *value, + static void submodule_destroy(void *data) + { + struct tunnel *t = data; ++ // struct profile *p; + + spa_list_remove(&t->link); ++ ++ /* ++ spa_list_consume(p, &t->profile_list, link) ++ spa_list_remove(&p->link); ++ */ + spa_hook_remove(&t->module_listener); + + free((char *) t->info.name); +- free((char *) t->info.type); + free((char *) t->info.domain); + + free(t); +@@ -294,6 +325,7 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr + struct impl *impl = userdata; + struct tunnel *t; + struct tunnel_info tinfo; ++ struct profile_info pinfo; + const char *str; + AvahiStringList *l; + FILE *f; +@@ -308,9 +340,11 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr + avahi_strerror(avahi_client_errno(impl->client))); + goto done; + } +- tinfo = TUNNEL_INFO(.interface = interface, +- .protocol = protocol, +- .name = name, ++ ++ pinfo = PROFILE_INFO(.interface = interface, ++ .protocol = protocol); ++ ++ tinfo = TUNNEL_INFO(.name = name, + .type = type, + .domain = domain); + +@@ -325,6 +359,9 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr + pw_properties_setf(props, "raop.hostname", "%s", at); + pw_properties_setf(props, "raop.port", "%u", port); + ++ // TODO do move to sink as default ++ //pw_properties_set(props, PW_KEY_DEVICE_ICON_NAME, "audio-speakers"); ++ + if ((str = strstr(name, "@"))) { + str++; + if (strlen(str) > 0) +@@ -371,6 +408,8 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr + goto done; + } + ++ pw_log_info("about to load raop-sink module"); ++ + t = make_tunnel(impl, &tinfo); + if (t == NULL) { + pw_log_error("Can't make tunnel: %m"); +@@ -378,6 +417,12 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr + goto done; + } + ++ pw_log_info("about to add raop-sink profile"); ++ ++ add_profile(t, &pinfo); ++ ++ pw_log_info("about to add listener"); ++ + pw_impl_module_add_listener(mod, &t->module_listener, &submodule_events, t); + + t->module = mod; +@@ -392,24 +437,46 @@ static void browser_cb(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProt + AvahiLookupResultFlags flags, void *userdata) + { + struct impl *impl = userdata; +- struct tunnel_info info; ++ struct tunnel_info tinfo; + struct tunnel *t; ++ struct profile_info pinfo; ++ struct profile *p; ++ bool p_found; ++ int p_count; + + if (flags & AVAHI_LOOKUP_RESULT_LOCAL) + return; + +- info = TUNNEL_INFO(.interface = interface, +- .protocol = protocol, +- .name = name, +- .type = type, +- .domain = domain); ++ tinfo = TUNNEL_INFO(.name = name, ++ .domain = domain); + +- t = find_tunnel(impl, &info); ++ pinfo = PROFILE_INFO(.interface = interface, ++ .protocol = protocol); ++ ++ t = find_tunnel(impl, &tinfo); + + switch (event) { + case AVAHI_BROWSER_NEW: +- if (t != NULL) ++ pw_log_info("case AVAHI_BROWSER_NEW"); ++ if (t != NULL) { ++ p_found = false; ++ spa_list_for_each(p, &t->profile_list, link) { ++ if (p->info.interface == interface && ++ p->info.protocol == protocol) { ++ p_found = true; ++ } ++ }; ++ if (p_found) { ++ pw_log_info("raop profile already known"); ++ return; ++ } ++ ++ pw_log_info("adding profile to existing raop tunnel"); ++ ++ add_profile(t, &pinfo); ++ + return; ++ } + if (!(avahi_service_resolver_new(impl->client, + interface, protocol, + name, type, domain, +@@ -419,8 +486,25 @@ static void browser_cb(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProt + avahi_strerror(avahi_client_errno(impl->client))); + break; + case AVAHI_BROWSER_REMOVE: ++ pw_log_info("case AVAHI_BROWSER_REMOVE"); + if (t == NULL) + return; ++ p_count = 0; ++ spa_list_for_each(p, &t->profile_list, link) { ++ if (p->info.interface == interface && ++ p->info.protocol == protocol) { ++ pw_log_info("removing profile from existing raop tunnel"); ++ spa_list_remove(&p->link); ++ } else { ++ p_count++; ++ } ++ }; ++ if (p_count > 0) { ++ pw_log_info("keeping tunnel alive"); ++ return; ++ } ++ ++ pw_log_info("freeing tunnel"); + free_tunnel(t); + break; + default: +-- +2.37.1 + diff --git a/pipewire.spec b/pipewire.spec index 8590a61..31eaa6a 100644 --- a/pipewire.spec +++ b/pipewire.spec @@ -9,7 +9,7 @@ %global ms_version 0.4.1 # For rpmdev-bumpspec and releng automation -%global baserelease 1 +%global baserelease 4 #global snapdate 20210107 #global gitcommit b17db2cebc1a5ab2c01851d29c05f79cd2f262bb @@ -73,6 +73,7 @@ Source1: https://gitlab.freedesktop.org/pipewire/media-session/-/archive/ %endif ## upstream patches +Patch0001: 0001-WIP-Dedupe-RAOP-sink-discovery.patch ## upstreamable patches diff --git a/sources b/sources deleted file mode 100644 index b857e1f..0000000 --- a/sources +++ /dev/null @@ -1,2 +0,0 @@ -SHA512 (pipewire-0.3.63.tar.gz) = 3c1808a2adb3dfe2fcaf5e3c7a0ae2f7f0194e7fe25f22fa6d4aec1665d9d5ffec5294cae57e1f6e4d8a360ab6550c193902f0e9996b0abfee09ed9b80d720aa -SHA512 (media-session-0.4.1.tar.gz) = bfce472b7260b280c0d3cd74d917f48655b5be9976c89a109e94b81af2c3664e83446e97db573cedba6e5d54dedf77195b80eb0a76f6bfc0e96e342557469f99