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