Skip to content

Instantly share code, notes, and snippets.

@Diefenthal
Created December 21, 2014 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Diefenthal/32956e58c9428ba2d58c to your computer and use it in GitHub Desktop.
Save Diefenthal/32956e58c9428ba2d58c to your computer and use it in GitHub Desktop.
Recieves RTP Packets from a Satip Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SatIp.Library.Rtp
{
class RtpPacket
{
private static int MinHeaderLength = 12;
// <summary>
/// Construktor
/// </summary>
public RtpPacket()
{
}
/// <summary>
/// Constuktor
/// </summary>
/// <param name="_data"></param>
public RtpPacket(byte[] data)
{
Parse(data);
}
public Int32 HeaderSize = MinHeaderLength;
public Int32 Version { get; set; }
public Boolean Padding { get; set; }
public Boolean Extension { get; set; }
public Int32 CsrcCount { get; set; }
public Boolean Marker { get; set; }
public Int32 PayloadType { get; set; }
public UInt16 SequenceNumber { get; set; }
public UInt32 Timestamp { get; set; }
public UInt32 SourceId { get; set; }
public UInt16 ExtensionHeaderId = 0;
public UInt16 ExtensionLengthAsCount = 0;
public Int32 ExtensionLengthInBytes = 0;
public Byte[] Payload { get; set; }
///<summary>
///Parse
///</summary>
///<param name="linearData"></param>
public void Parse(Byte[] data)
{
if (data.Length >= MinHeaderLength)
{
Version = ValueFromByte(data[0], 6, 2);
Padding = Convert.ToBoolean(ValueFromByte(data[0], 5, 1));
Extension = Convert.ToBoolean(ValueFromByte(data[0], 4, 1));
CsrcCount = ValueFromByte(data[0], 0, 4);
Marker = Convert.ToBoolean(ValueFromByte(data[1], 7, 1));
PayloadType = ValueFromByte(data[1], 0, 7);
HeaderSize = MinHeaderLength + (CsrcCount * 4);
Byte[] seqNum = new Byte[2];
seqNum[0] = data[3];
seqNum[1] = data[2];
SequenceNumber = System.BitConverter.ToUInt16(seqNum, 0);
Byte[] timeStmp = new Byte[4];
timeStmp[0] = data[7];
timeStmp[1] = data[6];
timeStmp[2] = data[5];
timeStmp[3] = data[4];
Timestamp = System.BitConverter.ToUInt32(timeStmp, 0);
Byte[] srcId = new Byte[4];
srcId[0] = data[11];
srcId[1] = data[10];
srcId[2] = data[9];
srcId[3] = data[8];
SourceId = System.BitConverter.ToUInt32(srcId, 0);
Byte[] csrcid = new byte[4];
if (Extension)
{
Byte[] extHeaderId = new Byte[2];
extHeaderId[1] = data[HeaderSize + 0];
extHeaderId[0] = data[HeaderSize + 1];
ExtensionHeaderId = System.BitConverter.ToUInt16(extHeaderId, 0);
Byte[] extHeaderLength16 = new Byte[2];
extHeaderLength16[1] = data[HeaderSize + 2];
extHeaderLength16[0] = data[HeaderSize + 3];
ExtensionLengthAsCount = System.BitConverter.ToUInt16(extHeaderLength16.ToArray(), 0);
ExtensionLengthInBytes = ExtensionLengthAsCount * 4;
HeaderSize += ExtensionLengthInBytes + 4;
}
Payload = new Byte[data.Length - HeaderSize];
Array.Copy(data, HeaderSize, Payload, 0, data.Length - HeaderSize);
}
}
/// <summary>
/// GetValueFromByte
/// </summary>
/// <param name="value"></param>
/// <param name="startPos"></param>
/// <param name="length"></param>
/// <returns></returns>
private Int32 ValueFromByte(Byte value, int startPos, int length)
{
Byte mask = 0;
for (int i = 0; i < length; i++)
{
mask = (Byte)(mask | 0x1 << startPos + i);
}
Byte result = (Byte)((value & mask) >> startPos);
return Convert.ToInt32(result);
}
public override string ToString()
{
return string.Format(" RtpPacket V:{0}, P:{1}, EX:{2}, CSRC:{3}, M:{4}, PT:{5}, SQ:{6}, TS:{7}, SSRC:{8}", Version, Padding, Extension, CsrcCount, Marker, PayloadType, SequenceNumber, Timestamp, SourceId);
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace SatIp.Library.Rtp
{
public class RtpClient
{
#region Private Fields
private Thread _rtpListenerThread;
private AutoResetEvent _rtpListenerThreadStopEvent = null;
private UdpClient _udpClient;
private IPEndPoint _serverEndPoint;
private int _receivedBytes;
private int _receivedPackets;
#endregion
#region Constructor
/// <summary>
/// Recieves RtpPackets
/// </summary>
/// <param name="destination">is the Address for Recieving the Data it can be a Unicast or Multicast Address</param>
/// <param name="clientRtpPort">is only needed for Unicast Transmission</param>
/// <param name="source">is only needed for Unicast Transmission</param>
/// <param name="serverRtpPort">is needed for Unicast and Multicast Transmission</param>
public RtpClient(string destination, int clientRtpPort, string source, int serverRtpPort)
{
if (isValid(destination))
{
_serverEndPoint = new IPEndPoint(IPAddress.Parse(destination), serverRtpPort);
_udpClient = new UdpClient(serverRtpPort);
_udpClient.JoinMulticastGroup(IPAddress.Parse(destination));
}
else
{
_serverEndPoint = new IPEndPoint(IPAddress.Parse(source), serverRtpPort);
_udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(destination), clientRtpPort));
_udpClient.Client.ReceiveTimeout = 400;
}
}
#endregion
#region Properties
/// <summary>
///
/// </summary>
public int ReceivedBytes
{
get { return _receivedBytes; }
set { _receivedBytes = value; }
}
/// <summary>
///
/// </summary>
public int ReceivedPackets
{
get { return _receivedPackets; }
set { _receivedPackets = value; }
}
#endregion
#region Methods
public static bool isValid(string ip)
{
try
{
int octet1 = Int32.Parse(ip.Split(new Char[] { '.' }, 4)[0]);
if ((octet1 >= 224) && (octet1 <= 239))
return true;
}
catch (Exception e)
{
}
return false;
}
public void StartRtpListenerThread()
{
if (_rtpListenerThread != null && !_rtpListenerThread.IsAlive)
{
StopRtpListenerThread();
}
if (_rtpListenerThread == null)
{
_rtpListenerThreadStopEvent = new AutoResetEvent(false);
_rtpListenerThread = new Thread(new ThreadStart(RtpListener));
_rtpListenerThread.Name = string.Format("SAT>IP tuner RTP listener");
_rtpListenerThread.IsBackground = true;
_rtpListenerThread.Priority = ThreadPriority.Lowest;
_rtpListenerThread.Start();
}
}
public void StopRtpListenerThread()
{
if (_rtpListenerThread != null)
{
if (!_rtpListenerThread.IsAlive)
{
_rtpListenerThread.Abort();
}
else
{
_rtpListenerThreadStopEvent.Set();
if (!_rtpListenerThread.Join(400 * 2))
{
_rtpListenerThread.Abort();
}
}
_rtpListenerThread = null;
if (_rtpListenerThreadStopEvent != null)
{
_rtpListenerThreadStopEvent.Close();
_rtpListenerThreadStopEvent = null;
}
}
}
private void RtpListener()
{
try
{
_receivedBytes = 0;
_receivedPackets = 0;
try
{
while (!_rtpListenerThreadStopEvent.WaitOne(1))
{
byte[] packets = _udpClient.Receive(ref _serverEndPoint);
RtpPacket packet = new RtpPacket();
packet.Parse(packets);
Console.Write(packet.ToString()+"\r\n");
if (packets == null)
{
continue;
}
_receivedBytes += packets.Length;
_receivedPackets++;
}
}
finally
{
_udpClient.Close();
}
}
catch (ThreadAbortException)
{
}
catch (Exception ex)
{
return;
}
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment