Pārlūkot izejas kodu

Rtp Rtcp fix Discovery #2116

Luke Pulverenti 8 gadi atpakaļ
vecāks
revīzija
fb251448c9
16 mainītis faili ar 1222 papildinājumiem un 16 dzēšanām
  1. 79 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs
  2. 68 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs
  3. 59 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs
  4. 203 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs
  5. 37 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs
  6. 68 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs
  7. 105 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs
  8. 57 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs
  9. 65 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs
  10. 60 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs
  11. 160 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs
  12. 116 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs
  13. 16 16
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
  14. 25 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/TransmissionMode.cs
  15. 90 0
      MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Utils.cs
  16. 14 0
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

+ 79 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs

@@ -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);
+
+            
+        }
+    }
+}

+ 68 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs

@@ -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();
+        }
+    }
+}

+ 59 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs

@@ -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();
+        }
+    }
+}

+ 203 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs

@@ -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);
+            }
+        }
+    }
+}

+ 37 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs

@@ -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;             
+        }
+    }
+}

+ 68 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs

@@ -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();
+        }
+    }
+}

+ 105 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs

@@ -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();
+        }
+    }
+}

+ 57 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs

@@ -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();
+        }
+    }
+}

+ 65 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs

@@ -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);            
+        }
+    }
+}

+ 60 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs

@@ -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);
+            }            
+        }
+    }
+}

+ 160 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs

@@ -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);
+            }
+        }
+    }
+}

+ 116 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs

@@ -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();
+        }
+
+    }
+
+}

+ 16 - 16
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs

@@ -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
             };
 

+ 25 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/TransmissionMode.cs

@@ -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
+    }
+}

+ 90 - 0
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Utils.cs

@@ -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);
+
+    }
+}

+ 14 - 0
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -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" />