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 Picure 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; // Payload header only on first packet in frame. if (vp8Header.StartOfVP8Partition) { byte s0 = (byte)((rtpPayload[payloadHeaderStartIndex] >> 5) & 0x07); vp8Header.ShowFrame = (byte)((rtpPayload[payloadHeaderStartIndex] >> 4) & 0x01) == 1; vp8Header.IsKeyFrame = (rtpPayload[payloadHeaderStartIndex] & 0x01) == 0; byte s1 = rtpPayload[payloadHeaderStartIndex + 1]; byte s2 = rtpPayload[payloadHeaderStartIndex + 2]; vp8Header.FirstPartitionSize = s0 + (8 * s1) + (2048 * s2); vp8Header._length += 3; } return(vp8Header); }
public byte[] GetFramePayload() { List <byte> payload = new List <byte>(); foreach (var rtpPacket in _packets.OrderBy(x => x.Header.SequenceNumber)) { if (FrameType == FrameTypesEnum.VP8) { var vp8Header = RTPVP8Header.GetVP8Header(rtpPacket.Payload); payload.AddRange(rtpPacket.Payload.Skip(vp8Header.PayloadDescriptorLength)); } else { payload.AddRange(rtpPacket.Payload); } } return(payload.ToArray()); }