Hello,

I think I've figured out how to cleanly synchronise audio and video
with RAOP with relying on my empirical "shifting audio 2300ms in
mplayer works".

The attached patch adds 2000ms of latency (as spec'ed by Apple from
what I've found on the internet) plus the length of the last audio
packet sent to the initial latency calculation. This works great on my
computer. The added latency is 2352ms which is very close to my
empirical finding.

I'd love for others to test it with different hardware (mine's a Pioneer
N-30) and if it's deemed good, to have it merged upstream!

PS: here's a video showing the synchronisation (sorry, when slowed out
too much, you can't really hear the "bops" :
https://www.youtube.com/watch?v=iOs6XYpNdos
(At the beginning, sync isn't perfect, I suspect it's due to the
connecting etc.)
-- 
Colin
From 44c1fcab64cd37cf57f19f9f0ee30d3433919310 Mon Sep 17 00:00:00 2001
From: Colin Leroy <[email protected]>
Date: Sat, 22 Jul 2017 14:50:40 +0200
Subject: [PATCH] RAOP: Correctly compute latency

Add a two-second delay as per Apple specifications, plus the length
of the last audio packet sent.
---
 src/modules/raop/raop-client.c | 13 +++++++++++--
 src/modules/raop/raop-client.h |  2 ++
 src/modules/raop/raop-sink.c   |  7 +++++++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index ae950f7..f8e00d6 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -111,6 +111,7 @@ struct pa_raop_client {
     pa_raop_packet_buffer *pbuf;
 
     uint16_t seq;
+    uint32_t rtpdiff;
     uint32_t rtptime;
     bool is_recording;
     uint32_t ssrc;
@@ -339,7 +340,8 @@ static size_t build_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, pa_m
         size += length;
     }
 
-    c->rtptime += length / 4;
+    c->rtpdiff = length / 4;
+    c->rtptime += c->rtpdiff;
 
     pa_memblock_release(block->memblock);
 
@@ -427,7 +429,8 @@ static size_t build_udp_audio_packet(pa_raop_client *c, pa_memchunk *block, pa_m
         size += length;
     }
 
-    c->rtptime += length / 4;
+    c->rtpdiff = length / 4;
+    c->rtptime += c->rtpdiff;
 
     /* Wrap sequence number to 0 then UINT16_MAX is reached */
     if (c->seq == UINT16_MAX)
@@ -1531,6 +1534,12 @@ bool pa_raop_client_is_alive(pa_raop_client *c) {
     return false;
 }
 
+uint32_t pa_raop_client_get_rtp_diff(pa_raop_client *c) {
+    pa_assert(c);
+
+    return c->rtpdiff;
+}
+
 bool pa_raop_client_can_stream(pa_raop_client *c) {
     pa_assert(c);
 
diff --git a/src/modules/raop/raop-client.h b/src/modules/raop/raop-client.h
index 72e6018..9c2dff1 100644
--- a/src/modules/raop/raop-client.h
+++ b/src/modules/raop/raop-client.h
@@ -77,6 +77,8 @@ pa_volume_t pa_raop_client_adjust_volume(pa_raop_client *c, pa_volume_t volume);
 void pa_raop_client_handle_oob_packet(pa_raop_client *c, const int fd, const uint8_t packet[], ssize_t size);
 ssize_t pa_raop_client_send_audio_packet(pa_raop_client *c, pa_memchunk *block, size_t offset);
 
+uint32_t pa_raop_client_get_rtp_diff(pa_raop_client *c);
+
 typedef void (*pa_raop_client_state_cb_t)(pa_raop_state_t state, void *userdata);
 void pa_raop_client_set_state_callback(pa_raop_client *c, pa_raop_client_state_cb_t callback, void *userdata);
 
diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index e5d219e..108f855 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -118,6 +118,13 @@ static int64_t sink_get_latency(const struct userdata *u) {
     now = pa_smoother_get(u->smoother, now);
 
     latency = pa_bytes_to_usec(u->write_count, &u->sink->sample_spec) - (int64_t) now;
+    if (latency < 0) {
+	latency = 0;
+    }
+
+    latency += 2000000; /* RAOP default latency */
+    latency += pa_raop_client_get_rtp_diff(u->raop) * 1000; /* plus last packet length in usec */
+
 
     return latency;
 }
-- 
2.9.3

Attachment: pgprlFUuXdQsE.pgp
Description: OpenPGP digital signature

_______________________________________________
pulseaudio-discuss mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to