1 #ifndef fooprotocolnativehfoo
2 #define fooprotocolnativehfoo
3
4 /***
5 This file is part of PulseAudio.
6
7 Copyright 2004-2006 Lennart Poettering
8 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9
10 PulseAudio is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published
12 by the Free Software Foundation; either version 2.1 of the License,
13 or (at your option) any later version.
14
15 PulseAudio is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
22 ***/
23 // GCC does not warn for unused *static inline* functions, but clang does.
24 #ifdef __clang__
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wunused-function"
27 #endif
28
29 #include <pulsecore/core.h>
30 #include <pulsecore/ipacl.h>
31 #include <pulsecore/auth-cookie.h>
32 #include <pulsecore/iochannel.h>
33 #include <pulsecore/module.h>
34 #include <pulsecore/modargs.h>
35 #include <pulsecore/strlist.h>
36 #include <pulsecore/hook-list.h>
37 #include <pulsecore/pstream.h>
38 #include <pulsecore/tagstruct.h>
39
40 typedef struct pa_native_protocol pa_native_protocol;
41
42 typedef struct pa_native_connection pa_native_connection;
43
44 typedef struct pa_native_options {
45 PA_REFCNT_DECLARE;
46
47 pa_module *module;
48
49 bool auth_anonymous;
50 bool srbchannel;
51 char *auth_group;
52 pa_ip_acl *auth_ip_acl;
53 pa_auth_cookie *auth_cookie;
54 } pa_native_options;
55
56 typedef enum pa_native_hook {
57 PA_NATIVE_HOOK_SERVERS_CHANGED,
58 PA_NATIVE_HOOK_CONNECTION_PUT,
59 PA_NATIVE_HOOK_CONNECTION_UNLINK,
60 PA_NATIVE_HOOK_MAX
61 } pa_native_hook_t;
62
63
64 struct pa_native_protocol;
65
66 typedef struct record_stream {
67 pa_msgobject parent;
68
69 pa_native_connection *connection;
70 uint32_t index;
71
72 pa_source_output *source_output;
73 pa_memblockq *memblockq;
74
75 bool adjust_latency : 1;
76 bool early_requests : 1;
77
78 /* Requested buffer attributes */
79 pa_buffer_attr buffer_attr_req;
80 /* Fixed-up and adjusted buffer attributes */
81 pa_buffer_attr buffer_attr;
82
83 pa_atomic_t on_the_fly;
84 pa_usec_t configured_source_latency;
85 size_t drop_initial;
86
87 /* Only updated after SOURCE_OUTPUT_MESSAGE_UPDATE_LATENCY */
88 size_t on_the_fly_snapshot;
89 pa_usec_t current_monitor_latency;
90 pa_usec_t current_source_latency;
91 } record_stream;
92
93 #define RECORD_STREAM(o) (record_stream_cast(o))
94 PA_DEFINE_PRIVATE_CLASS(record_stream, pa_msgobject);
95
96 typedef struct output_stream {
97 pa_msgobject parent;
98 } output_stream;
99
100 #define OUTPUT_STREAM(o) (output_stream_cast(o))
101 PA_DEFINE_PRIVATE_CLASS(output_stream, pa_msgobject);
102
103 typedef struct playback_stream {
104 output_stream parent;
105
106 pa_native_connection *connection;
107 uint32_t index;
108
109 pa_sink_input *sink_input;
110 pa_memblockq *memblockq;
111
112 bool adjust_latency : 1;
113 bool early_requests : 1;
114
115 bool is_underrun : 1;
116 bool drain_request : 1;
117 uint32_t drain_tag;
118 uint32_t syncid;
119
120 /* Optimization to avoid too many rewinds with a lot of small blocks */
121 pa_atomic_t seek_or_post_in_queue;
122 int64_t seek_windex;
123
124 pa_atomic_t missing;
125 pa_usec_t configured_sink_latency;
126 /* Requested buffer attributes */
127 pa_buffer_attr buffer_attr_req;
128 /* Fixed-up and adjusted buffer attributes */
129 pa_buffer_attr buffer_attr;
130
131 /* Only updated after SINK_INPUT_MESSAGE_UPDATE_LATENCY */
132 int64_t read_index, write_index;
133 size_t render_memblockq_length;
134 pa_usec_t current_sink_latency;
135 uint64_t playing_for, underrun_for;
136 } playback_stream;
137
138 #define PLAYBACK_STREAM(o) (playback_stream_cast(o))
139 PA_DEFINE_PRIVATE_CLASS(playback_stream, output_stream);
140
141 typedef struct upload_stream {
142 output_stream parent;
143
144 pa_native_connection *connection;
145 uint32_t index;
146
147 pa_memchunk memchunk;
148 size_t length;
149 char *name;
150 pa_sample_spec sample_spec;
151 pa_channel_map channel_map;
152 pa_proplist *proplist;
153 } upload_stream;
154
155 #define UPLOAD_STREAM(o) (upload_stream_cast(o))
156 PA_DEFINE_PRIVATE_CLASS(upload_stream, output_stream);
157
158 struct pa_native_connection {
159 pa_msgobject parent;
160 pa_native_protocol *protocol;
161 pa_native_options *options;
162 bool authorized : 1;
163 bool is_local : 1;
164 uint32_t version;
165 pa_client *client;
166 /* R/W mempool, one per client connection, for srbchannel transport.
167 * Both server and client can write to this shm area.
168 *
169 * Note: This will be NULL if our connection with the client does
170 * not support srbchannels */
171 pa_mempool *rw_mempool;
172 pa_pstream *pstream;
173 pa_pdispatch *pdispatch;
174 pa_idxset *record_streams, *output_streams;
175 uint32_t rrobin_index;
176 pa_subscription *subscription;
177 pa_time_event *auth_timeout_event;
178 pa_srbchannel *srbpending;
179 };
180
181 #define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o))
182 PA_DEFINE_PRIVATE_CLASS(pa_native_connection, pa_msgobject);
183
184 struct pa_native_protocol {
185 PA_REFCNT_DECLARE;
186
187 pa_core *core;
188 pa_idxset *connections;
189
190 pa_strlist *servers;
191 pa_hook hooks[PA_NATIVE_HOOK_MAX];
192
193 pa_hashmap *extensions;
194 };
195
196 enum {
197 SOURCE_OUTPUT_MESSAGE_UPDATE_LATENCY = PA_SOURCE_OUTPUT_MESSAGE_MAX
198 };
199
200 enum {
201 SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, /* data from main loop to sink input */
202 SINK_INPUT_MESSAGE_DRAIN, /* disabled prebuf, get playback started. */
203 SINK_INPUT_MESSAGE_FLUSH,
204 SINK_INPUT_MESSAGE_TRIGGER,
205 SINK_INPUT_MESSAGE_SEEK,
206 SINK_INPUT_MESSAGE_PREBUF_FORCE,
207 SINK_INPUT_MESSAGE_UPDATE_LATENCY,
208 SINK_INPUT_MESSAGE_UPDATE_BUFFER_ATTR
209 };
210
211 enum {
212 PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, /* data requested from sink input from the main loop */
213 PLAYBACK_STREAM_MESSAGE_UNDERFLOW,
214 PLAYBACK_STREAM_MESSAGE_OVERFLOW,
215 PLAYBACK_STREAM_MESSAGE_DRAIN_ACK,
216 PLAYBACK_STREAM_MESSAGE_STARTED,
217 PLAYBACK_STREAM_MESSAGE_UPDATE_TLENGTH,
218 PLAYBACK_STREAM_MESSAGE_UNDERFLOW_OHOS,
219 };
220
221 enum {
222 RECORD_STREAM_MESSAGE_POST_DATA /* data from source output to main loop */
223 };
224
225 enum {
226 CONNECTION_MESSAGE_RELEASE,
227 CONNECTION_MESSAGE_REVOKE
228 };
229
230 /* Called from IO context */
playback_stream_request_bytes(playback_stream * s)231 static void playback_stream_request_bytes(playback_stream *s)
232 {
233 size_t m;
234
235 playback_stream_assert_ref(s);
236
237 m = pa_memblockq_pop_missing(s->memblockq);
238 if (m <= 0) {
239 return;
240 }
241 /* pa_log("request_bytes(%lu) (tlength=%lu minreq=%lu length=%lu really missing=%lli)", */
242 /* (unsigned long) m, */
243 /* pa_memblockq_get_tlength(s->memblockq), */
244 /* pa_memblockq_get_minreq(s->memblockq), */
245 /* pa_memblockq_get_length(s->memblockq), */
246 /* (long long) pa_memblockq_get_tlength(s->memblockq) - (long long) pa_memblockq_get_length(s->memblockq)); */
247 #ifdef PROTOCOL_NATIVE_DEBUG
248 pa_log("request_bytes(%lu)", (unsigned long) m);
249 #endif
250
251 if (pa_atomic_add(&s->missing, (int) m) <= 0) {
252 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s),
253 PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);
254 }
255 }
256
257 pa_native_protocol* pa_native_protocol_get(pa_core *core);
258 pa_native_protocol* pa_native_protocol_ref(pa_native_protocol *p);
259 void pa_native_protocol_unref(pa_native_protocol *p);
260 void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_native_options *a);
261 void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m);
262
263 pa_hook *pa_native_protocol_hooks(pa_native_protocol *p);
264
265 void pa_native_protocol_add_server_string(pa_native_protocol *p, const char *name);
266 void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char *name);
267 pa_strlist *pa_native_protocol_servers(pa_native_protocol *p);
268
269 typedef int (*pa_native_protocol_ext_cb_t)(
270 pa_native_protocol *p,
271 pa_module *m,
272 pa_native_connection *c,
273 uint32_t tag,
274 pa_tagstruct *t);
275
276 int pa_native_protocol_install_ext(pa_native_protocol *p, pa_module *m, pa_native_protocol_ext_cb_t cb);
277 void pa_native_protocol_remove_ext(pa_native_protocol *p, pa_module *m);
278
279 pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c);
280 pa_client* pa_native_connection_get_client(pa_native_connection *c);
281
282 pa_native_options* pa_native_options_new(void);
283 pa_native_options* pa_native_options_ref(pa_native_options *o);
284 void pa_native_options_unref(pa_native_options *o);
285 int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma);
286
287 #endif
288