+ send_bytes(u);
+}
+
+static void stream_get_latency_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+ struct userdata *u = userdata;
+ pa_usec_t buffer_usec, sink_usec, source_usec, transport_usec;
+ int playing;
+ uint32_t queue_length;
+ struct timeval local, remote, now;
+ assert(pd && u && t);
+
+ if (command != PA_COMMAND_REPLY) {
+ if (command == PA_COMMAND_ERROR)
+ pa_log(__FILE__": failed to get latency.\n");
+ else
+ pa_log(__FILE__": protocol error.\n");
+ die(u);
+ return;
+ }
+
+ if (pa_tagstruct_get_usec(t, &buffer_usec) < 0 ||
+ pa_tagstruct_get_usec(t, &sink_usec) < 0 ||
+ pa_tagstruct_get_usec(t, &source_usec) < 0 ||
+ pa_tagstruct_get_boolean(t, &playing) < 0 ||
+ pa_tagstruct_getu32(t, &queue_length) < 0 ||
+ pa_tagstruct_get_timeval(t, &local) < 0 ||
+ pa_tagstruct_get_timeval(t, &remote) < 0 ||
+ !pa_tagstruct_eof(t)) {
+ pa_log(__FILE__": invalid reply.\n");
+ die(u);
+ return;
+ }
+
+ gettimeofday(&now, NULL);
+
+ if (pa_timeval_cmp(&local, &remote) < 0 && pa_timeval_cmp(&remote, &now))
+ /* local and remote seem to have synchronized clocks */
+ transport_usec = pa_timeval_diff(&remote, &local);
+ else
+ transport_usec = pa_timeval_diff(&now, &local)/2;
+
+ u->host_latency = sink_usec + transport_usec;
+
+/* pa_log(__FILE__": estimated host latency: %0.0f usec\n", (double) u->host_latency); */