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