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