关于C#中读取RTP协议数据包的说明

/// <summary>
/// RTP数据包类
/// </summary>
public class RTPPacket
{
    /// <summary>
    /// 获取数据包头信息V
    /// </summary>
    public int V
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息P
    /// </summary>
    public bool P
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息X
    /// </summary>
    public bool X
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息CC
    /// </summary>
    public int CC
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息M
    /// </summary>
    public bool M
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息PT
    /// </summary>
    public int PT
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息SequenceNumber
    /// </summary>
    public ushort SequenceNumber
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息Timestamp
    /// </summary>
    public uint Timestamp
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息SSRC
    /// </summary>
    public uint SSRC
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息CSRC
    /// </summary>
    public List<uint> CSRC
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包有效数据
    /// </summary>
    public byte[] Payload
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包有效数据长度
    /// </summary>
    public uint PayloadSize
    {
        get;
        private set;
    }

    /// <summary>
    /// 获取数据包头信息长度
    /// </summary>
    public uint HeaderSize
    {
        get;
        private set;
    }

    /// <summary>
    /// 构造RTP数据包类
    /// </summary>
    /// <param name="buffer">RTP数据包数据</param>
    public RTPPacket(byte[] buffer)
    {
        // 判断数据长度是否有效
        if (buffer.LongLength > 12)
        {
            // 根据RTP数据包头信息解析数据
            byte item = buffer[0];
            V = item >> 6;
            P = Convert.ToBoolean((item >> 5) & 1);
            X = Convert.ToBoolean((item >> 4) & 1);
            CC = item & 15;
            item = buffer[1];
            M = Convert.ToBoolean((item >> 7) & 1);
            PT = item & 127;
            SequenceNumber = ReadUInt16(buffer[2], buffer[3]);
            Timestamp = ReadUInt32(buffer[4], buffer[5], buffer[6], buffer[7]);
            SSRC = ReadUInt32(buffer[8], buffer[9], buffer[10], buffer[11]);
            int index = 12;
            CSRC = new List<uint>();
            for (var i = 0; i < CC; i++)
            {
                index = i * 4 + index;
                uint csrc = ReadUInt32(buffer[index], buffer[index + 1], buffer[index + 2], buffer[index + 3]);
                CSRC.Add(csrc);
            }
            index = CC * 4 + index;
            if (X)
            {
                index++;
                index += buffer[index];
            }
            Payload = buffer.Skip(index).ToArray();
            PayloadSize = (uint)Payload.LongLength;
            HeaderSize = (uint)(CSRC.Count * 4 + 12);
        }
    }

    /// <summary>
    /// 构造RTP数据包类
    /// </summary>
    /// <param name="packet">RTP数据包</param>
    public RTPPacket(RTPPacket packet)
    {
        // 复制RTP数据包成员
        V = packet.V;
        P = packet.P;
        X = packet.X;
        CC = packet.CC;
        M = packet.M;
        PT = packet.PT;
        SequenceNumber = packet.SequenceNumber;
        Timestamp = packet.Timestamp;
        SSRC = packet.SSRC;
        CSRC = packet.CSRC;
        Payload = packet.Payload;
        PayloadSize = packet.PayloadSize;
        HeaderSize = packet.HeaderSize;
        Debug.WriteLine(ToString());
    }

    /// <summary>
    /// 根据四个字节读取UInt32数据
    /// </summary>
    /// <param name="byte1">字节1</param>
    /// <param name="byte2">字节2</param>
    /// <param name="byte3">字节3</param>
    /// <param name="byte4">字节4</param>
    /// <returns>返回UInt32数据</returns>
    private uint ReadUInt32(byte byte1, byte byte2, byte byte3, byte byte4)
    {
        uint uint1 = (uint)(byte1 << 24);
        uint uint2 = (uint)(byte2 << 16);
        uint uint3 = (uint)(byte3 << 8);
        uint uint4 = (uint)byte4;
        return (uint)(((uint1 | uint2) | uint3) | uint4);
    }

    /// <summary>
    /// 根据两个字节读取UInt16数据
    /// </summary>
    /// <param name="byte1">字节1</param>
    /// <param name="byte2">字节2</param>
    /// <returns>返回UInt16数据</returns>
    private ushort ReadUInt16(byte byte1, byte byte2)
    {
        ushort ushort1 = (ushort)(byte1 << 8);
        ushort ushort2 = (ushort)byte2;
        return (ushort)(ushort1 | ushort2);
    }

    /// <summary>
    /// 重载获取字符串方法
    /// </summary>
    /// <returns>返回RTP数据包对象的字符串表现形式</returns>
    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        builder.Append(string.Format("V: {0}, ", V));
        builder.Append(string.Format("P: {0}, ", P));
        builder.Append(string.Format("X: {0}, ", X));
        builder.Append(string.Format("CC: {0}, ", CC));
        builder.Append(string.Format("M: {0}, ", M));
        builder.Append(string.Format("PT: {0}, ", PT));
        builder.Append(string.Format("SequenceNumber: {0}, ", SequenceNumber));
        builder.Append(string.Format("Timestamp: {0}, ", Timestamp));
        builder.Append(string.Format("SSRC: {0}, ", SSRC));
        builder.Append(string.Format("CSRC: {0}, ", string.Join(" ", CSRC)));
        builder.Append(string.Format("PayloadSize: {0};", PayloadSize));
        return builder.ToString();
    }

    /// <summary>
    /// 重载对象是否相同
    /// </summary>
    /// <param name="obj">要比较的对象</param>
    /// <returns>返回对象是否相同</returns>
    public override bool Equals(object obj)
    {
        RTPPacket packet = obj as RTPPacket;
        if (packet == null)
        {
            return false;
        }
        else
        {
            return SequenceNumber == packet.SequenceNumber;
        }
    }

    /// <summary>
    /// 重载获取HashCode
    /// </summary>
    /// <returns>返回SequenceNumber</returns>
    public override int GetHashCode()
    {
        return SequenceNumber;
    }

    /// <summary>
    /// ==运算符重载
    /// </summary>
    /// <param name="packet1">左边RTP数据包对象</param>
    /// <param name="packet2">右边RTP数据包对象</param>
    /// <returns>返回是否相等</returns>
    public static bool operator ==(RTPPacket packet1, RTPPacket packet2)
    {
        if (ReferenceEquals(packet1, packet2))
        {
            return true;
        }
        else if (ReferenceEquals(packet1, null) || ReferenceEquals(packet2, null))
        {
            return false;
        }
        else
        {
            return packet1.Equals(packet2);
        }
    }

    /// <summary>
    /// !=运算符重载
    /// </summary>
    /// <param name="packet1">左边RTP数据包对象</param>
    /// <param name="packet2">右边RTP数据包对象</param>
    /// <returns>返回是否不相等</returns>
    public static bool operator !=(RTPPacket packet1, RTPPacket packet2)
    {
        return !(packet1 == packet2);
    }
}

发布者

陆 煜涛

http://luyutao.com/

发表评论

电子邮件地址不会被公开。 必填项已用*标注