I'm working on a project to multiplex several RTSP streams, from cameras, into a simple 
"grid" output.    The issue is that the cameras are intended to form an 
ultra-wide (panoramic) view and while total latency is never as low as one would like, 
relatively latency is a real problem.

I'm not expecting frame-accurate synchronization as one might get from genlocked analog 
or SDI sources, rather superficially synchronized - to within a few hundred msec, as 
would be sufficient for the visual perception of a live panorama.  As source start times 
and network connection times are not deterministic, manually tuning with incremental 
absolute offsets wouldn't work (though could help).  Currently the best I've been able to 
get is about 3 seconds differential latency, which is a fun way to do an automated 
one-person "wave" but not really the desired effect.  All devices are synced to 
NTP, which is more than sufficiently in sync for the application if I could figure out 
how to use it.

below is the command I'm using to connect, composite, and display that yields 
the fastest frame rates and least drop frames. Curiously, changing setpts from 
N/(8.33*TB) to the recommended for live stream setpts='(RTCTIME - RTCSTART) / 
(TB * 1000000)' for each stream results in really choppy playback (but no 
improvement in inter-stream sync).

ffmpeg  -max_delay 500000 -reorder_queue_size 10000 \
         -fflags nobuffer -re -rtsp_transport udp -an -flags low_delay -strict 
experimental\
         -fflags nobuffer -re -thread_queue_size 1024 -i 
rtsp://192.168.100.34:554/stream/profile0\
         -fflags nobuffer -re -thread_queue_size 1024 -i 
rtsp://192.168.100.57:554/stream/profile0\
         -fflags nobuffer -re -thread_queue_size 1024 -i 
rtsp://192.168.100.48:554/stream/profile0\
         -fflags nobuffer -re -thread_queue_size 1024 -i 
rtsp://192.168.100.34:554/stream/profile1\
         -fflags nobuffer -re -thread_queue_size 1024 -i 
rtsp://192.168.100.57:554/stream/profile1\
         -fflags nobuffer -re -thread_queue_size 1024 -i 
rtsp://192.168.100.48:554/stream/profile1\
        -filter_complex "
        nullsrc=size=3554x480 [base];
        [0:v] setpts=N/(8.33*TB) [CAM1];
        [1:v] setpts=N/(8.33*TB) [CAM2];
        [2:v] setpts=N/(8.33*TB) [CAM3];
        [3:v] setpts=N/(8.33*TB) [CAM4];
        [4:v] setpts=N/(8.33*TB) [CAM5];
        [5:v] setpts=N/(8.33*TB) [CAM6];
        [base][CAM1] overlay=x=0 [tmp1];
        [tmp1][CAM2] overlay=x=583 [tmp2];
        [tmp2][CAM3] overlay=x=1165 [tmp3];
        [tmp3][CAM4] overlay=x=1748 [tmp4];
        [tmp4][CAM5] overlay=x=2331 [tmp5];
        [tmp5][CAM6] overlay=x=2914 " \
        -c:v libx264 -tune zerolatency -an -preset ultrafast -crf 22 -f 
matroska - |\
    ffplay -framedrop -sync ext -probesize 32 -

What I was looking for was some way to set offsets to either:

* Least Latency - treat each inbound source as "live" and "best effort" rather 
than trying to sync to the start of each stream on the receiver (which is fairly arbitrary) or the 
start of the stream on the source (which is completely arbitrary).  I suspect this is doable, but I 
haven't found an obvious way to do it yet - any advice much appreciated.

* Absolute sync to NTP packets. This seems like it should be the "right" 
solution.  I've found some links that suggest I'm not the only one looking for a 
multi-source NTP sync solution, but I haven't found anyone with a clear solution.

I've tried the a few setpoints constructions to no obvious improvement in 
absolute synchronization including:

setpts=PTS-STARTPTS
setpts='(RTCTIME - RTCSTART) / (TB * 1000000)'
setpts=N/(8.33*TB

To no avail.

The RTCP Sender Report from these cameras do contain accurate wallclock time 
and are sent every 4-5 seconds:

Real-time Transport Control Protocol (Sender Report)
    [Stream setup by RTSP (frame 12)]
    10.. .... = Version: RFC 1889 Version (2)
    ..0. .... = Padding: False
    ...0 0000 = Reception report count: 0
    Packet type: Sender Report (200)
    Length: 6 (28 bytes)
    Sender SSRC: 0xcd323da7 (3442621863)
    Timestamp, MSW: 3819623083 (0xe3aad2ab)
    Timestamp, LSW: 3277326335 (0xc35807ff)
    [MSW and LSW as NTP timestamp: Jan 14, 2021 14:24:43.763062000 UTC]
    RTP timestamp: 2329505188
    Sender's packet count: 479641
    Sender's octet count: 674869163

My understanding is that NTP is included in RTCP specifically for inter-media 
global synchronization but I don't know how to enable this.

This stack overflow question seems to be on the right path, but implies that 
some mods needed to be made, at least 7 years ago:

https://stackoverflow.com/questions/20265546/reading-rtcp-packets-from-an-ip-camera-using-ffmpeg
 but

On Trac #4586 inspired me to try -use_wallclock_as_timestamps, but that seems to be 
receiver wallclock, not source.  The only other option in options_table.h that seems 
relevant is "start_time_realitme" - but this is encode.

It looks like there was a patch proposed in 2016 as a step toward multi-source 
synchronization:

https://ffmpeg.org/pipermail/ffmpeg-devel/2016-March/191683.html

libavformat/rtpdec.c seems to parse the NTP RTCP timestamps, but I don't see 
any method of using them to setpts (or otherwise sync sources), though it looks 
like this was a topic of discussion back in 2008:

https://ffmpeg.org/pipermail/ffmpeg-devel/2008-June/050416.html.

Which is to say, I looked through all the hints I could find, and while there 
are many tantalizing clues, nothing indicates an obvious solution to me.  Is 
there perhaps some obvious parameter I'm just not understanding or other 
solution escaping my search engine skills?

_______________________________________________
ffmpeg-user mailing list
[email protected]
https://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".

Reply via email to