Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RtpStream does not exclude RTP package when the payload type of RTP package mismatches with payload number in describe(SDP) #98

Open
xingshuangs opened this issue Sep 28, 2020 · 0 comments

Comments

@xingshuangs
Copy link

Describe the bug
I 'm not sure if this is a bug, as this is first time I commit the issue.
In my case, I need to remote control cameras, just rotate it.
When I rotate it, the timestamp of RawFrame in feedback will be discontinuous, so I think the frame is alse not discontinuous.
When I do not rotate it, the frame will be continuous.

Why?

I find that the payload type is 105 and the sequence number adds 1 normally in every rtp package when I do not remote rotate, the payload type will be 50 and the sequence number will not be changed in rtp package as I rotate.
In the function 'ProcessImmediately' of RtpSteam class, it does not exclude the rtp package mismatches with payload number in SDP, and it invokes ‘_mediaPayloadParser.ResetState()’ immediately when the ‘SeqNumber‘ offset is not equal to 1.

 SyncSourceId = rtpPacket.SyncSourceId;
            if (!_isFirstPacket)
            {
                int delta = (ushort) (rtpPacket.SeqNumber - _previousSeqNumber);

                if (delta != 1)
                {
                    int lostCount = delta - 1;

                    if (lostCount == -1)
                        lostCount = ushort.MaxValue;

                    CumulativePacketLost += (uint) lostCount;

                    if (CumulativePacketLost > 0x7FFFFF)
                        CumulativePacketLost = 0x7FFFFF;

                    PacketsLostSinceLastReset += lostCount;

                    _mediaPayloadParser.ResetState();
                }

                if (rtpPacket.SeqNumber < HighestSequenceNumberReceived)
                    ++SequenceCycles;

                _samplesSum += rtpPacket.Timestamp - _previousTimestamp;
            }

To Change
Steps to change the behavior:

  1. In 'PayloadFormatInfo' class, I add 'PayloadFormatNumber' property, and add 'PayloadFormatNumber' to 'PayloadFormatInfo' object when 'ParseMediaLine' .
private class PayloadFormatInfo
        {
            public string TrackName { get; set; }
            public CodecInfo CodecInfo { get; set; }
            public int SamplesFrequency { get; set; }
            public int PayloadFormatNumber { get; set; }

            public PayloadFormatInfo(CodecInfo codecInfo, int samplesFrequency,int payloadFormatNumber)
            {
                CodecInfo = codecInfo;
                SamplesFrequency = samplesFrequency;
                PayloadFormatNumber = payloadFormatNumber;
            }
        }
private void ParseMediaLine(string line)
        {
            string[] tokens = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (tokens.Length < 4)
            {
                _lastParsedFormatInfo = null;
                return;
            }

            string payloadFormat = tokens[3];

            if (!int.TryParse(payloadFormat, out int payloadFormatNumber))
            {
                _lastParsedFormatInfo = null;
                return;
            }

            CodecInfo codecInfo = TryCreateCodecInfo(payloadFormatNumber);
            int samplesFrequency = GetSamplesFrequencyFromPayloadType(payloadFormatNumber);

            _lastParsedFormatInfo = new PayloadFormatInfo(codecInfo, samplesFrequency, payloadFormatNumber);
            _payloadFormatNumberToInfoMap[payloadFormatNumber] = _lastParsedFormatInfo;
        }
  1. Add ‘_payloadFormatNumber’ field in ‘RtpStream’ class
class RtpStream : ITransportStream, IRtpStatisticsProvider
    {
        private readonly IRtpSequenceAssembler _rtpSequenceAssembler;
        private readonly IMediaPayloadParser _mediaPayloadParser;
        private readonly int _samplesFrequency;
        private readonly int _payloadFormatNumber;

.... ....


public RtpStream(IMediaPayloadParser mediaPayloadParser, int samplesFrequency,
            IRtpSequenceAssembler rtpSequenceAssembler = null, int payloadFormatNumber = -1)
        {
            _mediaPayloadParser = mediaPayloadParser ?? throw new ArgumentNullException(nameof(mediaPayloadParser));
            _samplesFrequency = samplesFrequency;

            if (rtpSequenceAssembler != null)
            {
                _rtpSequenceAssembler = rtpSequenceAssembler;
                _rtpSequenceAssembler.PacketPassed += ProcessImmediately;
            }
            _payloadFormatNumber = payloadFormatNumber;
        }

add ‘track.PayloadFormatNumber’ to ‘RtpStream’ object in the function 'SetupTrackAsync' of 'RtspClientInternal' class,

 var rtpStream = new RtpStream(mediaPayloadParser, track.SamplesFrequency, rtpSequenceAssembler,track.PayloadFormatNumber);
            _streamsMap.Add(rtpChannelNumber, rtpStream);
  1. Add filter code in the function 'ProcessImmediately' of 'RtpStream' class .
 private void ProcessImmediately(ref RtpPacket rtpPacket)
        {
            SyncSourceId = rtpPacket.SyncSourceId;

            if (_payloadFormatNumber > 0 && _payloadFormatNumber != rtpPacket.PayloadType) return;

            if (!_isFirstPacket)
            {
                int delta = (ushort) (rtpPacket.SeqNumber - _previousSeqNumber);

                if (delta != 1)
                {
                    int lostCount = delta - 1;

                    if (lostCount == -1)
                        lostCount = ushort.MaxValue;

                    CumulativePacketLost += (uint) lostCount;

                    if (CumulativePacketLost > 0x7FFFFF)
                        CumulativePacketLost = 0x7FFFFF;

                    PacketsLostSinceLastReset += lostCount;

                    _mediaPayloadParser.ResetState();
                }

                if (rtpPacket.SeqNumber < HighestSequenceNumberReceived)
                    ++SequenceCycles;

                _samplesSum += rtpPacket.Timestamp - _previousTimestamp;
            }
  1. that‘s all.

Additional context
Looking forward to your reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant