• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef foointernalhfoo
2 #define foointernalhfoo
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 
24 #include <pulse/mainloop-api.h>
25 #include <pulse/context.h>
26 #include <pulse/stream.h>
27 #include <pulse/operation.h>
28 #include <pulse/subscribe.h>
29 #include <pulse/ext-device-manager.h>
30 #include <pulse/ext-device-restore.h>
31 #include <pulse/ext-stream-restore.h>
32 
33 #include <pulsecore/socket-client.h>
34 #include <pulsecore/pstream.h>
35 #include <pulsecore/pdispatch.h>
36 #include <pulsecore/llist.h>
37 #include <pulsecore/native-common.h>
38 #include <pulsecore/strlist.h>
39 #include <pulsecore/mcalign.h>
40 #include <pulsecore/memblockq.h>
41 #include <pulsecore/hashmap.h>
42 #include <pulsecore/refcnt.h>
43 
44 #ifdef USE_SMOOTHER_2
45 #include <pulsecore/time-smoother_2.h>
46 #else
47 #include <pulsecore/time-smoother.h>
48 #endif
49 
50 #ifdef HAVE_DBUS
51 #include <pulsecore/dbus-util.h>
52 #endif
53 
54 #include "client-conf.h"
55 
56 #define DEFAULT_TIMEOUT (9)
57 
58 #define PA_PROTOCOL_FLAG_MASK 0xFFFF0000U
59 #define PA_PROTOCOL_VERSION_MASK 0x0000FFFFU
60 
61 #define PA_PROTOCOL_FLAG_SHM 0x80000000U
62 #define PA_PROTOCOL_FLAG_MEMFD 0x40000000U
63 
64 typedef struct pa_context_error {
65     int error;
66 } pa_context_error;
67 
68 struct pa_context {
69     PA_REFCNT_DECLARE;
70 
71 #ifdef HAVE_DBUS
72     pa_dbus_wrap_connection *system_bus;
73     pa_dbus_wrap_connection *session_bus;
74 #endif
75 
76     pa_proplist *proplist;
77     pa_mainloop_api* mainloop;
78 
79     pa_socket_client *client;
80     pa_pstream *pstream;
81     pa_pdispatch *pdispatch;
82 
83     pa_srbchannel_template srb_template;
84     uint32_t srb_setup_tag;
85 
86     pa_hashmap *record_streams, *playback_streams;
87     PA_LLIST_HEAD(pa_stream, streams);
88     PA_LLIST_HEAD(pa_operation, operations);
89 
90     uint32_t version;
91     uint32_t ctag;
92     uint32_t csyncid;
93     pa_context_error *error;
94     pa_context_state_t state;
95 
96     pa_context_notify_cb_t state_callback;
97     void *state_userdata;
98     pa_context_subscribe_cb_t subscribe_callback;
99     void *subscribe_userdata;
100     pa_context_event_cb_t event_callback;
101     void *event_userdata;
102 
103     pa_mempool *mempool;
104 
105     bool is_local:1;
106     bool do_shm:1;
107     bool memfd_on_local:1;
108     bool server_specified:1;
109     bool no_fail:1;
110     bool do_autospawn:1;
111     bool use_rtclock:1;
112     bool filter_added:1;
113     pa_spawn_api spawn_api;
114 
115     pa_mem_type_t shm_type;
116 
117     pa_strlist *server_list;
118 
119     char *server;
120 
121     pa_client_conf *conf;
122 
123     uint32_t client_index;
124 
125     /* Extension specific data */
126     struct {
127         pa_ext_device_manager_subscribe_cb_t callback;
128         void *userdata;
129     } ext_device_manager;
130     struct {
131         pa_ext_device_restore_subscribe_cb_t callback;
132         void *userdata;
133     } ext_device_restore;
134     struct {
135         pa_ext_stream_restore_subscribe_cb_t callback;
136         void *userdata;
137     } ext_stream_restore;
138 };
139 
140 #define PA_MAX_WRITE_INDEX_CORRECTIONS 32
141 
142 typedef struct pa_index_correction {
143     uint32_t tag;
144     int64_t value;
145     bool valid:1;
146     bool absolute:1;
147     bool corrupt:1;
148 } pa_index_correction;
149 
150 #define PA_MAX_FORMATS (PA_ENCODING_MAX)
151 
152 struct pa_stream {
153     PA_REFCNT_DECLARE;
154     PA_LLIST_FIELDS(pa_stream);
155 
156     pa_context *context;
157     pa_mainloop_api *mainloop;
158 
159     uint32_t direct_on_input;
160 
161     pa_stream_direction_t direction;
162     pa_stream_state_t state;
163     pa_stream_flags_t flags;
164 
165     pa_sample_spec sample_spec;
166     pa_channel_map channel_map;
167     uint8_t n_formats;
168     pa_format_info *req_formats[PA_MAX_FORMATS];
169     pa_format_info *format;
170 
171     pa_proplist *proplist;
172 
173     bool channel_valid:1;
174     bool suspended:1;
175     bool corked:1;
176     bool timing_info_valid:1;
177     bool auto_timing_update_requested:1;
178 
179     uint32_t channel;
180     uint32_t syncid;
181     uint32_t stream_index;
182 
183     int64_t requested_bytes;
184     pa_buffer_attr buffer_attr;
185 
186     uint32_t device_index;
187     char *device_name;
188 
189     /* playback */
190     pa_memblock *write_memblock;
191     void *write_data;
192     int64_t latest_underrun_at_index;
193 
194     /* recording */
195     pa_memchunk peek_memchunk;
196     void *peek_data;
197     pa_memblockq *record_memblockq;
198 
199     /* Store latest latency info */
200     pa_timing_info timing_info;
201 
202     /* Use to make sure that time advances monotonically */
203     pa_usec_t previous_time;
204 
205     /* time updates with tags older than these are invalid */
206     uint32_t write_index_not_before;
207     uint32_t read_index_not_before;
208 
209     /* Data about individual timing update corrections */
210     pa_index_correction write_index_corrections[PA_MAX_WRITE_INDEX_CORRECTIONS];
211     int current_write_index_correction;
212 
213     /* Latency interpolation stuff */
214     pa_time_event *auto_timing_update_event;
215     pa_usec_t auto_timing_interval_usec;
216 
217 #ifdef USE_SMOOTHER_2
218     pa_smoother_2 *smoother;
219 #else
220     pa_smoother *smoother;
221 #endif
222 
223     /* Callbacks */
224     pa_stream_notify_cb_t state_callback;
225     void *state_userdata;
226     pa_stream_request_cb_t read_callback;
227     void *read_userdata;
228     pa_stream_request_cb_t write_callback;
229     void *write_userdata;
230     pa_stream_notify_cb_t overflow_callback;
231     void *overflow_userdata;
232     pa_stream_notify_cb_t underflow_callback;
233     void *underflow_userdata;
234     pa_stream_notify_cb_t latency_update_callback;
235     void *latency_update_userdata;
236     pa_stream_notify_cb_t moved_callback;
237     void *moved_userdata;
238     pa_stream_notify_cb_t suspended_callback;
239     void *suspended_userdata;
240     pa_stream_notify_cb_t started_callback;
241     void *started_userdata;
242     pa_stream_event_cb_t event_callback;
243     void *event_userdata;
244     pa_stream_notify_cb_t buffer_attr_callback;
245     void *buffer_attr_userdata;
246 };
247 
248 typedef void (*pa_operation_cb_t)(void);
249 
250 struct pa_operation {
251     PA_REFCNT_DECLARE;
252 
253     pa_context *context;
254     pa_stream *stream;
255 
256     PA_LLIST_FIELDS(pa_operation);
257 
258     pa_operation_state_t state;
259     void *userdata;
260     pa_operation_cb_t callback;
261     void *state_userdata;
262     pa_operation_notify_cb_t state_callback;
263 
264     void *private; /* some operations might need this */
265 };
266 
267 void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
268 void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
269 void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
270 void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
271 void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
272 void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
273 void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
274 void pa_command_stream_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
275 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
276 void pa_command_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
277 
278 pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t callback, void *userdata);
279 void pa_operation_done(pa_operation *o);
280 
281 void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
282 void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
283 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
284 void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
285 
286 void pa_context_fail(pa_context *c, int error);
287 int pa_context_set_error(const pa_context *c, int error);
288 void pa_context_set_state(pa_context *c, pa_context_state_t st);
289 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail);
290 pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, void (*internal_callback)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata), void (*cb)(void), void *userdata);
291 
292 void pa_stream_set_state(pa_stream *s, pa_stream_state_t st);
293 
294 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag);
295 
296 #define PA_CHECK_VALIDITY(context, expression, error)         \
297     do {                                                      \
298         if (!(expression))                                    \
299             return -pa_context_set_error((context), (error)); \
300     } while(false)
301 
302 #define PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, value) \
303     do {                                                                \
304         if (!(expression)) {                                            \
305             pa_context_set_error((context), (error));                   \
306             return value;                                               \
307         }                                                               \
308     } while(false)
309 
310 #define PA_CHECK_VALIDITY_RETURN_NULL(context, expression, error)       \
311     PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, NULL)
312 
313 #define PA_FAIL(context, error)                                 \
314     do {                                                        \
315         return -pa_context_set_error((context), (error));       \
316     } while(false)
317 
318 #define PA_FAIL_RETURN_ANY(context, error, value)      \
319     do {                                               \
320         pa_context_set_error((context), (error));      \
321         return value;                                  \
322     } while(false)
323 
324 #define PA_FAIL_RETURN_NULL(context, error)     \
325     PA_FAIL_RETURN_ANY(context, error, NULL)
326 
327 void pa_ext_device_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
328 void pa_ext_device_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
329 void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
330 
331 bool pa_mainloop_is_our_api(const pa_mainloop_api*m);
332 
333 #endif
334