/// <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);
}
}