public byte[] GotRtpPacket(RTPPacket rtpPacket) { var payload = rtpPacket.Payload; var hdr = rtpPacket.Header; if (_codec == VideoCodecsEnum.VP8) { //logger.LogDebug($"rtp VP8 video, seqnum {hdr.SequenceNumber}, ts {hdr.Timestamp}, marker {hdr.MarkerBit}, payload {payload.Length}."); if (_currVideoFramePosn + payload.Length >= MAX_FRAME_SIZE) { // Something has gone very wrong. Clear the buffer. _currVideoFramePosn = 0; } // New frames must have the VP8 Payload Descriptor Start bit set. // The tracking of the current video frame position is to deal with a VP8 frame being split across multiple RTP packets // as per https://tools.ietf.org/html/rfc7741#section-4.4. if (_currVideoFramePosn > 0 || (payload[0] & 0x10) > 0) { RtpVP8Header vp8Header = RtpVP8Header.GetVP8Header(payload); Buffer.BlockCopy(payload, vp8Header.Length, _currVideoFrame, _currVideoFramePosn, payload.Length - vp8Header.Length); _currVideoFramePosn += payload.Length - vp8Header.Length; if (rtpPacket.Header.MarkerBit > 0) { var frame = _currVideoFrame.Take(_currVideoFramePosn).ToArray(); _currVideoFramePosn = 0; return(frame); } } else { logger.LogWarning("Discarding RTP packet, VP8 header Start bit not set."); //logger.LogWarning($"rtp video, seqnum {hdr.SequenceNumber}, ts {hdr.Timestamp}, marker {hdr.MarkerBit}, payload {payload.Length}."); } } else if (_codec == VideoCodecsEnum.H264) { //logger.LogDebug($"rtp H264 video, seqnum {hdr.SequenceNumber}, ts {hdr.Timestamp}, marker {hdr.MarkerBit}, payload {payload.Length}."); //var hdr = rtpPacket.Header; var frameStream = _h264Depacketiser.ProcessRTPPayload(payload, hdr.SequenceNumber, hdr.Timestamp, hdr.MarkerBit, out bool isKeyFrame); if (frameStream != null) { return(frameStream.ToArray()); } } else { logger.LogWarning($"rtp unknown video, seqnum {hdr.SequenceNumber}, ts {hdr.Timestamp}, marker {hdr.MarkerBit}, payload {payload.Length}."); } return(null); }
public static RtpVP8Header GetVP8Header(byte[] rtpPayload) { RtpVP8Header vp8Header = new RtpVP8Header(); int payloadHeaderStartIndex = 1; // First byte of payload descriptor. vp8Header.ExtendedControlBitsPresent = ((rtpPayload[0] >> 7) & 0x01) == 1; vp8Header.StartOfVP8Partition = ((rtpPayload[0] >> 4) & 0x01) == 1; vp8Header._length = 1; // Is second byte being used. if (vp8Header.ExtendedControlBitsPresent) { vp8Header.IsPictureIDPresent = ((rtpPayload[1] >> 7) & 0x01) == 1; vp8Header._length = 2; payloadHeaderStartIndex = 2; } // Is the picture ID being used. if (vp8Header.IsPictureIDPresent) { if (((rtpPayload[2] >> 7) & 0x01) == 1) { // The Picture ID is using two bytes. vp8Header._length = 4; payloadHeaderStartIndex = 4; vp8Header.PictureID = BitConverter.ToUInt16(rtpPayload, 2); } else { // The picture ID is using one byte. vp8Header.PictureID = rtpPayload[2]; vp8Header._length = 3; payloadHeaderStartIndex = 3; } } vp8Header._payloadDescriptorLength = payloadHeaderStartIndex; return(vp8Header); }
public byte[] GotRtpPacket(RTPPacket rtpPacket) { var payload = rtpPacket.Payload; //logger.LogDebug($"rtp video, seqnum {seqnum}, ts {timestamp}, marker {marker}, payload {payload.Length}."); if (_currVideoFramePosn + payload.Length >= _currVideoFrame.Length) { // Something has gone very wrong. Clear the buffer. _currVideoFramePosn = 0; } // New frames must have the VP8 Payload Descriptor Start bit set. // The tracking of the current video frame position is to deal with a VP8 frame being split across multiple RTP packets // as per https://tools.ietf.org/html/rfc7741#section-4.4. if (_currVideoFramePosn > 0 || (payload[0] & 0x10) > 0) { RtpVP8Header vp8Header = RtpVP8Header.GetVP8Header(payload); Buffer.BlockCopy(payload, vp8Header.Length, _currVideoFrame, _currVideoFramePosn, payload.Length - vp8Header.Length); _currVideoFramePosn += payload.Length - vp8Header.Length; if (rtpPacket.Header.MarkerBit > 0) { var frame = _currVideoFrame.Take(_currVideoFramePosn).ToArray(); _currVideoFramePosn = 0; return(frame); } } else { var hdr = rtpPacket.Header; logger.LogWarning("Discarding RTP packet, VP8 header Start bit not set."); logger.LogWarning( $"rtp video, seqnum {hdr.SequenceNumber}, ts {hdr.Timestamp}, marker {hdr.MarkerBit}, payload {payload.Length}."); } return(null); }