Problem using SimulcastConsumer on piped transports

Yes, it’s on purpose (there is no sense in creating a PipeTransport to communicate two routers within the same worker.

Although probably I’ll remove such a limitation.

If I remove the limitation I get this:

transportConsume Error: Producer already present in mapProducers [producerId:a712c51e-c120-4da2-95b7-fc758cd3fe98]

It should not happen. When calling router1.pipeToRouter({ router: router2, producerId: '1234' }), a Pipe Producer with id:"1234" is created in router2, so both router1 and router2 have a Producer with same id:"1234". That should not be a problem at all. Testing it, will have something today or tomorrow.

Yes, but I can’t pipe a producer to the same router, because it will create e producer with the same id.

Investigating the server logs I found that CanSwitchToSpatialLayer fails on spatial layers 0 and 2, and so they are excluded from the test loop.

Yes, but I can’t pipe a producer to the same router, because it will create e producer with the same id.

Sure, I did not mean “using the same router” but using the same worker :slight_smile:

In fact, there is no limitation, I was wrong, you can perfectly pipe router1 to router2 even if both routers have been created on the same worker.

Investigating the server logs I found that CanSwitchToSpatialLayer fails on spatial layers 0 and 2, and so they are excluded from the test loop.

Interesting. Let me explain what that method does:

  • Let’s imagine the remote simulcast producers sends 3 SSRC streams.
  • The first key frame is received for, let’s say, stream 2 (so “spatial layer 1” in the SimulcastConsumer).
  • The SimulcastConsumer selects it.
  • The SimulcastConsumer cannot switch to a different producer stream (for example, stream 3) until it has received RTCP SenderReports for both the already handled stream 2 and the desired stream 3.
    • This is because we need the NTP timestamp in both SR to correlate them and properly rewrite the RTP timestamp in packets forwarded by the SimulcastConsumer (otherwise we get lipsync, etc).

So, if you see that it means that, somehow, the PipeProducer in router_2 is NOT receiving RTCP Sender Reports from the PipeConsumer in router_1, so the SimulcastConsumer2 in router_2 can just select the first RTP stream that it received from the PipeConsumer (so the first RTP stream that the original sender sent).

And here the problem. This is super helpful !!!

It’s gonna be super hard for me to use your repo to test this issue. Can you please do this easy checks? Let me explain:

  • A mediasoup C++ transport sends RTCP SenderReports (and ReceiverReports) when the periodic Transport::rtcpTimer triggers its OnTimer callback (defined in Transport.cpp).
  • However such a Transport::rtcpTimer is not started until the Transport::Connected() method is called, which happens different in each kind of transport.
  • In a PipeTransport it’s called after calling pipeTransport.connect() (see here).

Can you please add a MS_DUMP("whatever") on it and verify whether such a log is printed twice (since 2 PipeTransports are created to pipe router1 into router2)?

Confirmed: it is called 2 times.

Oh, and also a MS_DUMP("foo and bar") in the PipeTransport::GetRtcp() method, please, to verify it’s being called.

Even more, please add this:

void PipeConsumer::GetRtcp(
  RTC::RTCP::CompoundPacket* packet, RTC::RtpStreamSend* rtpStream, uint64_t now)
{
	MS_TRACE();

    MS_DUMP("------1");

	MS_ASSERT(
	  std::find(this->rtpStreams.begin(), this->rtpStreams.end(), rtpStream) != this->rtpStreams.end(),
	  "RTP stream does exist");

	if (static_cast<float>((now - this->lastRtcpSentTime) * 1.15) < this->maxRtcpInterval)
		return;

    MS_DUMP("------2");

	auto* report = rtpStream->GetRtcpSenderReport(now);

	if (!report)
		return;

    MS_DUMP("------3");
    report->Dump();

	packet->AddSenderReport(report);

	// Build SDES chunk for this sender.
	auto* sdesChunk = rtpStream->GetRtcpSdesChunk();

	packet->AddSdesChunk(sdesChunk);

	this->lastRtcpSentTime = now;
}

Thanks so much BTW. We’ll add a “piped demo” some day to have a proper scenario to test it.

I get this kind of output:

RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------2
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------2
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------2
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------2
RTC::PipeConsumer::GetRtcp() | ------3
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 363878317
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 783821
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 1941325217
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 318523258
RTC::RTCP::SenderReport::Dump() |   packet count : 1724
RTC::RTCP::SenderReport::Dump() |   octet count  : 670039
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------2
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------1
RTC::PipeConsumer::GetRtcp() | ------2

so just RTCP Sender Reports for a single SSRC, right? and that SSRC matches one in the pipeProducer.rtpParameters.encodings right?

Yes,

pipeProducer { id: '2221337e-c055-4497-b1d1-0d321d691ef2',
  kind: 'video',
  paused: false,
  rtpMapping:
   { codecs:
      [ { mappedPayloadType: 107, payloadType: 107 }, [length]: 1 ],
     encodings:
      [ { mappedSsrc: 427149297, rid: null, ssrc: 993848071 },
        { mappedSsrc: 427149298, rid: null, ssrc: 993848072 },
        { mappedSsrc: 427149299, rid: null, ssrc: 993848073 },
        [length]: 3 ] },
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 993848071
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 784112
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 1894080577
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 3636828927
RTC::RTCP::SenderReport::Dump() |   packet count : 962
RTC::RTCP::SenderReport::Dump() |   octet count  : 268931
RTC::RTCP::SenderReport::Dump() | </SenderReport>

Good… I think I strongly need the stats of the PipeConsumer and PipeProducer (once RTP is running for a while).

NOTE: score is included in both Producer and Consumer stats, within each RTP stream in them:

  • In a Producer stats, the score of a RTP stream is 0 if no RTCP SenderReport have been received for it.
  • In a Consumer stats, the score of a RTP stream is 0 if no RTCP ReceiverReport have been received for it.

We also need the bitrates of each stream (included in those stats). Can you get them please? I think those will be definitive to figure out what is wrong.

Here are the dump after 10 seconds:

pipeConsumer:

{ consumableRtpEncodings:
   [ { ksvc: false,
       maxBitrate: 750000,
       scalabilityMode: 'S1T3',
       spatialLayers: 1,
       ssrc: 621531086,
       temporalLayers: 3 },
     { ksvc: false,
       maxBitrate: 1500000,
       scalabilityMode: 'S1T3',
       spatialLayers: 1,
       ssrc: 621531087,
       temporalLayers: 3 },
     { ksvc: false,
       maxBitrate: 3000000,
       scalabilityMode: 'S1T3',
       spatialLayers: 1,
       ssrc: 621531088,
       temporalLayers: 3 },
     [length]: 3 ],
  id: '3b20c2c0-c2e1-4ce2-9261-b0f925fe7943',
  kind: 'video',
  paused: false,
  producerPaused: false,
  rtpParameters:
   { codecs:
      [ { clockRate: 90000,
          mimeType: 'video/H264',
          parameters:
           { 'level-asymmetry-allowed': 1,
             'packetization-mode': 1,
             'profile-level-id': '42e01f' },
          payloadType: 107,
          rtcpFeedback:
           [ { parameter: 'pli', type: 'nack' },
             { parameter: 'fir', type: 'ccm' },
             [length]: 2 ] },
        [length]: 1 ],
     encodings:
      [ { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 750000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 621531086,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 1500000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 621531087,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 3000000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 621531088,
          temporalLayers: 3 },
        [length]: 3 ],
     headerExtensions:
      [ { encrypt: false,
          id: 6,
          parameters: {},
          uri:
           'http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07' },
        { encrypt: false,
          id: 7,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:framemarking' },
        { encrypt: false,
          id: 11,
          parameters: {},
          uri: 'urn:3gpp:video-orientation' },
        { encrypt: false,
          id: 12,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:toffset' },
        [length]: 4 ],
     rtcp: { cname: 'xwtzzkYsz87COsv6', reducedSize: true } },
  rtpStreams:
   [ { params:
        { clockRate: 90000,
          cname: 'xwtzzkYsz87COsv6',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 621531088,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'xwtzzkYsz87COsv6',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 621531087,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'xwtzzkYsz87COsv6',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 621531086,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     [length]: 3 ],
  supportedCodecPayloadTypes: [ 107, [length]: 1 ],
  type: 'pipe' }

pipeProducer:

{ id: 'b27ee0a1-da7a-4f19-80ce-f97eafb665ee',
  kind: 'video',
  paused: false,
  rtpMapping:
   { codecs:
      [ { mappedPayloadType: 107, payloadType: 107 }, [length]: 1 ],
     encodings:
      [ { mappedSsrc: 600836793, rid: null, ssrc: 621531086 },
        { mappedSsrc: 600836794, rid: null, ssrc: 621531087 },
        { mappedSsrc: 600836795, rid: null, ssrc: 621531088 },
        [length]: 3 ] },
  rtpParameters:
   { codecs:
      [ { clockRate: 90000,
          mimeType: 'video/H264',
          parameters:
           { 'level-asymmetry-allowed': 1,
             'packetization-mode': 1,
             'profile-level-id': '42e01f' },
          payloadType: 107,
          rtcpFeedback:
           [ { parameter: 'pli', type: 'nack' },
             { parameter: 'fir', type: 'ccm' },
             [length]: 2 ] },
        [length]: 1 ],
     encodings:
      [ { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 750000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 621531086,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 1500000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 621531087,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 3000000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 621531088,
          temporalLayers: 3 },
        [length]: 3 ],
     headerExtensions:
      [ { encrypt: false,
          id: 6,
          parameters: {},
          uri:
           'http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07' },
        { encrypt: false,
          id: 7,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:framemarking' },
        { encrypt: false,
          id: 11,
          parameters: {},
          uri: 'urn:3gpp:video-orientation' },
        { encrypt: false,
          id: 12,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:toffset' },
        [length]: 4 ],
     rtcp: { cname: 'xwtzzkYsz87COsv6', reducedSize: true } },
  rtpStreams:
   [ { params:
        { clockRate: 90000,
          cname: 'xwtzzkYsz87COsv6',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 621531086,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'xwtzzkYsz87COsv6',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 621531087,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'xwtzzkYsz87COsv6',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 621531088,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     [length]: 3 ],
  type: 'simulcast' }

Dump & stats:

  app:dump pipeConsumer { consumableRtpEncodings:
   [ { ksvc: false,
       maxBitrate: 750000,
       scalabilityMode: 'S1T3',
       spatialLayers: 1,
       ssrc: 858673697,
       temporalLayers: 3 },
     { ksvc: false,
       maxBitrate: 1500000,
       scalabilityMode: 'S1T3',
       spatialLayers: 1,
       ssrc: 858673698,
       temporalLayers: 3 },
     { ksvc: false,
       maxBitrate: 3000000,
       scalabilityMode: 'S1T3',
       spatialLayers: 1,
       ssrc: 858673699,
       temporalLayers: 3 },
     [length]: 3 ],
  id: 'abf41bff-5a65-4319-ab59-2af23f736666',
  kind: 'video',
  paused: false,
  producerPaused: false,
  rtpParameters:
   { codecs:
      [ { clockRate: 90000,
          mimeType: 'video/H264',
          parameters:
           { 'level-asymmetry-allowed': 1,
             'packetization-mode': 1,
             'profile-level-id': '42e01f' },
          payloadType: 107,
          rtcpFeedback:
           [ { parameter: 'pli', type: 'nack' },
             { parameter: 'fir', type: 'ccm' },
             [length]: 2 ] },
        [length]: 1 ],
     encodings:
      [ { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 750000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 858673697,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 1500000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 858673698,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 3000000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 858673699,
          temporalLayers: 3 },
        [length]: 3 ],
     headerExtensions:
      [ { encrypt: false,
          id: 6,
          parameters: {},
          uri:
           'http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07' },
        { encrypt: false,
          id: 7,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:framemarking' },
        { encrypt: false,
          id: 11,
          parameters: {},
          uri: 'urn:3gpp:video-orientation' },
        { encrypt: false,
          id: 12,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:toffset' },
        [length]: 4 ],
     rtcp: { cname: 'S1nqZZopaYilXDfS', reducedSize: true } },
  rtpStreams:
   [ { params:
        { clockRate: 90000,
          cname: 'S1nqZZopaYilXDfS',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 858673699,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'S1nqZZopaYilXDfS',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 858673698,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'S1nqZZopaYilXDfS',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 858673697,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     [length]: 3 ],
  supportedCodecPayloadTypes: [ 107, [length]: 1 ],
  type: 'pipe' } +0ms
  app:stats pipeConsumer [ { bitrate: 2538560,
    byteCount: 3084697,
    firCount: 0,
    fractionLost: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 2730,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    roundTripTime: 0,
    score: 10,
    ssrc: 858673699,
    timestamp: 785130806,
    type: 'outbound-rtp' },
  { bitrate: 507528,
    byteCount: 594013,
    firCount: 0,
    fractionLost: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 657,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    roundTripTime: 0,
    score: 10,
    ssrc: 858673698,
    timestamp: 785130806,
    type: 'outbound-rtp' },
  { bitrate: 128000,
    byteCount: 152072,
    firCount: 0,
    fractionLost: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 306,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    roundTripTime: 0.0152587890625,
    score: 10,
    ssrc: 858673697,
    timestamp: 785130806,
    type: 'outbound-rtp' },
  [length]: 3 ] +0ms
  app:dump pipeProducer { id: 'a905ddee-a90b-44b5-8e12-30eb3711d7aa',
  kind: 'video',
  paused: false,
  rtpMapping:
   { codecs:
      [ { mappedPayloadType: 107, payloadType: 107 }, [length]: 1 ],
     encodings:
      [ { mappedSsrc: 845053550, rid: null, ssrc: 858673697 },
        { mappedSsrc: 845053551, rid: null, ssrc: 858673698 },
        { mappedSsrc: 845053552, rid: null, ssrc: 858673699 },
        [length]: 3 ] },
  rtpParameters:
   { codecs:
      [ { clockRate: 90000,
          mimeType: 'video/H264',
          parameters:
           { 'level-asymmetry-allowed': 1,
             'packetization-mode': 1,
             'profile-level-id': '42e01f' },
          payloadType: 107,
          rtcpFeedback:
           [ { parameter: 'pli', type: 'nack' },
             { parameter: 'fir', type: 'ccm' },
             [length]: 2 ] },
        [length]: 1 ],
     encodings:
      [ { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 750000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 858673697,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 1500000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 858673698,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 3000000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 858673699,
          temporalLayers: 3 },
        [length]: 3 ],
     headerExtensions:
      [ { encrypt: false,
          id: 6,
          parameters: {},
          uri:
           'http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07' },
        { encrypt: false,
          id: 7,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:framemarking' },
        { encrypt: false,
          id: 11,
          parameters: {},
          uri: 'urn:3gpp:video-orientation' },
        { encrypt: false,
          id: 12,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:toffset' },
        [length]: 4 ],
     rtcp: { cname: 'S1nqZZopaYilXDfS', reducedSize: true } },
  rtpStreams:
   [ { params:
        { clockRate: 90000,
          cname: 'S1nqZZopaYilXDfS',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 858673697,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'S1nqZZopaYilXDfS',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 858673698,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'S1nqZZopaYilXDfS',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 858673699,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     [length]: 3 ],
  type: 'simulcast' } +0ms
  app:stats pipeProducer [ { bitrate: 128000,
    bitrateByLayer: { '0.0': 57920, '0.1': 91064, '0.2': 128000 },
    byteCount: 152072,
    firCount: 0,
    fractionLost: 0,
    jitter: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 306,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    score: 10,
    ssrc: 858673697,
    timestamp: 785130807,
    type: 'inbound-rtp' },
  { bitrate: 507528,
    bitrateByLayer: { '0.0': 233432, '0.1': 373840, '0.2': 507528 },
    byteCount: 594013,
    firCount: 0,
    fractionLost: 0,
    jitter: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 657,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    score: 10,
    ssrc: 858673698,
    timestamp: 785130807,
    type: 'inbound-rtp' },
  { bitrate: 2538560,
    bitrateByLayer: { '0.0': 1000552, '0.1': 1728368, '0.2': 2538560 },
    byteCount: 3084697,
    firCount: 0,
    fractionLost: 0,
    jitter: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 2730,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    score: 10,
    ssrc: 858673699,
    timestamp: 785130807,
    type: 'inbound-rtp' },
  [length]: 3 ]

Everything looks extremely correct… All stream score values are 10 in the PipeProducer. However the initial value of a stream score is always 10 so I was wrong. It may become 0 later but initially it’s 10 even if no RTCP SenderReport has been received.

So the only possible option is that no RTCP Sender Report has been received from the PipeConsumer to the PipeProducer. And, if so, indeed the SimulcastConsumer won’t be able to switch stream.

Now the question is: how to check that? I wonder if you can do a tshark in IP:127.0.0.1 (the one used by default when calling router.pipeToRoute() and check which RTCP traffic there is between both (basically there should be SenderReports from the PipeConsumer to the PipeProducer and ReceiverReport from the PipeProducer to the PipeConsumer.

I know this is tedious but, may you do it please?

Or you could just add this here:

MS_DUMP(
  "RTCP SenderRepot received [producerId:%s, ssrc:%" PRIu32 "]",
  this->id.c_str(),
  report->GetSsrc());

report->Dump(); 

Then you can filter those logs by just selecting those for the PipeProducer (by checking the pipeProducer.id).

Done using the report->Dump()
All the received reports belong to the pipeProducer, but only video ssrc=966663761 is received:

TC::Producer::ReceiveRtcpSenderReport() | RTCP SenderReport received [producerId:5ba865e5-0e67-44df-8534-86bb7437a2ef, ssrc:94461288]
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 94461288
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 3771302538
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 1213044793
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1753876113
RTC::RTCP::SenderReport::Dump() |   packet count : 617
RTC::RTCP::SenderReport::Dump() |   octet count  : 600221
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::Producer::ReceiveRtcpSenderReport() | RTCP SenderReport received [producerId:5ba865e5-0e67-44df-8534-86bb7437a2ef, ssrc:966663761]
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 966663761
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 849124
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 3831110828
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 2363327287
RTC::RTCP::SenderReport::Dump() |   packet count : 63
RTC::RTCP::SenderReport::Dump() |   octet count  : 26011
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::Producer::ReceiveRtcpSenderReport() | RTCP SenderReport received [producerId:5ba865e5-0e67-44df-8534-86bb7437a2ef, ssrc:94461288]
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 94461288
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 3771302538
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 1874431102
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1753889973
RTC::RTCP::SenderReport::Dump() |   packet count : 657
RTC::RTCP::SenderReport::Dump() |   octet count  : 644848
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::Producer::ReceiveRtcpSenderReport() | RTCP SenderReport received [producerId:5ba865e5-0e67-44df-8534-86bb7437a2ef, ssrc:94461286]
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 94461286
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 3771302538
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 2122066031
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 2363337727
RTC::RTCP::SenderReport::Dump() |   packet count : 66
RTC::RTCP::SenderReport::Dump() |   octet count  : 25739
RTC::RTCP::SenderReport::Dump() | </SenderReport>
  app:dump pipeProducer { id: '5ba865e5-0e67-44df-8534-86bb7437a2ef',
  kind: 'video',
  paused: false,
  rtpMapping:
   { codecs:
      [ { mappedPayloadType: 107, payloadType: 107 }, [length]: 1 ],
     encodings:
      [ { mappedSsrc: 499381194, rid: null, ssrc: 966663761 },
        { mappedSsrc: 499381195, rid: null, ssrc: 966663762 },
        { mappedSsrc: 499381196, rid: null, ssrc: 966663763 },
        [length]: 3 ] },
  rtpParameters:
   { codecs:
      [ { clockRate: 90000,
          mimeType: 'video/H264',
          parameters:
           { 'level-asymmetry-allowed': 1,
             'packetization-mode': 1,
             'profile-level-id': '42e01f' },
          payloadType: 107,
          rtcpFeedback:
           [ { parameter: 'pli', type: 'nack' },
             { parameter: 'fir', type: 'ccm' },
             [length]: 2 ] },
        [length]: 1 ],
     encodings:
      [ { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 750000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 966663761,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 1500000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 966663762,
          temporalLayers: 3 },
        { codecPayloadType: 107,
          ksvc: false,
          maxBitrate: 3000000,
          scalabilityMode: 'S1T3',
          spatialLayers: 1,
          ssrc: 966663763,
          temporalLayers: 3 },
        [length]: 3 ],
     headerExtensions:
      [ { encrypt: false,
          id: 6,
          parameters: {},
          uri:
           'http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07' },
        { encrypt: false,
          id: 7,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:framemarking' },
        { encrypt: false,
          id: 11,
          parameters: {},
          uri: 'urn:3gpp:video-orientation' },
        { encrypt: false,
          id: 12,
          parameters: {},
          uri: 'urn:ietf:params:rtp-hdrext:toffset' },
        [length]: 4 ],
     rtcp: { cname: 'GNQA2kAFM49N6r8m', reducedSize: true } },
  rtpStreams:
   [ { params:
        { clockRate: 90000,
          cname: 'GNQA2kAFM49N6r8m',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 966663761,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'GNQA2kAFM49N6r8m',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 966663762,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     { params:
        { clockRate: 90000,
          cname: 'GNQA2kAFM49N6r8m',
          mimeType: 'video/H264',
          payloadType: 107,
          spatialLayers: 1,
          ssrc: 966663763,
          temporalLayers: 3,
          useDtx: false,
          useFir: true,
          useInBandFec: false,
          useNack: false,
          usePli: true },
       score: 10,
       totalReportedLoss: 0,
       totalSourceLoss: 0 },
     [length]: 3 ],
  type: 'simulcast' } +0ms
  app:stats pipeProducer [ { bitrate: 114072,
    bitrateByLayer: { '0.0': 59312, '0.1': 89792, '0.2': 114072 },
    byteCount: 102960,
    firCount: 0,
    fractionLost: 0,
    jitter: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 299,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    score: 10,
    ssrc: 966663761,
    timestamp: 849132558,
    type: 'inbound-rtp' },
  { bitrate: 498664,
    bitrateByLayer: { '0.0': 242152, '0.1': 376568, '0.2': 498664 },
    byteCount: 488959,
    firCount: 0,
    fractionLost: 0,
    jitter: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 555,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    score: 10,
    ssrc: 966663762,
    timestamp: 849132558,
    type: 'inbound-rtp' },
  { bitrate: 2550336,
    bitrateByLayer: { '0.0': 876152, '0.1': 1724392, '0.2': 2550336 },
    byteCount: 3155587,
    firCount: 0,
    fractionLost: 0,
    jitter: 0,
    kind: 'video',
    mimeType: 'video/H264',
    nackCount: 0,
    nackPacketCount: 0,
    packetCount: 2790,
    packetsDiscarded: 0,
    packetsLost: 0,
    packetsRepaired: 0,
    packetsRetransmitted: 0,
    pliCount: 0,
    score: 10,
    ssrc: 966663763,
    timestamp: 849132558,
    type: 'inbound-rtp' },
  [length]: 3 ] 

mmmm, something is wrong here:

That Sender Reports belongs to the PipeProducer (producerId:5ba865e5-0e67-44df-8534-86bb7437a2ef), however its ssrc 94461288 is completely unrelated here! do you agree?

I mean, it seems that the PipeConsumer is sending Sender Reports to the PipeProducer with wrong ssrc values! That would explain everything.

Can we please move to the PipeConsumer? AFAIS there must be the problem. Can you please add this code into Transport::SendRtcp() (in Transport.cpp):

void Transport::SendRtcp(uint64_t now)
{
	MS_TRACE();

	std::unique_ptr<RTC::RTCP::CompoundPacket> packet{ nullptr };

	for (auto& kv : this->mapConsumers)
	{
		auto* consumer = kv.second;

		for (auto& rtpStream : consumer->GetRtpStreams())
		{
			// Reset the Compound packet.
			packet.reset(new RTC::RTCP::CompoundPacket());

			consumer->GetRtcp(packet.get(), rtpStream, now);

			// Send the RTCP compound packet if there is a sender report.
			if (packet->HasSenderReport())
			{
				packet->Serialize(RTC::RTCP::Buffer);
				SendRtcpCompoundPacket(packet.get());

				// -----------------------
				MS_DUMP(
				  "Sending RTCP compound packet por Consumer [consumerId:%s, ssrc:%" PRIu32 "]",
				  consumer->id.c_str(),
				  rtpStream->GetSsrc());

				packet.get()->Dump(); 
				// -----------------------
			}
		}
	}

And also provide please a dump and stats of the PipeConsumer once there is RTP for a while. Then you can filter in the dumps above just those with the id of the PipeConsumer. We need to see how the RTCP generated by the PipeConsumer look like.

NOTE: For this you do not need any real receiving browser that consumes from the PipeProducer (without it you’ll have less dumps to filter).

I’m also doing some checks and, at least in JS land, everything looks fine. Will try to print the RTCP generated by the PipeConsumer.

pipeConsumer dump:

{
  "consumableRtpEncodings": [
    {
      "ksvc": false,
      "maxBitrate": 180000,
      "scalabilityMode": "S1T3",
      "spatialLayers": 1,
      "ssrc": 821371575,
      "temporalLayers": 3
    },
    {
      "ksvc": false,
      "maxBitrate": 360000,
      "scalabilityMode": "S1T3",
      "spatialLayers": 1,
      "ssrc": 821371576,
      "temporalLayers": 3
    },
    {
      "ksvc": false,
      "maxBitrate": 1500000,
      "scalabilityMode": "S1T3",
      "spatialLayers": 1,
      "ssrc": 821371577,
      "temporalLayers": 3
    }
  ],
  "id": "1234",
  "kind": "video",
  "paused": false,
  "producerPaused": false,
  "rtpParameters": {
    "codecs": [
      {
        "clockRate": 90000,
        "mimeType": "video/VP8",
        "parameters": {},
        "payloadType": 101,
        "rtcpFeedback": [
          {
            "parameter": "pli",
            "type": "nack"
          },
          {
            "parameter": "fir",
            "type": "ccm"
          }
        ]
      }
    ],
    "encodings": [
      {
        "codecPayloadType": 101,
        "ksvc": false,
        "maxBitrate": 180000,
        "scalabilityMode": "S1T3",
        "spatialLayers": 1,
        "ssrc": 821371575,
        "temporalLayers": 3
      },
      {
        "codecPayloadType": 101,
        "ksvc": false,
        "maxBitrate": 360000,
        "scalabilityMode": "S1T3",
        "spatialLayers": 1,
        "ssrc": 821371576,
        "temporalLayers": 3
      },
      {
        "codecPayloadType": 101,
        "ksvc": false,
        "maxBitrate": 1500000,
        "scalabilityMode": "S1T3",
        "spatialLayers": 1,
        "ssrc": 821371577,
        "temporalLayers": 3
      }
    ],
    "headerExtensions": [
      {
        "encrypt": false,
        "id": 6,
        "parameters": {},
        "uri": "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07"
      },
      {
        "encrypt": false,
        "id": 7,
        "parameters": {},
        "uri": "urn:ietf:params:rtp-hdrext:framemarking"
      },
      {
        "encrypt": false,
        "id": 11,
        "parameters": {},
        "uri": "urn:3gpp:video-orientation"
      },
      {
        "encrypt": false,
        "id": 12,
        "parameters": {},
        "uri": "urn:ietf:params:rtp-hdrext:toffset"
      }
    ],
    "rtcp": {
      "cname": "g+jI9mw+zTO4Ttig",
      "reducedSize": true
    }
  },
  "rtpStreams": [
    {
      "params": {
        "clockRate": 90000,
        "cname": "g+jI9mw+zTO4Ttig",
        "mimeType": "video/VP8",
        "payloadType": 101,
        "spatialLayers": 1,
        "ssrc": 821371577,
        "temporalLayers": 3,
        "useDtx": false,
        "useFir": true,
        "useInBandFec": false,
        "useNack": false,
        "usePli": true
      },
      "score": 10,
      "totalReportedLoss": 0,
      "totalSourceLoss": 0
    },
    {
      "params": {
        "clockRate": 90000,
        "cname": "g+jI9mw+zTO4Ttig",
        "mimeType": "video/VP8",
        "payloadType": 101,
        "spatialLayers": 1,
        "ssrc": 821371576,
        "temporalLayers": 3,
        "useDtx": false,
        "useFir": true,
        "useInBandFec": false,
        "useNack": false,
        "usePli": true
      },
      "score": 10,
      "totalReportedLoss": 0,
      "totalSourceLoss": 0
    },
    {
      "params": {
        "clockRate": 90000,
        "cname": "g+jI9mw+zTO4Ttig",
        "mimeType": "video/VP8",
        "payloadType": 101,
        "spatialLayers": 1,
        "ssrc": 821371575,
        "temporalLayers": 3,
        "useDtx": false,
        "useFir": true,
        "useInBandFec": false,
        "useNack": false,
        "usePli": true
      },
      "score": 10,
      "totalReportedLoss": 0,
      "totalSourceLoss": 0
    }
  ],
  "supportedCodecPayloadTypes": [
    101
  ],
  "type": "pipe"
}

pipeConsumer stats:

[
  {
    "bitrate": 865808,
    "byteCount": 3774908,
    "firCount": 0,
    "fractionLost": 0,
    "kind": "video",
    "mimeType": "video/VP8",
    "nackCount": 0,
    "nackPacketCount": 0,
    "packetCount": 3649,
    "packetsDiscarded": 0,
    "packetsLost": 0,
    "packetsRepaired": 0,
    "packetsRetransmitted": 0,
    "pliCount": 0,
    "roundTripTime": 0,
    "score": 10,
    "ssrc": 821371577,
    "timestamp": 883986939,
    "type": "outbound-rtp"
  },
  {
    "bitrate": 336664,
    "byteCount": 2013112,
    "firCount": 0,
    "fractionLost": 0,
    "kind": "video",
    "mimeType": "video/VP8",
    "nackCount": 0,
    "nackPacketCount": 0,
    "packetCount": 2195,
    "packetsDiscarded": 0,
    "packetsLost": 0,
    "packetsRepaired": 0,
    "packetsRetransmitted": 0,
    "pliCount": 0,
    "roundTripTime": 0,
    "score": 10,
    "ssrc": 821371576,
    "timestamp": 883986939,
    "type": "outbound-rtp"
  },
  {
    "bitrate": 144816,
    "byteCount": 691708,
    "firCount": 0,
    "fractionLost": 0,
    "kind": "video",
    "mimeType": "video/VP8",
    "nackCount": 0,
    "nackPacketCount": 0,
    "packetCount": 1126,
    "packetsDiscarded": 0,
    "packetsLost": 0,
    "packetsRepaired": 0,
    "packetsRetransmitted": 0,
    "pliCount": 0,
    "roundTripTime": 1.007080078125,
    "score": 10,
    "ssrc": 821371575,
    "timestamp": 883986939,
    "type": "outbound-rtp"
  }
]

pipeConsumers generated RTCP compound packets:

BUG! There are Sender Reports for just a stream! (with ssrc 821371575):

RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884001
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 1894080577
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1675677216
RTC::RTCP::SenderReport::Dump() |   packet count : 1567
RTC::RTCP::SenderReport::Dump() |   octet count  : 948513
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>
RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884002
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 1829656068
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1675765056
RTC::RTCP::SenderReport::Dump() |   packet count : 1597
RTC::RTCP::SenderReport::Dump() |   octet count  : 966334
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>
RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884003
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 2388001816
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1675866846
RTC::RTCP::SenderReport::Dump() |   packet count : 1633
RTC::RTCP::SenderReport::Dump() |   octet count  : 989235
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>
RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884004
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 3126736191
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1675972326
RTC::RTCP::SenderReport::Dump() |   packet count : 1668
RTC::RTCP::SenderReport::Dump() |   octet count  : 1008100
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>

terminal>
terminal> RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884005
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 3753801416
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1676075736
RTC::RTCP::SenderReport::Dump() |   packet count : 1704
RTC::RTCP::SenderReport::Dump() |   octet count  : 1029537
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>

(To exit, press ^C again or type .exit)
terminal> RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884006
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 3779571220
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1676165916
RTC::RTCP::SenderReport::Dump() |   packet count : 1735
RTC::RTCP::SenderReport::Dump() |   octet count  : 1048311
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>
RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884007
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 3246995275
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1676243856
RTC::RTCP::SenderReport::Dump() |   packet count : 1760
RTC::RTCP::SenderReport::Dump() |   octet count  : 1063378
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>
RTC::Transport::SendRtcp() | Sending RTCP compound packet por Consumer [consumerId:1234, ssrc:821371575]
RTC::RTCP::CompoundPacket::Dump() | <CompoundPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReportPacket>
RTC::RTCP::SenderReport::Dump() | <SenderReport>
RTC::RTCP::SenderReport::Dump() |   ssrc         : 821371575
RTC::RTCP::SenderReport::Dump() |   ntp sec      : 884008
RTC::RTCP::SenderReport::Dump() |   ntp frac     : 2985002270
RTC::RTCP::SenderReport::Dump() |   rtp ts       : 1676329446
RTC::RTCP::SenderReport::Dump() |   packet count : 1788
RTC::RTCP::SenderReport::Dump() |   octet count  : 1080692
RTC::RTCP::SenderReport::Dump() | </SenderReport>
RTC::RTCP::SenderReport::Dump() | </SenderReportPacket>
RTC::RTCP::Sdes::Dump() | <SdesPacket>
RTC::RTCP::Sdes::Dump() | <SdesChunk>
RTC::RTCP::Sdes::Dump() |   ssrc : 821371575
RTC::RTCP::Sdes::Dump() | <SdesItem>
RTC::RTCP::Sdes::Dump() |   type   : CNAME
RTC::RTCP::Sdes::Dump() |   length : 16
RTC::RTCP::Sdes::Dump() |   value  : g+jI9mw+zTO4Ttig
RTC::RTCP::Sdes::Dump() | </SdesItem>
RTC::RTCP::Sdes::Dump() | </SdesChunk>
RTC::RTCP::Sdes::Dump() | </SdesPacket>
RTC::RTCP::CompoundPacket::Dump() | </CompoundPacket>