From 25123469d53e2ef555549984ea4e8b028c1632fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Sep 2004 22:35:12 +0000 Subject: add support for module search path as command line argument protocol-native: move first data request into ack of stream creation improve mainloop API: return the number of dispatched sources on iterate() fix a resampling bug introduce network latency measurement WARNING: all these changes together may break some applications git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@189 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/polyplib-stream.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'polyp/polyplib-stream.c') diff --git a/polyp/polyplib-stream.c b/polyp/polyplib-stream.c index a66a0fc6..e128a773 100644 --- a/polyp/polyplib-stream.c +++ b/polyp/polyplib-stream.c @@ -30,6 +30,7 @@ #include "polyplib-internal.h" #include "xmalloc.h" #include "pstream-util.h" +#include "util.h" struct pa_stream *pa_stream_new(struct pa_context *c, const char *name, const struct pa_sample_spec *ss) { struct pa_stream *s; @@ -193,6 +194,7 @@ void pa_create_stream_callback(struct pa_pdispatch *pd, uint32_t command, uint32 if (pa_tagstruct_getu32(t, &s->channel) < 0 || ((s->direction != PA_STREAM_UPLOAD) && pa_tagstruct_getu32(t, &s->device_index) < 0) || + ((s->direction == PA_STREAM_PLAYBACK) && pa_tagstruct_getu32(t, &s->requested_bytes) < 0) || !pa_tagstruct_eof(t)) { pa_context_fail(s->context, PA_ERROR_PROTOCOL); goto finish; @@ -202,6 +204,9 @@ void pa_create_stream_callback(struct pa_pdispatch *pd, uint32_t command, uint32 pa_dynarray_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, s->channel, s); pa_stream_set_state(s, PA_STREAM_READY); + if (s->requested_bytes && s->ref > 1 && s->write_callback) + s->write_callback(s, s->requested_bytes, s->write_userdata); + finish: pa_stream_unref(s); } @@ -321,6 +326,7 @@ struct pa_operation * pa_stream_drain(struct pa_stream *s, void (*cb) (struct pa static void stream_get_latency_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { struct pa_operation *o = userdata; struct pa_latency_info i, *p = NULL; + struct timeval local, remote, now; assert(pd && o && o->stream && o->context); if (command != PA_COMMAND_REPLY) { @@ -331,12 +337,23 @@ static void stream_get_latency_callback(struct pa_pdispatch *pd, uint32_t comman pa_tagstruct_getu32(t, &i.sink_usec) < 0 || pa_tagstruct_get_boolean(t, &i.playing) < 0 || pa_tagstruct_getu32(t, &i.queue_length) < 0 || + pa_tagstruct_get_timeval(t, &local) < 0 || + pa_tagstruct_get_timeval(t, &remote) < 0 || !pa_tagstruct_eof(t)) { pa_context_fail(o->context, PA_ERROR_PROTOCOL); goto finish; } else p = &i; + gettimeofday(&now, NULL); + + if (pa_timeval_cmp(&local, &remote) < 0 && pa_timeval_cmp(&remote, &now)) + /* local and remote seem to have synchronized clocks */ + i.transport_usec = pa_timeval_diff(&remote, &local); + else + /* clocks are not synchronized, let's estimate latency then */ + i.transport_usec = pa_timeval_diff(&now, &local)/2; + if (o->callback) { void (*cb)(struct pa_stream *s, const struct pa_latency_info *i, void *userdata) = o->callback; cb(o->stream, p, o->userdata); @@ -351,6 +368,7 @@ struct pa_operation* pa_stream_get_latency(struct pa_stream *s, void (*cb)(struc uint32_t tag; struct pa_operation *o; struct pa_tagstruct *t; + struct timeval now; o = pa_operation_new(s->context, s); assert(o); @@ -362,6 +380,10 @@ struct pa_operation* pa_stream_get_latency(struct pa_stream *s, void (*cb)(struc pa_tagstruct_putu32(t, PA_COMMAND_GET_PLAYBACK_LATENCY); pa_tagstruct_putu32(t, tag = s->context->ctag++); pa_tagstruct_putu32(t, s->channel); + + gettimeofday(&now, NULL); + pa_tagstruct_put_timeval(t, &now); + pa_pstream_send_tagstruct(s->context->pstream, t); pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, stream_get_latency_callback, o); -- cgit