paullouisageneau / libdatachannel

C/C++ WebRTC network library featuring Data Channels, Media Transport, and WebSockets
https://libdatachannel.org/
Mozilla Public License 2.0
1.79k stars 361 forks source link

how to deal with the media packets loss #893

Open ella-yy opened 1 year ago

ella-yy commented 1 year ago

Does libdatachannel support packet retransmission? I found in my application some rtp packets were lost.

paullouisageneau commented 1 year ago

Yes it does, the RtcpNackResponder element handles retransmission, it's used in the streamer example for instance: https://github.com/paullouisageneau/libdatachannel/blob/8679ca4714258a58669133bf636a29e4c896c418/examples/streamer/main.cpp#L220

ella-yy commented 1 year ago

I found in the client side,it does not send RtcpNack when some rtp packets are lost.

paullouisageneau commented 1 year ago

The NACK responder is server-side and answsers the RTCP NACK, the client side element is missing for now because you typically send to browsers. It should be part of the depacketizer, see issue https://github.com/paullouisageneau/libdatachannel/issues/676.

If you use libdatachannel on client-side and redirect the incoming RTP stream to an external pipeline, you can do it manually: look at RTP sequence numbers and send a NACK when the sequence is discontinuous. The RTCP nack packet can be formatted with: https://github.com/paullouisageneau/libdatachannel/blob/8679ca4714258a58669133bf636a29e4c896c418/include/rtc/rtp.hpp#L318

H4k4nn commented 7 months ago

I get h264 RTP streams from browser. I depacketize them and reordered if needed. Problem is packet loss. IF I have loss any frame my decoder gets error and I think this error goes on until keyframe? This keyframe maybe comes one in 1000 frames maybe?

I know sequence number and timestamp for the lost packet of h264 frame. What can I do? Do I need to ask specific sequence number packet again? or should I ask for keyframe to browser?

baerrus commented 7 months ago

At 30 fps one I-frame per 1000 is like once every 30 seconds. Can you force the video source to generate an I-frame at maximum every few seconds?

H4k4nn commented 7 months ago

At 30 fps one I-frame per 1000 is like once every 30 seconds. Can you force the video source to generate an I-frame at maximum every few seconds?

I say maybe 1000 but sometimes there is no I-frame for long time maybe minutes. My video source is browser JS. Can I make it? IF yes how? :)

paullouisageneau commented 7 months ago

I know sequence number and timestamp for the lost packet of h264 frame. What can I do? Do I need to ask specific sequence number packet again? or should I ask for keyframe to browser?

You can do both: it's possible to send a NACK message to the browser (you have to manually populate and send an RtcpNack as the logic is not yet in the library), and you can request a new keyframe with a PLI (This is done by calling track->requestKeyframe() and it requires a RtcprReceivingSession to be chained).

You typically request a NACK first to try to complete the frame before it has to be presented, and a PLI if you failed to get the complete frame before presentation.

H4k4nn commented 7 months ago

In media-sfu example requestKeyframe() is calling by peerconnection but there is no RtcprReceivingSession of Receiver PeerConnection. Why do I need RtcprReceivingSession to send keyframe request?