mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-12 13:30:10 -05:00
notify clients about tlength changes
This commit is contained in:
parent
491aafd8dc
commit
65b787d000
7 changed files with 327 additions and 206 deletions
|
|
@ -99,7 +99,9 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
|
|||
[PA_COMMAND_EXTENSION] = pa_command_extension,
|
||||
[PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
|
||||
[PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
|
||||
[PA_COMMAND_CLIENT_EVENT] = pa_command_client_event
|
||||
[PA_COMMAND_CLIENT_EVENT] = pa_command_client_event,
|
||||
[PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
|
||||
[PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr
|
||||
};
|
||||
static void context_free(pa_context *c);
|
||||
|
||||
|
|
|
|||
|
|
@ -185,6 +185,8 @@ struct pa_stream {
|
|||
void *started_userdata;
|
||||
pa_stream_event_cb_t event_callback;
|
||||
void *event_userdata;
|
||||
pa_stream_notify_cb_t buffer_attr_callback;
|
||||
void *buffer_attr_userdata;
|
||||
};
|
||||
|
||||
typedef void (*pa_operation_cb_t)(void);
|
||||
|
|
@ -213,6 +215,7 @@ void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
|
|||
void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
|
||||
void pa_command_stream_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
|
||||
void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
|
||||
void pa_command_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
|
||||
|
||||
pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t callback, void *userdata);
|
||||
void pa_operation_done(pa_operation *o);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ static void reset_callbacks(pa_stream *s) {
|
|||
s->started_userdata = NULL;
|
||||
s->event_callback = NULL;
|
||||
s->event_userdata = NULL;
|
||||
s->buffer_attr_callback = NULL;
|
||||
s->buffer_attr_userdata = NULL;
|
||||
}
|
||||
|
||||
pa_stream *pa_stream_new_with_proplist(
|
||||
|
|
@ -396,7 +398,7 @@ void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
|
|||
const char *dn;
|
||||
pa_bool_t suspended;
|
||||
uint32_t di;
|
||||
pa_usec_t usec;
|
||||
pa_usec_t usec = 0;
|
||||
uint32_t maxlength = 0, fragsize = 0, minreq = 0, tlength = 0, prebuf = 0;
|
||||
|
||||
pa_assert(pd);
|
||||
|
|
@ -486,6 +488,80 @@ finish:
|
|||
pa_context_unref(c);
|
||||
}
|
||||
|
||||
void pa_command_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
|
||||
pa_context *c = userdata;
|
||||
pa_stream *s;
|
||||
uint32_t channel;
|
||||
pa_usec_t usec = 0;
|
||||
uint32_t maxlength = 0, fragsize = 0, minreq = 0, tlength = 0, prebuf = 0;
|
||||
|
||||
pa_assert(pd);
|
||||
pa_assert(command == PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED || command == PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED);
|
||||
pa_assert(t);
|
||||
pa_assert(c);
|
||||
pa_assert(PA_REFCNT_VALUE(c) >= 1);
|
||||
|
||||
pa_context_ref(c);
|
||||
|
||||
if (c->version < 15) {
|
||||
pa_context_fail(c, PA_ERR_PROTOCOL);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (pa_tagstruct_getu32(t, &channel) < 0) {
|
||||
pa_context_fail(c, PA_ERR_PROTOCOL);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (command == PA_COMMAND_RECORD_STREAM_MOVED) {
|
||||
if (pa_tagstruct_getu32(t, &maxlength) < 0 ||
|
||||
pa_tagstruct_getu32(t, &fragsize) < 0 ||
|
||||
pa_tagstruct_get_usec(t, &usec) < 0) {
|
||||
pa_context_fail(c, PA_ERR_PROTOCOL);
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
if (pa_tagstruct_getu32(t, &maxlength) < 0 ||
|
||||
pa_tagstruct_getu32(t, &tlength) < 0 ||
|
||||
pa_tagstruct_getu32(t, &prebuf) < 0 ||
|
||||
pa_tagstruct_getu32(t, &minreq) < 0 ||
|
||||
pa_tagstruct_get_usec(t, &usec) < 0) {
|
||||
pa_context_fail(c, PA_ERR_PROTOCOL);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pa_tagstruct_eof(t)) {
|
||||
pa_context_fail(c, PA_ERR_PROTOCOL);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED ? c->playback_streams : c->record_streams, channel)))
|
||||
goto finish;
|
||||
|
||||
if (s->state != PA_STREAM_READY)
|
||||
goto finish;
|
||||
|
||||
if (s->direction == PA_STREAM_RECORD)
|
||||
s->timing_info.configured_source_usec = usec;
|
||||
else
|
||||
s->timing_info.configured_sink_usec = usec;
|
||||
|
||||
s->buffer_attr.maxlength = maxlength;
|
||||
s->buffer_attr.fragsize = fragsize;
|
||||
s->buffer_attr.tlength = tlength;
|
||||
s->buffer_attr.prebuf = prebuf;
|
||||
s->buffer_attr.minreq = minreq;
|
||||
|
||||
request_auto_timing_update(s, TRUE);
|
||||
|
||||
if (s->buffer_attr_callback)
|
||||
s->buffer_attr_callback(s, s->buffer_attr_userdata);
|
||||
|
||||
finish:
|
||||
pa_context_unref(c);
|
||||
}
|
||||
|
||||
void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
|
||||
pa_context *c = userdata;
|
||||
pa_stream *s;
|
||||
|
|
@ -1798,6 +1874,20 @@ void pa_stream_set_event_callback(pa_stream *s, pa_stream_event_cb_t cb, void *u
|
|||
s->event_userdata = userdata;
|
||||
}
|
||||
|
||||
void pa_stream_set_buffer_attr_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) {
|
||||
pa_assert(s);
|
||||
pa_assert(PA_REFCNT_VALUE(s) >= 1);
|
||||
|
||||
if (pa_detect_fork())
|
||||
return;
|
||||
|
||||
if (s->state == PA_STREAM_TERMINATED || s->state == PA_STREAM_FAILED)
|
||||
return;
|
||||
|
||||
s->buffer_attr_callback = cb;
|
||||
s->buffer_attr_userdata = userdata;
|
||||
}
|
||||
|
||||
void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
|
||||
pa_operation *o = userdata;
|
||||
int success = 1;
|
||||
|
|
|
|||
|
|
@ -512,6 +512,13 @@ void pa_stream_set_suspended_callback(pa_stream *p, pa_stream_notify_cb_t cb, vo
|
|||
* control event is received.\since 0.9.15 */
|
||||
void pa_stream_set_event_callback(pa_stream *p, pa_stream_event_cb_t cb, void *userdata);
|
||||
|
||||
/** Set the callback function that is called whenver the buffer
|
||||
* attributes on the server side change. Please note that the buffer
|
||||
* attributes can change when moving a stream to a different
|
||||
* sink/source too, hence if you use this callback you should use
|
||||
* pa_stream_set_moved_callback() as well. \since 0.9.15 */
|
||||
void pa_stream_set_buffer_attr_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
|
||||
|
||||
/** Pause (or resume) playback of this stream temporarily. Available on both playback and recording streams. */
|
||||
pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata);
|
||||
|
||||
|
|
@ -530,7 +537,7 @@ pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *us
|
|||
* temporarily. Available for playback streams only. */
|
||||
pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
|
||||
|
||||
/** Rename the stream.*/
|
||||
/** Rename the stream. */
|
||||
pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_success_cb_t cb, void *userdata);
|
||||
|
||||
/** Return the current playback/recording time. This is based on the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue