UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
pipewire_common.cpp
Go to the documentation of this file.
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#include "config_unix.h"
4#endif
5
6#include "debug.h"
7#include "utils/color_out.h"
8
9#include "pipewire_common.hpp"
10
11static void on_core_done(void *data, uint32_t /*id*/, int seq)
12{
13 auto s = static_cast<pipewire_state_common *>(data);
14
15 s->pw_last_seq = seq;
16 pw_thread_loop_signal(s->pipewire_loop.get(), false);
17}
18
19static void on_core_error(void * /*data*/, uint32_t id, int seq, int res, const char *message)
20{
21 log_msg(LOG_LEVEL_ERROR, "Pipewire error: id:%d seq:%x res:%d msg: %s\n", id, seq, res, message);
22}
23
24static const struct pw_core_events core_events = {
25 PW_VERSION_CORE_EVENTS,
26 .info = nullptr,
27 .done = on_core_done,
28 .ping = nullptr,
29 .error = on_core_error,
30 .remove_id = nullptr,
31 .bound_id = nullptr,
32 .add_mem = nullptr,
33 .remove_mem = nullptr,
34#if PW_MAJOR > 0 || PW_MINOR > 3 || (PW_MINOR == 3 && PW_MICRO > 67)
35 .bound_props = nullptr,
36#endif
37};
38
40 s.init_guard.init();
41 s.pipewire_loop.reset(pw_thread_loop_new("Playback", nullptr));
42 s.pipewire_context.reset(pw_context_new(pw_thread_loop_get_loop(s.pipewire_loop.get()), nullptr, 0)); //TODO check return
43
44 if(fd != -1)
45 s.pipewire_core.reset(pw_context_connect_fd(s.pipewire_context.get(), fd, nullptr, 0));
46 else
47 s.pipewire_core.reset(pw_context_connect(s.pipewire_context.get(), nullptr, 0));
48
49 pw_core_add_listener(s.pipewire_core.get(), &s.core_listener.get(), &core_events, &s);
50
51 pw_thread_loop_start(s.pipewire_loop.get());
52
53 return true;
54}
55
56static void on_registry_event_global(void *data, uint32_t /*id*/,
57 uint32_t /*permissions*/, const char *type, uint32_t /*version*/,
58 const struct spa_dict *props)
59{
60 auto result = static_cast<std::vector<Pipewire_device> *>(data);
61 std::string_view type_sv(type);
62 if(type_sv != "PipeWire:Interface:Node")
63 return;
64
66 for(unsigned i = 0; i < props->n_items; i++){
67 std::string_view key(props->items[i].key);
68 std::string_view val(props->items[i].value);
69
70 if(key == "node.description")
71 dev.description = val;
72 else if(key == "node.nick")
73 dev.nick = val;
74 else if(key == "media.class")
75 dev.media_class = val;
76 else if(key == "node.name")
77 dev.name = val;
78 else if(key == "object.serial")
79 dev.serial = val;
80 }
81
82 result->push_back(std::move(dev));
83}
84
85std::vector<Pipewire_device> get_pw_device_list(){
88
89 std::vector<Pipewire_device> result;
90
92
93 pw_registry_uniq registry(pw_core_get_registry(s.pipewire_core.get(), PW_VERSION_REGISTRY, 0));
94
95 const static pw_registry_events registry_events = {
96 PW_VERSION_REGISTRY_EVENTS,
98 .global_remove = nullptr
99 };
100
101 spa_hook_uniq registry_listener;
102 pw_registry_add_listener(registry.get(), &registry_listener.get(), &registry_events, &result);
103
104 s.pw_pending_seq = pw_core_sync(s.pipewire_core.get(), PW_ID_CORE, s.pw_pending_seq);
105 int wait_seq = s.pw_pending_seq;
106
107 do{
108 pw_thread_loop_wait(s.pipewire_loop.get());
109 } while(s.pw_last_seq < wait_seq);
110
111 return result;
112}
113
114
116 if(pipewire_loop)
117 pw_thread_loop_stop(pipewire_loop.get());
118}
119
120void print_devices(std::string_view media_class){
121 auto devices = get_pw_device_list();
122
123 for(const auto& dev : devices){
124 if(dev.media_class == media_class){
125 color_printf("\t%s: %s (%s)\n", dev.serial.c_str(), dev.description.c_str(), dev.name.c_str());
126 }
127 }
128}
129
130
int void * val
int color_printf(const char *format,...)
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
void print_devices(std::string_view media_class)
bool initialize_pw_common(pipewire_state_common &s, int fd)
static void on_core_error(void *, uint32_t id, int seq, int res, const char *message)
std::vector< Pipewire_device > get_pw_device_list()
static void on_registry_event_global(void *data, uint32_t, uint32_t, const char *type, uint32_t, const struct spa_dict *props)
static void on_core_done(void *data, uint32_t, int seq)
static const struct pw_core_events core_events
raii_uniq_proxy_handle< pw_registry > pw_registry_uniq
Option::OptType type
Definition settings.cpp:194
std::string description
std::string media_class
pw_context_uniq pipewire_context
pw_thread_loop_uniq pipewire_loop
pipewire_init_guard init_guard
spa_hook & get()
uint32_t seq
Definition tfrc.c:100
const char * key
Definition cineform.cpp:125