no Producer for received SDES chunk

Hi,

I’m outputting video from mediasoup to an RTP endpoint (GStreamer receiver), in single direction, where mediasoup receives WebRTC media from browser, then sends the media to GStreamer via RTP:

Browser --WebRTC--> mediasoup --RTP--> GStreamer

While running mediasoup with debug enabled, when GStreamer sends its RTCP Receiver Report + Session Description packets, and I see these messages cropping up: RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk.

Seeing the code, looks like mediasoup tries to find a producer that corresponds to the SSRC provided in the RTCP SDES. I don’t know the internals of that find.

Is it correct & expected that in such scenario these messages should appear? Afaik the RTCP SDES simply informs about what is the SSRC of the receiving party (GStreamer), so it can later be expected and matched with metadata in other RTCP messages. It seems normal that there wouldn’t be any Producer with that SSRC, but I wanted to confirm that.

Ultimately the reason to worry about this is that some of these find operations seem to take a lot of time, some times getting close to 1 second (if the times shown in the log lines mean how much time the operation took, something that I’m not sure about but it looks like that’s the case):

  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +5s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +1s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +868ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +361ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +42ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +5s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +1s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +197ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +1s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +5s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +267ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +5s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +5s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +694ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +401ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +725ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +548ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +799ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +540ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +943ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +690ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +6s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +518ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +186ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +6s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +292ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +1s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +337ms
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +5s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +1s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +1s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +3s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +4s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +1s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +2s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:2956732221] +5s
  mediasoup:worker[pid:28711] RTC::Transport::HandleRtcpPacket() | no Producer for received SDES chunk [ssrc:17350745] +948ms

In this case, ssrc 17350745 is from the video rtcp, and ssrc 2956732221 is from the audio. It happens exactly the same if only a single media is used, though.

(Using mediasoup 3.4.2)

As the RFC 3550 says:

End systems send one SDES packet containing their own source
identifier (the same as the SSRC in the fixed RTP header).

So an endpoint should just send SDES if it’s sending a RTP stream. Otherwise it does not make sense since the ssrc in the SDES means nothing.

Regarding the +1s etc in the logs, that’s just the time elapsed since a previous log in the same debug instance:

@jmillan can you confirm that SDES does not make any sense if they are not associated to a RTP stream being sent by the same SDES sender?

I thought it made sense (in the world of pure RTP, not taking into account additional systems such as SDP re-negotiations), because every “end system” should identify itself, even if it’s only for the purpose of letting the other part know that there is someone at the other end… and also the fact that not sending RTP now doesn’t mean it couldn’t suddenly start sending RTP at any time in the future.

Granted, this has a limited use in today’s systems, and WebRTC in particular. But that’s my 2 cents.

Also glad to know the +1s are not an actual count of time spent looking for a corresponding Producer; that was my main worry.

I’ve bee reading about the original intent of SSRC, even in recv-only peers, starting from the comments in the related Github issue:

  1. The common header has sender ssrc : 1825801961 , being “1825801961” a random SSRC that nobody knows about and was just placed there by Firefox to satisfy the ugly text in RFC 3550.
  • In mediasoup we do nothing with such a sender ssrc value.
  • In fact, there is absolutely nothing we can do with it.

Sender SSRC of a mediasoup producer stream is non existent. Is not negotiated and it is represented in RTCP packets as 0 . Others (like FF in this case) may simply invent it.

thinking about why Firefox would invent a previously unknown SSRC that is of no use… seems that, even if nowadays it is of no use, the main purposes for a recv-only peer to include a well-formed SSRC in its Receiver Reports, is (or was):

  • To allow all participants in the “RTP session” to know about the size of the session, i.e. to know how many participants really are, and let everybody be ready to identify incoming RTP packets if the currently recv-only peer(s) suddenly decided to become send-recv and start sending RTP packets.

  • To use this session size in the calculations of sender RTCP frequency (section 6.2.1):

    Calculation of the RTCP packet interval depends upon an estimate of
    the number of sites participating in the session.

  • To know that the other part is there and is still listening, and otherwise maybe decide to stop sending (depending on the implementation) (section 6.2.1 again):

    A participant MAY mark another site inactive, or delete it if not yet
    valid, if no RTP or RTCP packet has been received for a small number of RTCP report intervals (5 is RECOMMENDED).

So, it’s been interesting to dig a bit on this one. I agree that these RFCs are pretty old and didn’t age very well… but these are mandatory fields so better do it “right”.

Specifically for the issue of choosing either 0 or any other random number, I guess Firefox just generates a random SSRC for itself and used that. The initialization section (6.3.2) seems to imply that self-assigning a ssrc is indeed independent from the fact of whether RTP will be sent in the future, so probably Firefox just follows the same procedure for both sendrecv and recvonly endpoints. I doubt it’s a critical issue but maybe mediasoup would avoid potential problems with its choice of 0 if it did the same.

I don’t agree with this. The identification of an endpoint is not a “ssrc”. I don’t even think there is any “endpoint identification”. If I’m sending RTP to a destination I’ll know there is somebody in the other side once I receive RTCP from it. That’s the only I need to be sure that there is somebody receiving my packets.

In addition, a RTP endpoint should not pre-announce future SSRCs for streams that it’s not even sending yet. In fact, the random valud in the “sender ssrc” of some RTCP packets does not correspond to the SSRC of a future RTP that the endpoint will send to us.

All those bullets you mention talk about “participants in a session”, meaning that you may send the same RTP stream to N receivers. Not sure if this is multicast or what, but definitely it’s something that makes zero sense today.

Anyway, I still don’t know what is wrong in mediasoup. We must choose a “random” ssrc value for “sender ssrc” field in our RTCP packets. We choose “0”. Not that random, ok, but still valid.

Hi, just a note:

SDES: Source Description RTCP Packet

Where Source is the RTP source for the RTCP SDES chunk as you can take from RFC 3550. I would say gstreamer should not send any SDES packet since it is not sending RTP.

Anyway we do nothing with SDES packets.

Fair enough :slight_smile: (but then let’s have it clear that it’s a mediasoup decision, not a MUST as it was stated before, which can cause confusion)

I agree, it doesn’t make much sense. They have to do so, though, because GStreamer works in full-size RTCP mode, and that same RFC forces them when saying that all RTCP compound packets must include a Receiver Report and a SDES. So I guess that’s the reason GStreamer sends one.

(Note 1: Neither FFmpeg or GStreamer have support for sending reduced-size rtcp… that was the reason I worried about it being always forced from mediasoup in a previous conversation… but it turns out that they can receive rtcp-rsize without problems --at least I verified it for GStreamer)
(Note 2: Actually, GStreamer has private support for sending rtcp-rsize, but not exposed in the public API of the CLI tool gst-launch that end users can use)

I think we just said that there are some specs telling that media ssrc (and not sender ssrc) must be 0 in certain specs, such as REMB and Transport-CC feedbacks, since they do not report about a specific RTP stream. I we said otherwise, our fault :slight_smile:

Can you point to the exact text in the RFC, please? If so we’ll relax the warning or just ignore it.

Yep, here is the info:

In section 6.1:

Thus, all RTCP packets MUST be sent in a compound packet of at least
two individual packets, with the following format:

[…]

SR or RR: The first RTCP packet in the compound packet MUST
always be a report packet to facilitate header validation […]

SDES: An SDES packet containing a CNAME item MUST be included
in each compound RTCP packet, except as noted in Section 9.1.
[…]

I’ve also seen this, helpfully summarized in the RFC 5506 (Reduced-Size RTCP) where it does a bit of a “quick recap” of full-sized RTCP in section 3.1:

Section 6.1 in [RFC3550] specifies that an RTCP packet must be sent
as a compound RTCP packet consisting of at least two individual RTCP
packets, first a sender report (SR) or receiver report (RR), followed
by additional packets including a mandatory SDES packet containing a
CNAME item for the transmitting source identifier.

I think it’s a good idea because that warning doesn’t actually warn of… anything, at all, given today’s use of “recv-only” SDES. It’s only noise in mediasoup logs, so removing it would make sense.

So SDES completely ignored now:

Will be released in next version once we change something else :slight_smile:

Nice!