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 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/timeval.h>
33 #include <pulse/xmalloc.h>
35 #include <pulsecore/pstream-util.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/hashmap.h>
38 #include <pulsecore/macro.h>
39 #include <pulsecore/rtclock.h>
43 #define LATENCY_IPOL_INTERVAL_USEC (333*PA_USEC_PER_MSEC)
45 #define SMOOTHER_ADJUST_TIME (1000*PA_USEC_PER_MSEC)
46 #define SMOOTHER_HISTORY_TIME (5000*PA_USEC_PER_MSEC)
47 #define SMOOTHER_MIN_HISTORY (4)
49 pa_stream
*pa_stream_new(pa_context
*c
, const char *name
, const pa_sample_spec
*ss
, const pa_channel_map
*map
) {
50 return pa_stream_new_with_proplist(c
, name
, ss
, map
, NULL
);
53 static void reset_callbacks(pa_stream
*s
) {
54 s
->read_callback
= NULL
;
55 s
->read_userdata
= NULL
;
56 s
->write_callback
= NULL
;
57 s
->write_userdata
= NULL
;
58 s
->state_callback
= NULL
;
59 s
->state_userdata
= NULL
;
60 s
->overflow_callback
= NULL
;
61 s
->overflow_userdata
= NULL
;
62 s
->underflow_callback
= NULL
;
63 s
->underflow_userdata
= NULL
;
64 s
->latency_update_callback
= NULL
;
65 s
->latency_update_userdata
= NULL
;
66 s
->moved_callback
= NULL
;
67 s
->moved_userdata
= NULL
;
68 s
->suspended_callback
= NULL
;
69 s
->suspended_userdata
= NULL
;
70 s
->started_callback
= NULL
;
71 s
->started_userdata
= NULL
;
74 pa_stream
*pa_stream_new_with_proplist(
77 const pa_sample_spec
*ss
,
78 const pa_channel_map
*map
,
86 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
88 PA_CHECK_VALIDITY_RETURN_NULL(c
, ss
&& pa_sample_spec_valid(ss
), PA_ERR_INVALID
);
89 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 12 || (ss
->format
!= PA_SAMPLE_S32LE
|| ss
->format
!= PA_SAMPLE_S32NE
), PA_ERR_NOTSUPPORTED
);
90 PA_CHECK_VALIDITY_RETURN_NULL(c
, !map
|| (pa_channel_map_valid(map
) && map
->channels
== ss
->channels
), PA_ERR_INVALID
);
91 PA_CHECK_VALIDITY_RETURN_NULL(c
, name
|| (p
&& pa_proplist_contains(p
, PA_PROP_MEDIA_NAME
)), PA_ERR_INVALID
);
94 PA_CHECK_VALIDITY_RETURN_NULL(c
, map
= pa_channel_map_init_auto(&tmap
, ss
->channels
, PA_CHANNEL_MAP_DEFAULT
), PA_ERR_INVALID
);
96 s
= pa_xnew(pa_stream
, 1);
99 s
->mainloop
= c
->mainloop
;
101 s
->direction
= PA_STREAM_NODIRECTION
;
102 s
->state
= PA_STREAM_UNCONNECTED
;
105 s
->sample_spec
= *ss
;
106 s
->channel_map
= *map
;
108 s
->direct_on_input
= PA_INVALID_INDEX
;
110 s
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
112 pa_proplist_sets(s
->proplist
, PA_PROP_MEDIA_NAME
, name
);
115 s
->channel_valid
= FALSE
;
116 s
->syncid
= c
->csyncid
++;
117 s
->stream_index
= PA_INVALID_INDEX
;
119 s
->requested_bytes
= 0;
120 memset(&s
->buffer_attr
, 0, sizeof(s
->buffer_attr
));
122 /* We initialize der target length here, so that if the user
123 * passes no explicit buffering metrics the default is similar to
124 * what older PA versions provided. */
125 s
->buffer_attr
.tlength
= pa_usec_to_bytes(250*PA_USEC_PER_MSEC
, ss
); /* 250ms of buffering */
127 s
->device_index
= PA_INVALID_INDEX
;
128 s
->device_name
= NULL
;
129 s
->suspended
= FALSE
;
131 pa_memchunk_reset(&s
->peek_memchunk
);
134 s
->record_memblockq
= NULL
;
138 memset(&s
->timing_info
, 0, sizeof(s
->timing_info
));
139 s
->timing_info_valid
= FALSE
;
141 s
->previous_time
= 0;
143 s
->read_index_not_before
= 0;
144 s
->write_index_not_before
= 0;
145 for (i
= 0; i
< PA_MAX_WRITE_INDEX_CORRECTIONS
; i
++)
146 s
->write_index_corrections
[i
].valid
= 0;
147 s
->current_write_index_correction
= 0;
149 s
->auto_timing_update_event
= NULL
;
150 s
->auto_timing_update_requested
= FALSE
;
156 /* Refcounting is strictly one-way: from the "bigger" to the "smaller" object. */
157 PA_LLIST_PREPEND(pa_stream
, c
->streams
, s
);
163 static void stream_unlink(pa_stream
*s
) {
170 /* Detach from context */
172 /* Unref all operatio object that point to us */
173 for (o
= s
->context
->operations
; o
; o
= n
) {
177 pa_operation_cancel(o
);
180 /* Drop all outstanding replies for this stream */
181 if (s
->context
->pdispatch
)
182 pa_pdispatch_unregister_reply(s
->context
->pdispatch
, s
);
184 if (s
->channel_valid
) {
185 pa_dynarray_put((s
->direction
== PA_STREAM_PLAYBACK
) ? s
->context
->playback_streams
: s
->context
->record_streams
, s
->channel
, NULL
);
187 s
->channel_valid
= FALSE
;
190 PA_LLIST_REMOVE(pa_stream
, s
->context
->streams
, s
);
195 if (s
->auto_timing_update_event
) {
196 pa_assert(s
->mainloop
);
197 s
->mainloop
->time_free(s
->auto_timing_update_event
);
203 static void stream_free(pa_stream
*s
) {
208 if (s
->peek_memchunk
.memblock
) {
210 pa_memblock_release(s
->peek_memchunk
.memblock
);
211 pa_memblock_unref(s
->peek_memchunk
.memblock
);
214 if (s
->record_memblockq
)
215 pa_memblockq_free(s
->record_memblockq
);
218 pa_proplist_free(s
->proplist
);
221 pa_smoother_free(s
->smoother
);
223 pa_xfree(s
->device_name
);
227 void pa_stream_unref(pa_stream
*s
) {
229 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
231 if (PA_REFCNT_DEC(s
) <= 0)
235 pa_stream
* pa_stream_ref(pa_stream
*s
) {
237 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
243 pa_stream_state_t
pa_stream_get_state(pa_stream
*s
) {
245 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
250 pa_context
* pa_stream_get_context(pa_stream
*s
) {
252 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
257 uint32_t pa_stream_get_index(pa_stream
*s
) {
259 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
261 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
263 return s
->stream_index
;
266 void pa_stream_set_state(pa_stream
*s
, pa_stream_state_t st
) {
268 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
277 if (s
->state_callback
)
278 s
->state_callback(s
, s
->state_userdata
);
280 if ((st
== PA_STREAM_FAILED
|| st
== PA_STREAM_TERMINATED
))
286 static void request_auto_timing_update(pa_stream
*s
, pa_bool_t force
) {
288 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
290 if (!(s
->flags
& PA_STREAM_AUTO_TIMING_UPDATE
))
293 if (s
->state
== PA_STREAM_READY
&&
294 (force
|| !s
->auto_timing_update_requested
)) {
297 /* pa_log("automatically requesting new timing data"); */
299 if ((o
= pa_stream_update_timing_info(s
, NULL
, NULL
))) {
300 pa_operation_unref(o
);
301 s
->auto_timing_update_requested
= TRUE
;
305 if (s
->auto_timing_update_event
) {
307 pa_gettimeofday(&next
);
308 pa_timeval_add(&next
, LATENCY_IPOL_INTERVAL_USEC
);
309 s
->mainloop
->time_restart(s
->auto_timing_update_event
, &next
);
313 void pa_command_stream_killed(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
314 pa_context
*c
= userdata
;
319 pa_assert(command
== PA_COMMAND_PLAYBACK_STREAM_KILLED
|| command
== PA_COMMAND_RECORD_STREAM_KILLED
);
322 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
326 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
327 !pa_tagstruct_eof(t
)) {
328 pa_context_fail(c
, PA_ERR_PROTOCOL
);
332 if (!(s
= pa_dynarray_get(command
== PA_COMMAND_PLAYBACK_STREAM_KILLED
? c
->playback_streams
: c
->record_streams
, channel
)))
335 if (s
->state
!= PA_STREAM_READY
)
338 pa_context_set_error(c
, PA_ERR_KILLED
);
339 pa_stream_set_state(s
, PA_STREAM_FAILED
);
345 static void check_smoother_status(pa_stream
*s
, pa_bool_t aposteriori
, pa_bool_t force_start
, pa_bool_t force_stop
) {
349 pa_assert(!force_start
|| !force_stop
);
354 x
= pa_rtclock_usec();
356 if (s
->timing_info_valid
) {
358 x
-= s
->timing_info
.transport_usec
;
360 x
+= s
->timing_info
.transport_usec
;
362 if (s
->direction
== PA_STREAM_PLAYBACK
)
363 /* it takes a while until the pause/resume is actually
365 x
+= s
->timing_info
.sink_usec
;
367 /* Data froma while back will be dropped */
368 x
-= s
->timing_info
.source_usec
;
371 if (s
->suspended
|| s
->corked
|| force_stop
)
372 pa_smoother_pause(s
->smoother
, x
);
373 else if (force_start
|| s
->buffer_attr
.prebuf
== 0)
374 pa_smoother_resume(s
->smoother
, x
);
376 /* Please note that we have no idea if playback actually started
377 * if prebuf is non-zero! */
380 void pa_command_stream_moved(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
381 pa_context
*c
= userdata
;
388 uint32_t maxlength
= 0, fragsize
= 0, minreq
= 0, tlength
= 0, prebuf
= 0;
391 pa_assert(command
== PA_COMMAND_PLAYBACK_STREAM_MOVED
|| command
== PA_COMMAND_RECORD_STREAM_MOVED
);
394 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
398 if (c
->version
< 12) {
399 pa_context_fail(c
, PA_ERR_PROTOCOL
);
403 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
404 pa_tagstruct_getu32(t
, &di
) < 0 ||
405 pa_tagstruct_gets(t
, &dn
) < 0 ||
406 pa_tagstruct_get_boolean(t
, &suspended
) < 0) {
407 pa_context_fail(c
, PA_ERR_PROTOCOL
);
411 if (c
->version
>= 13) {
413 if (command
== PA_COMMAND_RECORD_STREAM_MOVED
) {
414 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
415 pa_tagstruct_getu32(t
, &fragsize
) < 0 ||
416 pa_tagstruct_get_usec(t
, &usec
) < 0) {
417 pa_context_fail(c
, PA_ERR_PROTOCOL
);
421 if (pa_tagstruct_getu32(t
, &maxlength
) < 0 ||
422 pa_tagstruct_getu32(t
, &tlength
) < 0 ||
423 pa_tagstruct_getu32(t
, &prebuf
) < 0 ||
424 pa_tagstruct_getu32(t
, &minreq
) < 0 ||
425 pa_tagstruct_get_usec(t
, &usec
) < 0) {
426 pa_context_fail(c
, PA_ERR_PROTOCOL
);
432 if (!pa_tagstruct_eof(t
)) {
433 pa_context_fail(c
, PA_ERR_PROTOCOL
);
437 if (!dn
|| di
== PA_INVALID_INDEX
) {
438 pa_context_fail(c
, PA_ERR_PROTOCOL
);
442 if (!(s
= pa_dynarray_get(command
== PA_COMMAND_PLAYBACK_STREAM_MOVED
? c
->playback_streams
: c
->record_streams
, channel
)))
445 if (s
->state
!= PA_STREAM_READY
)
448 if (c
->version
>= 13) {
449 if (s
->direction
== PA_STREAM_RECORD
)
450 s
->timing_info
.configured_source_usec
= usec
;
452 s
->timing_info
.configured_sink_usec
= usec
;
454 s
->buffer_attr
.maxlength
= maxlength
;
455 s
->buffer_attr
.fragsize
= fragsize
;
456 s
->buffer_attr
.tlength
= tlength
;
457 s
->buffer_attr
.prebuf
= prebuf
;
458 s
->buffer_attr
.minreq
= minreq
;
461 pa_xfree(s
->device_name
);
462 s
->device_name
= pa_xstrdup(dn
);
463 s
->device_index
= di
;
465 s
->suspended
= suspended
;
467 check_smoother_status(s
, TRUE
, FALSE
, FALSE
);
468 request_auto_timing_update(s
, TRUE
);
470 if (s
->moved_callback
)
471 s
->moved_callback(s
, s
->moved_userdata
);
477 void pa_command_stream_suspended(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
478 pa_context
*c
= userdata
;
484 pa_assert(command
== PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
|| command
== PA_COMMAND_RECORD_STREAM_SUSPENDED
);
487 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
491 if (c
->version
< 12) {
492 pa_context_fail(c
, PA_ERR_PROTOCOL
);
496 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
497 pa_tagstruct_get_boolean(t
, &suspended
) < 0 ||
498 !pa_tagstruct_eof(t
)) {
499 pa_context_fail(c
, PA_ERR_PROTOCOL
);
503 if (!(s
= pa_dynarray_get(command
== PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
? c
->playback_streams
: c
->record_streams
, channel
)))
506 if (s
->state
!= PA_STREAM_READY
)
509 s
->suspended
= suspended
;
511 check_smoother_status(s
, TRUE
, FALSE
, FALSE
);
512 request_auto_timing_update(s
, TRUE
);
514 if (s
->suspended_callback
)
515 s
->suspended_callback(s
, s
->suspended_userdata
);
521 void pa_command_stream_started(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
522 pa_context
*c
= userdata
;
527 pa_assert(command
== PA_COMMAND_STARTED
);
530 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
534 if (c
->version
< 13) {
535 pa_context_fail(c
, PA_ERR_PROTOCOL
);
539 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
540 !pa_tagstruct_eof(t
)) {
541 pa_context_fail(c
, PA_ERR_PROTOCOL
);
545 if (!(s
= pa_dynarray_get(c
->playback_streams
, channel
)))
548 if (s
->state
!= PA_STREAM_READY
)
551 check_smoother_status(s
, TRUE
, TRUE
, FALSE
);
552 request_auto_timing_update(s
, TRUE
);
554 if (s
->started_callback
)
555 s
->started_callback(s
, s
->suspended_userdata
);
561 void pa_command_request(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
563 pa_context
*c
= userdata
;
564 uint32_t bytes
, channel
;
567 pa_assert(command
== PA_COMMAND_REQUEST
);
570 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
574 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
575 pa_tagstruct_getu32(t
, &bytes
) < 0 ||
576 !pa_tagstruct_eof(t
)) {
577 pa_context_fail(c
, PA_ERR_PROTOCOL
);
581 if (!(s
= pa_dynarray_get(c
->playback_streams
, channel
)))
584 if (s
->state
!= PA_STREAM_READY
)
587 s
->requested_bytes
+= bytes
;
589 if (s
->requested_bytes
> 0 && s
->write_callback
)
590 s
->write_callback(s
, s
->requested_bytes
, s
->write_userdata
);
596 void pa_command_overflow_or_underflow(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
598 pa_context
*c
= userdata
;
602 pa_assert(command
== PA_COMMAND_OVERFLOW
|| command
== PA_COMMAND_UNDERFLOW
);
605 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
609 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
610 !pa_tagstruct_eof(t
)) {
611 pa_context_fail(c
, PA_ERR_PROTOCOL
);
615 if (!(s
= pa_dynarray_get(c
->playback_streams
, channel
)))
618 if (s
->state
!= PA_STREAM_READY
)
621 if (s
->buffer_attr
.prebuf
> 0)
622 check_smoother_status(s
, TRUE
, FALSE
, TRUE
);
624 request_auto_timing_update(s
, TRUE
);
626 if (command
== PA_COMMAND_OVERFLOW
) {
627 if (s
->overflow_callback
)
628 s
->overflow_callback(s
, s
->overflow_userdata
);
629 } else if (command
== PA_COMMAND_UNDERFLOW
) {
630 if (s
->underflow_callback
)
631 s
->underflow_callback(s
, s
->underflow_userdata
);
638 static void invalidate_indexes(pa_stream
*s
, pa_bool_t r
, pa_bool_t w
) {
640 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
642 /* pa_log("invalidate r:%u w:%u tag:%u", r, w, s->context->ctag); */
644 if (s
->state
!= PA_STREAM_READY
)
648 s
->write_index_not_before
= s
->context
->ctag
;
650 if (s
->timing_info_valid
)
651 s
->timing_info
.write_index_corrupt
= TRUE
;
653 /* pa_log("write_index invalidated"); */
657 s
->read_index_not_before
= s
->context
->ctag
;
659 if (s
->timing_info_valid
)
660 s
->timing_info
.read_index_corrupt
= TRUE
;
662 /* pa_log("read_index invalidated"); */
665 request_auto_timing_update(s
, TRUE
);
668 static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api
*m
, PA_GCC_UNUSED pa_time_event
*e
, PA_GCC_UNUSED
const struct timeval
*tv
, void *userdata
) {
669 pa_stream
*s
= userdata
;
672 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
675 request_auto_timing_update(s
, FALSE
);
679 static void create_stream_complete(pa_stream
*s
) {
681 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
682 pa_assert(s
->state
== PA_STREAM_CREATING
);
684 pa_stream_set_state(s
, PA_STREAM_READY
);
686 if (s
->requested_bytes
> 0 && s
->write_callback
)
687 s
->write_callback(s
, s
->requested_bytes
, s
->write_userdata
);
689 if (s
->flags
& PA_STREAM_AUTO_TIMING_UPDATE
) {
691 pa_gettimeofday(&tv
);
692 tv
.tv_usec
+= LATENCY_IPOL_INTERVAL_USEC
; /* every 100 ms */
693 pa_assert(!s
->auto_timing_update_event
);
694 s
->auto_timing_update_event
= s
->mainloop
->time_new(s
->mainloop
, &tv
, &auto_timing_update_callback
, s
);
696 request_auto_timing_update(s
, TRUE
);
699 check_smoother_status(s
, TRUE
, FALSE
, FALSE
);
702 static void automatic_buffer_attr(pa_stream
*s
, pa_buffer_attr
*attr
, const pa_sample_spec
*ss
) {
707 if (s
->context
->version
>= 13)
710 /* Version older than 0.9.10 didn't do server side buffer_attr
711 * selection, hence we have to fake it on the client side. */
713 /* We choose fairly conservative values here, to not confuse
714 * old clients with extremely large playback buffers */
716 if (!attr
->maxlength
<= 0)
717 attr
->maxlength
= 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */
719 if (!attr
->tlength
<= 0)
720 attr
->tlength
= pa_usec_to_bytes(250*PA_USEC_PER_MSEC
, ss
); /* 250ms of buffering */
722 if (!attr
->minreq
<= 0)
723 attr
->minreq
= (attr
->tlength
)/5; /* Ask for more data when there are only 200ms left in the playback buffer */
726 attr
->prebuf
= attr
->tlength
; /* Start to play only when the playback is fully filled up once */
729 attr
->fragsize
= attr
->tlength
; /* Pass data to the app only when the buffer is filled up once */
732 void pa_create_stream_callback(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
733 pa_stream
*s
= userdata
;
737 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
738 pa_assert(s
->state
== PA_STREAM_CREATING
);
742 if (command
!= PA_COMMAND_REPLY
) {
743 if (pa_context_handle_error(s
->context
, command
, t
, FALSE
) < 0)
746 pa_stream_set_state(s
, PA_STREAM_FAILED
);
750 if (pa_tagstruct_getu32(t
, &s
->channel
) < 0 ||
751 s
->channel
== PA_INVALID_INDEX
||
752 ((s
->direction
!= PA_STREAM_UPLOAD
) && (pa_tagstruct_getu32(t
, &s
->stream_index
) < 0 || s
->stream_index
== PA_INVALID_INDEX
)) ||
753 ((s
->direction
!= PA_STREAM_RECORD
) && pa_tagstruct_getu32(t
, &s
->requested_bytes
) < 0)) {
754 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
758 if (s
->context
->version
>= 9) {
759 if (s
->direction
== PA_STREAM_PLAYBACK
) {
760 if (pa_tagstruct_getu32(t
, &s
->buffer_attr
.maxlength
) < 0 ||
761 pa_tagstruct_getu32(t
, &s
->buffer_attr
.tlength
) < 0 ||
762 pa_tagstruct_getu32(t
, &s
->buffer_attr
.prebuf
) < 0 ||
763 pa_tagstruct_getu32(t
, &s
->buffer_attr
.minreq
) < 0) {
764 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
767 } else if (s
->direction
== PA_STREAM_RECORD
) {
768 if (pa_tagstruct_getu32(t
, &s
->buffer_attr
.maxlength
) < 0 ||
769 pa_tagstruct_getu32(t
, &s
->buffer_attr
.fragsize
) < 0) {
770 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
776 if (s
->context
->version
>= 12 && s
->direction
!= PA_STREAM_UPLOAD
) {
779 const char *dn
= NULL
;
782 if (pa_tagstruct_get_sample_spec(t
, &ss
) < 0 ||
783 pa_tagstruct_get_channel_map(t
, &cm
) < 0 ||
784 pa_tagstruct_getu32(t
, &s
->device_index
) < 0 ||
785 pa_tagstruct_gets(t
, &dn
) < 0 ||
786 pa_tagstruct_get_boolean(t
, &suspended
) < 0) {
787 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
791 if (!dn
|| s
->device_index
== PA_INVALID_INDEX
||
792 ss
.channels
!= cm
.channels
||
793 !pa_channel_map_valid(&cm
) ||
794 !pa_sample_spec_valid(&ss
) ||
795 (!(s
->flags
& PA_STREAM_FIX_FORMAT
) && ss
.format
!= s
->sample_spec
.format
) ||
796 (!(s
->flags
& PA_STREAM_FIX_RATE
) && ss
.rate
!= s
->sample_spec
.rate
) ||
797 (!(s
->flags
& PA_STREAM_FIX_CHANNELS
) && !pa_channel_map_equal(&cm
, &s
->channel_map
))) {
798 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
802 pa_xfree(s
->device_name
);
803 s
->device_name
= pa_xstrdup(dn
);
804 s
->suspended
= suspended
;
810 if (s
->context
->version
>= 13 && s
->direction
!= PA_STREAM_UPLOAD
) {
813 if (pa_tagstruct_get_usec(t
, &usec
) < 0) {
814 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
818 if (s
->direction
== PA_STREAM_RECORD
)
819 s
->timing_info
.configured_source_usec
= usec
;
821 s
->timing_info
.configured_sink_usec
= usec
;
824 if (!pa_tagstruct_eof(t
)) {
825 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
829 if (s
->direction
== PA_STREAM_RECORD
) {
830 pa_assert(!s
->record_memblockq
);
832 s
->record_memblockq
= pa_memblockq_new(
834 s
->buffer_attr
.maxlength
,
836 pa_frame_size(&s
->sample_spec
),
843 s
->channel_valid
= TRUE
;
844 pa_dynarray_put((s
->direction
== PA_STREAM_RECORD
) ? s
->context
->record_streams
: s
->context
->playback_streams
, s
->channel
, s
);
846 create_stream_complete(s
);
852 static int create_stream(
853 pa_stream_direction_t direction
,
856 const pa_buffer_attr
*attr
,
857 pa_stream_flags_t flags
,
858 const pa_cvolume
*volume
,
859 pa_stream
*sync_stream
) {
865 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
866 pa_assert(direction
== PA_STREAM_PLAYBACK
|| direction
== PA_STREAM_RECORD
);
868 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_UNCONNECTED
, PA_ERR_BADSTATE
);
869 PA_CHECK_VALIDITY(s
->context
, s
->direct_on_input
== PA_INVALID_INDEX
|| direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
);
870 PA_CHECK_VALIDITY(s
->context
, !(flags
& ~(PA_STREAM_START_CORKED
|
871 PA_STREAM_INTERPOLATE_TIMING
|
872 PA_STREAM_NOT_MONOTONOUS
|
873 PA_STREAM_AUTO_TIMING_UPDATE
|
874 PA_STREAM_NO_REMAP_CHANNELS
|
875 PA_STREAM_NO_REMIX_CHANNELS
|
876 PA_STREAM_FIX_FORMAT
|
878 PA_STREAM_FIX_CHANNELS
|
880 PA_STREAM_VARIABLE_RATE
|
881 PA_STREAM_PEAK_DETECT
|
882 PA_STREAM_START_MUTED
|
883 PA_STREAM_ADJUST_LATENCY
)), PA_ERR_INVALID
);
885 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 12 || !(flags
& PA_STREAM_VARIABLE_RATE
), PA_ERR_NOTSUPPORTED
);
886 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 13 || !(flags
& PA_STREAM_PEAK_DETECT
), PA_ERR_NOTSUPPORTED
);
887 /* Althought some of the other flags are not supported on older
888 * version, we don't check for them here, because it doesn't hurt
889 * when they are passed but actually not supported. This makes
890 * client development easier */
892 PA_CHECK_VALIDITY(s
->context
, direction
== PA_STREAM_PLAYBACK
|| !(flags
& (PA_STREAM_START_MUTED
)), PA_ERR_INVALID
);
893 PA_CHECK_VALIDITY(s
->context
, direction
== PA_STREAM_RECORD
|| !(flags
& (PA_STREAM_PEAK_DETECT
)), PA_ERR_INVALID
);
894 PA_CHECK_VALIDITY(s
->context
, !volume
|| volume
->channels
== s
->sample_spec
.channels
, PA_ERR_INVALID
);
895 PA_CHECK_VALIDITY(s
->context
, !sync_stream
|| (direction
== PA_STREAM_PLAYBACK
&& sync_stream
->direction
== PA_STREAM_PLAYBACK
), PA_ERR_INVALID
);
899 s
->direction
= direction
;
901 s
->corked
= !!(flags
& PA_STREAM_START_CORKED
);
904 s
->syncid
= sync_stream
->syncid
;
907 s
->buffer_attr
= *attr
;
908 automatic_buffer_attr(s
, &s
->buffer_attr
, &s
->sample_spec
);
910 if (flags
& PA_STREAM_INTERPOLATE_TIMING
) {
914 pa_smoother_free(s
->smoother
);
916 s
->smoother
= pa_smoother_new(SMOOTHER_ADJUST_TIME
, SMOOTHER_HISTORY_TIME
, !(flags
& PA_STREAM_NOT_MONOTONIC
), SMOOTHER_MIN_HISTORY
);
918 x
= pa_rtclock_usec();
919 pa_smoother_set_time_offset(s
->smoother
, x
);
920 pa_smoother_pause(s
->smoother
, x
);
924 dev
= s
->direction
== PA_STREAM_PLAYBACK
? s
->context
->conf
->default_sink
: s
->context
->conf
->default_source
;
926 t
= pa_tagstruct_command(
928 s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_CREATE_PLAYBACK_STREAM
: PA_COMMAND_CREATE_RECORD_STREAM
,
931 if (s
->context
->version
< 13)
932 pa_tagstruct_puts(t
, pa_proplist_gets(s
->proplist
, PA_PROP_MEDIA_NAME
));
936 PA_TAG_SAMPLE_SPEC
, &s
->sample_spec
,
937 PA_TAG_CHANNEL_MAP
, &s
->channel_map
,
938 PA_TAG_U32
, PA_INVALID_INDEX
,
940 PA_TAG_U32
, s
->buffer_attr
.maxlength
,
941 PA_TAG_BOOLEAN
, s
->corked
,
944 if (s
->direction
== PA_STREAM_PLAYBACK
) {
949 PA_TAG_U32
, s
->buffer_attr
.tlength
,
950 PA_TAG_U32
, s
->buffer_attr
.prebuf
,
951 PA_TAG_U32
, s
->buffer_attr
.minreq
,
952 PA_TAG_U32
, s
->syncid
,
956 volume
= pa_cvolume_reset(&cv
, s
->sample_spec
.channels
);
958 pa_tagstruct_put_cvolume(t
, volume
);
960 pa_tagstruct_putu32(t
, s
->buffer_attr
.fragsize
);
962 if (s
->context
->version
>= 12) {
965 PA_TAG_BOOLEAN
, flags
& PA_STREAM_NO_REMAP_CHANNELS
,
966 PA_TAG_BOOLEAN
, flags
& PA_STREAM_NO_REMIX_CHANNELS
,
967 PA_TAG_BOOLEAN
, flags
& PA_STREAM_FIX_FORMAT
,
968 PA_TAG_BOOLEAN
, flags
& PA_STREAM_FIX_RATE
,
969 PA_TAG_BOOLEAN
, flags
& PA_STREAM_FIX_CHANNELS
,
970 PA_TAG_BOOLEAN
, flags
& PA_STREAM_DONT_MOVE
,
971 PA_TAG_BOOLEAN
, flags
& PA_STREAM_VARIABLE_RATE
,
975 if (s
->context
->version
>= 13) {
977 if (s
->direction
== PA_STREAM_PLAYBACK
)
978 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_START_MUTED
);
980 pa_tagstruct_put_boolean(t
, flags
& PA_STREAM_PEAK_DETECT
);
984 PA_TAG_BOOLEAN
, flags
& PA_STREAM_ADJUST_LATENCY
,
985 PA_TAG_PROPLIST
, s
->proplist
,
988 if (s
->direction
== PA_STREAM_RECORD
)
989 pa_tagstruct_putu32(t
, s
->direct_on_input
);
992 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
993 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_create_stream_callback
, s
, NULL
);
995 pa_stream_set_state(s
, PA_STREAM_CREATING
);
1001 int pa_stream_connect_playback(
1004 const pa_buffer_attr
*attr
,
1005 pa_stream_flags_t flags
,
1007 pa_stream
*sync_stream
) {
1010 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1012 return create_stream(PA_STREAM_PLAYBACK
, s
, dev
, attr
, flags
, volume
, sync_stream
);
1015 int pa_stream_connect_record(
1018 const pa_buffer_attr
*attr
,
1019 pa_stream_flags_t flags
) {
1022 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1024 return create_stream(PA_STREAM_RECORD
, s
, dev
, attr
, flags
, NULL
, NULL
);
1027 int pa_stream_write(
1031 void (*free_cb
)(void *p
),
1033 pa_seek_mode_t seek
) {
1036 pa_seek_mode_t t_seek
;
1042 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1045 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1046 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
|| s
->direction
== PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1047 PA_CHECK_VALIDITY(s
->context
, seek
<= PA_SEEK_RELATIVE_END
, PA_ERR_INVALID
);
1048 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
|| (seek
== PA_SEEK_RELATIVE
&& offset
== 0), PA_ERR_INVALID
);
1058 while (t_length
> 0) {
1062 if (free_cb
&& !pa_pstream_get_shm(s
->context
->pstream
)) {
1063 chunk
.memblock
= pa_memblock_new_user(s
->context
->mempool
, (void*) t_data
, t_length
, free_cb
, 1);
1064 chunk
.length
= t_length
;
1068 chunk
.length
= PA_MIN(t_length
, pa_mempool_block_size_max(s
->context
->mempool
));
1069 chunk
.memblock
= pa_memblock_new(s
->context
->mempool
, chunk
.length
);
1071 d
= pa_memblock_acquire(chunk
.memblock
);
1072 memcpy(d
, t_data
, chunk
.length
);
1073 pa_memblock_release(chunk
.memblock
);
1076 pa_pstream_send_memblock(s
->context
->pstream
, s
->channel
, t_offset
, t_seek
, &chunk
);
1079 t_seek
= PA_SEEK_RELATIVE
;
1081 t_data
= (const uint8_t*) t_data
+ chunk
.length
;
1082 t_length
-= chunk
.length
;
1084 pa_memblock_unref(chunk
.memblock
);
1087 if (free_cb
&& pa_pstream_get_shm(s
->context
->pstream
))
1088 free_cb((void*) data
);
1090 if (length
< s
->requested_bytes
)
1091 s
->requested_bytes
-= length
;
1093 s
->requested_bytes
= 0;
1095 /* FIXME!!! ^^^ will break when offset is != 0 and mode is not RELATIVE*/
1097 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1099 /* Update latency request correction */
1100 if (s
->write_index_corrections
[s
->current_write_index_correction
].valid
) {
1102 if (seek
== PA_SEEK_ABSOLUTE
) {
1103 s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
= FALSE
;
1104 s
->write_index_corrections
[s
->current_write_index_correction
].absolute
= TRUE
;
1105 s
->write_index_corrections
[s
->current_write_index_correction
].value
= offset
+ length
;
1106 } else if (seek
== PA_SEEK_RELATIVE
) {
1107 if (!s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
)
1108 s
->write_index_corrections
[s
->current_write_index_correction
].value
+= offset
+ length
;
1110 s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
= TRUE
;
1113 /* Update the write index in the already available latency data */
1114 if (s
->timing_info_valid
) {
1116 if (seek
== PA_SEEK_ABSOLUTE
) {
1117 s
->timing_info
.write_index_corrupt
= FALSE
;
1118 s
->timing_info
.write_index
= offset
+ length
;
1119 } else if (seek
== PA_SEEK_RELATIVE
) {
1120 if (!s
->timing_info
.write_index_corrupt
)
1121 s
->timing_info
.write_index
+= offset
+ length
;
1123 s
->timing_info
.write_index_corrupt
= TRUE
;
1126 if (!s
->timing_info_valid
|| s
->timing_info
.write_index_corrupt
)
1127 request_auto_timing_update(s
, TRUE
);
1133 int pa_stream_peek(pa_stream
*s
, const void **data
, size_t *length
) {
1135 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1139 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1140 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
);
1142 if (!s
->peek_memchunk
.memblock
) {
1144 if (pa_memblockq_peek(s
->record_memblockq
, &s
->peek_memchunk
) < 0) {
1150 s
->peek_data
= pa_memblock_acquire(s
->peek_memchunk
.memblock
);
1153 pa_assert(s
->peek_data
);
1154 *data
= (uint8_t*) s
->peek_data
+ s
->peek_memchunk
.index
;
1155 *length
= s
->peek_memchunk
.length
;
1159 int pa_stream_drop(pa_stream
*s
) {
1161 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1163 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1164 PA_CHECK_VALIDITY(s
->context
, s
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
);
1165 PA_CHECK_VALIDITY(s
->context
, s
->peek_memchunk
.memblock
, PA_ERR_BADSTATE
);
1167 pa_memblockq_drop(s
->record_memblockq
, s
->peek_memchunk
.length
);
1169 /* Fix the simulated local read index */
1170 if (s
->timing_info_valid
&& !s
->timing_info
.read_index_corrupt
)
1171 s
->timing_info
.read_index
+= s
->peek_memchunk
.length
;
1173 pa_assert(s
->peek_data
);
1174 pa_memblock_release(s
->peek_memchunk
.memblock
);
1175 pa_memblock_unref(s
->peek_memchunk
.memblock
);
1176 pa_memchunk_reset(&s
->peek_memchunk
);
1181 size_t pa_stream_writable_size(pa_stream
*s
) {
1183 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1185 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, (size_t) -1);
1186 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direction
!= PA_STREAM_RECORD
, PA_ERR_BADSTATE
, (size_t) -1);
1188 return s
->requested_bytes
;
1191 size_t pa_stream_readable_size(pa_stream
*s
) {
1193 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1195 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, (size_t) -1);
1196 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
, (size_t) -1);
1198 return pa_memblockq_get_length(s
->record_memblockq
);
1201 pa_operation
* pa_stream_drain(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
1207 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1209 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1210 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
);
1212 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
1214 t
= pa_tagstruct_command(s
->context
, PA_COMMAND_DRAIN_PLAYBACK_STREAM
, &tag
);
1215 pa_tagstruct_putu32(t
, s
->channel
);
1216 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1217 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
);
1222 static pa_usec_t
calc_time(pa_stream
*s
, pa_bool_t ignore_transport
) {
1226 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1227 pa_assert(s
->state
== PA_STREAM_READY
);
1228 pa_assert(s
->direction
!= PA_STREAM_UPLOAD
);
1229 pa_assert(s
->timing_info_valid
);
1230 pa_assert(s
->direction
!= PA_STREAM_PLAYBACK
|| !s
->timing_info
.read_index_corrupt
);
1231 pa_assert(s
->direction
!= PA_STREAM_RECORD
|| !s
->timing_info
.write_index_corrupt
);
1233 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1234 /* The last byte that was written into the output device
1235 * had this time value associated */
1236 usec
= pa_bytes_to_usec(s
->timing_info
.read_index
< 0 ? 0 : (uint64_t) s
->timing_info
.read_index
, &s
->sample_spec
);
1238 if (!s
->corked
&& !s
->suspended
) {
1240 if (!ignore_transport
)
1241 /* Because the latency info took a little time to come
1242 * to us, we assume that the real output time is actually
1244 usec
+= s
->timing_info
.transport_usec
;
1246 /* However, the output device usually maintains a buffer
1247 too, hence the real sample currently played is a little
1249 if (s
->timing_info
.sink_usec
>= usec
)
1252 usec
-= s
->timing_info
.sink_usec
;
1255 } else if (s
->direction
== PA_STREAM_RECORD
) {
1256 /* The last byte written into the server side queue had
1257 * this time value associated */
1258 usec
= pa_bytes_to_usec(s
->timing_info
.write_index
< 0 ? 0 : (uint64_t) s
->timing_info
.write_index
, &s
->sample_spec
);
1260 if (!s
->corked
&& !s
->suspended
) {
1262 if (!ignore_transport
)
1263 /* Add transport latency */
1264 usec
+= s
->timing_info
.transport_usec
;
1266 /* Add latency of data in device buffer */
1267 usec
+= s
->timing_info
.source_usec
;
1269 /* If this is a monitor source, we need to correct the
1270 * time by the playback device buffer */
1271 if (s
->timing_info
.sink_usec
>= usec
)
1274 usec
-= s
->timing_info
.sink_usec
;
1281 static void stream_get_timing_info_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1282 pa_operation
*o
= userdata
;
1283 struct timeval local
, remote
, now
;
1285 pa_bool_t playing
= FALSE
;
1286 uint64_t underrun_for
= 0, playing_for
= 0;
1290 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1292 if (!o
->context
|| !o
->stream
)
1295 i
= &o
->stream
->timing_info
;
1297 o
->stream
->timing_info_valid
= FALSE
;
1298 i
->write_index_corrupt
= TRUE
;
1299 i
->read_index_corrupt
= TRUE
;
1301 if (command
!= PA_COMMAND_REPLY
) {
1302 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1307 if (pa_tagstruct_get_usec(t
, &i
->sink_usec
) < 0 ||
1308 pa_tagstruct_get_usec(t
, &i
->source_usec
) < 0 ||
1309 pa_tagstruct_get_boolean(t
, &playing
) < 0 ||
1310 pa_tagstruct_get_timeval(t
, &local
) < 0 ||
1311 pa_tagstruct_get_timeval(t
, &remote
) < 0 ||
1312 pa_tagstruct_gets64(t
, &i
->write_index
) < 0 ||
1313 pa_tagstruct_gets64(t
, &i
->read_index
) < 0) {
1315 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1319 if (o
->context
->version
>= 13 &&
1320 o
->stream
->direction
== PA_STREAM_PLAYBACK
)
1321 if (pa_tagstruct_getu64(t
, &underrun_for
) < 0 ||
1322 pa_tagstruct_getu64(t
, &playing_for
) < 0) {
1324 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1329 if (!pa_tagstruct_eof(t
)) {
1330 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1333 o
->stream
->timing_info_valid
= TRUE
;
1334 i
->write_index_corrupt
= FALSE
;
1335 i
->read_index_corrupt
= FALSE
;
1337 i
->playing
= (int) playing
;
1338 i
->since_underrun
= playing
? playing_for
: underrun_for
;
1340 pa_gettimeofday(&now
);
1342 /* Calculcate timestamps */
1343 if (pa_timeval_cmp(&local
, &remote
) <= 0 && pa_timeval_cmp(&remote
, &now
) <= 0) {
1344 /* local and remote seem to have synchronized clocks */
1346 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
)
1347 i
->transport_usec
= pa_timeval_diff(&remote
, &local
);
1349 i
->transport_usec
= pa_timeval_diff(&now
, &remote
);
1351 i
->synchronized_clocks
= TRUE
;
1352 i
->timestamp
= remote
;
1354 /* clocks are not synchronized, let's estimate latency then */
1355 i
->transport_usec
= pa_timeval_diff(&now
, &local
)/2;
1356 i
->synchronized_clocks
= FALSE
;
1357 i
->timestamp
= local
;
1358 pa_timeval_add(&i
->timestamp
, i
->transport_usec
);
1361 /* Invalidate read and write indexes if necessary */
1362 if (tag
< o
->stream
->read_index_not_before
)
1363 i
->read_index_corrupt
= TRUE
;
1365 if (tag
< o
->stream
->write_index_not_before
)
1366 i
->write_index_corrupt
= TRUE
;
1368 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
) {
1369 /* Write index correction */
1372 uint32_t ctag
= tag
;
1374 /* Go through the saved correction values and add up the
1375 * total correction.*/
1376 for (n
= 0, j
= o
->stream
->current_write_index_correction
+1;
1377 n
< PA_MAX_WRITE_INDEX_CORRECTIONS
;
1378 n
++, j
= (j
+ 1) % PA_MAX_WRITE_INDEX_CORRECTIONS
) {
1380 /* Step over invalid data or out-of-date data */
1381 if (!o
->stream
->write_index_corrections
[j
].valid
||
1382 o
->stream
->write_index_corrections
[j
].tag
< ctag
)
1385 /* Make sure that everything is in order */
1386 ctag
= o
->stream
->write_index_corrections
[j
].tag
+1;
1388 /* Now fix the write index */
1389 if (o
->stream
->write_index_corrections
[j
].corrupt
) {
1390 /* A corrupting seek was made */
1391 i
->write_index_corrupt
= TRUE
;
1392 } else if (o
->stream
->write_index_corrections
[j
].absolute
) {
1393 /* An absolute seek was made */
1394 i
->write_index
= o
->stream
->write_index_corrections
[j
].value
;
1395 i
->write_index_corrupt
= FALSE
;
1396 } else if (!i
->write_index_corrupt
) {
1397 /* A relative seek was made */
1398 i
->write_index
+= o
->stream
->write_index_corrections
[j
].value
;
1402 /* Clear old correction entries */
1403 for (n
= 0; n
< PA_MAX_WRITE_INDEX_CORRECTIONS
; n
++) {
1404 if (!o
->stream
->write_index_corrections
[n
].valid
)
1407 if (o
->stream
->write_index_corrections
[n
].tag
<= tag
)
1408 o
->stream
->write_index_corrections
[n
].valid
= FALSE
;
1412 if (o
->stream
->direction
== PA_STREAM_RECORD
) {
1413 /* Read index correction */
1415 if (!i
->read_index_corrupt
)
1416 i
->read_index
-= pa_memblockq_get_length(o
->stream
->record_memblockq
);
1419 /* Update smoother */
1420 if (o
->stream
->smoother
) {
1423 u
= x
= pa_rtclock_usec() - i
->transport_usec
;
1425 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
&& o
->context
->version
>= 13) {
1428 /* If we weren't playing then it will take some time
1429 * until the audio will actually come out through the
1430 * speakers. Since we follow that timing here, we need
1431 * to try to fix this up */
1433 su
= pa_bytes_to_usec(i
->since_underrun
, &o
->stream
->sample_spec
);
1435 if (su
< i
->sink_usec
)
1436 x
+= i
->sink_usec
- su
;
1440 pa_smoother_pause(o
->stream
->smoother
, x
);
1442 /* Update the smoother */
1443 if ((o
->stream
->direction
== PA_STREAM_PLAYBACK
&& !i
->read_index_corrupt
) ||
1444 (o
->stream
->direction
== PA_STREAM_RECORD
&& !i
->write_index_corrupt
))
1445 pa_smoother_put(o
->stream
->smoother
, u
, calc_time(o
->stream
, TRUE
));
1448 pa_smoother_resume(o
->stream
->smoother
, x
);
1452 o
->stream
->auto_timing_update_requested
= FALSE
;
1454 if (o
->stream
->latency_update_callback
)
1455 o
->stream
->latency_update_callback(o
->stream
, o
->stream
->latency_update_userdata
);
1457 if (o
->callback
&& o
->stream
&& o
->stream
->state
== PA_STREAM_READY
) {
1458 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
1459 cb(o
->stream
, o
->stream
->timing_info_valid
, o
->userdata
);
1464 pa_operation_done(o
);
1465 pa_operation_unref(o
);
1468 pa_operation
* pa_stream_update_timing_info(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
1476 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1478 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1479 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1481 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1482 /* Find a place to store the write_index correction data for this entry */
1483 cidx
= (s
->current_write_index_correction
+ 1) % PA_MAX_WRITE_INDEX_CORRECTIONS
;
1485 /* Check if we could allocate a correction slot. If not, there are too many outstanding queries */
1486 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, !s
->write_index_corrections
[cidx
].valid
, PA_ERR_INTERNAL
);
1488 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
1490 t
= pa_tagstruct_command(
1492 s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_GET_PLAYBACK_LATENCY
: PA_COMMAND_GET_RECORD_LATENCY
,
1494 pa_tagstruct_putu32(t
, s
->channel
);
1495 pa_tagstruct_put_timeval(t
, pa_gettimeofday(&now
));
1497 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1498 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
);
1500 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1501 /* Fill in initial correction data */
1503 s
->current_write_index_correction
= cidx
;
1505 s
->write_index_corrections
[cidx
].valid
= TRUE
;
1506 s
->write_index_corrections
[cidx
].absolute
= FALSE
;
1507 s
->write_index_corrections
[cidx
].corrupt
= FALSE
;
1508 s
->write_index_corrections
[cidx
].tag
= tag
;
1509 s
->write_index_corrections
[cidx
].value
= 0;
1515 void pa_stream_disconnect_callback(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1516 pa_stream
*s
= userdata
;
1520 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1524 if (command
!= PA_COMMAND_REPLY
) {
1525 if (pa_context_handle_error(s
->context
, command
, t
, FALSE
) < 0)
1528 pa_stream_set_state(s
, PA_STREAM_FAILED
);
1530 } else if (!pa_tagstruct_eof(t
)) {
1531 pa_context_fail(s
->context
, PA_ERR_PROTOCOL
);
1535 pa_stream_set_state(s
, PA_STREAM_TERMINATED
);
1541 int pa_stream_disconnect(pa_stream
*s
) {
1546 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1548 PA_CHECK_VALIDITY(s
->context
, s
->channel_valid
, PA_ERR_BADSTATE
);
1549 PA_CHECK_VALIDITY(s
->context
, s
->context
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1553 t
= pa_tagstruct_command(
1555 s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_DELETE_PLAYBACK_STREAM
:
1556 (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_DELETE_RECORD_STREAM
: PA_COMMAND_DELETE_UPLOAD_STREAM
),
1558 pa_tagstruct_putu32(t
, s
->channel
);
1559 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1560 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, pa_stream_disconnect_callback
, s
, NULL
);
1566 void pa_stream_set_read_callback(pa_stream
*s
, pa_stream_request_cb_t cb
, void *userdata
) {
1568 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1570 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1573 s
->read_callback
= cb
;
1574 s
->read_userdata
= userdata
;
1577 void pa_stream_set_write_callback(pa_stream
*s
, pa_stream_request_cb_t cb
, void *userdata
) {
1579 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1581 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1584 s
->write_callback
= cb
;
1585 s
->write_userdata
= userdata
;
1588 void pa_stream_set_state_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1590 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1592 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1595 s
->state_callback
= cb
;
1596 s
->state_userdata
= userdata
;
1599 void pa_stream_set_overflow_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1601 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1603 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1606 s
->overflow_callback
= cb
;
1607 s
->overflow_userdata
= userdata
;
1610 void pa_stream_set_underflow_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1612 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1614 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1617 s
->underflow_callback
= cb
;
1618 s
->underflow_userdata
= userdata
;
1621 void pa_stream_set_latency_update_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1623 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1625 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1628 s
->latency_update_callback
= cb
;
1629 s
->latency_update_userdata
= userdata
;
1632 void pa_stream_set_moved_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1634 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1636 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1639 s
->moved_callback
= cb
;
1640 s
->moved_userdata
= userdata
;
1643 void pa_stream_set_suspended_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1645 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1647 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1650 s
->suspended_callback
= cb
;
1651 s
->suspended_userdata
= userdata
;
1654 void pa_stream_set_started_callback(pa_stream
*s
, pa_stream_notify_cb_t cb
, void *userdata
) {
1656 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1658 if (s
->state
== PA_STREAM_TERMINATED
|| s
->state
== PA_STREAM_FAILED
)
1661 s
->started_callback
= cb
;
1662 s
->started_userdata
= userdata
;
1665 void pa_stream_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1666 pa_operation
*o
= userdata
;
1671 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1676 if (command
!= PA_COMMAND_REPLY
) {
1677 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1681 } else if (!pa_tagstruct_eof(t
)) {
1682 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1687 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
1688 cb(o
->stream
, success
, o
->userdata
);
1692 pa_operation_done(o
);
1693 pa_operation_unref(o
);
1696 pa_operation
* pa_stream_cork(pa_stream
*s
, int b
, pa_stream_success_cb_t cb
, void *userdata
) {
1702 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1704 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1705 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1709 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
1711 t
= pa_tagstruct_command(
1713 s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_CORK_PLAYBACK_STREAM
: PA_COMMAND_CORK_RECORD_STREAM
,
1715 pa_tagstruct_putu32(t
, s
->channel
);
1716 pa_tagstruct_put_boolean(t
, !!b
);
1717 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1718 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
);
1720 check_smoother_status(s
, FALSE
, FALSE
, FALSE
);
1722 /* This might cause the indexes to hang/start again, hence
1723 * let's request a timing update */
1724 request_auto_timing_update(s
, TRUE
);
1729 static pa_operation
* stream_send_simple_command(pa_stream
*s
, uint32_t command
, pa_stream_success_cb_t cb
, void *userdata
) {
1735 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1737 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1739 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
1741 t
= pa_tagstruct_command(s
->context
, command
, &tag
);
1742 pa_tagstruct_putu32(t
, s
->channel
);
1743 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1744 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
);
1749 pa_operation
* pa_stream_flush(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
1753 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1755 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1756 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1758 if (!(o
= stream_send_simple_command(s
, s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_FLUSH_PLAYBACK_STREAM
: PA_COMMAND_FLUSH_RECORD_STREAM
, cb
, userdata
)))
1761 if (s
->direction
== PA_STREAM_PLAYBACK
) {
1763 if (s
->write_index_corrections
[s
->current_write_index_correction
].valid
)
1764 s
->write_index_corrections
[s
->current_write_index_correction
].corrupt
= TRUE
;
1766 if (s
->buffer_attr
.prebuf
> 0)
1767 check_smoother_status(s
, FALSE
, FALSE
, TRUE
);
1769 /* This will change the write index, but leave the
1770 * read index untouched. */
1771 invalidate_indexes(s
, FALSE
, TRUE
);
1774 /* For record streams this has no influence on the write
1775 * index, but the read index might jump. */
1776 invalidate_indexes(s
, TRUE
, FALSE
);
1781 pa_operation
* pa_stream_prebuf(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
1785 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1787 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1788 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
);
1789 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->buffer_attr
.prebuf
> 0, PA_ERR_BADSTATE
);
1791 if (!(o
= stream_send_simple_command(s
, PA_COMMAND_PREBUF_PLAYBACK_STREAM
, cb
, userdata
)))
1794 /* This might cause the read index to hang again, hence
1795 * let's request a timing update */
1796 request_auto_timing_update(s
, TRUE
);
1801 pa_operation
* pa_stream_trigger(pa_stream
*s
, pa_stream_success_cb_t cb
, void *userdata
) {
1805 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1807 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1808 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
);
1809 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->buffer_attr
.prebuf
> 0, PA_ERR_BADSTATE
);
1811 if (!(o
= stream_send_simple_command(s
, PA_COMMAND_TRIGGER_PLAYBACK_STREAM
, cb
, userdata
)))
1814 /* This might cause the read index to start moving again, hence
1815 * let's request a timing update */
1816 request_auto_timing_update(s
, TRUE
);
1821 pa_operation
* pa_stream_set_name(pa_stream
*s
, const char *name
, pa_stream_success_cb_t cb
, void *userdata
) {
1825 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1828 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1829 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1831 if (s
->context
->version
>= 13) {
1832 pa_proplist
*p
= pa_proplist_new();
1834 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1835 o
= pa_stream_proplist_update(s
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1836 pa_proplist_free(p
);
1841 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
1842 t
= pa_tagstruct_command(
1844 s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_SET_RECORD_STREAM_NAME
: PA_COMMAND_SET_PLAYBACK_STREAM_NAME
,
1846 pa_tagstruct_putu32(t
, s
->channel
);
1847 pa_tagstruct_puts(t
, name
);
1848 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
1849 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
);
1855 int pa_stream_get_time(pa_stream
*s
, pa_usec_t
*r_usec
) {
1859 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1861 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1862 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1863 PA_CHECK_VALIDITY(s
->context
, s
->timing_info_valid
, PA_ERR_NODATA
);
1864 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_PLAYBACK
|| !s
->timing_info
.read_index_corrupt
, PA_ERR_NODATA
);
1865 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_RECORD
|| !s
->timing_info
.write_index_corrupt
, PA_ERR_NODATA
);
1868 usec
= pa_smoother_get(s
->smoother
, pa_rtclock_usec());
1870 usec
= calc_time(s
, FALSE
);
1872 /* Make sure the time runs monotonically */
1873 if (!(s
->flags
& PA_STREAM_NOT_MONOTONOUS
)) {
1874 if (usec
< s
->previous_time
)
1875 usec
= s
->previous_time
;
1877 s
->previous_time
= usec
;
1886 static pa_usec_t
time_counter_diff(pa_stream
*s
, pa_usec_t a
, pa_usec_t b
, int *negative
) {
1888 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1896 if (negative
&& s
->direction
== PA_STREAM_RECORD
) {
1904 int pa_stream_get_latency(pa_stream
*s
, pa_usec_t
*r_usec
, int *negative
) {
1910 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1913 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1914 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1915 PA_CHECK_VALIDITY(s
->context
, s
->timing_info_valid
, PA_ERR_NODATA
);
1916 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_PLAYBACK
|| !s
->timing_info
.write_index_corrupt
, PA_ERR_NODATA
);
1917 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_RECORD
|| !s
->timing_info
.read_index_corrupt
, PA_ERR_NODATA
);
1919 if ((r
= pa_stream_get_time(s
, &t
)) < 0)
1922 if (s
->direction
== PA_STREAM_PLAYBACK
)
1923 cindex
= s
->timing_info
.write_index
;
1925 cindex
= s
->timing_info
.read_index
;
1930 c
= pa_bytes_to_usec(cindex
, &s
->sample_spec
);
1932 if (s
->direction
== PA_STREAM_PLAYBACK
)
1933 *r_usec
= time_counter_diff(s
, c
, t
, negative
);
1935 *r_usec
= time_counter_diff(s
, t
, c
, negative
);
1940 const pa_timing_info
* pa_stream_get_timing_info(pa_stream
*s
) {
1942 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1944 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1945 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1946 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->timing_info_valid
, PA_ERR_BADSTATE
);
1948 return &s
->timing_info
;
1951 const pa_sample_spec
* pa_stream_get_sample_spec(pa_stream
*s
) {
1953 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1955 return &s
->sample_spec
;
1958 const pa_channel_map
* pa_stream_get_channel_map(pa_stream
*s
) {
1960 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1962 return &s
->channel_map
;
1965 const pa_buffer_attr
* pa_stream_get_buffer_attr(pa_stream
*s
) {
1967 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
1969 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
1970 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
1971 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 9, PA_ERR_NOTSUPPORTED
);
1973 return &s
->buffer_attr
;
1976 static void stream_set_buffer_attr_callback(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1977 pa_operation
*o
= userdata
;
1982 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1987 if (command
!= PA_COMMAND_REPLY
) {
1988 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1994 if (o
->stream
->direction
== PA_STREAM_PLAYBACK
) {
1995 if (pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.maxlength
) < 0 ||
1996 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.tlength
) < 0 ||
1997 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.prebuf
) < 0 ||
1998 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.minreq
) < 0) {
1999 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2002 } else if (o
->stream
->direction
== PA_STREAM_RECORD
) {
2003 if (pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.maxlength
) < 0 ||
2004 pa_tagstruct_getu32(t
, &o
->stream
->buffer_attr
.fragsize
) < 0) {
2005 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2010 if (!pa_tagstruct_eof(t
)) {
2011 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2017 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
2018 cb(o
->stream
, success
, o
->userdata
);
2022 pa_operation_done(o
);
2023 pa_operation_unref(o
);
2027 pa_operation
* pa_stream_set_buffer_attr(pa_stream
*s
, const pa_buffer_attr
*attr
, pa_stream_success_cb_t cb
, void *userdata
) {
2033 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2036 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2037 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2038 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2040 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2042 t
= pa_tagstruct_command(
2044 s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR
: PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR
,
2046 pa_tagstruct_putu32(t
, s
->channel
);
2048 pa_tagstruct_putu32(t
, attr
->maxlength
);
2050 if (s
->direction
== PA_STREAM_PLAYBACK
)
2053 PA_TAG_U32
, attr
->tlength
,
2054 PA_TAG_U32
, attr
->prebuf
,
2055 PA_TAG_U32
, attr
->minreq
,
2058 pa_tagstruct_putu32(t
, attr
->fragsize
);
2060 if (s
->context
->version
>= 13)
2061 pa_tagstruct_put_boolean(t
, !!(s
->flags
& PA_STREAM_ADJUST_LATENCY
));
2063 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2064 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
);
2066 /* This might cause changes in the read/write indexex, hence let's
2067 * request a timing update */
2068 request_auto_timing_update(s
, TRUE
);
2073 uint32_t pa_stream_get_device_index(pa_stream
*s
) {
2075 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2077 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2078 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2079 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
2080 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->device_index
!= PA_INVALID_INDEX
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2082 return s
->device_index
;
2085 const char *pa_stream_get_device_name(pa_stream
*s
) {
2087 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2089 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2090 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2091 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2092 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->device_name
, PA_ERR_BADSTATE
);
2094 return s
->device_name
;
2097 int pa_stream_is_suspended(pa_stream
*s
) {
2099 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2101 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2102 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2103 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2105 return s
->suspended
;
2108 int pa_stream_is_corked(pa_stream
*s
) {
2110 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2112 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2113 PA_CHECK_VALIDITY(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2118 static void stream_update_sample_rate_callback(pa_pdispatch
*pd
, uint32_t command
, PA_GCC_UNUSED
uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
2119 pa_operation
*o
= userdata
;
2124 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
2129 if (command
!= PA_COMMAND_REPLY
) {
2130 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
2136 if (!pa_tagstruct_eof(t
)) {
2137 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
2142 o
->stream
->sample_spec
.rate
= PA_PTR_TO_UINT(o
->private);
2143 pa_assert(pa_sample_spec_valid(&o
->stream
->sample_spec
));
2146 pa_stream_success_cb_t cb
= (pa_stream_success_cb_t
) o
->callback
;
2147 cb(o
->stream
, success
, o
->userdata
);
2151 pa_operation_done(o
);
2152 pa_operation_unref(o
);
2156 pa_operation
*pa_stream_update_sample_rate(pa_stream
*s
, uint32_t rate
, pa_stream_success_cb_t cb
, void *userdata
) {
2162 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2164 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, rate
> 0 && rate
<= PA_RATE_MAX
, PA_ERR_INVALID
);
2165 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2166 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2167 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->flags
& PA_STREAM_VARIABLE_RATE
, PA_ERR_BADSTATE
);
2168 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 12, PA_ERR_NOTSUPPORTED
);
2170 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2171 o
->private = PA_UINT_TO_PTR(rate
);
2173 t
= pa_tagstruct_command(
2175 s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE
: PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE
,
2177 pa_tagstruct_putu32(t
, s
->channel
);
2178 pa_tagstruct_putu32(t
, rate
);
2180 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2181 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
);
2186 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
) {
2192 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2194 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
2195 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2196 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2197 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
);
2199 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2201 t
= pa_tagstruct_command(
2203 s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST
: PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST
,
2205 pa_tagstruct_putu32(t
, s
->channel
);
2206 pa_tagstruct_putu32(t
, (uint32_t) mode
);
2207 pa_tagstruct_put_proplist(t
, p
);
2209 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2210 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
);
2212 /* Please note that we don't update s->proplist here, because we
2213 * don't export that field */
2218 pa_operation
*pa_stream_proplist_remove(pa_stream
*s
, const char *const keys
[], pa_stream_success_cb_t cb
, void *userdata
) {
2222 const char * const*k
;
2225 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2227 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, keys
&& keys
[0], PA_ERR_INVALID
);
2228 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->state
== PA_STREAM_READY
, PA_ERR_BADSTATE
);
2229 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->direction
!= PA_STREAM_UPLOAD
, PA_ERR_BADSTATE
);
2230 PA_CHECK_VALIDITY_RETURN_NULL(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
);
2232 o
= pa_operation_new(s
->context
, s
, (pa_operation_cb_t
) cb
, userdata
);
2234 t
= pa_tagstruct_command(
2236 s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST
: PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST
,
2238 pa_tagstruct_putu32(t
, s
->channel
);
2240 for (k
= keys
; *k
; k
++)
2241 pa_tagstruct_puts(t
, *k
);
2243 pa_tagstruct_puts(t
, NULL
);
2245 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
2246 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
);
2248 /* Please note that we don't update s->proplist here, because we
2249 * don't export that field */
2254 int pa_stream_set_monitor_stream(pa_stream
*s
, uint32_t sink_input_idx
) {
2256 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2258 PA_CHECK_VALIDITY(s
->context
, sink_input_idx
!= PA_INVALID_INDEX
, PA_ERR_INVALID
);
2259 PA_CHECK_VALIDITY(s
->context
, s
->state
== PA_STREAM_UNCONNECTED
, PA_ERR_BADSTATE
);
2260 PA_CHECK_VALIDITY(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
);
2262 s
->direct_on_input
= sink_input_idx
;
2267 uint32_t pa_stream_get_monitor_stream(pa_stream
*s
) {
2269 pa_assert(PA_REFCNT_VALUE(s
) >= 1);
2271 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->direct_on_input
!= PA_INVALID_INDEX
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
2272 PA_CHECK_VALIDITY_RETURN_ANY(s
->context
, s
->context
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
2274 return s
->direct_on_input
;