mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-16 02:18:54 -07:00
Rtp Rtcp fix Discovery #2116
This commit is contained in:
parent
2f67a007cd
commit
fb251448c9
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
public class ReportBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the length of the block.
|
||||
/// </summary>
|
||||
public int BlockLength { get { return (24); } }
|
||||
/// <summary>
|
||||
/// Get the synchronization source.
|
||||
/// </summary>
|
||||
public string SynchronizationSource { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the fraction lost.
|
||||
/// </summary>
|
||||
public int FractionLost { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the cumulative packets lost.
|
||||
/// </summary>
|
||||
public int CumulativePacketsLost { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the highest number received.
|
||||
/// </summary>
|
||||
public int HighestNumberReceived { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the inter arrival jitter.
|
||||
/// </summary>
|
||||
public int InterArrivalJitter { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the timestamp of the last report.
|
||||
/// </summary>
|
||||
public int LastReportTimeStamp { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the delay since the last report.
|
||||
/// </summary>
|
||||
public int DelaySinceLastReport { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the ReportBlock class.
|
||||
/// </summary>
|
||||
public ReportBlock() { }
|
||||
|
||||
/// <summary>
|
||||
/// Unpack the data in a packet.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer containing the packet.</param>
|
||||
/// <param name="offset">The offset to the first byte of the packet within the buffer.</param>
|
||||
/// <returns>An ErrorSpec instance if an error occurs; null otherwise.</returns>
|
||||
public void Process(byte[] buffer, int offset)
|
||||
{
|
||||
SynchronizationSource = Utils.ConvertBytesToString(buffer, offset, 4);
|
||||
FractionLost = buffer[offset + 4];
|
||||
CumulativePacketsLost = Utils.Convert3BytesToInt(buffer, offset + 5);
|
||||
HighestNumberReceived = Utils.Convert4BytesToInt(buffer, offset + 8);
|
||||
InterArrivalJitter = Utils.Convert4BytesToInt(buffer, offset + 12);
|
||||
LastReportTimeStamp = Utils.Convert4BytesToInt(buffer, offset + 16);
|
||||
DelaySinceLastReport = Utils.Convert4BytesToInt(buffer, offset + 20);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
class RtcpAppPacket : RtcpPacket
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the synchronization source.
|
||||
/// </summary>
|
||||
public int SynchronizationSource { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the name.
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the identity.
|
||||
/// </summary>
|
||||
public int Identity { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the variable data portion.
|
||||
/// </summary>
|
||||
public string Data { get; private set; }
|
||||
|
||||
public override void Parse(byte[] buffer, int offset)
|
||||
{
|
||||
base.Parse(buffer, offset);
|
||||
SynchronizationSource = Utils.Convert4BytesToInt(buffer, offset + 4);
|
||||
Name = Utils.ConvertBytesToString(buffer, offset + 8, 4);
|
||||
Identity = Utils.Convert2BytesToInt(buffer, offset + 12);
|
||||
|
||||
int dataLength = Utils.Convert2BytesToInt(buffer, offset + 14);
|
||||
if (dataLength != 0)
|
||||
Data = Utils.ConvertBytesToString(buffer, offset + 16, dataLength);
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("Application Specific.\n");
|
||||
sb.AppendFormat("Version : {0} .\n", Version);
|
||||
sb.AppendFormat("Padding : {0} .\n", Padding);
|
||||
sb.AppendFormat("Report Count : {0} .\n", ReportCount);
|
||||
sb.AppendFormat("PacketType: {0} .\n", Type);
|
||||
sb.AppendFormat("Length : {0} .\n", Length);
|
||||
sb.AppendFormat("SynchronizationSource : {0} .\n", SynchronizationSource);
|
||||
sb.AppendFormat("Name : {0} .\n", Name);
|
||||
sb.AppendFormat("Identity : {0} .\n", Identity);
|
||||
sb.AppendFormat("Data : {0} .\n", Data);
|
||||
sb.AppendFormat(".\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
using System.Collections.ObjectModel;
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
public class RtcpByePacket :RtcpPacket
|
||||
{
|
||||
public Collection<string> SynchronizationSources { get; private set; }
|
||||
public string ReasonForLeaving { get; private set; }
|
||||
public override void Parse(byte[] buffer, int offset)
|
||||
{
|
||||
base.Parse(buffer, offset);
|
||||
SynchronizationSources = new Collection<string>();
|
||||
int index = 4;
|
||||
|
||||
while (SynchronizationSources.Count < ReportCount)
|
||||
{
|
||||
SynchronizationSources.Add(Utils.ConvertBytesToString(buffer, offset + index, 4));
|
||||
index += 4;
|
||||
}
|
||||
|
||||
if (index < Length)
|
||||
{
|
||||
int reasonLength = buffer[offset + index];
|
||||
ReasonForLeaving = Utils.ConvertBytesToString(buffer, offset + index + 1, reasonLength);
|
||||
}
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("ByeBye .\n");
|
||||
sb.AppendFormat("Version : {0} .\n", Version);
|
||||
sb.AppendFormat("Padding : {0} .\n", Padding);
|
||||
sb.AppendFormat("Report Count : {0} .\n", ReportCount);
|
||||
sb.AppendFormat("PacketType: {0} .\n", Type);
|
||||
sb.AppendFormat("Length : {0} .\n", Length);
|
||||
sb.AppendFormat("SynchronizationSources : {0} .\n", SynchronizationSources);
|
||||
sb.AppendFormat("ReasonForLeaving : {0} .\n", ReasonForLeaving);
|
||||
sb.AppendFormat(".\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
public class RtcpListener
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private Thread _rtcpListenerThread;
|
||||
private AutoResetEvent _rtcpListenerThreadStopEvent = null;
|
||||
private UdpClient _udpClient;
|
||||
private IPEndPoint _multicastEndPoint;
|
||||
private IPEndPoint _serverEndPoint;
|
||||
private TransmissionMode _transmissionMode;
|
||||
|
||||
public RtcpListener(String address, int port, TransmissionMode mode,ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_transmissionMode = mode;
|
||||
switch (mode)
|
||||
{
|
||||
case TransmissionMode.Unicast:
|
||||
_udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(address), port));
|
||||
_serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
break;
|
||||
case TransmissionMode.Multicast:
|
||||
_multicastEndPoint = new IPEndPoint(IPAddress.Parse(address), port);
|
||||
_serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
_udpClient = new UdpClient();
|
||||
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
|
||||
_udpClient.ExclusiveAddressUse = false;
|
||||
_udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
|
||||
_udpClient.JoinMulticastGroup(_multicastEndPoint.Address);
|
||||
break;
|
||||
}
|
||||
//StartRtcpListenerThread();
|
||||
}
|
||||
|
||||
public void StartRtcpListenerThread()
|
||||
{
|
||||
// Kill the existing thread if it is in "zombie" state.
|
||||
if (_rtcpListenerThread != null && !_rtcpListenerThread.IsAlive)
|
||||
{
|
||||
StopRtcpListenerThread();
|
||||
}
|
||||
|
||||
if (_rtcpListenerThread == null)
|
||||
{
|
||||
_logger.Info("SAT>IP : starting new RTCP listener thread");
|
||||
_rtcpListenerThreadStopEvent = new AutoResetEvent(false);
|
||||
_rtcpListenerThread = new Thread(new ThreadStart(RtcpListenerThread));
|
||||
_rtcpListenerThread.Name = string.Format("SAT>IP tuner RTCP listener");
|
||||
_rtcpListenerThread.IsBackground = true;
|
||||
_rtcpListenerThread.Priority = ThreadPriority.Lowest;
|
||||
_rtcpListenerThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopRtcpListenerThread()
|
||||
{
|
||||
if (_rtcpListenerThread != null)
|
||||
{
|
||||
if (!_rtcpListenerThread.IsAlive)
|
||||
{
|
||||
_logger.Info("SAT>IP : aborting old RTCP listener thread");
|
||||
_rtcpListenerThread.Abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
_rtcpListenerThreadStopEvent.Set();
|
||||
if (!_rtcpListenerThread.Join(400 * 2))
|
||||
{
|
||||
_logger.Info("SAT>IP : failed to join RTCP listener thread, aborting thread");
|
||||
_rtcpListenerThread.Abort();
|
||||
}
|
||||
}
|
||||
_rtcpListenerThread = null;
|
||||
if (_rtcpListenerThreadStopEvent != null)
|
||||
{
|
||||
_rtcpListenerThreadStopEvent.Close();
|
||||
_rtcpListenerThreadStopEvent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RtcpListenerThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool receivedGoodBye = false;
|
||||
try
|
||||
{
|
||||
_udpClient.Client.ReceiveTimeout = 400;
|
||||
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
while (!receivedGoodBye && !_rtcpListenerThreadStopEvent.WaitOne(1))
|
||||
{
|
||||
byte[] packets = _udpClient.Receive(ref serverEndPoint);
|
||||
if (packets == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
while (offset < packets.Length)
|
||||
{
|
||||
switch (packets[offset + 1])
|
||||
{
|
||||
case 200: //sr
|
||||
var sr = new RtcpSenderReportPacket();
|
||||
sr.Parse(packets, offset);
|
||||
offset += sr.Length;
|
||||
break;
|
||||
case 201: //rr
|
||||
var rr = new RtcpReceiverReportPacket();
|
||||
rr.Parse(packets, offset);
|
||||
offset += rr.Length;
|
||||
break;
|
||||
case 202: //sd
|
||||
var sd = new RtcpSourceDescriptionPacket();
|
||||
sd.Parse(packets, offset);
|
||||
offset += sd.Length;
|
||||
break;
|
||||
case 203: // bye
|
||||
var bye = new RtcpByePacket();
|
||||
bye.Parse(packets, offset);
|
||||
receivedGoodBye = true;
|
||||
OnPacketReceived(new RtcpPacketReceivedArgs(bye));
|
||||
offset += bye.Length;
|
||||
break;
|
||||
case 204: // app
|
||||
var app = new RtcpAppPacket();
|
||||
app.Parse(packets, offset);
|
||||
OnPacketReceived(new RtcpPacketReceivedArgs(app));
|
||||
offset += app.Length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
switch (_transmissionMode)
|
||||
{
|
||||
case TransmissionMode.Multicast:
|
||||
_udpClient.DropMulticastGroup(_multicastEndPoint.Address);
|
||||
_udpClient.Close();
|
||||
break;
|
||||
case TransmissionMode.Unicast:
|
||||
_udpClient.Close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Info(string.Format("SAT>IP : RTCP listener thread exception"), ex);
|
||||
return;
|
||||
}
|
||||
_logger.Info("SAT>IP : RTCP listener thread stopping");
|
||||
}
|
||||
public delegate void PacketReceivedHandler(object sender, RtcpPacketReceivedArgs e);
|
||||
public event PacketReceivedHandler PacketReceived;
|
||||
public class RtcpPacketReceivedArgs : EventArgs
|
||||
{
|
||||
public Object Packet { get; private set; }
|
||||
|
||||
public RtcpPacketReceivedArgs(Object packet)
|
||||
{
|
||||
Packet = packet;
|
||||
}
|
||||
}
|
||||
protected void OnPacketReceived(RtcpPacketReceivedArgs args)
|
||||
{
|
||||
if (PacketReceived != null)
|
||||
{
|
||||
PacketReceived(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
public abstract class RtcpPacket
|
||||
{
|
||||
public int Version { get; private set; }
|
||||
public bool Padding { get; private set; }
|
||||
public int ReportCount { get; private set; }
|
||||
public int Type { get; private set; }
|
||||
public int Length { get; private set; }
|
||||
|
||||
public virtual void Parse(byte[] buffer, int offset)
|
||||
{
|
||||
Version = buffer[offset] >> 6;
|
||||
Padding = (buffer[offset] & 0x20) != 0;
|
||||
ReportCount = buffer[offset] & 0x1f;
|
||||
Type = buffer[offset + 1];
|
||||
Length = (Utils.Convert2BytesToInt(buffer, offset + 2) * 4) + 4;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
using System.Collections.ObjectModel;
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
public class RtcpReceiverReportPacket :RtcpPacket
|
||||
{
|
||||
public string SynchronizationSource { get; private set; }
|
||||
public Collection<ReportBlock> ReportBlocks { get; private set; }
|
||||
public byte[] ProfileExtension { get; private set; }
|
||||
public override void Parse(byte[] buffer, int offset)
|
||||
{
|
||||
base.Parse(buffer, offset);
|
||||
SynchronizationSource = Utils.ConvertBytesToString(buffer, offset + 4, 4);
|
||||
|
||||
ReportBlocks = new Collection<ReportBlock>();
|
||||
int index = 8;
|
||||
|
||||
while (ReportBlocks.Count < ReportCount)
|
||||
{
|
||||
ReportBlock reportBlock = new ReportBlock();
|
||||
reportBlock.Process(buffer, offset + index);
|
||||
ReportBlocks.Add(reportBlock);
|
||||
index += reportBlock.BlockLength;
|
||||
}
|
||||
|
||||
if (index < Length)
|
||||
{
|
||||
ProfileExtension = new byte[Length - index];
|
||||
|
||||
for (int extensionIndex = 0; index < Length; index++)
|
||||
{
|
||||
ProfileExtension[extensionIndex] = buffer[offset + index];
|
||||
extensionIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("Receiver Report.\n");
|
||||
sb.AppendFormat("Version : {0} .\n", Version);
|
||||
sb.AppendFormat("Padding : {0} .\n", Padding);
|
||||
sb.AppendFormat("Report Count : {0} .\n", ReportCount);
|
||||
sb.AppendFormat("PacketType: {0} .\n", Type);
|
||||
sb.AppendFormat("Length : {0} .\n", Length);
|
||||
sb.AppendFormat("SynchronizationSource : {0} .\n", SynchronizationSource);
|
||||
sb.AppendFormat(".\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
using System.Collections.ObjectModel;
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
public class RtcpSenderReportPacket : RtcpPacket
|
||||
{
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// Get the synchronization source.
|
||||
/// </summary>
|
||||
public int SynchronizationSource { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the NPT timestamp.
|
||||
/// </summary>
|
||||
public long NPTTimeStamp { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the RTP timestamp.
|
||||
/// </summary>
|
||||
public int RTPTimeStamp { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the packet count.
|
||||
/// </summary>
|
||||
public int SenderPacketCount { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the octet count.
|
||||
/// </summary>
|
||||
public int SenderOctetCount { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the list of report blocks.
|
||||
/// </summary>
|
||||
public Collection<ReportBlock> ReportBlocks { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the profile extension data.
|
||||
/// </summary>
|
||||
public byte[] ProfileExtension { get; private set; }
|
||||
#endregion
|
||||
|
||||
public override void Parse(byte[] buffer, int offset)
|
||||
{
|
||||
base.Parse(buffer, offset);
|
||||
SynchronizationSource = Utils.Convert4BytesToInt(buffer, offset + 4);
|
||||
NPTTimeStamp = Utils.Convert8BytesToLong(buffer, offset + 8);
|
||||
RTPTimeStamp = Utils.Convert4BytesToInt(buffer, offset + 16);
|
||||
SenderPacketCount = Utils.Convert4BytesToInt(buffer, offset + 20);
|
||||
SenderOctetCount = Utils.Convert4BytesToInt(buffer, offset + 24);
|
||||
|
||||
ReportBlocks = new Collection<ReportBlock>();
|
||||
int index = 28;
|
||||
|
||||
while (ReportBlocks.Count < ReportCount)
|
||||
{
|
||||
ReportBlock reportBlock = new ReportBlock();
|
||||
reportBlock.Process(buffer, offset + index);
|
||||
ReportBlocks.Add(reportBlock);
|
||||
index += reportBlock.BlockLength;
|
||||
}
|
||||
|
||||
if (index < Length)
|
||||
{
|
||||
ProfileExtension = new byte[Length - index];
|
||||
|
||||
for (int extensionIndex = 0; index < Length; index++)
|
||||
{
|
||||
ProfileExtension[extensionIndex] = buffer[offset + index];
|
||||
extensionIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("Sender Report.\n");
|
||||
sb.AppendFormat("Version : {0} .\n", Version);
|
||||
sb.AppendFormat("Padding : {0} .\n", Padding);
|
||||
sb.AppendFormat("Report Count : {0} .\n", ReportCount);
|
||||
sb.AppendFormat("PacketType: {0} .\n", Type);
|
||||
sb.AppendFormat("Length : {0} .\n", Length);
|
||||
sb.AppendFormat("SynchronizationSource : {0} .\n", SynchronizationSource);
|
||||
sb.AppendFormat("NTP Timestamp : {0} .\n", Utils.NptTimestampToDateTime(NPTTimeStamp));
|
||||
sb.AppendFormat("RTP Timestamp : {0} .\n", RTPTimeStamp);
|
||||
sb.AppendFormat("Sender PacketCount : {0} .\n", SenderPacketCount);
|
||||
sb.AppendFormat("Sender Octet Count : {0} .\n", SenderOctetCount);
|
||||
sb.AppendFormat(".\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
using System.Collections.ObjectModel;
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
class RtcpSourceDescriptionPacket :RtcpPacket
|
||||
{ /// <summary>
|
||||
/// Get the list of source descriptions.
|
||||
/// </summary>
|
||||
public Collection<SourceDescriptionBlock> Descriptions;
|
||||
public override void Parse(byte[] buffer, int offset)
|
||||
{
|
||||
base.Parse(buffer, offset);
|
||||
Descriptions = new Collection<SourceDescriptionBlock>();
|
||||
|
||||
int index = 4;
|
||||
|
||||
while (Descriptions.Count < ReportCount)
|
||||
{
|
||||
SourceDescriptionBlock descriptionBlock = new SourceDescriptionBlock();
|
||||
descriptionBlock.Process(buffer, offset + index);
|
||||
Descriptions.Add(descriptionBlock);
|
||||
index += descriptionBlock.BlockLength;
|
||||
}
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("Source Description.\n");
|
||||
sb.AppendFormat("Version : {0} .\n", Version);
|
||||
sb.AppendFormat("Padding : {0} .\n", Padding);
|
||||
sb.AppendFormat("Report Count : {0} .\n", ReportCount);
|
||||
sb.AppendFormat("PacketType: {0} .\n", Type);
|
||||
sb.AppendFormat("Length : {0} .\n", Length);
|
||||
sb.AppendFormat("Descriptions : {0} .\n", Descriptions);
|
||||
|
||||
sb.AppendFormat(".\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
class SourceDescriptionBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the length of the block.
|
||||
/// </summary>
|
||||
public int BlockLength { get { return (blockLength + (blockLength % 4)); } }
|
||||
|
||||
/// <summary>
|
||||
/// Get the synchronization source.
|
||||
/// </summary>
|
||||
public string SynchronizationSource { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the list of source descriptioni items.
|
||||
/// </summary>
|
||||
public Collection<SourceDescriptionItem> Items;
|
||||
|
||||
private int blockLength;
|
||||
|
||||
public void Process(byte[] buffer, int offset)
|
||||
{
|
||||
SynchronizationSource = Utils.ConvertBytesToString(buffer, offset, 4);
|
||||
Items = new Collection<SourceDescriptionItem>();
|
||||
int index = 4;
|
||||
bool done = false;
|
||||
do
|
||||
{
|
||||
SourceDescriptionItem item = new SourceDescriptionItem();
|
||||
item.Process(buffer, offset + index);
|
||||
|
||||
if (item.Type != 0)
|
||||
{
|
||||
Items.Add(item);
|
||||
index += item.ItemLength;
|
||||
blockLength += item.ItemLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockLength++;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
|
||||
{
|
||||
/// <summary>
|
||||
/// The class that describes a source description item.
|
||||
/// </summary>
|
||||
public class SourceDescriptionItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the type.
|
||||
/// </summary>
|
||||
public int Type { get; private set; }
|
||||
/// <summary>
|
||||
/// Get the text.
|
||||
/// </summary>
|
||||
public string Text { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the length of the item.
|
||||
/// </summary>
|
||||
public int ItemLength { get { return (Text.Length + 2); } }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the SourceDescriptionItem class.
|
||||
/// </summary>
|
||||
public SourceDescriptionItem() { }
|
||||
|
||||
/// <summary>
|
||||
/// Unpack the data in a packet.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer containing the packet.</param>
|
||||
/// <param name="offset">The offset to the first byte of the packet within the buffer.</param>
|
||||
/// <returns>An ErrorSpec instance if an error occurs; null otherwise.</returns>
|
||||
public void Process(byte[] buffer, int offset)
|
||||
{
|
||||
Type = buffer[offset];
|
||||
if (Type != 0)
|
||||
{
|
||||
int length = buffer[offset + 1];
|
||||
Text = Utils.ConvertBytesToString(buffer, offset + 2, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtp
|
||||
{
|
||||
public class RtpListener
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private AutoResetEvent _rtpListenerThreadStopEvent;
|
||||
private Thread _rtpListenerThread;
|
||||
private UdpClient _udpClient;
|
||||
private IPEndPoint _multicastEndPoint;
|
||||
private IPEndPoint _serverEndPoint;
|
||||
private TransmissionMode _transmissionMode;
|
||||
public RtpListener(String address, int port,TransmissionMode mode,ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_transmissionMode = mode;
|
||||
switch (mode)
|
||||
{
|
||||
case TransmissionMode.Unicast:
|
||||
_udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(address), port));
|
||||
_serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
break;
|
||||
case TransmissionMode.Multicast:
|
||||
_multicastEndPoint = new IPEndPoint(IPAddress.Parse(address), port);
|
||||
_serverEndPoint = null;
|
||||
_udpClient = new UdpClient();
|
||||
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
|
||||
_udpClient.ExclusiveAddressUse = false;
|
||||
_udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, _multicastEndPoint.Port));
|
||||
_udpClient.JoinMulticastGroup(_multicastEndPoint.Address);
|
||||
break;
|
||||
}
|
||||
//StartRtpListenerThread();
|
||||
}
|
||||
public void StartRtpListenerThread()
|
||||
{
|
||||
// Kill the existing thread if it is in "zombie" state.
|
||||
if (_rtpListenerThread != null && !_rtpListenerThread.IsAlive)
|
||||
{
|
||||
StopRtpListenerThread();
|
||||
}
|
||||
|
||||
if (_rtpListenerThread == null)
|
||||
{
|
||||
_logger.Info("SAT>IP : starting new RTP listener thread");
|
||||
_rtpListenerThreadStopEvent = new AutoResetEvent(false);
|
||||
_rtpListenerThread = new Thread(new ThreadStart(RtpListenerThread));
|
||||
_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)
|
||||
{
|
||||
_logger.Info("SAT>IP : aborting old RTP listener thread");
|
||||
_rtpListenerThread.Abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
_rtpListenerThreadStopEvent.Set();
|
||||
if (!_rtpListenerThread.Join(400 * 2))
|
||||
{
|
||||
_logger.Info("SAT>IP : failed to join RTP listener thread, aborting thread");
|
||||
_rtpListenerThread.Abort();
|
||||
}
|
||||
}
|
||||
_rtpListenerThread = null;
|
||||
if (_rtpListenerThreadStopEvent != null)
|
||||
{
|
||||
_rtpListenerThreadStopEvent.Close();
|
||||
_rtpListenerThreadStopEvent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RtpListenerThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
while (!_rtpListenerThreadStopEvent.WaitOne(1))
|
||||
{
|
||||
byte[] receivedbytes = _udpClient.Receive(ref _serverEndPoint);
|
||||
RtpPacket packet = RtpPacket.Decode(receivedbytes);
|
||||
OnPacketReceived(new RtpPacketReceivedArgs(packet));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
switch (_transmissionMode)
|
||||
{
|
||||
case TransmissionMode.Multicast:
|
||||
_udpClient.DropMulticastGroup(_multicastEndPoint.Address);
|
||||
_udpClient.Close();
|
||||
break;
|
||||
case TransmissionMode.Unicast:
|
||||
_udpClient.Close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Info(string.Format("SAT>IP : RTP listener thread exception"), ex);
|
||||
return;
|
||||
}
|
||||
_logger.Info("SAT>IP : RTP listener thread stopping");
|
||||
}
|
||||
public delegate void PacketReceivedHandler(object sender, RtpPacketReceivedArgs e);
|
||||
public event PacketReceivedHandler PacketReceived;
|
||||
public class RtpPacketReceivedArgs : EventArgs
|
||||
{
|
||||
public RtpPacket Packet { get; private set; }
|
||||
|
||||
public RtpPacketReceivedArgs(RtpPacket packet)
|
||||
{
|
||||
Packet = packet;
|
||||
}
|
||||
}
|
||||
protected void OnPacketReceived(RtpPacketReceivedArgs args)
|
||||
{
|
||||
if (PacketReceived != null)
|
||||
{
|
||||
PacketReceived(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtp
|
||||
{
|
||||
public class RtpPacket
|
||||
{
|
||||
private static int MinHeaderLength = 12;
|
||||
public int HeaderSize = MinHeaderLength;
|
||||
public int Version { get; set; }
|
||||
public Boolean Padding { get; set; }
|
||||
public Boolean Extension { get; set; }
|
||||
public int ContributingSourceCount { get; set; }
|
||||
public Boolean Marker { get; set; }
|
||||
public int PayloadType { get; set; }
|
||||
public int SequenceNumber { get; set; }
|
||||
public long TimeStamp { get; set; }
|
||||
public long SynchronizationSource { get; set; }
|
||||
public Collection<string> ContributingSources { get; private set; }
|
||||
public int ExtensionHeaderId = 0;
|
||||
public int ExtensionHeaderLength = 0;
|
||||
public bool HasPayload { get; set; }
|
||||
public byte[] Payload { get; set; }
|
||||
public RtpPacket()
|
||||
{
|
||||
|
||||
}
|
||||
public static RtpPacket Decode(byte[] buffer)
|
||||
{
|
||||
var packet = new RtpPacket();
|
||||
packet.Version = buffer[0] >> 6;
|
||||
packet.Padding = (buffer[0] & 0x20) != 0;
|
||||
packet.Extension = (buffer[0] & 0x10) != 0;
|
||||
packet.ContributingSourceCount = buffer[0] & 0x0f;
|
||||
|
||||
packet.Marker = (buffer[1] & 0x80) != 0;
|
||||
packet.PayloadType = buffer[1] & 0x7f;
|
||||
|
||||
packet.SequenceNumber = Utils.Convert2BytesToInt(buffer, 2);
|
||||
packet.TimeStamp = Utils.Convert4BytesToLong(buffer, 4);
|
||||
packet.SynchronizationSource = Utils.Convert4BytesToLong(buffer, 8);
|
||||
|
||||
int index = 12;
|
||||
|
||||
if (packet.ContributingSourceCount != 0)
|
||||
{
|
||||
packet.ContributingSources = new Collection<string>();
|
||||
|
||||
while (packet.ContributingSources.Count < packet.ContributingSourceCount)
|
||||
{
|
||||
packet.ContributingSources.Add(Utils.ConvertBytesToString(buffer, index, 4));
|
||||
index += 4;
|
||||
}
|
||||
}
|
||||
var dataoffset = 0;
|
||||
if (!packet.Extension)
|
||||
dataoffset = index;
|
||||
else
|
||||
{
|
||||
packet.ExtensionHeaderId = Utils.Convert2BytesToInt(buffer, index);
|
||||
packet.ExtensionHeaderLength = Utils.Convert2BytesToInt(buffer, index + 2);
|
||||
dataoffset = index + packet.ExtensionHeaderLength + 4;
|
||||
}
|
||||
|
||||
var dataLength = buffer.Length - dataoffset;
|
||||
if (dataLength > dataoffset)
|
||||
{
|
||||
packet.HasPayload = true;
|
||||
packet.Payload = new byte[dataLength];
|
||||
Array.Copy(buffer, dataoffset, packet.Payload, 0, dataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.HasPayload = false;
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("RTP Packet");
|
||||
sb.AppendFormat("Version: {0} \n", Version);
|
||||
sb.AppendFormat("Padding: {0} \n", Padding);
|
||||
sb.AppendFormat("Extension: {0} \n", Extension);
|
||||
sb.AppendFormat("Contributing Source Identifiers Count: {0} \n", ContributingSourceCount);
|
||||
sb.AppendFormat("Marker: {0} \n", Marker);
|
||||
sb.AppendFormat("Payload Type: {0} \n", PayloadType);
|
||||
sb.AppendFormat("Sequence Number: {0} \n", SequenceNumber);
|
||||
sb.AppendFormat("Timestamp: {0} .\n", TimeStamp);
|
||||
sb.AppendFormat("Synchronization Source Identifier: {0} \n", SynchronizationSource);
|
||||
sb.AppendFormat("\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -237,7 +237,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
|
||||
string modelurl = "";
|
||||
string serialnumber = "";
|
||||
string presentationurl = "";
|
||||
string capabilities = "";
|
||||
//string capabilities = "";
|
||||
string m3u = "";
|
||||
var document = XDocument.Load(locationUri.AbsoluteUri);
|
||||
var xnm = new XmlNamespaceManager(new NameTable());
|
||||
@ -284,20 +284,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
|
||||
var capabilitiesElement = deviceElement.Element(n1 + "X_SATIPCAP");
|
||||
if (capabilitiesElement != null)
|
||||
{
|
||||
//_capabilities = capabilitiesElement.Value;
|
||||
//if (capabilitiesElement.Value.Contains(','))
|
||||
//{
|
||||
// string[] capabilities = capabilitiesElement.Value.Split(',');
|
||||
// foreach (var capability in capabilities)
|
||||
// {
|
||||
// ReadCapability(capability);
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// ReadCapability(capabilitiesElement.Value);
|
||||
//}
|
||||
//_capabilities = capabilitiesElement.Value;
|
||||
if (capabilitiesElement.Value.Contains(','))
|
||||
{
|
||||
string[] capabilities = capabilitiesElement.Value.Split(',');
|
||||
foreach (var capability in capabilities)
|
||||
{
|
||||
ReadCapability(capability);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadCapability(capabilitiesElement.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_supportsDVBS = true;
|
||||
@ -314,8 +314,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
|
||||
Id = uniquedevicename,
|
||||
IsEnabled = true,
|
||||
Type = SatIpHost.DeviceType,
|
||||
Tuners = 1,
|
||||
TunersAvailable = 1,
|
||||
Tuners = _tunerCountDVBS,
|
||||
TunersAvailable = _tunerCountDVBS,
|
||||
M3UUrl = m3u
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
|
||||
{
|
||||
public enum TransmissionMode
|
||||
{
|
||||
Unicast,
|
||||
Multicast
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
|
||||
{
|
||||
public class Utils
|
||||
{
|
||||
public static int Convert2BytesToInt(byte[] buffer, int offset)
|
||||
{
|
||||
int temp = (int)buffer[offset];
|
||||
temp = (temp * 256) + buffer[offset + 1];
|
||||
|
||||
return (temp);
|
||||
}
|
||||
public static int Convert3BytesToInt(byte[] buffer, int offset)
|
||||
{
|
||||
int temp = (int)buffer[offset];
|
||||
temp = (temp * 256) + buffer[offset + 1];
|
||||
temp = (temp * 256) + buffer[offset + 2];
|
||||
|
||||
return (temp);
|
||||
}
|
||||
public static int Convert4BytesToInt(byte[] buffer, int offset)
|
||||
{
|
||||
int temp =(int)buffer[offset];
|
||||
temp = (temp * 256) + buffer[offset + 1];
|
||||
temp = (temp * 256) + buffer[offset + 2];
|
||||
temp = (temp * 256) + buffer[offset + 3];
|
||||
|
||||
return (temp);
|
||||
}
|
||||
public static long Convert4BytesToLong(byte[] buffer, int offset)
|
||||
{
|
||||
long temp = 0;
|
||||
|
||||
for (int index = 0; index < 4; index++)
|
||||
temp = (temp * 256) + buffer[offset + index];
|
||||
|
||||
return (temp);
|
||||
}
|
||||
public static long Convert8BytesToLong(byte[] buffer, int offset)
|
||||
{
|
||||
long temp = 0;
|
||||
|
||||
for (int index = 0; index < 8; index++)
|
||||
temp = (temp * 256) + buffer[offset + index];
|
||||
|
||||
return (temp);
|
||||
}
|
||||
public static string ConvertBytesToString(byte[] buffer, int offset, int length)
|
||||
{
|
||||
StringBuilder reply = new StringBuilder(4);
|
||||
for (int index = 0; index < length; index++)
|
||||
reply.Append((char)buffer[offset + index]);
|
||||
return (reply.ToString());
|
||||
}
|
||||
public static DateTime NptTimestampToDateTime(long nptTimestamp) { return NptTimestampToDateTime((uint)((nptTimestamp >> 32) & 0xFFFFFFFF), (uint)(nptTimestamp & 0xFFFFFFFF),null); }
|
||||
|
||||
public static DateTime NptTimestampToDateTime(uint seconds, uint fractions, DateTime? epoch )
|
||||
{
|
||||
ulong ticks =(ulong)((seconds * TimeSpan.TicksPerSecond) + ((fractions * TimeSpan.TicksPerSecond) / 0x100000000L));
|
||||
if (epoch.HasValue) return epoch.Value + TimeSpan.FromTicks((Int64)ticks);
|
||||
return (seconds & 0x80000000L) == 0 ? UtcEpoch2036 + TimeSpan.FromTicks((Int64)ticks) : UtcEpoch1900 + TimeSpan.FromTicks((Int64)ticks);
|
||||
}
|
||||
|
||||
//When the First Epoch will wrap (The real Y2k)
|
||||
public static DateTime UtcEpoch2036 = new DateTime(2036, 2, 7, 6, 28, 16, DateTimeKind.Utc);
|
||||
|
||||
public static DateTime UtcEpoch1900 = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
public static DateTime UtcEpoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
}
|
||||
}
|
@ -251,6 +251,18 @@
|
||||
<Compile Include="LiveTv\RecordingImageProvider.cs" />
|
||||
<Compile Include="LiveTv\RefreshChannelsScheduledTask.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\ReportBlock.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpAppPacket.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpByePacket.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpListener.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpPacket.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpReceiverReportPacket.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSenderReportPacket.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSourceDescriptionPacket.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionBlock.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionItem.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpListener.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpPacket.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspMethod.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspRequest.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspResponse.cs" />
|
||||
@ -258,6 +270,8 @@
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspStatusCode.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\SatIpHost.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\SatIpDiscovery.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\TransmissionMode.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Utils.cs" />
|
||||
<Compile Include="Localization\LocalizationManager.cs" />
|
||||
<Compile Include="Logging\PatternsLogger.cs" />
|
||||
<Compile Include="MediaEncoder\EncodingManager.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user