Dropped buffers with rtprtxreceive
Samuel Hurst
samuelh at rd.bbc.co.uk
Mon Jan 31 16:38:41 UTC 2022
Hello again,
I've managed to make progress with my issue but I still don't think
rtprtxreceive is working right. I've also validated the same behaviour
in the GStreamer 1.18.5 package that comes with Ubuntu 21.10. More
details below.
On 28/01/2022 15:41, Samuel Hurst via gstreamer-devel wrote:
> Hello all,
>
> I'm doing some investigation with the rtprtx* elements for GStreamer and
> running into a few issues. Primarily, when I induce packet loss using
> netem [1] on the link in order to test the retransmission functionality,
> I get a lot of WARN-level debug output that says there's no clock-rate
> in caps and that it's dropping buffers:
>
>
>> 0:00:10.753827153 197836 0x55f378160060 ERROR rtpjitterbuffer
>> gstrtpjitterbuffer.c:1401:gst_jitter_buffer_sink_parse_caps:<rtpjitterbuffer2>
>> Got caps with wrong payload type (got 97, expected 96)
>> 0:00:10.753875088 197836 0x55f378160060 WARN rtpjitterbuffer
>> gstrtpjitterbuffer.c:3316:gst_rtp_jitter_buffer_chain:<rtpjitterbuffer2>
>> No clock-rate in caps!, dropping buffer
>> 0:00:10.754099058 197836 0x55f378160060 WARN rtpsource
>> rtpsource.c:1015:calculate_jitter: cannot get clock-rate for pt 97
<snip>
> And my receiving pipeline:
>
>> gst-launch-1.0 -e rtpbin name=r
>> sdes="application/x-rtp-source-sdes,cname=(string)\"samuelh\@rd.bbc.co.uk\""
>> udpsrc port=5000 !
>> "application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264,payload=(int)96"
>> ! r.recv_rtp_sink_0 r.recv_rtp_src_0_123456_96 ! rtprtxreceive
>> payload-type-map="application/x-rtp-pt-map,96=(uint)97" ! rtpssrcdemux
>> ! rtpjitterbuffer do-retransmission=true ! rtph264depay ! queue !
>> avdec_h264 ! videoconvert ! queue ! xvimagesink udpsrc port=5001 !
>> r.recv_rtcp_sink_0 r.send_rtcp_src_0 ! udpsink host=192.168.57.101
>> port=6001 sync=false async=false
So today I realised that rtpbin includes an rtpjitterbuffer element,
which explains why I was getting that message as rtpbin was before the
rtprtxreceive element in my pipeline. I've reformulated the receiving
pipeline so that it's now like this (without options):
udpsrc ! rtprtxreceive ! rtpssrcdemux ! rtpbin ! rtpjitterbuffer ! ...
And this has made the "No clock-rate in caps!, dropping buffer" messages
go away. However, I'm still not convinced it's actually doing
retransmissions properly, as I still get choppy playback.
For reference to the below, I have also added "max-size-packets=8192" to
rtprtxsend as I was seeing the sender not having the lost packets
available when requested occasionally.
Looking at the debug logs now, the following lines are of interest. It
seems that the jitter buffer on the receiver side spots that a packet
hasn't arrived in-sequence (#13935), and it sets a timer to wait for it
to arrive (I've trimmed the log to just messages I think are relevant -
if anyone wants the full log with rtp*:5, they are available at [1]):
> 0:00:16.885946848 48505 0x562bedce11e0 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:2337:update_rtx_timers:<rtpjitterbuffer0> Add RTX timer #13935, next_expected_pts 0:00:16.892798447, delay 0:00:00.020000024, est packet duration 0:00:00.040000048, jitter 0:00:00.000000006
> 0:00:16.885979722 48505 0x562bedbeca40 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:3098:gst_rtp_jitter_buffer_chain:<rtpjitterbuffer1> expected #13935, got #13936, gap of 1
> 0:00:16.885996300 48505 0x562bedbeca40 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:2461:gst_rtp_jitter_buffer_handle_missing_packets:<rtpjitterbuffer1> Missing packets: (#13935->#13935), gap 1, pts 0:00:16.852819575, last-pts 0:00:16.852819575
> 0:00:16.886016596 48505 0x562bedbeca40 INFO rtpjitterbuffer gstrtpjitterbuffer.c:2615:gst_rtp_jitter_buffer_handle_missing_packets:<rtpjitterbuffer1> Add Lost timer for #13935, pts 0:00:16.852819575, duration 0:00:00.000000000, offset +0:00:00.200000000
> 0:00:16.886051415 48505 0x562bedce11e0 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:3715:handle_next_buffer:<rtpjitterbuffer1> Sequence number GAP detected: expected 13935 instead of 13936 (1 missing)
> 0:00:16.886089699 48505 0x562bedce1180 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:4148:wait_next_timeout:<rtpjitterbuffer1> timer #13935 sync to timestamp 0:00:16.852819575 with sync time 6:20:02.704478418
After ~150ms, it appears to give up on the packet arriving and then
issues a NACK:
> 0:00:17.023860714 48505 0x562bedbec980 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:3878:do_expected_timeout:<rtpjitterbuffer0> expected #13935 didn't arrive, now 0:00:16.992903378
> 0:00:17.023878235 48505 0x562bedbec980 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:3906:do_expected_timeout:<rtpjitterbuffer0> Request RTX: custom-upstream event: 0x7f03d4003900, time 99:99:99.999999999, seq-num 771, GstRTPRetransmissionRequest, seqnum=(uint)13935, running-time=(guint64)16892798447, delay=(uint)100, retry=(uint)0, frequency=(uint)40, period=(uint)159, deadline=(uint)200, packet-spacing=(guint64)40000048, avg-rtt=(uint)0;
> 0:00:17.023882867 48505 0x562bedbec980 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:3930:do_expected_timeout:<rtpjitterbuffer0> timer #13935 new timeout 0:00:17.032929711, rtx retry timeout 0:00:00.040000048, num_retry 1
> 0:00:17.023887233 48505 0x562bedbec980 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:4148:wait_next_timeout:<rtpjitterbuffer0> timer #13935 sync to timestamp 0:00:17.032929711 with sync time 6:20:02.884588554
> 0:00:17.023897214 48505 0x562bedbec980 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:1745:gst_rtp_jitter_buffer_src_event:<rtpjitterbuffer1> received custom-upstream
> 0:00:17.023905885 48505 0x562bedbec980 DEBUG rtpsession rtpsession.c:4851:rtp_session_request_nack: request NACK for SSRC 0001e240, #13935, deadline 6:20:02.744611847
> 0:00:17.023910025 48505 0x562bedbec980 DEBUG rtpsource rtpsource.c:2003:rtp_source_register_nack: append NACK #13935 with deadline 6:20:02.744611847
> 0:00:17.024010175 48505 0x562bedce08c0 DEBUG rtpsession rtpsession.c:3601:session_start_rtcp: create RR for SSRC c515aea0
> 0:00:17.024015496 48505 0x562bedce08c0 DEBUG rtpsession rtpsession.c:3792:session_nack: 1 NACKs current time 6:20:02.644636451
> 0:00:17.024018188 48505 0x562bedce08c0 DEBUG rtpsession rtpsession.c:3797:session_nack: #13935 deadline 6:20:02.744611847
> 0:00:17.024021299 48505 0x562bedce08c0 DEBUG rtpsession rtpsession.c:3878:session_nack: Sent 1 seqnums into 1 FB NACKs
The server then responds with a retransmission packet with sequence
number #45306 (the machines are two VMs on the same physical host, so
minimal latency between them), but for some reason the receiver doesn't
think that it's actually expecting #13935?!?
> 0:00:17.044164098 48505 0x562bedbeca40 DEBUG rtprtxreceive gstrtprtxreceive.c:588:gst_rtp_rtx_receive_chain:<rtprtxreceive0> Got rtx packet: rtx seqnum 45306, rtx ssrc 3A5CC61F, rtx pt 97, orig seqnum 13935, orig pt 96
> 0:00:17.044167915 48505 0x562bedbeca40 INFO rtprtxreceive gstrtprtxreceive.c:638:gst_rtp_rtx_receive_chain:<rtprtxreceive0> dropping rtx packet 45306 because its orig seqnum (13935) is not in our pending retransmission requests
It then seems to loop on that packet for a bit, then eventually giving
up and declaring it lost, even though it's had the retransmission packet
(as verified using Wireshark):
> 0:00:17.303858296 48505 0x562bedbec980 DEBUG rtpjitterbuffer gstrtpjitterbuffer.c:2413:insert_lost_event:<rtpjitterbuffer0> Packet #13935 lost
Can someone please point out what I'm missing? Or is this a bug?
Best regards,
-Sam
[1]:
https://www.dropbox.com/sh/ffm6zgdh3xpo0ju/AAAhtin6PIMAMb__EF-SlEyla?dl=0
More information about the gstreamer-devel
mailing list