4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2 of the License,
12 or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
32 #include <sys/types.h>
36 #include <pulse/timeval.h>
37 #include <pulse/util.h>
38 #include <pulse/version.h>
39 #include <pulse/xmalloc.h>
41 #include <pulsecore/module.h>
42 #include <pulsecore/core-util.h>
43 #include <pulsecore/modargs.h>
44 #include <pulsecore/log.h>
45 #include <pulsecore/core-subscribe.h>
46 #include <pulsecore/sink-input.h>
47 #include <pulsecore/pdispatch.h>
48 #include <pulsecore/pstream.h>
49 #include <pulsecore/pstream-util.h>
50 #include <pulsecore/authkey.h>
51 #include <pulsecore/socket-client.h>
52 #include <pulsecore/socket-util.h>
53 #include <pulsecore/authkey-prop.h>
54 #include <pulsecore/time-smoother.h>
55 #include <pulsecore/thread.h>
56 #include <pulsecore/thread-mq.h>
57 #include <pulsecore/rtclock.h>
58 #include <pulsecore/core-error.h>
61 #include "module-tunnel-sink-symdef.h"
62 PA_MODULE_DESCRIPTION("Tunnel module for sinks");
63 PA_MODULE_LOAD_ONCE(FALSE
);
66 "sink=<remote sink name> "
68 "format=<sample format> "
69 "channels=<number of channels> "
71 "sink_name=<name for the local sink> "
72 "channel_map=<channel map>");
74 #include "module-tunnel-source-symdef.h"
75 PA_MODULE_DESCRIPTION("Tunnel module for sources");
78 "source=<remote source name> "
80 "format=<sample format> "
81 "channels=<number of channels> "
83 "source_name=<name for the local source> "
84 "channel_map=<channel map>");
87 PA_MODULE_AUTHOR("Lennart Poettering");
88 PA_MODULE_VERSION(PACKAGE_VERSION
);
90 #define DEFAULT_TLENGTH_MSEC 100
91 #define DEFAULT_MINREQ_MSEC 10
92 #define DEFAULT_MAXLENGTH_MSEC ((DEFAULT_TLENGTH_MSEC*3)/2)
93 #define DEFAULT_FRAGSIZE_MSEC 10
95 #define DEFAULT_TIMEOUT 5
97 #define LATENCY_INTERVAL 10
99 static const char* const valid_modargs
[] = {
117 SOURCE_MESSAGE_POST
= PA_SOURCE_MESSAGE_MAX
121 SINK_MESSAGE_REQUEST
= PA_SINK_MESSAGE_MAX
,
126 static void command_request(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
128 static void command_subscribe_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
129 static void command_stream_killed(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
130 static void command_overflow(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
131 static void command_underflow(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
132 static void command_suspend(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
133 static void command_moved(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
);
135 static const pa_pdispatch_cb_t command_table
[PA_COMMAND_MAX
] = {
137 [PA_COMMAND_REQUEST
] = command_request
,
139 [PA_COMMAND_SUBSCRIBE_EVENT
] = command_subscribe_event
,
140 [PA_COMMAND_OVERFLOW
] = command_overflow
,
141 [PA_COMMAND_UNDERFLOW
] = command_underflow
,
142 [PA_COMMAND_PLAYBACK_STREAM_KILLED
] = command_stream_killed
,
143 [PA_COMMAND_RECORD_STREAM_KILLED
] = command_stream_killed
,
144 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
] = command_suspend
,
145 [PA_COMMAND_RECORD_STREAM_SUSPENDED
] = command_suspend
,
146 [PA_COMMAND_PLAYBACK_STREAM_MOVED
] = command_moved
,
147 [PA_COMMAND_RECORD_STREAM_MOVED
] = command_moved
,
154 pa_thread_mq thread_mq
;
158 pa_socket_client
*client
;
160 pa_pdispatch
*pdispatch
;
166 uint32_t requested_bytes
;
172 uint8_t auth_cookie
[PA_NATIVE_COOKIE_LENGTH
];
176 uint32_t device_index
;
179 int64_t counter
, counter_delta
;
181 pa_time_event
*time_event
;
183 pa_bool_t auth_cookie_in_property
;
185 pa_smoother
*smoother
;
187 char *device_description
;
201 static void command_stream_killed(pa_pdispatch
*pd
, PA_GCC_UNUSED
uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
202 struct userdata
*u
= userdata
;
207 pa_assert(u
->pdispatch
== pd
);
209 pa_log_warn("Stream killed");
210 pa_module_unload_request(u
->module
);
213 static void command_overflow(pa_pdispatch
*pd
, PA_GCC_UNUSED
uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
214 struct userdata
*u
= userdata
;
219 pa_assert(u
->pdispatch
== pd
);
221 pa_log_warn("Server signalled buffer overrun.");
224 static void command_underflow(pa_pdispatch
*pd
, PA_GCC_UNUSED
uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
225 struct userdata
*u
= userdata
;
230 pa_assert(u
->pdispatch
== pd
);
232 pa_log_warn("Server signalled buffer underrun.");
235 static void command_suspend(pa_pdispatch
*pd
, PA_GCC_UNUSED
uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
236 struct userdata
*u
= userdata
;
241 pa_assert(u
->pdispatch
== pd
);
243 pa_log_debug("Server reports a stream suspension.");
246 static void command_moved(pa_pdispatch
*pd
, PA_GCC_UNUSED
uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
247 struct userdata
*u
= userdata
;
252 pa_assert(u
->pdispatch
== pd
);
254 pa_log_debug("Server reports a stream move.");
257 static void stream_cork(struct userdata
*u
, pa_bool_t cork
) {
262 pa_smoother_pause(u
->smoother
, pa_rtclock_usec());
264 pa_smoother_resume(u
->smoother
, pa_rtclock_usec());
269 t
= pa_tagstruct_new(NULL
, 0);
271 pa_tagstruct_putu32(t
, PA_COMMAND_CORK_PLAYBACK_STREAM
);
273 pa_tagstruct_putu32(t
, PA_COMMAND_CORK_RECORD_STREAM
);
275 pa_tagstruct_putu32(t
, u
->ctag
++);
276 pa_tagstruct_putu32(t
, u
->channel
);
277 pa_tagstruct_put_boolean(t
, !!cork
);
278 pa_pstream_send_tagstruct(u
->pstream
, t
);
283 static void send_data(struct userdata
*u
) {
286 while (u
->requested_bytes
> 0) {
287 pa_memchunk memchunk
;
288 pa_sink_render(u
->sink
, u
->requested_bytes
, &memchunk
);
289 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->sink
), SINK_MESSAGE_POST
, NULL
, 0, &memchunk
, NULL
);
290 pa_memblock_unref(memchunk
.memblock
);
291 u
->requested_bytes
-= memchunk
.length
;
295 /* This function is called from IO context -- except when it is not. */
296 static int sink_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
297 struct userdata
*u
= PA_SINK(o
)->userdata
;
301 case PA_SINK_MESSAGE_SET_STATE
: {
304 /* First, change the state, because otherwide pa_sink_render() would fail */
305 if ((r
= pa_sink_process_msg(o
, code
, data
, offset
, chunk
)) >= 0)
306 if (PA_SINK_OPENED((pa_sink_state_t
) PA_PTR_TO_UINT(data
)))
312 case SINK_MESSAGE_REQUEST
:
314 pa_assert(offset
> 0);
315 u
->requested_bytes
+= (size_t) offset
;
317 if (PA_SINK_OPENED(u
->sink
->thread_info
.state
))
322 case SINK_MESSAGE_POST
:
324 /* OK, This might be a bit confusing. This message is
325 * delivered to us from the main context -- NOT from the
326 * IO thread context where the rest of the messages are
327 * dispatched. Yeah, ugly, but I am a lazy bastard. */
329 pa_pstream_send_memblock(u
->pstream
, u
->channel
, 0, PA_SEEK_RELATIVE
, chunk
);
330 u
->counter
+= chunk
->length
;
331 u
->counter_delta
+= chunk
->length
;
335 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
338 static int sink_set_state(pa_sink
*s
, pa_sink_state_t state
) {
340 pa_sink_assert_ref(s
);
343 switch ((pa_sink_state_t
) state
) {
345 case PA_SINK_SUSPENDED
:
346 pa_assert(PA_SINK_OPENED(s
->state
));
347 stream_cork(u
, TRUE
);
351 case PA_SINK_RUNNING
:
352 if (s
->state
== PA_SINK_SUSPENDED
)
353 stream_cork(u
, FALSE
);
356 case PA_SINK_UNLINKED
:
366 static int source_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
367 struct userdata
*u
= PA_SOURCE(o
)->userdata
;
370 case SOURCE_MESSAGE_POST
:
372 if (PA_SOURCE_OPENED(u
->source
->thread_info
.state
))
373 pa_source_post(u
->source
, chunk
);
377 return pa_source_process_msg(o
, code
, data
, offset
, chunk
);
380 static int source_set_state(pa_source
*s
, pa_source_state_t state
) {
382 pa_source_assert_ref(s
);
385 switch ((pa_source_state_t
) state
) {
387 case PA_SOURCE_SUSPENDED
:
388 pa_assert(PA_SOURCE_OPENED(s
->state
));
389 stream_cork(u
, TRUE
);
393 case PA_SOURCE_RUNNING
:
394 if (s
->state
== PA_SOURCE_SUSPENDED
)
395 stream_cork(u
, FALSE
);
398 case PA_SOURCE_UNLINKED
:
408 static void thread_func(void *userdata
) {
409 struct userdata
*u
= userdata
;
413 pa_log_debug("Thread starting up");
415 pa_thread_mq_install(&u
->thread_mq
);
416 pa_rtpoll_install(u
->rtpoll
);
421 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0)
429 /* If this was no regular exit from the loop we have to continue
430 * processing messages until we received PA_MESSAGE_SHUTDOWN */
431 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->core
), PA_CORE_MESSAGE_UNLOAD_MODULE
, u
->module
, 0, NULL
, NULL
);
432 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
435 pa_log_debug("Thread shutting down");
439 static void command_request(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
440 struct userdata
*u
= userdata
;
441 uint32_t bytes
, channel
;
444 pa_assert(command
== PA_COMMAND_REQUEST
);
447 pa_assert(u
->pdispatch
== pd
);
449 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
450 pa_tagstruct_getu32(t
, &bytes
) < 0) {
451 pa_log("Invalid protocol reply");
455 if (channel
!= u
->channel
) {
456 pa_log("Recieved data for invalid channel");
460 pa_asyncmsgq_send(u
->sink
->asyncmsgq
, PA_MSGOBJECT(u
->sink
), SINK_MESSAGE_REQUEST
, NULL
, bytes
, NULL
);
464 pa_module_unload_request(u
->module
);
469 static void stream_get_latency_callback(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
470 struct userdata
*u
= userdata
;
471 pa_usec_t sink_usec
, source_usec
, transport_usec
, host_usec
, k
;
473 int64_t write_index
, read_index
;
474 struct timeval local
, remote
, now
;
479 if (command
!= PA_COMMAND_REPLY
) {
480 if (command
== PA_COMMAND_ERROR
)
481 pa_log("Failed to get latency.");
483 pa_log("Protocol error 1.");
487 if (pa_tagstruct_get_usec(t
, &sink_usec
) < 0 ||
488 pa_tagstruct_get_usec(t
, &source_usec
) < 0 ||
489 pa_tagstruct_get_boolean(t
, &playing
) < 0 ||
490 pa_tagstruct_get_timeval(t
, &local
) < 0 ||
491 pa_tagstruct_get_timeval(t
, &remote
) < 0 ||
492 pa_tagstruct_gets64(t
, &write_index
) < 0 ||
493 pa_tagstruct_gets64(t
, &read_index
) < 0) {
494 pa_log("Invalid reply. (latency)");
498 pa_gettimeofday(&now
);
500 if (pa_timeval_cmp(&local
, &remote
) < 0 && pa_timeval_cmp(&remote
, &now
)) {
501 /* local and remote seem to have synchronized clocks */
503 transport_usec
= pa_timeval_diff(&remote
, &local
);
505 transport_usec
= pa_timeval_diff(&now
, &remote
);
508 transport_usec
= pa_timeval_diff(&now
, &local
)/2;
511 host_usec
= sink_usec
+ transport_usec
;
513 host_usec
= source_usec
+ transport_usec
;
514 if (host_usec
> sink_usec
)
515 host_usec
-= sink_usec
;
521 k
= pa_bytes_to_usec(u
->counter
- u
->counter_delta
, &u
->sink
->sample_spec
);
528 k
= pa_bytes_to_usec(u
->counter
- u
->counter_delta
, &u
->source
->sample_spec
);
532 pa_smoother_put(u
->smoother
, pa_rtclock_usec(), k
);
537 pa_module_unload_request(u
->module
);
540 static void request_latency(struct userdata
*u
) {
546 t
= pa_tagstruct_new(NULL
, 0);
548 pa_tagstruct_putu32(t
, PA_COMMAND_GET_PLAYBACK_LATENCY
);
550 pa_tagstruct_putu32(t
, PA_COMMAND_GET_RECORD_LATENCY
);
552 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
553 pa_tagstruct_putu32(t
, u
->channel
);
555 pa_gettimeofday(&now
);
556 pa_tagstruct_put_timeval(t
, &now
);
558 pa_pstream_send_tagstruct(u
->pstream
, t
);
559 pa_pdispatch_register_reply(u
->pdispatch
, tag
, DEFAULT_TIMEOUT
, stream_get_latency_callback
, u
, NULL
);
561 u
->counter_delta
= 0;
564 static void timeout_callback(pa_mainloop_api
*m
, pa_time_event
*e
, PA_GCC_UNUSED
const struct timeval
*tv
, void *userdata
) {
565 struct userdata
*u
= userdata
;
574 pa_gettimeofday(&ntv
);
575 ntv
.tv_sec
+= LATENCY_INTERVAL
;
576 m
->time_restart(e
, &ntv
);
580 static pa_usec_t
sink_get_latency(pa_sink
*s
) {
582 struct userdata
*u
= s
->userdata
;
584 pa_sink_assert_ref(s
);
586 c
= pa_bytes_to_usec(u
->counter
, &s
->sample_spec
);
587 t
= pa_smoother_get(u
->smoother
, pa_rtclock_usec());
589 return c
> t
? c
- t
: 0;
592 static pa_usec_t
source_get_latency(pa_source
*s
) {
594 struct userdata
*u
= s
->userdata
;
596 pa_source_assert_ref(s
);
598 c
= pa_bytes_to_usec(u
->counter
, &s
->sample_spec
);
599 t
= pa_smoother_get(u
->smoother
, pa_rtclock_usec());
601 return t
> c
? t
- c
: 0;
605 static void update_description(struct userdata
*u
) {
607 char un
[128], hn
[128];
612 if (!u
->server_fqdn
|| !u
->user_name
|| !u
->device_description
)
615 d
= pa_sprintf_malloc("%s on %s@%s", u
->device_description
, u
->user_name
, u
->server_fqdn
);
618 pa_sink_set_description(u
->sink
, d
);
620 pa_source_set_description(u
->source
, d
);
625 d
= pa_sprintf_malloc("%s for %s@%s", u
->device_description
,
626 pa_get_user_name(un
, sizeof(un
)),
627 pa_get_host_name(hn
, sizeof(hn
)));
629 t
= pa_tagstruct_new(NULL
, 0);
631 pa_tagstruct_putu32(t
, PA_COMMAND_SET_PLAYBACK_STREAM_NAME
);
633 pa_tagstruct_putu32(t
, PA_COMMAND_SET_RECORD_STREAM_NAME
);
635 pa_tagstruct_putu32(t
, u
->ctag
++);
636 pa_tagstruct_putu32(t
, u
->channel
);
637 pa_tagstruct_puts(t
, d
);
638 pa_pstream_send_tagstruct(u
->pstream
, t
);
643 static void server_info_cb(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
644 struct userdata
*u
= userdata
;
646 const char *server_name
, *server_version
, *user_name
, *host_name
, *default_sink_name
, *default_source_name
;
652 if (command
!= PA_COMMAND_REPLY
) {
653 if (command
== PA_COMMAND_ERROR
)
654 pa_log("Failed to get info.");
656 pa_log("Protocol error 6.");
660 if (pa_tagstruct_gets(t
, &server_name
) < 0 ||
661 pa_tagstruct_gets(t
, &server_version
) < 0 ||
662 pa_tagstruct_gets(t
, &user_name
) < 0 ||
663 pa_tagstruct_gets(t
, &host_name
) < 0 ||
664 pa_tagstruct_get_sample_spec(t
, &ss
) < 0 ||
665 pa_tagstruct_gets(t
, &default_sink_name
) < 0 ||
666 pa_tagstruct_gets(t
, &default_source_name
) < 0 ||
667 pa_tagstruct_getu32(t
, &cookie
) < 0) {
668 pa_log("Invalid reply. (get_server_info)");
672 pa_xfree(u
->server_fqdn
);
673 u
->server_fqdn
= pa_xstrdup(host_name
);
675 pa_xfree(u
->user_name
);
676 u
->user_name
= pa_xstrdup(user_name
);
678 update_description(u
);
683 pa_module_unload_request(u
->module
);
688 static void sink_info_cb(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
689 struct userdata
*u
= userdata
;
690 uint32_t idx
, owner_module
, monitor_source
, flags
;
691 const char *name
, *description
, *monitor_source_name
, *driver
;
701 if (command
!= PA_COMMAND_REPLY
) {
702 if (command
== PA_COMMAND_ERROR
)
703 pa_log("Failed to get info.");
705 pa_log("Protocol error 5.");
709 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
710 pa_tagstruct_gets(t
, &name
) < 0 ||
711 pa_tagstruct_gets(t
, &description
) < 0 ||
712 pa_tagstruct_get_sample_spec(t
, &ss
) < 0 ||
713 pa_tagstruct_get_channel_map(t
, &cm
) < 0 ||
714 pa_tagstruct_getu32(t
, &owner_module
) < 0 ||
715 pa_tagstruct_get_cvolume(t
, &volume
) < 0 ||
716 pa_tagstruct_get_boolean(t
, &mute
) < 0 ||
717 pa_tagstruct_getu32(t
, &monitor_source
) < 0 ||
718 pa_tagstruct_gets(t
, &monitor_source_name
) < 0 ||
719 pa_tagstruct_get_usec(t
, &latency
) < 0 ||
720 pa_tagstruct_gets(t
, &driver
) < 0 ||
721 pa_tagstruct_getu32(t
, &flags
) < 0) {
722 pa_log("Invalid reply. (get_sink_info)");
726 if (strcmp(name
, u
->sink_name
))
729 pa_xfree(u
->device_description
);
730 u
->device_description
= pa_xstrdup(description
);
732 update_description(u
);
737 pa_module_unload_request(u
->module
);
740 static void sink_input_info_cb(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
741 struct userdata
*u
= userdata
;
742 uint32_t idx
, owner_module
, client
, sink
;
743 pa_usec_t buffer_usec
, sink_usec
;
744 const char *name
, *driver
, *resample_method
;
746 pa_sample_spec sample_spec
;
747 pa_channel_map channel_map
;
753 if (command
!= PA_COMMAND_REPLY
) {
754 if (command
== PA_COMMAND_ERROR
)
755 pa_log("Failed to get info.");
757 pa_log("Protocol error 2.");
761 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
762 pa_tagstruct_gets(t
, &name
) < 0 ||
763 pa_tagstruct_getu32(t
, &owner_module
) < 0 ||
764 pa_tagstruct_getu32(t
, &client
) < 0 ||
765 pa_tagstruct_getu32(t
, &sink
) < 0 ||
766 pa_tagstruct_get_sample_spec(t
, &sample_spec
) < 0 ||
767 pa_tagstruct_get_channel_map(t
, &channel_map
) < 0 ||
768 pa_tagstruct_get_cvolume(t
, &volume
) < 0 ||
769 pa_tagstruct_get_usec(t
, &buffer_usec
) < 0 ||
770 pa_tagstruct_get_usec(t
, &sink_usec
) < 0 ||
771 pa_tagstruct_gets(t
, &resample_method
) < 0 ||
772 pa_tagstruct_gets(t
, &driver
) < 0 ||
773 (u
->version
>= 11 && pa_tagstruct_get_boolean(t
, &mute
) < 0)) {
774 pa_log("Invalid reply. (get_info)");
778 if (idx
!= u
->device_index
)
783 if ((u
->version
< 11 || !!mute
== !!u
->sink
->muted
) &&
784 pa_cvolume_equal(&volume
, &u
->sink
->volume
))
787 memcpy(&u
->sink
->volume
, &volume
, sizeof(pa_cvolume
));
789 if (u
->version
>= 11)
790 u
->sink
->muted
= !!mute
;
792 pa_subscription_post(u
->sink
->core
, PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
, u
->sink
->index
);
796 pa_module_unload_request(u
->module
);
801 static void source_info_cb(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
802 struct userdata
*u
= userdata
;
803 uint32_t idx
, owner_module
, monitor_of_sink
, flags
;
804 const char *name
, *description
, *monitor_of_sink_name
, *driver
;
814 if (command
!= PA_COMMAND_REPLY
) {
815 if (command
== PA_COMMAND_ERROR
)
816 pa_log("Failed to get info.");
818 pa_log("Protocol error 5.");
822 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
823 pa_tagstruct_gets(t
, &name
) < 0 ||
824 pa_tagstruct_gets(t
, &description
) < 0 ||
825 pa_tagstruct_get_sample_spec(t
, &ss
) < 0 ||
826 pa_tagstruct_get_channel_map(t
, &cm
) < 0 ||
827 pa_tagstruct_getu32(t
, &owner_module
) < 0 ||
828 pa_tagstruct_get_cvolume(t
, &volume
) < 0 ||
829 pa_tagstruct_get_boolean(t
, &mute
) < 0 ||
830 pa_tagstruct_getu32(t
, &monitor_of_sink
) < 0 ||
831 pa_tagstruct_gets(t
, &monitor_of_sink_name
) < 0 ||
832 pa_tagstruct_get_usec(t
, &latency
) < 0 ||
833 pa_tagstruct_gets(t
, &driver
) < 0 ||
834 pa_tagstruct_getu32(t
, &flags
) < 0) {
835 pa_log("Invalid reply. (get_source_info)");
839 if (strcmp(name
, u
->source_name
))
842 pa_xfree(u
->device_description
);
843 u
->device_description
= pa_xstrdup(description
);
845 update_description(u
);
850 pa_module_unload_request(u
->module
);
855 static void request_info(struct userdata
*u
) {
860 t
= pa_tagstruct_new(NULL
, 0);
861 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SERVER_INFO
);
862 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
863 pa_pstream_send_tagstruct(u
->pstream
, t
);
864 pa_pdispatch_register_reply(u
->pdispatch
, tag
, DEFAULT_TIMEOUT
, server_info_cb
, u
, NULL
);
867 t
= pa_tagstruct_new(NULL
, 0);
868 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SINK_INPUT_INFO
);
869 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
870 pa_tagstruct_putu32(t
, u
->device_index
);
871 pa_pstream_send_tagstruct(u
->pstream
, t
);
872 pa_pdispatch_register_reply(u
->pdispatch
, tag
, DEFAULT_TIMEOUT
, sink_input_info_cb
, u
, NULL
);
874 t
= pa_tagstruct_new(NULL
, 0);
875 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SINK_INFO
);
876 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
877 pa_tagstruct_putu32(t
, PA_INVALID_INDEX
);
878 pa_tagstruct_puts(t
, u
->sink_name
);
879 pa_pstream_send_tagstruct(u
->pstream
, t
);
880 pa_pdispatch_register_reply(u
->pdispatch
, tag
, DEFAULT_TIMEOUT
, sink_info_cb
, u
, NULL
);
882 t
= pa_tagstruct_new(NULL
, 0);
883 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SOURCE_INFO
);
884 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
885 pa_tagstruct_putu32(t
, PA_INVALID_INDEX
);
886 pa_tagstruct_puts(t
, u
->source_name
);
887 pa_pstream_send_tagstruct(u
->pstream
, t
);
888 pa_pdispatch_register_reply(u
->pdispatch
, tag
, DEFAULT_TIMEOUT
, source_info_cb
, u
, NULL
);
892 static void command_subscribe_event(pa_pdispatch
*pd
, PA_GCC_UNUSED
uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
893 struct userdata
*u
= userdata
;
894 pa_subscription_event_type_t e
;
900 pa_assert(command
== PA_COMMAND_SUBSCRIBE_EVENT
);
902 if (pa_tagstruct_getu32(t
, &e
) < 0 ||
903 pa_tagstruct_getu32(t
, &idx
) < 0) {
904 pa_log("Invalid protocol reply");
905 pa_module_unload_request(u
->module
);
909 if (e
!= (PA_SUBSCRIPTION_EVENT_SERVER
|PA_SUBSCRIPTION_EVENT_CHANGE
) &&
911 e
!= (PA_SUBSCRIPTION_EVENT_SINK_INPUT
|PA_SUBSCRIPTION_EVENT_CHANGE
) &&
912 e
!= (PA_SUBSCRIPTION_EVENT_SINK
|PA_SUBSCRIPTION_EVENT_CHANGE
)
914 e
!= (PA_SUBSCRIPTION_EVENT_SOURCE
|PA_SUBSCRIPTION_EVENT_CHANGE
)
922 static void start_subscribe(struct userdata
*u
) {
927 t
= pa_tagstruct_new(NULL
, 0);
928 pa_tagstruct_putu32(t
, PA_COMMAND_SUBSCRIBE
);
929 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
930 pa_tagstruct_putu32(t
, PA_SUBSCRIPTION_MASK_SERVER
|
932 PA_SUBSCRIPTION_MASK_SINK_INPUT
|PA_SUBSCRIPTION_MASK_SINK
934 PA_SUBSCRIPTION_MASK_SOURCE
938 pa_pstream_send_tagstruct(u
->pstream
, t
);
941 static void create_stream_callback(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
942 struct userdata
*u
= userdata
;
950 pa_assert(u
->pdispatch
== pd
);
952 if (command
!= PA_COMMAND_REPLY
) {
953 if (command
== PA_COMMAND_ERROR
)
954 pa_log("Failed to create stream.");
956 pa_log("Protocol error 3.");
960 if (pa_tagstruct_getu32(t
, &u
->channel
) < 0 ||
961 pa_tagstruct_getu32(t
, &u
->device_index
) < 0
963 || pa_tagstruct_getu32(t
, &bytes
) < 0
968 if (u
->version
>= 9) {
970 uint32_t maxlength
, tlength
, prebuf
, minreq
;
972 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
973 pa_tagstruct_getu32(t
, &tlength
) < 0 ||
974 pa_tagstruct_getu32(t
, &prebuf
) < 0 ||
975 pa_tagstruct_getu32(t
, &minreq
) < 0)
978 uint32_t maxlength
, fragsize
;
980 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
981 pa_tagstruct_getu32(t
, &fragsize
) < 0)
989 pa_assert(!u
->time_event
);
990 pa_gettimeofday(&ntv
);
991 ntv
.tv_sec
+= LATENCY_INTERVAL
;
992 u
->time_event
= u
->core
->mainloop
->time_new(u
->core
->mainloop
, &ntv
, timeout_callback
, u
);
996 pa_log_debug("Stream created.");
999 pa_asyncmsgq_post(u
->sink
->asyncmsgq
, PA_MSGOBJECT(u
->sink
), SINK_MESSAGE_REQUEST
, NULL
, bytes
, NULL
, NULL
);
1005 pa_log("Invalid reply. (Create stream)");
1008 pa_module_unload_request(u
->module
);
1011 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1012 struct userdata
*u
= userdata
;
1013 pa_tagstruct
*reply
;
1014 char name
[256], un
[128], hn
[128];
1021 pa_assert(u
->pdispatch
== pd
);
1023 if (command
!= PA_COMMAND_REPLY
||
1024 pa_tagstruct_getu32(t
, &u
->version
) < 0) {
1025 if (command
== PA_COMMAND_ERROR
)
1026 pa_log("Failed to authenticate");
1028 pa_log("Protocol error 4.");
1033 /* Minimum supported protocol version */
1034 if (u
->version
< 8) {
1035 pa_log("Incompatible protocol version");
1040 pa_snprintf(name
, sizeof(name
), "%s for %s@%s",
1042 pa_get_user_name(un
, sizeof(un
)),
1043 pa_get_host_name(hn
, sizeof(hn
)));
1045 pa_snprintf(name
, sizeof(name
), "%s for %s@%s",
1047 pa_get_user_name(un
, sizeof(un
)),
1048 pa_get_host_name(hn
, sizeof(hn
)));
1051 reply
= pa_tagstruct_new(NULL
, 0);
1052 pa_tagstruct_putu32(reply
, PA_COMMAND_SET_CLIENT_NAME
);
1053 pa_tagstruct_putu32(reply
, tag
= u
->ctag
++);
1054 pa_tagstruct_puts(reply
, "PulseAudio");
1055 pa_pstream_send_tagstruct(u
->pstream
, reply
);
1056 /* We ignore the server's reply here */
1058 reply
= pa_tagstruct_new(NULL
, 0);
1061 pa_tagstruct_putu32(reply
, PA_COMMAND_CREATE_PLAYBACK_STREAM
);
1062 pa_tagstruct_putu32(reply
, tag
= u
->ctag
++);
1063 pa_tagstruct_puts(reply
, name
);
1064 pa_tagstruct_put_sample_spec(reply
, &u
->sink
->sample_spec
);
1065 pa_tagstruct_put_channel_map(reply
, &u
->sink
->channel_map
);
1066 pa_tagstruct_putu32(reply
, PA_INVALID_INDEX
);
1067 pa_tagstruct_puts(reply
, u
->sink_name
);
1068 pa_tagstruct_putu32(reply
, u
->maxlength
);
1069 pa_tagstruct_put_boolean(reply
, !PA_SINK_OPENED(pa_sink_get_state(u
->sink
)));
1070 pa_tagstruct_putu32(reply
, u
->tlength
);
1071 pa_tagstruct_putu32(reply
, u
->prebuf
);
1072 pa_tagstruct_putu32(reply
, u
->minreq
);
1073 pa_tagstruct_putu32(reply
, 0);
1074 pa_cvolume_reset(&volume
, u
->sink
->sample_spec
.channels
);
1075 pa_tagstruct_put_cvolume(reply
, &volume
);
1077 pa_tagstruct_putu32(reply
, PA_COMMAND_CREATE_RECORD_STREAM
);
1078 pa_tagstruct_putu32(reply
, tag
= u
->ctag
++);
1079 pa_tagstruct_puts(reply
, name
);
1080 pa_tagstruct_put_sample_spec(reply
, &u
->source
->sample_spec
);
1081 pa_tagstruct_put_channel_map(reply
, &u
->source
->channel_map
);
1082 pa_tagstruct_putu32(reply
, PA_INVALID_INDEX
);
1083 pa_tagstruct_puts(reply
, u
->source_name
);
1084 pa_tagstruct_putu32(reply
, u
->maxlength
);
1085 pa_tagstruct_put_boolean(reply
, !PA_SOURCE_OPENED(pa_source_get_state(u
->source
)));
1086 pa_tagstruct_putu32(reply
, u
->fragsize
);
1089 /* New flags added in 0.9.8 */
1090 if (u
->version
>= 12) {
1091 /* TODO: set these to useful values */
1092 pa_tagstruct_put_boolean(reply
, FALSE
); /*no_remap*/
1093 pa_tagstruct_put_boolean(reply
, FALSE
); /*no_remix*/
1094 pa_tagstruct_put_boolean(reply
, FALSE
); /*fix_format*/
1095 pa_tagstruct_put_boolean(reply
, FALSE
); /*fix_rate*/
1096 pa_tagstruct_put_boolean(reply
, FALSE
); /*fix_channels*/
1097 pa_tagstruct_put_boolean(reply
, FALSE
); /*no_move*/
1098 pa_tagstruct_put_boolean(reply
, FALSE
); /*variable_rate*/
1101 pa_pstream_send_tagstruct(u
->pstream
, reply
);
1102 pa_pdispatch_register_reply(u
->pdispatch
, tag
, DEFAULT_TIMEOUT
, create_stream_callback
, u
, NULL
);
1104 pa_log_debug("Connection authenticated, creating stream ...");
1109 pa_module_unload_request(u
->module
);
1112 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
1113 struct userdata
*u
= userdata
;
1118 pa_log_warn("Stream died.");
1119 pa_module_unload_request(u
->module
);
1122 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
1123 struct userdata
*u
= userdata
;
1129 if (pa_pdispatch_run(u
->pdispatch
, packet
, creds
, u
) < 0) {
1130 pa_log("Invalid packet");
1131 pa_module_unload_request(u
->module
);
1137 static void pstream_memblock_callback(pa_pstream
*p
, uint32_t channel
, int64_t offset
, pa_seek_mode_t seek
, const pa_memchunk
*chunk
, void *userdata
) {
1138 struct userdata
*u
= userdata
;
1144 if (channel
!= u
->channel
) {
1145 pa_log("Recieved memory block on bad channel.");
1146 pa_module_unload_request(u
->module
);
1150 pa_asyncmsgq_send(u
->source
->asyncmsgq
, PA_MSGOBJECT(u
->source
), SOURCE_MESSAGE_POST
, PA_UINT_TO_PTR(seek
), offset
, chunk
);
1152 u
->counter
+= chunk
->length
;
1153 u
->counter_delta
+= chunk
->length
;
1158 static void on_connection(pa_socket_client
*sc
, pa_iochannel
*io
, void *userdata
) {
1159 struct userdata
*u
= userdata
;
1165 pa_assert(u
->client
== sc
);
1167 pa_socket_client_unref(u
->client
);
1171 pa_log("Connection failed: %s", pa_cstrerror(errno
));
1172 pa_module_unload_request(u
->module
);
1176 u
->pstream
= pa_pstream_new(u
->core
->mainloop
, io
, u
->core
->mempool
);
1177 u
->pdispatch
= pa_pdispatch_new(u
->core
->mainloop
, command_table
, PA_COMMAND_MAX
);
1179 pa_pstream_set_die_callback(u
->pstream
, pstream_die_callback
, u
);
1180 pa_pstream_set_recieve_packet_callback(u
->pstream
, pstream_packet_callback
, u
);
1182 pa_pstream_set_recieve_memblock_callback(u
->pstream
, pstream_memblock_callback
, u
);
1185 t
= pa_tagstruct_new(NULL
, 0);
1186 pa_tagstruct_putu32(t
, PA_COMMAND_AUTH
);
1187 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
1188 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
);
1189 pa_tagstruct_put_arbitrary(t
, u
->auth_cookie
, sizeof(u
->auth_cookie
));
1195 if (pa_iochannel_creds_supported(io
))
1196 pa_iochannel_creds_enable(io
);
1198 ucred
.uid
= getuid();
1199 ucred
.gid
= getgid();
1201 pa_pstream_send_tagstruct_with_creds(u
->pstream
, t
, &ucred
);
1204 pa_pstream_send_tagstruct(u
->pstream
, t
);
1207 pa_pdispatch_register_reply(u
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, u
, NULL
);
1209 pa_log_debug("Connection established, authenticating ...");
1214 static int sink_get_volume(pa_sink
*sink
) {
1218 static int sink_set_volume(pa_sink
*sink
) {
1227 t
= pa_tagstruct_new(NULL
, 0);
1228 pa_tagstruct_putu32(t
, PA_COMMAND_SET_SINK_INPUT_VOLUME
);
1229 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
1230 pa_tagstruct_putu32(t
, u
->device_index
);
1231 pa_tagstruct_put_cvolume(t
, &sink
->volume
);
1232 pa_pstream_send_tagstruct(u
->pstream
, t
);
1237 static int sink_get_mute(pa_sink
*sink
) {
1241 static int sink_set_mute(pa_sink
*sink
) {
1250 if (u
->version
< 11)
1253 t
= pa_tagstruct_new(NULL
, 0);
1254 pa_tagstruct_putu32(t
, PA_COMMAND_SET_SINK_INPUT_MUTE
);
1255 pa_tagstruct_putu32(t
, tag
= u
->ctag
++);
1256 pa_tagstruct_putu32(t
, u
->device_index
);
1257 pa_tagstruct_put_boolean(t
, !!sink
->muted
);
1258 pa_pstream_send_tagstruct(u
->pstream
, t
);
1265 static int load_key(struct userdata
*u
, const char*fn
) {
1268 u
->auth_cookie_in_property
= FALSE
;
1270 if (!fn
&& pa_authkey_prop_get(u
->core
, PA_NATIVE_COOKIE_PROPERTY_NAME
, u
->auth_cookie
, sizeof(u
->auth_cookie
)) >= 0) {
1271 pa_log_debug("Using already loaded auth cookie.");
1272 pa_authkey_prop_ref(u
->core
, PA_NATIVE_COOKIE_PROPERTY_NAME
);
1273 u
->auth_cookie_in_property
= 1;
1278 fn
= PA_NATIVE_COOKIE_FILE
;
1280 if (pa_authkey_load_auto(fn
, u
->auth_cookie
, sizeof(u
->auth_cookie
)) < 0)
1283 pa_log_debug("Loading cookie from disk.");
1285 if (pa_authkey_prop_put(u
->core
, PA_NATIVE_COOKIE_PROPERTY_NAME
, u
->auth_cookie
, sizeof(u
->auth_cookie
)) >= 0)
1286 u
->auth_cookie_in_property
= TRUE
;
1291 int pa__init(pa_module
*m
) {
1292 pa_modargs
*ma
= NULL
;
1293 struct userdata
*u
= NULL
;
1296 char *t
, *dn
= NULL
;
1300 if (!(ma
= pa_modargs_new(m
->argument
, valid_modargs
))) {
1301 pa_log("failed to parse module arguments");
1305 u
= pa_xnew0(struct userdata
, 1);
1310 u
->pdispatch
= NULL
;
1312 u
->server_name
= NULL
;
1314 u
->sink_name
= pa_xstrdup(pa_modargs_get_value(ma
, "sink", NULL
));;
1316 u
->requested_bytes
= 0;
1318 u
->source_name
= pa_xstrdup(pa_modargs_get_value(ma
, "source", NULL
));;
1321 u
->smoother
= pa_smoother_new(PA_USEC_PER_SEC
, PA_USEC_PER_SEC
*2, TRUE
);
1323 u
->device_index
= u
->channel
= PA_INVALID_INDEX
;
1324 u
->auth_cookie_in_property
= FALSE
;
1325 u
->time_event
= NULL
;
1327 pa_thread_mq_init(&u
->thread_mq
, m
->core
->mainloop
);
1328 u
->rtpoll
= pa_rtpoll_new();
1329 pa_rtpoll_item_new_asyncmsgq(u
->rtpoll
, PA_RTPOLL_EARLY
, u
->thread_mq
.inq
);
1331 if (load_key(u
, pa_modargs_get_value(ma
, "cookie", NULL
)) < 0)
1334 if (!(u
->server_name
= pa_xstrdup(pa_modargs_get_value(ma
, "server", NULL
)))) {
1335 pa_log("no server specified.");
1339 ss
= m
->core
->default_sample_spec
;
1340 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_DEFAULT
) < 0) {
1341 pa_log("invalid sample format specification");
1345 if (!(u
->client
= pa_socket_client_new_string(m
->core
->mainloop
, u
->server_name
, PA_NATIVE_DEFAULT_PORT
))) {
1346 pa_log("failed to connect to server '%s'", u
->server_name
);
1350 pa_socket_client_set_callback(u
->client
, on_connection
, u
);
1354 if (!(dn
= pa_xstrdup(pa_modargs_get_value(ma
, "sink_name", NULL
))))
1355 dn
= pa_sprintf_malloc("tunnel.%s", u
->server_name
);
1357 if (!(u
->sink
= pa_sink_new(m
->core
, __FILE__
, dn
, 1, &ss
, &map
))) {
1358 pa_log("Failed to create sink.");
1362 u
->sink
->parent
.process_msg
= sink_process_msg
;
1363 u
->sink
->userdata
= u
;
1364 u
->sink
->set_state
= sink_set_state
;
1365 u
->sink
->get_latency
= sink_get_latency
;
1366 u
->sink
->get_volume
= sink_get_volume
;
1367 u
->sink
->get_mute
= sink_get_mute
;
1368 u
->sink
->set_volume
= sink_set_volume
;
1369 u
->sink
->set_mute
= sink_set_mute
;
1370 u
->sink
->flags
= PA_SINK_NETWORK
|PA_SINK_LATENCY
|PA_SINK_HW_VOLUME_CTRL
;
1372 pa_sink_set_module(u
->sink
, m
);
1373 pa_sink_set_asyncmsgq(u
->sink
, u
->thread_mq
.inq
);
1374 pa_sink_set_rtpoll(u
->sink
, u
->rtpoll
);
1375 pa_sink_set_description(u
->sink
, t
= pa_sprintf_malloc("%s%s%s", u
->sink_name
? u
->sink_name
: "", u
->sink_name
? " on " : "", u
->server_name
));
1380 if (!(dn
= pa_xstrdup(pa_modargs_get_value(ma
, "source_name", NULL
))))
1381 dn
= pa_sprintf_malloc("tunnel.%s", u
->server_name
);
1383 if (!(u
->source
= pa_source_new(m
->core
, __FILE__
, dn
, 1, &ss
, &map
))) {
1384 pa_log("Failed to create source.");
1388 u
->source
->parent
.process_msg
= source_process_msg
;
1389 u
->source
->userdata
= u
;
1390 u
->source
->set_state
= source_set_state
;
1391 u
->source
->get_latency
= source_get_latency
;
1392 u
->source
->flags
= PA_SOURCE_NETWORK
|PA_SOURCE_LATENCY
;
1394 pa_source_set_module(u
->source
, m
);
1395 pa_source_set_asyncmsgq(u
->source
, u
->thread_mq
.inq
);
1396 pa_source_set_rtpoll(u
->source
, u
->rtpoll
);
1397 pa_source_set_description(u
->source
, t
= pa_sprintf_malloc("%s%s%s", u
->source_name
? u
->source_name
: "", u
->source_name
? " on " : "", u
->server_name
));
1403 u
->time_event
= NULL
;
1405 u
->maxlength
= pa_usec_to_bytes(PA_USEC_PER_MSEC
* DEFAULT_MAXLENGTH_MSEC
, &ss
);
1407 u
->tlength
= pa_usec_to_bytes(PA_USEC_PER_MSEC
* DEFAULT_TLENGTH_MSEC
, &ss
);
1408 u
->minreq
= pa_usec_to_bytes(PA_USEC_PER_MSEC
* DEFAULT_MINREQ_MSEC
, &ss
);
1409 u
->prebuf
= u
->tlength
;
1411 u
->fragsize
= pa_usec_to_bytes(PA_USEC_PER_MSEC
* DEFAULT_FRAGSIZE_MSEC
, &ss
);
1414 u
->counter
= u
->counter_delta
= 0;
1415 pa_smoother_set_time_offset(u
->smoother
, pa_rtclock_usec());
1417 if (!(u
->thread
= pa_thread_new(thread_func
, u
))) {
1418 pa_log("Failed to create thread.");
1423 pa_sink_put(u
->sink
);
1425 pa_source_put(u
->source
);
1428 pa_modargs_free(ma
);
1436 pa_modargs_free(ma
);
1443 void pa__done(pa_module
*m
) {
1448 if (!(u
= m
->userdata
))
1453 pa_sink_unlink(u
->sink
);
1456 pa_source_unlink(u
->source
);
1460 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
1461 pa_thread_free(u
->thread
);
1464 pa_thread_mq_done(&u
->thread_mq
);
1468 pa_sink_unref(u
->sink
);
1471 pa_source_unref(u
->source
);
1475 pa_rtpoll_free(u
->rtpoll
);
1478 pa_pstream_unlink(u
->pstream
);
1479 pa_pstream_unref(u
->pstream
);
1483 pa_pdispatch_unref(u
->pdispatch
);
1486 pa_socket_client_unref(u
->client
);
1488 if (u
->auth_cookie_in_property
)
1489 pa_authkey_prop_unref(m
->core
, PA_NATIVE_COOKIE_PROPERTY_NAME
);
1492 pa_smoother_free(u
->smoother
);
1495 u
->core
->mainloop
->time_free(u
->time_event
);
1498 pa_xfree(u
->sink_name
);
1500 pa_xfree(u
->source_name
);
1502 pa_xfree(u
->server_name
);
1504 pa_xfree(u
->device_description
);
1505 pa_xfree(u
->server_fqdn
);
1506 pa_xfree(u
->user_name
);