2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include <pulse/def.h>
32 #include <pulse/stream.h>
33 #include <pulse/timeval.h>
34 #include <pulse/rtclock.h>
35 #include <pulse/xmalloc.h>
37 #include <pulsecore/pstream-util.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/hashmap.h>
40 #include <pulsecore/macro.h>
41 #include <pulsecore/core-rtclock.h>
43 #include "fork-detect.h"
46 #define AUTO_TIMING_INTERVAL_START_USEC (10*PA_USEC_PER_MSEC)
47 #define AUTO_TIMING_INTERVAL_END_USEC (1500*PA_USEC_PER_MSEC)
49 #define SMOOTHER_ADJUST_TIME (1000*PA_USEC_PER_MSEC)
50 #define SMOOTHER_HISTORY_TIME (5000*PA_USEC_PER_MSEC)
51 #define SMOOTHER_MIN_HISTORY (4)
53 pa_stream
*pa_stream_new(pa_context
*c
, const char *name
, const pa_sample_spec
*ss
, const pa_channel_map
*map
) {
54 return pa_stream_new_with_proplist(c
, name
, ss
, map
, NULL
);
57 static void reset_callbacks(pa_stream
*s
) {
58 s
->read_callback
= NULL
;
59 s
->read_userdata
= NULL
;
60 s
->write_callback
= NULL
;
61 s
->write_userdata
= NULL
;
62 s
->state_callback
= NULL
;
63 s
->state_userdata
= NULL
;
64 s
->overflow_callback
= NULL
;
65 s
->overflow_userdata
= NULL
;
66 s
->underflow_callback
= NULL
;
67 s
->underflow_userdata
= NULL
;
68 s
->latency_update_callback
= NULL
;
69 s
->latency_update_userdata
= NULL
;
70 s
->moved_callback
= NULL
;
71 s
->moved_userdata
= NULL
;
72 s
->suspended_callback
= NULL
;
73 s
->suspended_userdata
= NULL
;
74 s
->started_callback
= NULL
;
75 s
->started_userdata
= NULL
;
76 s
->event_callback
= NULL
;
77 s
->event_userdata
= NULL
;
78 s
->buffer_attr_callback
= NULL
;
79 s
->buffer_attr_userdata
= NULL
;
82 pa_stream
*pa_stream_new_with_proplist(
85 const pa_sample_spec
*ss
,
86 const pa_channel_map
*map
,
94 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
96 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
97 PA_CHECK_VALIDITY_RETURN_NULL(c
, ss
&& pa_sample_spec_valid(ss
), PA_ERR_INVALID
);
98 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 12 || (ss
->format
!= PA_SAMPLE_S32LE
&& ss
->format
!= PA_SAMPLE_S32BE
), PA_ERR_NOTSUPPORTED
);
99 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 15 || (ss
->format
!= PA_SAMPLE_S24LE
&& ss
->format
!= PA_SAMPLE_S24BE
), PA_ERR_NOTSUPPORTED
);
100 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 15 || (ss
->format
!= PA_SAMPLE_S24_32LE
&& ss
->format
!= PA_SAMPLE_S24_32BE
), PA_ERR_NOTSUPPORTED
);
101 PA_CHECK_VALIDITY_RETURN_NULL(c
, !map
|| (pa_channel_map_valid(map
) && map
->channels
== ss
->channels
), PA_ERR_INVALID
);
102 PA_CHECK_VALIDITY_RETURN_NULL(c
, name
|| (p
&& pa_proplist_contains(p
, PA_PROP_MEDIA_NAME
)), PA_ERR_INVALID
);
105 PA_CHECK_VALIDITY_RETURN_NULL(c
, map
= pa_channel_map_init_auto(&tmap
, ss
->channels
, PA_CHANNEL_MAP_DEFAULT
), PA_ERR_INVALID
);
107 s
= pa_xnew(pa_stream
, 1);
110 s
->mainloop
= c
->mainloop
;
112 s
->direction
= PA_STREAM_NODIRECTION
;
113 s
->state
= PA_STREAM_UNCONNECTED
;
116 s
->sample_spec
= *ss
;
117 s
->channel_map
= *map
;
119 s
->direct_on_input
= PA_INVALID_INDEX
;
121 s
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
123 pa_proplist_sets(s
->proplist
, PA_PROP_MEDIA_NAME
, name
);
126 s
->channel_valid
= FALSE
;
127 s
->syncid
= c
->csyncid
++;
128 s
->stream_index
= PA_INVALID_INDEX
;
130 s
->requested_bytes
= 0;
131 memset(&s
->buffer_attr
, 0, sizeof(s
->buffer_attr
));
133 /* We initialize der target length here, so that if the user
134 * passes no explicit buffering metrics the default is similar to
135 * what older PA versions provided. */
137 s
->buffer_attr
.maxlength
= (uint32_t) -1;
138 s
->buffer_attr
.tlength
= (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC
, ss
); /* 250ms of buffering */
139 s
->buffer_attr
.minreq
= (uint32_t) -1;
140 s
->buffer_attr
.prebuf
= (uint32_t) -1;
141 s
->buffer_attr
.fragsize
= (uint32_t) -1;
143 s
->device_index
= PA_INVALID_INDEX
;
144 s
->device_name
= NULL
;
145 s
->suspended
= FALSE
;
148 s
->write_memblock
= NULL
;
149 s
->write_data
= NULL
;
151 pa_memchunk_reset(&s
->peek_memchunk
);
153 s
->record_memblockq
= NULL
;
155 memset(&s
->timing_info
, 0, sizeof(s
->timing_info
));
156 s
->timing_info_valid
= FALSE
;
158 s
->previous_time
= 0;
160 s
->read_index_not_before
= 0;
161 s
->write_index_not_before
= 0;
162 for (i
= 0; i
< PA_MAX_WRITE_INDEX_CORRECTIONS
; i
++)
163 s
->write_index_corrections
[i
].valid
= 0;
164 s
->current_write_index_correction
= 0;
166 s
->auto_timing_update_event
= NULL
;
167 s
->auto_timing_update_requested
= FALSE
;
168 s
->auto_timing_interval_usec
= AUTO_TIMING_INTERVAL_START_USEC
;
174 /* Refcounting is strictly one-way: from the "bigger" to the "smaller" object. */
175 PA_LLIST_PREPEND(pa_stream
, c
->streams
, s
);
181 static void stream_unlink(pa_stream
*s
) {
188 /* Detach from context */
190 /* Unref all operatio object that point to us */
191 for (o
= s
->context
->operations
; o
; o
= n
) {
195 pa_operation_cancel(o
);
198 /* Drop all outstanding replies for this stream */
199 if (s
->context
->pdispatch
)
200 pa_pdispatch_unregister_reply(s
->context
->pdispatch
, s
);
202 if (s
->channel_valid
) {
203 pa_hashmap_remove((s
->direction
== PA_STREAM_PLAYBACK
) ? s
->context
->playback_streams
: s
->context
->record_streams
, PA_UINT32_TO_PTR(s
->channel
));
205 s
->channel_valid
= FALSE
;
208 PA_LLIST_REMOVE(pa_stream
, s
->context
->streams
, s
);
213 if (s
->auto_timing_update_event
) {
214 pa_assert(s
->mainloop
);
215 s
->mainloop
->time_free(s
->auto_timing_update_event
);
221 static void stream_free(pa_stream
*s
) {
226 if (s
->write_memblock
) {
227 pa_memblock_release(s
->write_memblock
);
228 pa_memblock_unref(s
->write_data
);
231 if (s
->peek_memchunk
.memblock
) {
233 pa_memblock_release(s
->peek_memchunk
.memblock
);
234 pa_memblock_unref(s
->peek_memchunk
.memblock
);
237 if (s
->record_memblockq
)
238 pa_memblockq_free(s
->record_memblockq
);
241 pa_proplist_free(s
->proplist
);
244 pa_smoother_free(s
->smoother
);
246 pa_xfree(s
->device_name
);
250 void pa_stream_unref(pa_stream
*s
) {
252 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
254 if (PA_REFCNT_DEC(s
) <= 0)
258 pa_stream
* pa_stream_ref(pa_stream
*s
) {
260 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
266 pa_stream_state_t
pa_stream_get_state(pa_stream
*s
) {
268 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
273 pa_context
* pa_stream_get_context(pa_stream
*s
) {
275 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
280 uint32_t pa_stream_get_index(pa_stream
*s
) {
282 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
284 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
285 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
287 return s
->stream_index
;
290 void pa_stream_set_state(pa_stream
*s
, pa_stream_state_t st
) {
292 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
301 if (s
->state_callback
)
302 s
->state_callback(s
, s
->state_userdata
);
304 if ((st
== PA_STREAM_FAILED
|| st
== PA_STREAM_TERMINATED
))
310 static void request_auto_timing_update(pa_stream
*s
, pa_bool_t force
) {
312 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
314 if (!(s
->flags
& PA_STREAM_AUTO_TIMING_UPDATE
))
317 if (s
->state
== PA_STREAM_READY
&&
318 (force
|| !s
->auto_timing_update_requested
)) {
321 /* pa_log("Automatically requesting new timing data"); */
323 if ((o
= pa_stream_update_timing_info(s
, NULL
, NULL
))) {
324 pa_operation_unref(o
);
325 s
->auto_timing_update_requested
= TRUE
;
329 if (s
->auto_timing_update_event
) {
331 s
->auto_timing_interval_usec
= AUTO_TIMING_INTERVAL_START_USEC
;
333 pa_context_rttime_restart(s
->context
, s
->auto_timing_update_event
, pa_rtclock_now() + s
->auto_timing_interval_usec
);
335 s
->auto_timing_interval_usec
= PA_MIN(AUTO_TIMING_INTERVAL_END_USEC
, s
->auto_timing_interval_usec
*2);
339 void pa_command_stream_killed(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
340 pa_context
*c
= userdata
;
345 pa_assert(command
== PA_COMMAND_PLAYBACK_STREAM_KILLED
|| command
== PA_COMMAND_RECORD_STREAM_KILLED
);
348 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
352 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
353 !pa_tagstruct_eof(t
)) {
354 pa_context_fail(c
, PA_ERR_PROTOCOL
);
358 if (!(s
= pa_hashmap_get(command
== PA_COMMAND_PLAYBACK_STREAM_KILLED
? c
->playback_streams
: c
->record_streams
, PA_UINT32_TO_PTR(channel
))))
361 if (s
->state
!= PA_STREAM_READY
)
364 pa_context_set_error(c
, PA_ERR_KILLED
);
365 pa_stream_set_state(s
, PA_STREAM_FAILED
);
371 static void check_smoother_status(pa_stream
*s
, pa_bool_t aposteriori
, pa_bool_t force_start
, pa_bool_t force_stop
) {
375 pa_assert(!force_start
|| !force_stop
);
380 x
= pa_rtclock_now();
382 if (s
->timing_info_valid
) {
384 x
-= s
->timing_info
.transport_usec
;
386 x
+= s
->timing_info
.transport_usec
;
389 if (s
->suspended
|| s
->corked
|| force_stop
)
390 pa_smoother_pause(s
->smoother
, x
);
391 else if (force_start
|| s
->buffer_attr
.prebuf
== 0) {
393 if (!s
->timing_info_valid
&&
397 s
->context
->version
>= 13) {
399 /* If the server supports STARTED events we take them as
400 * indications when audio really starts/stops playing, if
401 * we don't have any timing info yet -- instead of trying
402 * to be smart and guessing the server time. Otherwise the
403 * unknown transport delay add too much noise to our time
409 pa_smoother_resume(s
->smoother
, x
, TRUE
);
412 /* Please note that we have no idea if playback actually started
413 * if prebuf is non-zero! */
416 void pa_command_stream_moved(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
417 pa_context
*c
= userdata
;
424 uint32_t maxlength
= 0, fragsize
= 0, minreq
= 0, tlength
= 0, prebuf
= 0;
427 pa_assert(command
== PA_COMMAND_PLAYBACK_STREAM_MOVED
|| command
== PA_COMMAND_RECORD_STREAM_MOVED
);
430 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
434 if (c
->version
< 12) {
435 pa_context_fail(c
, PA_ERR_PROTOCOL
);
439 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
440 pa_tagstruct_getu32(t
, &di
) < 0 ||
441 pa_tagstruct_gets(t
, &dn
) < 0 ||
442 pa_tagstruct_get_boolean(t
, &suspended
) < 0) {
443 pa_context_fail(c
, PA_ERR_PROTOCOL
);
447 if (c
->version
>= 13) {
449 if (command
== PA_COMMAND_RECORD_STREAM_MOVED
) {
450 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
451 pa_tagstruct_getu32(t
, &fragsize
) < 0 ||
452 pa_tagstruct_get_usec(t
, &usec
) < 0) {
453 pa_context_fail(c
, PA_ERR_PROTOCOL
);
457 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
458 pa_tagstruct_getu32(t
, &tlength
) < 0 ||
459 pa_tagstruct_getu32(t
, &prebuf
) < 0 ||
460 pa_tagstruct_getu32(t
, &minreq
) < 0 ||
461 pa_tagstruct_get_usec(t
, &usec
) < 0) {
462 pa_context_fail(c
, PA_ERR_PROTOCOL
);
468 if (!pa_tagstruct_eof(t
)) {
469 pa_context_fail(c
, PA_ERR_PROTOCOL
);
473 if (!dn
|| di
== PA_INVALID_INDEX
) {
474 pa_context_fail(c
, PA_ERR_PROTOCOL
);
478 if (!(s
= pa_hashmap_get(command
== PA_COMMAND_PLAYBACK_STREAM_MOVED
? c
->playback_streams
: c
->record_streams
, PA_UINT32_TO_PTR(channel
))))
481 if (s
->state
!= PA_STREAM_READY
)
484 if (c
->version
>= 13) {
485 if (s
->direction
== PA_STREAM_RECORD
)
486 s
->timing_info
.configured_source_usec
= usec
;
488 s
->timing_info
.configured_sink_usec
= usec
;
490 s
->buffer_attr
.maxlength
= maxlength
;
491 s
->buffer_attr
.fragsize
= fragsize
;
492 s
->buffer_attr
.tlength
= tlength
;
493 s
->buffer_attr
.prebuf
= prebuf
;
494 s
->buffer_attr
.minreq
= minreq
;
497 pa_xfree(s
->device_name
);
498 s
->device_name
= pa_xstrdup(dn
);
499 s
->device_index
= di
;
501 s
->suspended
= suspended
;
503 check_smoother_status(s
, TRUE
, FALSE
, FALSE
);
504 request_auto_timing_update(s
, TRUE
);
506 if (s
->moved_callback
)
507 s
->moved_callback(s
, s
->moved_userdata
);
513 void pa_command_stream_buffer_attr(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
514 pa_context
*c
= userdata
;
518 uint32_t maxlength
= 0, fragsize
= 0, minreq
= 0, tlength
= 0, prebuf
= 0;
521 pa_assert(command
== PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
|| command
== PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED
);
524 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
528 if (c
->version
< 15) {
529 pa_context_fail(c
, PA_ERR_PROTOCOL
);
533 if (pa_tagstruct_getu32(t
, &channel
) < 0) {
534 pa_context_fail(c
, PA_ERR_PROTOCOL
);
538 if (command
== PA_COMMAND_RECORD_STREAM_MOVED
) {
539 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
540 pa_tagstruct_getu32(t
, &fragsize
) < 0 ||
541 pa_tagstruct_get_usec(t
, &usec
) < 0) {
542 pa_context_fail(c
, PA_ERR_PROTOCOL
);
546 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
547 pa_tagstruct_getu32(t
, &tlength
) < 0 ||
548 pa_tagstruct_getu32(t
, &prebuf
) < 0 ||
549 pa_tagstruct_getu32(t
, &minreq
) < 0 ||
550 pa_tagstruct_get_usec(t
, &usec
) < 0) {
551 pa_context_fail(c
, PA_ERR_PROTOCOL
);
556 if (!pa_tagstruct_eof(t
)) {
557 pa_context_fail(c
, PA_ERR_PROTOCOL
);
561 if (!(s
= pa_hashmap_get(command
== PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
? c
->playback_streams
: c
->record_streams
, PA_UINT32_TO_PTR(channel
))))
564 if (s
->state
!= PA_STREAM_READY
)
567 if (s
->direction
== PA_STREAM_RECORD
)
568 s
->timing_info
.configured_source_usec
= usec
;
570 s
->timing_info
.configured_sink_usec
= usec
;
572 s
->buffer_attr
.maxlength
= maxlength
;
573 s
->buffer_attr
.fragsize
= fragsize
;
574 s
->buffer_attr
.tlength
= tlength
;
575 s
->buffer_attr
.prebuf
= prebuf
;
576 s
->buffer_attr
.minreq
= minreq
;
578 request_auto_timing_update(s
, TRUE
);
580 if (s
->buffer_attr_callback
)
581 s
->buffer_attr_callback(s
, s
->buffer_attr_userdata
);
587 void pa_command_stream_suspended(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
588 pa_context
*c
= userdata
;
594 pa_assert(command
== PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
|| command
== PA_COMMAND_RECORD_STREAM_SUSPENDED
);
597 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
601 if (c
->version
< 12) {
602 pa_context_fail(c
, PA_ERR_PROTOCOL
);
606 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
607 pa_tagstruct_get_boolean(t
, &suspended
) < 0 ||
608 !pa_tagstruct_eof(t
)) {
609 pa_context_fail(c
, PA_ERR_PROTOCOL
);
613 if (!(s
= pa_hashmap_get(command
== PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
? c
->playback_streams
: c
->record_streams
, PA_UINT32_TO_PTR(channel
))))
616 if (s
->state
!= PA_STREAM_READY
)
619 s
->suspended
= suspended
;
621 check_smoother_status(s
, TRUE
, FALSE
, FALSE
);
622 request_auto_timing_update(s
, TRUE
);
624 if (s
->suspended_callback
)
625 s
->suspended_callback(s
, s
->suspended_userdata
);
631 void pa_command_stream_started(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
632 pa_context
*c
= userdata
;
637 pa_assert(command
== PA_COMMAND_STARTED
);
640 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
644 if (c
->version
< 13) {
645 pa_context_fail(c
, PA_ERR_PROTOCOL
);
649 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
650 !pa_tagstruct_eof(t
)) {
651 pa_context_fail(c
, PA_ERR_PROTOCOL
);
655 if (!(s
= pa_hashmap_get(c
->playback_streams
, PA_UINT32_TO_PTR(channel
))))
658 if (s
->state
!= PA_STREAM_READY
)
661 check_smoother_status(s
, TRUE
, TRUE
, FALSE
);
662 request_auto_timing_update(s
, TRUE
);
664 if (s
->started_callback
)
665 s
->started_callback(s
, s
->started_userdata
);
671 void pa_command_stream_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
672 pa_context
*c
= userdata
;
675 pa_proplist
*pl
= NULL
;
679 pa_assert(command
== PA_COMMAND_PLAYBACK_STREAM_EVENT
|| command
== PA_COMMAND_RECORD_STREAM_EVENT
);
682 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
686 if (c
->version
< 15) {
687 pa_context_fail(c
, PA_ERR_PROTOCOL
);
691 pl
= pa_proplist_new();
693 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
694 pa_tagstruct_gets(t
, &event
) < 0 ||
695 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
696 !pa_tagstruct_eof(t
) || !event
) {
697 pa_context_fail(c
, PA_ERR_PROTOCOL
);
701 if (!(s
= pa_hashmap_get(command
== PA_COMMAND_PLAYBACK_STREAM_EVENT
? c
->playback_streams
: c
->record_streams
, PA_UINT32_TO_PTR(channel
))))
704 if (s
->state
!= PA_STREAM_READY
)
707 if (s
->event_callback
)
708 s
->event_callback(s
, event
, pl
, s
->event_userdata
);
714 pa_proplist_free(pl
);
717 void pa_command_request(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
719 pa_context
*c
= userdata
;
720 uint32_t bytes
, channel
;
723 pa_assert(command
== PA_COMMAND_REQUEST
);
726 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
730 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
731 pa_tagstruct_getu32(t
, &bytes
) < 0 ||
732 !pa_tagstruct_eof(t
)) {
733 pa_context_fail(c
, PA_ERR_PROTOCOL
);
737 if (!(s
= pa_hashmap_get(c
->playback_streams
, PA_UINT32_TO_PTR(channel
))))
740 if (s
->state
!= PA_STREAM_READY
)
743 s
->requested_bytes
+= bytes
;
745 /* pa_log("got request for %lli, now at %lli", (long long) bytes, (long long) s->requested_bytes); */
747 if (s
->requested_bytes
> 0 && s
->write_callback
)
748 s
->write_callback(s
, (size_t) s
->requested_bytes
, s
->write_userdata
);
754 void pa_command_overflow_or_underflow(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
756 pa_context
*c
= userdata
;
760 pa_assert(command
== PA_COMMAND_OVERFLOW
|| command
== PA_COMMAND_UNDERFLOW
);
763 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
767 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
768 !pa_tagstruct_eof(t
)) {
769 pa_context_fail(c
, PA_ERR_PROTOCOL
);
773 if (!(s
= pa_hashmap_get(c
->playback_streams
, PA_UINT32_TO_PTR(channel
))))
776 if (s
->state
!= PA_STREAM_READY
)
779 if (s
->buffer_attr
.prebuf
> 0)
780 check_smoother_status(s
, TRUE
, FALSE
, TRUE
);
782 request_auto_timing_update(s
, TRUE
);
784 if (command
== PA_COMMAND_OVERFLOW
) {
785 if (s
->overflow_callback
)
786 s
->overflow_callback(s
, s
->overflow_userdata
);
787 } else if (command
== PA_COMMAND_UNDERFLOW
) {
788 if (s
->underflow_callback
)
789 s
->underflow_callback(s
, s
->underflow_userdata
);
796 static void invalidate_indexes(pa_stream
*s
, pa_bool_t r
, pa_bool_t w
) {
798 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
800 /* pa_log("invalidate r:%u w:%u tag:%u", r, w, s->context->ctag); */
802 if (s
->state
!= PA_STREAM_READY
)
806 s
->write_index_not_before
= s
->context
->ctag
;
808 if (s
->timing_info_valid
)
809 s
->timing_info
.write_index_corrupt
= TRUE
;
811 /* pa_log("write_index invalidated"); */
815 s
->read_index_not_before
= s
->context
->ctag
;
817 if (s
->timing_info_valid
)
818 s
->timing_info
.read_index_corrupt
= TRUE
;
820 /* pa_log("read_index invalidated"); */
823 request_auto_timing_update(s
, TRUE
);
826 static void auto_timing_update_callback(pa_mainloop_api
*m
, pa_time_event
*e
, const struct timeval
*t
, void *userdata
) {
827 pa_stream
*s
= userdata
;
830 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
833 request_auto_timing_update(s
, FALSE
);
837 static void create_stream_complete(pa_stream
*s
) {
839 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
840 pa_assert(s
->state
== PA_STREAM_CREATING
);
842 pa_stream_set_state(s
, PA_STREAM_READY
);
844 if (s
->requested_bytes
> 0 && s
->write_callback
)
845 s
->write_callback(s
, (size_t) s
->requested_bytes
, s
->write_userdata
);
847 if (s
->flags
& PA_STREAM_AUTO_TIMING_UPDATE
) {
848 s
->auto_timing_interval_usec
= AUTO_TIMING_INTERVAL_START_USEC
;
849 pa_assert(!s
->auto_timing_update_event
);
850 s
->auto_timing_update_event
= pa_context_rttime_new(s
->context
, pa_rtclock_now() + s
->auto_timing_interval_usec
, &auto_timing_update_callback
, s
);
852 request_auto_timing_update(s
, TRUE
);
855 check_smoother_status(s
, TRUE
, FALSE
, FALSE
);
858 static void automatic_buffer_attr(pa_stream
*s
, pa_buffer_attr
*attr
, const pa_sample_spec
*ss
) {
863 if (s
->context
->version
>= 13)
866 /* Version older than 0.9.10 didn't do server side buffer_attr
867 * selection, hence we have to fake it on the client side. */
869 /* We choose fairly conservative values here, to not confuse
870 * old clients with extremely large playback buffers */
872 if (attr
->maxlength
== (uint32_t) -1)
873 attr
->maxlength
= 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */
875 if (attr
->tlength
== (uint32_t) -1)
876 attr
->tlength
= (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC
, ss
); /* 250ms of buffering */
878 if (attr
->minreq
== (uint32_t) -1)
879 attr
->minreq
= (attr
->tlength
)/5; /* Ask for more data when there are only 200ms left in the playback buffer */
881 if (attr
->prebuf
== (uint32_t) -1)
882 attr
->prebuf
= attr
->tlength
; /* Start to play only when the playback is fully filled up once */
884 if (attr
->fragsize
== (uint32_t) -1)
885 attr
->fragsize
= attr
->tlength
; /* Pass data to the app only when the buffer is filled up once */
888 void pa_create_stream_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
889 pa_stream
*s
= userdata
;
890 uint32_t requested_bytes
= 0;
894 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
895 pa_assert(s
->state
== PA_STREAM_CREATING
);
899 if (command
!= PA_COMMAND_REPLY
) {
900 if (pa_context_handle_error(s
->context
, command
, t
, FALSE
) < 0)
903 pa_stream_set_state(s
, PA_STREAM_FAILED
);
907 if (pa_tagstruct_getu32(t
, &s
->channel
) < 0 ||
908 s
->channel
== PA_INVALID_INDEX
||
909 ((s
->direction
!= PA_STREAM_UPLOAD
) && (pa_tagstruct_getu32(t
, &s
->stream_index
) < 0 || s
->stream_index
== PA_INVALID_INDEX
)) ||
910 ((s
->direction
!= PA_STREAM_RECORD
) && pa_tagstruct_getu32(t
, &requested_bytes
) < 0)) {
911 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
915 s
->requested_bytes
= (int64_t) requested_bytes
;
917 if (s
->context
->version
>= 9) {
918 if (s
->direction
== PA_STREAM_PLAYBACK
) {
919 if (pa_tagstruct_getu32(t
, &s
->buffer_attr
.maxlength
) < 0 ||
920 pa_tagstruct_getu32(t
, &s
->buffer_attr
.tlength
) < 0 ||
921 pa_tagstruct_getu32(t
, &s
->buffer_attr
.prebuf
) < 0 ||
922 pa_tagstruct_getu32(t
, &s
->buffer_attr
.minreq
) < 0) {
923 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
926 } else if (s
->direction
== PA_STREAM_RECORD
) {
927 if (pa_tagstruct_getu32(t
, &s
->buffer_attr
.maxlength
) < 0 ||
928 pa_tagstruct_getu32(t
, &s
->buffer_attr
.fragsize
) < 0) {
929 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
935 if (s
->context
->version
>= 12 && s
->direction
!= PA_STREAM_UPLOAD
) {
938 const char *dn
= NULL
;
941 if (pa_tagstruct_get_sample_spec(t
, &ss
) < 0 ||
942 pa_tagstruct_get_channel_map(t
, &cm
) < 0 ||
943 pa_tagstruct_getu32(t
, &s
->device_index
) < 0 ||
944 pa_tagstruct_gets(t
, &dn
) < 0 ||
945 pa_tagstruct_get_boolean(t
, &suspended
) < 0) {
946 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
950 if (!dn
|| s
->device_index
== PA_INVALID_INDEX
||
951 ss
.channels
!= cm
.channels
||
952 !pa_channel_map_valid(&cm
) ||
953 !pa_sample_spec_valid(&ss
) ||
954 (!(s
->flags
& PA_STREAM_FIX_FORMAT
) && ss
.format
!= s
->sample_spec
.format
) ||
955 (!(s
->flags
& PA_STREAM_FIX_RATE
) && ss
.rate
!= s
->sample_spec
.rate
) ||
956 (!(s
->flags
& PA_STREAM_FIX_CHANNELS
) && !pa_channel_map_equal(&cm
, &s
->channel_map
))) {
957 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
961 pa_xfree(s
->device_name
);
962 s
->device_name
= pa_xstrdup(dn
);
963 s
->suspended
= suspended
;
969 if (s
->context
->version
>= 13 && s
->direction
!= PA_STREAM_UPLOAD
) {
972 if (pa_tagstruct_get_usec(t
, &usec
) < 0) {
973 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
977 if (s
->direction
== PA_STREAM_RECORD
)
978 s
->timing_info
.configured_source_usec
= usec
;
980 s
->timing_info
.configured_sink_usec
= usec
;
983 if (!pa_tagstruct_eof(t
)) {
984 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
988 if (s
->direction
== PA_STREAM_RECORD
) {
989 pa_assert(!s
->record_memblockq
);
991 s
->record_memblockq
= pa_memblockq_new(
993 s
->buffer_attr
.maxlength
,
995 pa_frame_size(&s
->sample_spec
),
1002 s
->channel_valid
= TRUE
;
1003 pa_hashmap_put((s
->direction
== PA_STREAM_RECORD
) ? s
->context
->record_streams
: s
->context
->playback_streams
, PA_UINT32_TO_PTR(s
->channel
), s
);
1005 create_stream_complete(s
);
1011 static int create_stream(
1012 pa_stream_direction_t direction
,
1015 const pa_buffer_attr
*attr
,
1016 pa_stream_flags_t flags
,
1017 const pa_cvolume
*volume
,
1018 pa_stream
*sync_stream
) {
1022 pa_bool_t volume_set
= FALSE
;
1025 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1026 pa_assert(direction
== PA_STREAM_PLAYBACK
|| direction
== PA_STREAM_RECORD
);
1028 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1029 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_UNCONNECTED
, PA_ERR_BADSTATE
);
1030 PA_CHECK_VALIDITY(s
->context
, s
->direct_on_input
== PA_INVALID_INDEX
|| direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
);
1031 PA_CHECK_VALIDITY(s
->context
, !(flags
& ~(PA_STREAM_START_CORKED
|
1032 PA_STREAM_INTERPOLATE_TIMING
|
1033 PA_STREAM_NOT_MONOTONIC
|
1034 PA_STREAM_AUTO_TIMING_UPDATE
|
1035 PA_STREAM_NO_REMAP_CHANNELS
|
1036 PA_STREAM_NO_REMIX_CHANNELS
|
1037 PA_STREAM_FIX_FORMAT
|
1039 PA_STREAM_FIX_CHANNELS
|
1040 PA_STREAM_DONT_MOVE
|
1041 PA_STREAM_VARIABLE_RATE
|
1042 PA_STREAM_PEAK_DETECT
|
1043 PA_STREAM_START_MUTED
|
1044 PA_STREAM_ADJUST_LATENCY
|
1045 PA_STREAM_EARLY_REQUESTS
|
1046 PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
|
1047 PA_STREAM_START_UNMUTED
|
1048 PA_STREAM_FAIL_ON_SUSPEND
|
1049 PA_STREAM_RELATIVE_VOLUME
)), PA_ERR_INVALID
);
1051 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 12 || !(flags
& PA_STREAM_VARIABLE_RATE
), PA_ERR_NOTSUPPORTED
);
1052 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 13 || !(flags
& PA_STREAM_PEAK_DETECT
), PA_ERR_NOTSUPPORTED
);
1053 PA_CHECK_VALIDITY(s
->context
, s
->context
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1054 /* Althought some of the other flags are not supported on older
1055 * version, we don't check for them here, because it doesn't hurt
1056 * when they are passed but actually not supported. This makes
1057 * client development easier */
1059 PA_CHECK_VALIDITY(s
->context
, direction
== PA_STREAM_PLAYBACK
|| !(flags
& (PA_STREAM_START_MUTED
)), PA_ERR_INVALID
);
1060 PA_CHECK_VALIDITY(s
->context
, direction
== PA_STREAM_RECORD
|| !(flags
& (PA_STREAM_PEAK_DETECT
)), PA_ERR_INVALID
);
1061 PA_CHECK_VALIDITY(s
->context
, !volume
|| volume
->channels
== s
->sample_spec
.channels
, PA_ERR_INVALID
);
1062 PA_CHECK_VALIDITY(s
->context
, !sync_stream
|| (direction
== PA_STREAM_PLAYBACK
&& sync_stream
->direction
== PA_STREAM_PLAYBACK
), PA_ERR_INVALID
);
1063 PA_CHECK_VALIDITY(s
->context
, (flags
& (PA_STREAM_ADJUST_LATENCY
|PA_STREAM_EARLY_REQUESTS
)) != (PA_STREAM_ADJUST_LATENCY
|PA_STREAM_EARLY_REQUESTS
), PA_ERR_INVALID
);
1067 s
->direction
= direction
;
1069 s
->corked
= !!(flags
& PA_STREAM_START_CORKED
);
1072 s
->syncid
= sync_stream
->syncid
;
1075 s
->buffer_attr
= *attr
;
1076 automatic_buffer_attr(s
, &s
->buffer_attr
, &s
->sample_spec
);
1078 if (flags
& PA_STREAM_INTERPOLATE_TIMING
) {
1081 x
= pa_rtclock_now();
1083 pa_assert(!s
->smoother
);
1084 s
->smoother
= pa_smoother_new(
1085 SMOOTHER_ADJUST_TIME
,
1086 SMOOTHER_HISTORY_TIME
,
1087 !(flags
& PA_STREAM_NOT_MONOTONIC
),
1089 SMOOTHER_MIN_HISTORY
,
1095 dev
= s
->direction
== PA_STREAM_PLAYBACK
? s
->context
->conf
->default_sink
: s
->context
->conf
->default_source
;
1097 t
= pa_tagstruct_command(
1099 (uint32_t) (s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_CREATE_PLAYBACK_STREAM
: PA_COMMAND_CREATE_RECORD_STREAM
),
1102 if (s
->context
->version
< 13)
1103 pa_tagstruct_puts(t
, pa_proplist_gets(s
->proplist
, PA_PROP_MEDIA_NAME
));
1107 PA_TAG_SAMPLE_SPEC
, &s
->sample_spec
,
1108 PA_TAG_CHANNEL_MAP
, &s
->channel_map
,
1109 PA_TAG_U32
, PA_INVALID_INDEX
,
1111 PA_TAG_U32
, s
->buffer_attr
.maxlength
,
1112 PA_TAG_BOOLEAN
, s
->corked
,
1115 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1120 PA_TAG_U32
, s
->buffer_attr
.tlength
,
1121 PA_TAG_U32
, s
->buffer_attr
.prebuf
,
1122 PA_TAG_U32
, s
->buffer_attr
.minreq
,
1123 PA_TAG_U32
, s
->syncid
,
1126 volume_set
= !!volume
;
1129 volume
= pa_cvolume_reset(&cv
, s
->sample_spec
.channels
);
1131 pa_tagstruct_put_cvolume(t
, volume
);
1133 pa_tagstruct_putu32(t
, s
->buffer_attr
.fragsize
);
1135 if (s
->context
->version
>= 12) {
1138 PA_TAG_BOOLEAN
, flags
& PA_STREAM_NO_REMAP_CHANNELS
,
1139 PA_TAG_BOOLEAN
, flags
& PA_STREAM_NO_REMIX_CHANNELS
,
1140 PA_TAG_BOOLEAN
, flags
& PA_STREAM_FIX_FORMAT
,
1141 PA_TAG_BOOLEAN
, flags
& PA_STREAM_FIX_RATE
,
1142 PA_TAG_BOOLEAN
, flags
& PA_STREAM_FIX_CHANNELS
,
1143 PA_TAG_BOOLEAN
, flags
& PA_STREAM_DONT_MOVE
,
1144 PA_TAG_BOOLEAN
, flags
& PA_STREAM_VARIABLE_RATE
,
1148 if (s
->context
->version
>= 13) {
1150 if (s
->direction
== PA_STREAM_PLAYBACK
)
1151 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_START_MUTED
);
1153 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_PEAK_DETECT
);
1157 PA_TAG_BOOLEAN
, flags
& PA_STREAM_ADJUST_LATENCY
,
1158 PA_TAG_PROPLIST
, s
->proplist
,
1161 if (s
->direction
== PA_STREAM_RECORD
)
1162 pa_tagstruct_putu32(t
, s
->direct_on_input
);
1165 if (s
->context
->version
>= 14) {
1167 if (s
->direction
== PA_STREAM_PLAYBACK
)
1168 pa_tagstruct_put_boolean(t
, volume_set
);
1170 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_EARLY_REQUESTS
);
1173 if (s
->context
->version
>= 15) {
1175 if (s
->direction
== PA_STREAM_PLAYBACK
)
1176 pa_tagstruct_put_boolean(t
, flags
& (PA_STREAM_START_MUTED
|PA_STREAM_START_UNMUTED
));
1178 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
);
1179 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_FAIL_ON_SUSPEND
);
1182 if (s
->context
->version
>= 17) {
1184 if (s
->direction
== PA_STREAM_PLAYBACK
)
1185 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_RELATIVE_VOLUME
);
1189 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1190 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_create_stream_callback
, s
, NULL
);
1192 pa_stream_set_state(s
, PA_STREAM_CREATING
);
1198 int pa_stream_connect_playback(
1201 const pa_buffer_attr
*attr
,
1202 pa_stream_flags_t flags
,
1203 const pa_cvolume
*volume
,
1204 pa_stream
*sync_stream
) {
1207 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1209 return create_stream(PA_STREAM_PLAYBACK
, s
, dev
, attr
, flags
, volume
, sync_stream
);
1212 int pa_stream_connect_record(
1215 const pa_buffer_attr
*attr
,
1216 pa_stream_flags_t flags
) {
1219 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1221 return create_stream(PA_STREAM_RECORD
, s
, dev
, attr
, flags
, NULL
, NULL
);
1224 int pa_stream_begin_write(
1230 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1232 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1233 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1234 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
|| s
->direction
== PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1235 PA_CHECK_VALIDITY(s
->context
, data
, PA_ERR_INVALID
);
1236 PA_CHECK_VALIDITY(s
->context
, nbytes
&& *nbytes
!= 0, PA_ERR_INVALID
);
1238 if (*nbytes
!= (size_t) -1) {
1241 m
= pa_mempool_block_size_max(s
->context
->mempool
);
1242 fs
= pa_frame_size(&s
->sample_spec
);
1249 if (!s
->write_memblock
) {
1250 s
->write_memblock
= pa_memblock_new(s
->context
->mempool
, *nbytes
);
1251 s
->write_data
= pa_memblock_acquire(s
->write_memblock
);
1254 *data
= s
->write_data
;
1255 *nbytes
= pa_memblock_get_length(s
->write_memblock
);
1260 int pa_stream_cancel_write(
1264 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1266 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1267 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1268 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
|| s
->direction
== PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1269 PA_CHECK_VALIDITY(s
->context
, s
->write_memblock
, PA_ERR_BADSTATE
);
1271 pa_assert(s
->write_data
);
1273 pa_memblock_release(s
->write_memblock
);
1274 pa_memblock_unref(s
->write_memblock
);
1275 s
->write_memblock
= NULL
;
1276 s
->write_data
= NULL
;
1281 int pa_stream_write(
1285 pa_free_cb_t free_cb
,
1287 pa_seek_mode_t seek
) {
1290 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1293 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1294 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1295 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
|| s
->direction
== PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1296 PA_CHECK_VALIDITY(s
->context
, seek
<= PA_SEEK_RELATIVE_END
, PA_ERR_INVALID
);
1297 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
|| (seek
== PA_SEEK_RELATIVE
&& offset
== 0), PA_ERR_INVALID
);
1298 PA_CHECK_VALIDITY(s
->context
,
1299 !s
->write_memblock
||
1300 ((data
>= s
->write_data
) &&
1301 ((const char*) data
+ length
<= (const char*) s
->write_data
+ pa_memblock_get_length(s
->write_memblock
))),
1303 PA_CHECK_VALIDITY(s
->context
, !free_cb
|| !s
->write_memblock
, PA_ERR_INVALID
);
1305 if (s
->write_memblock
) {
1308 /* pa_stream_write_begin() was called before */
1310 pa_memblock_release(s
->write_memblock
);
1312 chunk
.memblock
= s
->write_memblock
;
1313 chunk
.index
= (const char *) data
- (const char *) s
->write_data
;
1314 chunk
.length
= length
;
1316 s
->write_memblock
= NULL
;
1317 s
->write_data
= NULL
;
1319 pa_pstream_send_memblock(s
->context
->pstream
, s
->channel
, offset
, seek
, &chunk
);
1320 pa_memblock_unref(chunk
.memblock
);
1323 pa_seek_mode_t t_seek
= seek
;
1324 int64_t t_offset
= offset
;
1325 size_t t_length
= length
;
1326 const void *t_data
= data
;
1328 /* pa_stream_write_begin() was not called before */
1330 while (t_length
> 0) {
1335 if (free_cb
&& !pa_pstream_get_shm(s
->context
->pstream
)) {
1336 chunk
.memblock
= pa_memblock_new_user(s
->context
->mempool
, (void*) t_data
, t_length
, free_cb
, 1);
1337 chunk
.length
= t_length
;
1341 chunk
.length
= PA_MIN(t_length
, pa_mempool_block_size_max(s
->context
->mempool
));
1342 chunk
.memblock
= pa_memblock_new(s
->context
->mempool
, chunk
.length
);
1344 d
= pa_memblock_acquire(chunk
.memblock
);
1345 memcpy(d
, t_data
, chunk
.length
);
1346 pa_memblock_release(chunk
.memblock
);
1349 pa_pstream_send_memblock(s
->context
->pstream
, s
->channel
, t_offset
, t_seek
, &chunk
);
1352 t_seek
= PA_SEEK_RELATIVE
;
1354 t_data
= (const uint8_t*) t_data
+ chunk
.length
;
1355 t_length
-= chunk
.length
;
1357 pa_memblock_unref(chunk
.memblock
);
1360 if (free_cb
&& pa_pstream_get_shm(s
->context
->pstream
))
1361 free_cb((void*) data
);
1364 /* This is obviously wrong since we ignore the seeking index . But
1365 * that's OK, the server side applies the same error */
1366 s
->requested_bytes
-= (seek
== PA_SEEK_RELATIVE
? offset
: 0) + (int64_t) length
;
1368 /* pa_log("wrote %lli, now at %lli", (long long) length, (long long) s->requested_bytes); */
1370 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1372 /* Update latency request correction */
1373 if (s
->write_index_corrections
[s
->current_write_index_correction
].valid
) {
1375 if (seek
== PA_SEEK_ABSOLUTE
) {
1376 s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
= FALSE
;
1377 s
->write_index_corrections
[s
->current_write_index_correction
].absolute
= TRUE
;
1378 s
->write_index_corrections
[s
->current_write_index_correction
].value
= offset
+ (int64_t) length
;
1379 } else if (seek
== PA_SEEK_RELATIVE
) {
1380 if (!s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
)
1381 s
->write_index_corrections
[s
->current_write_index_correction
].value
+= offset
+ (int64_t) length
;
1383 s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
= TRUE
;
1386 /* Update the write index in the already available latency data */
1387 if (s
->timing_info_valid
) {
1389 if (seek
== PA_SEEK_ABSOLUTE
) {
1390 s
->timing_info
.write_index_corrupt
= FALSE
;
1391 s
->timing_info
.write_index
= offset
+ (int64_t) length
;
1392 } else if (seek
== PA_SEEK_RELATIVE
) {
1393 if (!s
->timing_info
.write_index_corrupt
)
1394 s
->timing_info
.write_index
+= offset
+ (int64_t) length
;
1396 s
->timing_info
.write_index_corrupt
= TRUE
;
1399 if (!s
->timing_info_valid
|| s
->timing_info
.write_index_corrupt
)
1400 request_auto_timing_update(s
, TRUE
);
1406 int pa_stream_peek(pa_stream
*s
, const void **data
, size_t *length
) {
1408 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1412 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1413 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1414 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
);
1416 if (!s
->peek_memchunk
.memblock
) {
1418 if (pa_memblockq_peek(s
->record_memblockq
, &s
->peek_memchunk
) < 0) {
1424 s
->peek_data
= pa_memblock_acquire(s
->peek_memchunk
.memblock
);
1427 pa_assert(s
->peek_data
);
1428 *data
= (uint8_t*) s
->peek_data
+ s
->peek_memchunk
.index
;
1429 *length
= s
->peek_memchunk
.length
;
1433 int pa_stream_drop(pa_stream
*s
) {
1435 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1437 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1438 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1439 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
);
1440 PA_CHECK_VALIDITY(s
->context
, s
->peek_memchunk
.memblock
, PA_ERR_BADSTATE
);
1442 pa_memblockq_drop(s
->record_memblockq
, s
->peek_memchunk
.length
);
1444 /* Fix the simulated local read index */
1445 if (s
->timing_info_valid
&& !s
->timing_info
.read_index_corrupt
)
1446 s
->timing_info
.read_index
+= (int64_t) s
->peek_memchunk
.length
;
1448 pa_assert(s
->peek_data
);
1449 pa_memblock_release(s
->peek_memchunk
.memblock
);
1450 pa_memblock_unref(s
->peek_memchunk
.memblock
);
1451 pa_memchunk_reset(&s
->peek_memchunk
);
1456 size_t pa_stream_writable_size(pa_stream
*s
) {
1458 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1460 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
, (size_t) -1);
1461 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, (size_t) -1);
1462 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direction
!= PA_STREAM_RECORD
, PA_ERR_BADSTATE
, (size_t) -1);
1464 return s
->requested_bytes
> 0 ? (size_t) s
->requested_bytes
: 0;
1467 size_t pa_stream_readable_size(pa_stream
*s
) {
1469 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1471 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
, (size_t) -1);
1472 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, (size_t) -1);
1473 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
, (size_t) -1);
1475 return pa_memblockq_get_length(s
->record_memblockq
);
1478 pa_operation
* pa_stream_drain(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
1484 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1486 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1487 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1488 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
);
1490 /* Ask for a timing update before we cork/uncork to get the best
1491 * accuracy for the transport latency suitable for the
1492 * check_smoother_status() call in the started callback */
1493 request_auto_timing_update(s
, TRUE
);
1495 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
1497 t
= pa_tagstruct_command(s
->context
, PA_COMMAND_DRAIN_PLAYBACK_STREAM
, &tag
);
1498 pa_tagstruct_putu32(t
, s
->channel
);
1499 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1500 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_simple_ack_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1502 /* This might cause the read index to conitnue again, hence
1503 * let's request a timing update */
1504 request_auto_timing_update(s
, TRUE
);
1509 static pa_usec_t
calc_time(pa_stream
*s
, pa_bool_t ignore_transport
) {
1513 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1514 pa_assert(s
->state
== PA_STREAM_READY
);
1515 pa_assert(s
->direction
!= PA_STREAM_UPLOAD
);
1516 pa_assert(s
->timing_info_valid
);
1517 pa_assert(s
->direction
!= PA_STREAM_PLAYBACK
|| !s
->timing_info
.read_index_corrupt
);
1518 pa_assert(s
->direction
!= PA_STREAM_RECORD
|| !s
->timing_info
.write_index_corrupt
);
1520 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1521 /* The last byte that was written into the output device
1522 * had this time value associated */
1523 usec
= pa_bytes_to_usec(s
->timing_info
.read_index
< 0 ? 0 : (uint64_t) s
->timing_info
.read_index
, &s
->sample_spec
);
1525 if (!s
->corked
&& !s
->suspended
) {
1527 if (!ignore_transport
)
1528 /* Because the latency info took a little time to come
1529 * to us, we assume that the real output time is actually
1531 usec
+= s
->timing_info
.transport_usec
;
1533 /* However, the output device usually maintains a buffer
1534 too, hence the real sample currently played is a little
1536 if (s
->timing_info
.sink_usec
>= usec
)
1539 usec
-= s
->timing_info
.sink_usec
;
1543 pa_assert(s
->direction
== PA_STREAM_RECORD
);
1545 /* The last byte written into the server side queue had
1546 * this time value associated */
1547 usec
= pa_bytes_to_usec(s
->timing_info
.write_index
< 0 ? 0 : (uint64_t) s
->timing_info
.write_index
, &s
->sample_spec
);
1549 if (!s
->corked
&& !s
->suspended
) {
1551 if (!ignore_transport
)
1552 /* Add transport latency */
1553 usec
+= s
->timing_info
.transport_usec
;
1555 /* Add latency of data in device buffer */
1556 usec
+= s
->timing_info
.source_usec
;
1558 /* If this is a monitor source, we need to correct the
1559 * time by the playback device buffer */
1560 if (s
->timing_info
.sink_usec
>= usec
)
1563 usec
-= s
->timing_info
.sink_usec
;
1570 static void stream_get_timing_info_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1571 pa_operation
*o
= userdata
;
1572 struct timeval local
, remote
, now
;
1574 pa_bool_t playing
= FALSE
;
1575 uint64_t underrun_for
= 0, playing_for
= 0;
1579 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1581 if (!o
->context
|| !o
->stream
)
1584 i
= &o
->stream
->timing_info
;
1586 o
->stream
->timing_info_valid
= FALSE
;
1587 i
->write_index_corrupt
= TRUE
;
1588 i
->read_index_corrupt
= TRUE
;
1590 if (command
!= PA_COMMAND_REPLY
) {
1591 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1596 if (pa_tagstruct_get_usec(t
, &i
->sink_usec
) < 0 ||
1597 pa_tagstruct_get_usec(t
, &i
->source_usec
) < 0 ||
1598 pa_tagstruct_get_boolean(t
, &playing
) < 0 ||
1599 pa_tagstruct_get_timeval(t
, &local
) < 0 ||
1600 pa_tagstruct_get_timeval(t
, &remote
) < 0 ||
1601 pa_tagstruct_gets64(t
, &i
->write_index
) < 0 ||
1602 pa_tagstruct_gets64(t
, &i
->read_index
) < 0) {
1604 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1608 if (o
->context
->version
>= 13 &&
1609 o
->stream
->direction
== PA_STREAM_PLAYBACK
)
1610 if (pa_tagstruct_getu64(t
, &underrun_for
) < 0 ||
1611 pa_tagstruct_getu64(t
, &playing_for
) < 0) {
1613 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1618 if (!pa_tagstruct_eof(t
)) {
1619 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1622 o
->stream
->timing_info_valid
= TRUE
;
1623 i
->write_index_corrupt
= FALSE
;
1624 i
->read_index_corrupt
= FALSE
;
1626 i
->playing
= (int) playing
;
1627 i
->since_underrun
= (int64_t) (playing
? playing_for
: underrun_for
);
1629 pa_gettimeofday(&now
);
1631 /* Calculcate timestamps */
1632 if (pa_timeval_cmp(&local
, &remote
) <= 0 && pa_timeval_cmp(&remote
, &now
) <= 0) {
1633 /* local and remote seem to have synchronized clocks */
1635 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
)
1636 i
->transport_usec
= pa_timeval_diff(&remote
, &local
);
1638 i
->transport_usec
= pa_timeval_diff(&now
, &remote
);
1640 i
->synchronized_clocks
= TRUE
;
1641 i
->timestamp
= remote
;
1643 /* clocks are not synchronized, let's estimate latency then */
1644 i
->transport_usec
= pa_timeval_diff(&now
, &local
)/2;
1645 i
->synchronized_clocks
= FALSE
;
1646 i
->timestamp
= local
;
1647 pa_timeval_add(&i
->timestamp
, i
->transport_usec
);
1650 /* Invalidate read and write indexes if necessary */
1651 if (tag
< o
->stream
->read_index_not_before
)
1652 i
->read_index_corrupt
= TRUE
;
1654 if (tag
< o
->stream
->write_index_not_before
)
1655 i
->write_index_corrupt
= TRUE
;
1657 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
) {
1658 /* Write index correction */
1661 uint32_t ctag
= tag
;
1663 /* Go through the saved correction values and add up the
1664 * total correction.*/
1665 for (n
= 0, j
= o
->stream
->current_write_index_correction
+1;
1666 n
< PA_MAX_WRITE_INDEX_CORRECTIONS
;
1667 n
++, j
= (j
+ 1) % PA_MAX_WRITE_INDEX_CORRECTIONS
) {
1669 /* Step over invalid data or out-of-date data */
1670 if (!o
->stream
->write_index_corrections
[j
].valid
||
1671 o
->stream
->write_index_corrections
[j
].tag
< ctag
)
1674 /* Make sure that everything is in order */
1675 ctag
= o
->stream
->write_index_corrections
[j
].tag
+1;
1677 /* Now fix the write index */
1678 if (o
->stream
->write_index_corrections
[j
].corrupt
) {
1679 /* A corrupting seek was made */
1680 i
->write_index_corrupt
= TRUE
;
1681 } else if (o
->stream
->write_index_corrections
[j
].absolute
) {
1682 /* An absolute seek was made */
1683 i
->write_index
= o
->stream
->write_index_corrections
[j
].value
;
1684 i
->write_index_corrupt
= FALSE
;
1685 } else if (!i
->write_index_corrupt
) {
1686 /* A relative seek was made */
1687 i
->write_index
+= o
->stream
->write_index_corrections
[j
].value
;
1691 /* Clear old correction entries */
1692 for (n
= 0; n
< PA_MAX_WRITE_INDEX_CORRECTIONS
; n
++) {
1693 if (!o
->stream
->write_index_corrections
[n
].valid
)
1696 if (o
->stream
->write_index_corrections
[n
].tag
<= tag
)
1697 o
->stream
->write_index_corrections
[n
].valid
= FALSE
;
1701 if (o
->stream
->direction
== PA_STREAM_RECORD
) {
1702 /* Read index correction */
1704 if (!i
->read_index_corrupt
)
1705 i
->read_index
-= (int64_t) pa_memblockq_get_length(o
->stream
->record_memblockq
);
1708 /* Update smoother */
1709 if (o
->stream
->smoother
) {
1712 u
= x
= pa_rtclock_now() - i
->transport_usec
;
1714 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
&& o
->context
->version
>= 13) {
1717 /* If we weren't playing then it will take some time
1718 * until the audio will actually come out through the
1719 * speakers. Since we follow that timing here, we need
1720 * to try to fix this up */
1722 su
= pa_bytes_to_usec((uint64_t) i
->since_underrun
, &o
->stream
->sample_spec
);
1724 if (su
< i
->sink_usec
)
1725 x
+= i
->sink_usec
- su
;
1729 pa_smoother_pause(o
->stream
->smoother
, x
);
1731 /* Update the smoother */
1732 if ((o
->stream
->direction
== PA_STREAM_PLAYBACK
&& !i
->read_index_corrupt
) ||
1733 (o
->stream
->direction
== PA_STREAM_RECORD
&& !i
->write_index_corrupt
))
1734 pa_smoother_put(o
->stream
->smoother
, u
, calc_time(o
->stream
, TRUE
));
1737 pa_smoother_resume(o
->stream
->smoother
, x
, TRUE
);
1741 o
->stream
->auto_timing_update_requested
= FALSE
;
1743 if (o
->stream
->latency_update_callback
)
1744 o
->stream
->latency_update_callback(o
->stream
, o
->stream
->latency_update_userdata
);
1746 if (o
->callback
&& o
->stream
&& o
->stream
->state
== PA_STREAM_READY
) {
1747 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
1748 cb(o
->stream
, o
->stream
->timing_info_valid
, o
->userdata
);
1753 pa_operation_done(o
);
1754 pa_operation_unref(o
);
1757 pa_operation
* pa_stream_update_timing_info(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
1765 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1767 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1768 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1769 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1771 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1772 /* Find a place to store the write_index correction data for this entry */
1773 cidx
= (s
->current_write_index_correction
+ 1) % PA_MAX_WRITE_INDEX_CORRECTIONS
;
1775 /* Check if we could allocate a correction slot. If not, there are too many outstanding queries */
1776 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !s
->write_index_corrections
[cidx
].valid
, PA_ERR_INTERNAL
);
1778 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
1780 t
= pa_tagstruct_command(
1782 (uint32_t) (s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_GET_PLAYBACK_LATENCY
: PA_COMMAND_GET_RECORD_LATENCY
),
1784 pa_tagstruct_putu32(t
, s
->channel
);
1785 pa_tagstruct_put_timeval(t
, pa_gettimeofday(&now
));
1787 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1788 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, stream_get_timing_info_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1790 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1791 /* Fill in initial correction data */
1793 s
->current_write_index_correction
= cidx
;
1795 s
->write_index_corrections
[cidx
].valid
= TRUE
;
1796 s
->write_index_corrections
[cidx
].absolute
= FALSE
;
1797 s
->write_index_corrections
[cidx
].corrupt
= FALSE
;
1798 s
->write_index_corrections
[cidx
].tag
= tag
;
1799 s
->write_index_corrections
[cidx
].value
= 0;
1805 void pa_stream_disconnect_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1806 pa_stream
*s
= userdata
;
1810 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1814 if (command
!= PA_COMMAND_REPLY
) {
1815 if (pa_context_handle_error(s
->context
, command
, t
, FALSE
) < 0)
1818 pa_stream_set_state(s
, PA_STREAM_FAILED
);
1820 } else if (!pa_tagstruct_eof(t
)) {
1821 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
1825 pa_stream_set_state(s
, PA_STREAM_TERMINATED
);
1831 int pa_stream_disconnect(pa_stream
*s
) {
1836 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1838 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
1839 PA_CHECK_VALIDITY(s
->context
, s
->channel_valid
, PA_ERR_BADSTATE
);
1840 PA_CHECK_VALIDITY(s
->context
, s
->context
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1844 t
= pa_tagstruct_command(
1846 (uint32_t) (s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_DELETE_PLAYBACK_STREAM
:
1847 (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_DELETE_RECORD_STREAM
: PA_COMMAND_DELETE_UPLOAD_STREAM
)),
1849 pa_tagstruct_putu32(t
, s
->channel
);
1850 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1851 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_disconnect_callback
, s
, NULL
);
1857 void pa_stream_set_read_callback(pa_stream
*s
, pa_stream_request_cb_t cb
, void *userdata
) {
1859 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1861 if (pa_detect_fork())
1864 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1867 s
->read_callback
= cb
;
1868 s
->read_userdata
= userdata
;
1871 void pa_stream_set_write_callback(pa_stream
*s
, pa_stream_request_cb_t cb
, void *userdata
) {
1873 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1875 if (pa_detect_fork())
1878 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1881 s
->write_callback
= cb
;
1882 s
->write_userdata
= userdata
;
1885 void pa_stream_set_state_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1887 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1889 if (pa_detect_fork())
1892 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1895 s
->state_callback
= cb
;
1896 s
->state_userdata
= userdata
;
1899 void pa_stream_set_overflow_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1901 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1903 if (pa_detect_fork())
1906 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1909 s
->overflow_callback
= cb
;
1910 s
->overflow_userdata
= userdata
;
1913 void pa_stream_set_underflow_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1915 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1917 if (pa_detect_fork())
1920 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1923 s
->underflow_callback
= cb
;
1924 s
->underflow_userdata
= userdata
;
1927 void pa_stream_set_latency_update_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1929 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1931 if (pa_detect_fork())
1934 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1937 s
->latency_update_callback
= cb
;
1938 s
->latency_update_userdata
= userdata
;
1941 void pa_stream_set_moved_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1943 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1945 if (pa_detect_fork())
1948 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1951 s
->moved_callback
= cb
;
1952 s
->moved_userdata
= userdata
;
1955 void pa_stream_set_suspended_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1957 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1959 if (pa_detect_fork())
1962 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1965 s
->suspended_callback
= cb
;
1966 s
->suspended_userdata
= userdata
;
1969 void pa_stream_set_started_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1971 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1973 if (pa_detect_fork())
1976 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1979 s
->started_callback
= cb
;
1980 s
->started_userdata
= userdata
;
1983 void pa_stream_set_event_callback(pa_stream
*s
, pa_stream_event_cb_t cb
, void *userdata
) {
1985 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1987 if (pa_detect_fork())
1990 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1993 s
->event_callback
= cb
;
1994 s
->event_userdata
= userdata
;
1997 void pa_stream_set_buffer_attr_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1999 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2001 if (pa_detect_fork())
2004 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
2007 s
->buffer_attr_callback
= cb
;
2008 s
->buffer_attr_userdata
= userdata
;
2011 void pa_stream_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
2012 pa_operation
*o
= userdata
;
2017 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
2022 if (command
!= PA_COMMAND_REPLY
) {
2023 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
2027 } else if (!pa_tagstruct_eof(t
)) {
2028 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2033 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
2034 cb(o
->stream
, success
, o
->userdata
);
2038 pa_operation_done(o
);
2039 pa_operation_unref(o
);
2042 pa_operation
* pa_stream_cork(pa_stream
*s
, int b
, pa_stream_success_cb_t cb
, void *userdata
) {
2048 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2050 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2051 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2052 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2054 /* Ask for a timing update before we cork/uncork to get the best
2055 * accuracy for the transport latency suitable for the
2056 * check_smoother_status() call in the started callback */
2057 request_auto_timing_update(s
, TRUE
);
2061 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2063 t
= pa_tagstruct_command(
2065 (uint32_t) (s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_CORK_PLAYBACK_STREAM
: PA_COMMAND_CORK_RECORD_STREAM
),
2067 pa_tagstruct_putu32(t
, s
->channel
);
2068 pa_tagstruct_put_boolean(t
, !!b
);
2069 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2070 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_simple_ack_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
2072 check_smoother_status(s
, FALSE
, FALSE
, FALSE
);
2074 /* This might cause the indexes to hang/start again, hence let's
2075 * request a timing update, after the cork/uncork, too */
2076 request_auto_timing_update(s
, TRUE
);
2081 static pa_operation
* stream_send_simple_command(pa_stream
*s
, uint32_t command
, pa_stream_success_cb_t cb
, void *userdata
) {
2087 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2089 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2090 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2092 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2094 t
= pa_tagstruct_command(s
->context
, command
, &tag
);
2095 pa_tagstruct_putu32(t
, s
->channel
);
2096 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2097 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_simple_ack_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
2102 pa_operation
* pa_stream_flush(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
2106 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2108 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2109 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2110 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2112 /* Ask for a timing update *before* the flush, so that the
2113 * transport usec is as up to date as possible when we get the
2114 * underflow message and update the smoother status*/
2115 request_auto_timing_update(s
, TRUE
);
2117 if (!(o
= stream_send_simple_command(s
, (uint32_t) (s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_FLUSH_PLAYBACK_STREAM
: PA_COMMAND_FLUSH_RECORD_STREAM
), cb
, userdata
)))
2120 if (s
->direction
== PA_STREAM_PLAYBACK
) {
2122 if (s
->write_index_corrections
[s
->current_write_index_correction
].valid
)
2123 s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
= TRUE
;
2125 if (s
->buffer_attr
.prebuf
> 0)
2126 check_smoother_status(s
, FALSE
, FALSE
, TRUE
);
2128 /* This will change the write index, but leave the
2129 * read index untouched. */
2130 invalidate_indexes(s
, FALSE
, TRUE
);
2133 /* For record streams this has no influence on the write
2134 * index, but the read index might jump. */
2135 invalidate_indexes(s
, TRUE
, FALSE
);
2140 pa_operation
* pa_stream_prebuf(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
2144 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2146 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2147 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2148 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
);
2149 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->buffer_attr
.prebuf
> 0, PA_ERR_BADSTATE
);
2151 /* Ask for a timing update before we cork/uncork to get the best
2152 * accuracy for the transport latency suitable for the
2153 * check_smoother_status() call in the started callback */
2154 request_auto_timing_update(s
, TRUE
);
2156 if (!(o
= stream_send_simple_command(s
, PA_COMMAND_PREBUF_PLAYBACK_STREAM
, cb
, userdata
)))
2159 /* This might cause the read index to hang again, hence
2160 * let's request a timing update */
2161 request_auto_timing_update(s
, TRUE
);
2166 pa_operation
* pa_stream_trigger(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
2170 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2172 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2173 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2174 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
);
2175 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->buffer_attr
.prebuf
> 0, PA_ERR_BADSTATE
);
2177 /* Ask for a timing update before we cork/uncork to get the best
2178 * accuracy for the transport latency suitable for the
2179 * check_smoother_status() call in the started callback */
2180 request_auto_timing_update(s
, TRUE
);
2182 if (!(o
= stream_send_simple_command(s
, PA_COMMAND_TRIGGER_PLAYBACK_STREAM
, cb
, userdata
)))
2185 /* This might cause the read index to start moving again, hence
2186 * let's request a timing update */
2187 request_auto_timing_update(s
, TRUE
);
2192 pa_operation
* pa_stream_set_name(pa_stream
*s
, const char *name
, pa_stream_success_cb_t cb
, void *userdata
) {
2196 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2199 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2200 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2201 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2203 if (s
->context
->version
>= 13) {
2204 pa_proplist
*p
= pa_proplist_new();
2206 pa_proplist_sets(p
, PA_PROP_MEDIA_NAME
, name
);
2207 o
= pa_stream_proplist_update(s
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
2208 pa_proplist_free(p
);
2213 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2214 t
= pa_tagstruct_command(
2216 (uint32_t) (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_SET_RECORD_STREAM_NAME
: PA_COMMAND_SET_PLAYBACK_STREAM_NAME
),
2218 pa_tagstruct_putu32(t
, s
->channel
);
2219 pa_tagstruct_puts(t
, name
);
2220 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2221 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_simple_ack_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
2227 int pa_stream_get_time(pa_stream
*s
, pa_usec_t
*r_usec
) {
2231 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2233 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2234 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2235 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2236 PA_CHECK_VALIDITY(s
->context
, s
->timing_info_valid
, PA_ERR_NODATA
);
2237 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_PLAYBACK
|| !s
->timing_info
.read_index_corrupt
, PA_ERR_NODATA
);
2238 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_RECORD
|| !s
->timing_info
.write_index_corrupt
, PA_ERR_NODATA
);
2241 usec
= pa_smoother_get(s
->smoother
, pa_rtclock_now());
2243 usec
= calc_time(s
, FALSE
);
2245 /* Make sure the time runs monotonically */
2246 if (!(s
->flags
& PA_STREAM_NOT_MONOTONIC
)) {
2247 if (usec
< s
->previous_time
)
2248 usec
= s
->previous_time
;
2250 s
->previous_time
= usec
;
2259 static pa_usec_t
time_counter_diff(pa_stream
*s
, pa_usec_t a
, pa_usec_t b
, int *negative
) {
2261 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2269 if (negative
&& s
->direction
== PA_STREAM_RECORD
) {
2277 int pa_stream_get_latency(pa_stream
*s
, pa_usec_t
*r_usec
, int *negative
) {
2283 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2286 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2287 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2288 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2289 PA_CHECK_VALIDITY(s
->context
, s
->timing_info_valid
, PA_ERR_NODATA
);
2290 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_PLAYBACK
|| !s
->timing_info
.write_index_corrupt
, PA_ERR_NODATA
);
2291 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_RECORD
|| !s
->timing_info
.read_index_corrupt
, PA_ERR_NODATA
);
2293 if ((r
= pa_stream_get_time(s
, &t
)) < 0)
2296 if (s
->direction
== PA_STREAM_PLAYBACK
)
2297 cindex
= s
->timing_info
.write_index
;
2299 cindex
= s
->timing_info
.read_index
;
2304 c
= pa_bytes_to_usec((uint64_t) cindex
, &s
->sample_spec
);
2306 if (s
->direction
== PA_STREAM_PLAYBACK
)
2307 *r_usec
= time_counter_diff(s
, c
, t
, negative
);
2309 *r_usec
= time_counter_diff(s
, t
, c
, negative
);
2314 const pa_timing_info
* pa_stream_get_timing_info(pa_stream
*s
) {
2316 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2318 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2319 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2320 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2321 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->timing_info_valid
, PA_ERR_NODATA
);
2323 return &s
->timing_info
;
2326 const pa_sample_spec
* pa_stream_get_sample_spec(pa_stream
*s
) {
2328 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2330 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2332 return &s
->sample_spec
;
2335 const pa_channel_map
* pa_stream_get_channel_map(pa_stream
*s
) {
2337 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2339 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2341 return &s
->channel_map
;
2344 const pa_buffer_attr
* pa_stream_get_buffer_attr(pa_stream
*s
) {
2346 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2348 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2349 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2350 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 9, PA_ERR_NOTSUPPORTED
);
2352 return &s
->buffer_attr
;
2355 static void stream_set_buffer_attr_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
2356 pa_operation
*o
= userdata
;
2361 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
2366 if (command
!= PA_COMMAND_REPLY
) {
2367 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
2372 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
) {
2373 if (pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.maxlength
) < 0 ||
2374 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.tlength
) < 0 ||
2375 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.prebuf
) < 0 ||
2376 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.minreq
) < 0) {
2377 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2380 } else if (o
->stream
->direction
== PA_STREAM_RECORD
) {
2381 if (pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.maxlength
) < 0 ||
2382 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.fragsize
) < 0) {
2383 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2388 if (o
->stream
->context
->version
>= 13) {
2391 if (pa_tagstruct_get_usec(t
, &usec
) < 0) {
2392 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2396 if (o
->stream
->direction
== PA_STREAM_RECORD
)
2397 o
->stream
->timing_info
.configured_source_usec
= usec
;
2399 o
->stream
->timing_info
.configured_sink_usec
= usec
;
2402 if (!pa_tagstruct_eof(t
)) {
2403 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2409 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
2410 cb(o
->stream
, success
, o
->userdata
);
2414 pa_operation_done(o
);
2415 pa_operation_unref(o
);
2419 pa_operation
* pa_stream_set_buffer_attr(pa_stream
*s
, const pa_buffer_attr
*attr
, pa_stream_success_cb_t cb
, void *userdata
) {
2425 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2428 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2429 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2430 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2431 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2433 /* Ask for a timing update before we cork/uncork to get the best
2434 * accuracy for the transport latency suitable for the
2435 * check_smoother_status() call in the started callback */
2436 request_auto_timing_update(s
, TRUE
);
2438 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2440 t
= pa_tagstruct_command(
2442 (uint32_t) (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR
: PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR
),
2444 pa_tagstruct_putu32(t
, s
->channel
);
2446 pa_tagstruct_putu32(t
, attr
->maxlength
);
2448 if (s
->direction
== PA_STREAM_PLAYBACK
)
2451 PA_TAG_U32
, attr
->tlength
,
2452 PA_TAG_U32
, attr
->prebuf
,
2453 PA_TAG_U32
, attr
->minreq
,
2456 pa_tagstruct_putu32(t
, attr
->fragsize
);
2458 if (s
->context
->version
>= 13)
2459 pa_tagstruct_put_boolean(t
, !!(s
->flags
& PA_STREAM_ADJUST_LATENCY
));
2461 if (s
->context
->version
>= 14)
2462 pa_tagstruct_put_boolean(t
, !!(s
->flags
& PA_STREAM_EARLY_REQUESTS
));
2464 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2465 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, stream_set_buffer_attr_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
2467 /* This might cause changes in the read/write indexex, hence let's
2468 * request a timing update */
2469 request_auto_timing_update(s
, TRUE
);
2474 uint32_t pa_stream_get_device_index(pa_stream
*s
) {
2476 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2478 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
2479 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2480 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2481 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
2482 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->device_index
!= PA_INVALID_INDEX
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2484 return s
->device_index
;
2487 const char *pa_stream_get_device_name(pa_stream
*s
) {
2489 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2491 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2492 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2493 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2494 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2495 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->device_name
, PA_ERR_BADSTATE
);
2497 return s
->device_name
;
2500 int pa_stream_is_suspended(pa_stream
*s
) {
2502 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2504 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2505 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2506 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2507 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2509 return s
->suspended
;
2512 int pa_stream_is_corked(pa_stream
*s
) {
2514 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2516 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2517 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2518 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2523 static void stream_update_sample_rate_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
2524 pa_operation
*o
= userdata
;
2529 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
2534 if (command
!= PA_COMMAND_REPLY
) {
2535 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
2541 if (!pa_tagstruct_eof(t
)) {
2542 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2547 o
->stream
->sample_spec
.rate
= PA_PTR_TO_UINT(o
->private);
2548 pa_assert(pa_sample_spec_valid(&o
->stream
->sample_spec
));
2551 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
2552 cb(o
->stream
, success
, o
->userdata
);
2556 pa_operation_done(o
);
2557 pa_operation_unref(o
);
2561 pa_operation
*pa_stream_update_sample_rate(pa_stream
*s
, uint32_t rate
, pa_stream_success_cb_t cb
, void *userdata
) {
2567 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2569 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2570 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, rate
> 0 && rate
<= PA_RATE_MAX
, PA_ERR_INVALID
);
2571 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2572 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2573 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->flags
& PA_STREAM_VARIABLE_RATE
, PA_ERR_BADSTATE
);
2574 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2576 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2577 o
->private = PA_UINT_TO_PTR(rate
);
2579 t
= pa_tagstruct_command(
2581 (uint32_t) (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE
: PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE
),
2583 pa_tagstruct_putu32(t
, s
->channel
);
2584 pa_tagstruct_putu32(t
, rate
);
2586 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2587 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, stream_update_sample_rate_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
2592 pa_operation
*pa_stream_proplist_update(pa_stream
*s
, pa_update_mode_t mode
, pa_proplist
*p
, pa_stream_success_cb_t cb
, void *userdata
) {
2598 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2600 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2601 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
2602 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2603 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2604 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
);
2606 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2608 t
= pa_tagstruct_command(
2610 (uint32_t) (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST
: PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST
),
2612 pa_tagstruct_putu32(t
, s
->channel
);
2613 pa_tagstruct_putu32(t
, (uint32_t) mode
);
2614 pa_tagstruct_put_proplist(t
, p
);
2616 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2617 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_simple_ack_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
2619 /* Please note that we don't update s->proplist here, because we
2620 * don't export that field */
2625 pa_operation
*pa_stream_proplist_remove(pa_stream
*s
, const char *const keys
[], pa_stream_success_cb_t cb
, void *userdata
) {
2629 const char * const*k
;
2632 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2634 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2635 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, keys
&& keys
[0], PA_ERR_INVALID
);
2636 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2637 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2638 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
);
2640 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2642 t
= pa_tagstruct_command(
2644 (uint32_t) (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST
: PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST
),
2646 pa_tagstruct_putu32(t
, s
->channel
);
2648 for (k
= keys
; *k
; k
++)
2649 pa_tagstruct_puts(t
, *k
);
2651 pa_tagstruct_puts(t
, NULL
);
2653 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2654 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_simple_ack_callback
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
2656 /* Please note that we don't update s->proplist here, because we
2657 * don't export that field */
2662 int pa_stream_set_monitor_stream(pa_stream
*s
, uint32_t sink_input_idx
) {
2664 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2666 PA_CHECK_VALIDITY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
);
2667 PA_CHECK_VALIDITY(s
->context
, sink_input_idx
!= PA_INVALID_INDEX
, PA_ERR_INVALID
);
2668 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_UNCONNECTED
, PA_ERR_BADSTATE
);
2669 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
);
2671 s
->direct_on_input
= sink_input_idx
;
2676 uint32_t pa_stream_get_monitor_stream(pa_stream
*s
) {
2678 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2680 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
2681 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direct_on_input
!= PA_INVALID_INDEX
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2682 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
2684 return s
->direct_on_input
;