• 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     pa_stream_notify_cb_t underflow_ohos_callback;
247     void *underflow_ohos_userdata;
248 };
249 
250 typedef void (*pa_operation_cb_t)(void);
251 
252 struct pa_operation {
253     PA_REFCNT_DECLARE;
254 
255     pa_context *context;
256     pa_stream *stream;
257 
258     PA_LLIST_FIELDS(pa_operation);
259 
260     pa_operation_state_t state;
261     void *userdata;
262     pa_operation_cb_t callback;
263     void *state_userdata;
264     pa_operation_notify_cb_t state_callback;
265 
266     void *private; /* some operations might need this */
267 };
268 
269 void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
270 void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
271 void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
272 void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
273 void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
274 void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
275 void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
276 void pa_command_stream_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
277 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
278 void pa_command_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
279 
280 pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t callback, void *userdata);
281 void pa_operation_done(pa_operation *o);
282 
283 void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
284 void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
285 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
286 void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
287 
288 void pa_context_fail(pa_context *c, int error);
289 int pa_context_set_error(const pa_context *c, int error);
290 void pa_context_set_state(pa_context *c, pa_context_state_t st);
291 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail);
292 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);
293 
294 void pa_stream_set_state(pa_stream *s, pa_stream_state_t st);
295 
296 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag);
297 
298 #define PA_CHECK_VALIDITY(context, expression, error)         \
299     do {                                                      \
300         if (!(expression))                                    \
301             return -pa_context_set_error((context), (error)); \
302     } while(false)
303 
304 #define PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, value) \
305     do {                                                                \
306         if (!(expression)) {                                            \
307             pa_context_set_error((context), (error));                   \
308             return value;                                               \
309         }                                                               \
310     } while(false)
311 
312 #define PA_CHECK_VALIDITY_RETURN_NULL(context, expression, error)       \
313     PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, NULL)
314 
315 #define PA_FAIL(context, error)                                 \
316     do {                                                        \
317         return -pa_context_set_error((context), (error));       \
318     } while(false)
319 
320 #define PA_FAIL_RETURN_ANY(context, error, value)      \
321     do {                                               \
322         pa_context_set_error((context), (error));      \
323         return value;                                  \
324     } while(false)
325 
326 #define PA_FAIL_RETURN_NULL(context, error)     \
327     PA_FAIL_RETURN_ANY(context, error, NULL)
328 
329 void pa_ext_device_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
330 void pa_ext_device_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
331 void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
332 
333 bool pa_mainloop_is_our_api(const pa_mainloop_api*m);
334 
335 #endif
336