xref: /third_party/pulseaudio/src/pulse/internal.h (revision 53a5a1b3)
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
64typedef struct pa_context_error {
65    int error;
66} pa_context_error;
67
68struct 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
142typedef 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
152struct 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
250typedef void (*pa_operation_cb_t)(void);
251
252struct 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
269void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
270void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
271void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
272void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
273void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
274void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
275void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
276void pa_command_stream_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
277void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
278void pa_command_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
279
280pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t callback, void *userdata);
281void pa_operation_done(pa_operation *o);
282
283void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
284void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
285void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
286void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
287
288void pa_context_fail(pa_context *c, int error);
289int pa_context_set_error(const pa_context *c, int error);
290void pa_context_set_state(pa_context *c, pa_context_state_t st);
291int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail);
292pa_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
294void pa_stream_set_state(pa_stream *s, pa_stream_state_t st);
295
296pa_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
329void pa_ext_device_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
330void pa_ext_device_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
331void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
332
333bool pa_mainloop_is_our_api(const pa_mainloop_api*m);
334
335#endif
336