ristreceiver reports empty and full at the same time
Steps:
- Run
ristreceiver -i rist://@127.0.0.1:4754 -o udp://127.0.0.1:8010 -v 10
- Start a tunnel from 47540 to 4754 with base 30ms RTT that queues up to 450 packets before loss
- Run
ristsender -o rist://127.0.0.1:47540 -i udp://@127.0.0.1:8000
- Start a packet source at 6mbps e.g.
ffmpeg -f lavfi -re -i yuvtestsrc=r=60 -c:v libx264 -tune:v zerolatency -x264-params "nal-hrd=cbr" -g 120 -b:v 6M -minrate 6M -maxrate 6M -bufsize 12M -f mpegts -pkt_size '188*7' udp://127.0.0.1:8000
Messages this start showing up in the log:
1600218537.518287|140727595040768.0|[DEBUG] Buffer is empty, it has been for 0 < 1000 (ms)!
1600218537.521436|140727595040768.0|[DEBUG] Buffer is full, dropping packet 563/563
1600218537.524694|140727595040768.0|[DEBUG] Datagram 563 is missing, inserting into the missing queue with deadline in 177ms (queue=1), last_seq_found 562
1600218537.524709|140727595040768.0|[DEBUG] Empty buffer element, flushing 1 hole(s), now at index 564, size is 1316
Later this packet even gets NACKed:
1600218537.524694|140727595040768.0|[DEBUG] Datagram 563 is missing, inserting into the missing queue with deadline in 177ms (queue=1), last_seq_found 562
1600218537.704733|140727595040768.0|[DEBUG] Datagram 563 is missing, sending NACK!, next retry in 355ms, age is 180ms, retry #1, max_size is 1000ms
1600218537.704743|140727595040768.0|[DEBUG] Sending 1 nacks starting with 563, 0, 0, 0
1600218538.060944|140727595040768.0|[DEBUG] Datagram 563 is missing, sending NACK!, next retry in 344ms, age is 536ms, retry #2, max_size is 1000ms
1600218538.060963|140727595040768.0|[DEBUG] Sending 2 nacks starting with 563, 674, 0, 0
1600218538.407880|140727595040768.0|[DEBUG] Datagram 563 is missing, sending NACK!, next retry in 369ms, age is 883ms, retry #3, max_size is 1000ms
1600218538.407912|140727595040768.0|[DEBUG] Sending 4 nacks starting with 563, 672, 674, 773
1600218539.227399|140727595040768.0|[DEBUG] Packet 563 too late, dropping!
1600218539.594769|140727595040768.0|[DEBUG] Packet 563 too late, dropping!
1600218539.941437|140727595040768.0|[DEBUG] Packet 563 too late, dropping!
It seems like https://code.videolan.org/rist/librist/-/blob/f454148dad5d3584351ffe56ad76bf63242969ea/src/rist-common.c#L541 suffers from the classic ambiguous case of the read pointer and the write pointer pointing to the same index of a lock-free ring buffer.
I was able to mitigate by changing the comparison to RIST_UNLIKELY(idx == reader_idx - 1)