hawkeye camera support(not tested)
This commit is contained in:
231
framework/Inspectron.HawkEye/RTSP/UdpSocket.cs
Normal file
231
framework/Inspectron.HawkEye/RTSP/UdpSocket.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using Inspectron.HawkEye.RTSP.Messages;
|
||||
|
||||
namespace Inspectron.HawkEye.RTSP
|
||||
{
|
||||
public class UDPSocket
|
||||
{
|
||||
|
||||
private UdpClient data_socket = null;
|
||||
private UdpClient control_socket = null;
|
||||
|
||||
private Thread data_read_thread = null;
|
||||
private Thread control_read_thread = null;
|
||||
|
||||
public int data_port = 50000;
|
||||
public int control_port = 50001;
|
||||
|
||||
bool is_multicast = false;
|
||||
IPAddress data_mcast_addr;
|
||||
IPAddress control_mcast_addr;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UDPSocket"/> class.
|
||||
/// Creates two new UDP sockets using the start and end Port range
|
||||
/// </summary>
|
||||
public UDPSocket(int start_port, int end_port)
|
||||
{
|
||||
|
||||
is_multicast = false;
|
||||
|
||||
// open a pair of UDP sockets - one for data (video or audio) and one for the status channel (RTCP messages)
|
||||
data_port = start_port;
|
||||
control_port = start_port + 1;
|
||||
|
||||
bool ok = false;
|
||||
while (ok == false && (control_port < end_port))
|
||||
{
|
||||
// Video/Audio port must be odd and command even (next one)
|
||||
try
|
||||
{
|
||||
data_socket = new UdpClient(data_port);
|
||||
control_socket = new UdpClient(control_port);
|
||||
ok = true;
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
// Fail to allocate port, try again
|
||||
if (data_socket != null)
|
||||
data_socket.Close();
|
||||
if (control_socket != null)
|
||||
control_socket.Close();
|
||||
|
||||
// try next data or control port
|
||||
data_port += 2;
|
||||
control_port += 2;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
data_socket.Client.ReceiveBufferSize = 100 * 1024;
|
||||
data_socket.Client.SendBufferSize = 65535; // default is 8192. Make it as large as possible for large RTP packets which are not fragmented
|
||||
|
||||
control_socket.Client.DontFragment = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UDPSocket"/> class.
|
||||
/// Used with Multicast mode with the Multicast Address and Port
|
||||
/// </summary>
|
||||
public UDPSocket(String data_multicast_address, int data_multicast_port, String control_multicast_address, int control_multicast_port)
|
||||
{
|
||||
|
||||
is_multicast = true;
|
||||
|
||||
// open a pair of UDP sockets - one for data (video or audio) and one for the status channel (RTCP messages)
|
||||
this.data_port = data_multicast_port;
|
||||
this.control_port = control_multicast_port;
|
||||
|
||||
try
|
||||
{
|
||||
IPEndPoint data_ep = new IPEndPoint(IPAddress.Any, data_port);
|
||||
IPEndPoint control_ep = new IPEndPoint(IPAddress.Any, control_port);
|
||||
|
||||
data_mcast_addr = IPAddress.Parse(data_multicast_address);
|
||||
control_mcast_addr = IPAddress.Parse(control_multicast_address);
|
||||
|
||||
data_socket = new UdpClient();
|
||||
data_socket.Client.Bind(data_ep);
|
||||
data_socket.JoinMulticastGroup(data_mcast_addr);
|
||||
|
||||
control_socket = new UdpClient();
|
||||
control_socket.Client.Bind(control_ep);
|
||||
control_socket.JoinMulticastGroup(control_mcast_addr);
|
||||
|
||||
|
||||
data_socket.Client.ReceiveBufferSize = 100 * 1024;
|
||||
data_socket.Client.SendBufferSize = 65535; // default is 8192. Make it as large as possible for large RTP packets which are not fragmented
|
||||
|
||||
|
||||
control_socket.Client.DontFragment = false;
|
||||
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
// Fail to allocate port, try again
|
||||
if (data_socket != null)
|
||||
data_socket.Close();
|
||||
if (control_socket != null)
|
||||
control_socket.Close();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts this instance.
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
if (data_socket == null || control_socket == null)
|
||||
{
|
||||
throw new InvalidOperationException("UDP Forwader host was not initialized, can't continue");
|
||||
}
|
||||
|
||||
if (data_read_thread != null)
|
||||
{
|
||||
throw new InvalidOperationException("Forwarder was stopped, can't restart it");
|
||||
}
|
||||
|
||||
data_read_thread = new Thread(() => DoWorkerJob(data_socket, data_port));
|
||||
data_read_thread.Name = "DataPort " + data_port;
|
||||
data_read_thread.Start();
|
||||
|
||||
control_read_thread = new Thread(() => DoWorkerJob(control_socket, control_port));
|
||||
control_read_thread.Name = "ControlPort " + control_port;
|
||||
control_read_thread.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops this instance.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (is_multicast)
|
||||
{
|
||||
// leave the multicast groups
|
||||
data_socket.DropMulticastGroup(data_mcast_addr);
|
||||
control_socket.DropMulticastGroup(control_mcast_addr);
|
||||
}
|
||||
data_socket.Close();
|
||||
control_socket.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when message is received.
|
||||
/// </summary>
|
||||
public event EventHandler<RtspChunkEventArgs> DataReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="E:DataReceived"/> event.
|
||||
/// </summary>
|
||||
/// <param name="rtspChunkEventArgs">The <see cref="Rtsp.RtspChunkEventArgs"/> instance containing the event data.</param>
|
||||
protected void OnDataReceived(RtspChunkEventArgs rtspChunkEventArgs)
|
||||
{
|
||||
EventHandler<RtspChunkEventArgs> handler = DataReceived;
|
||||
|
||||
if (handler != null)
|
||||
handler(this, rtspChunkEventArgs);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Does the video job.
|
||||
/// </summary>
|
||||
private void DoWorkerJob(System.Net.Sockets.UdpClient socket, int data_port)
|
||||
{
|
||||
|
||||
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, data_port);
|
||||
try
|
||||
{
|
||||
// loop until we get an exception eg the socket closed
|
||||
while (true)
|
||||
{
|
||||
byte[] frame = socket.Receive(ref ipEndPoint);
|
||||
|
||||
// We have an RTP frame.
|
||||
// Fire the DataReceived event with 'frame'
|
||||
Console.WriteLine("Received RTP data on port " + data_port);
|
||||
|
||||
RtspChunk currentMessage = new RtspData();
|
||||
// aMessage.SourcePort = ??
|
||||
currentMessage.Data = frame;
|
||||
((RtspData)currentMessage).Channel = data_port;
|
||||
|
||||
|
||||
OnDataReceived(new RtspChunkEventArgs(currentMessage));
|
||||
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write to the RTP Data Port
|
||||
/// </summary>
|
||||
public void Write_To_Data_Port(byte[] data, String hostname, int port) {
|
||||
data_socket.Send(data,data.Length, hostname, port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write to the RTP Control Port
|
||||
/// </summary>
|
||||
public void Write_To_Control_Port(byte[] data, String hostname, int port)
|
||||
{
|
||||
data_socket.Send(data, data.Length, hostname, port);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user