public bool InitializePorts(out Socket socket, out int port, ref NATTraversalProtocol ppNATData, out Socket rtcp, out int rtcpPort, ref NATTraversalProtocol ppNATRTCP)
        {
            UDPCarrier carrier1 = null;
            UDPCarrier carrier2 = null;

            for (int i = 0; i < 10; i++)
            {
                if (carrier1 != null)
                {
                    carrier1.Dispose();
                    carrier1 = null;
                }
                if (carrier2 != null)
                {
                    carrier2.Dispose();
                    carrier2 = null;
                }

                carrier1 = UDPCarrier.Create("0.0.0.0", 0);
                if (carrier1 == null)
                {
                    WARN("Unable to create UDP carrier for RTP");
                    continue;
                }

                carrier2 = (carrier1.NearPort % 2) == 0 ? UDPCarrier.Create("0.0.0.0", carrier1.NearPort + 1) : UDPCarrier.Create("0.0.0.0", carrier1.NearPort - 1);

                if (carrier2 == null)
                {
                    WARN("Unable to create UDP carrier for RTCP");
                    continue;
                }

                if (carrier1.NearPort > carrier2.NearPort)
                {
                    WARN("Switch carriers");
                    UDPCarrier pTemp = carrier1;
                    carrier1 = carrier2;
                    carrier2 = pTemp;
                }

                Variant dummy = Variant.Get();
                socket    = carrier1.Socket;
                port      = carrier1.NearPort;
                ppNATData = (NATTraversalProtocol)ProtocolFactoryManager.CreateProtocolChain(Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy);
                if (ppNATData == null)
                {
                    rtcp     = null;
                    rtcpPort = 0;
                    FATAL("Unable to create the protocol chain {0}", Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL);
                    return(false);
                }
                carrier1.Protocol = ppNATData.FarEndpoint;
                ppNATData.FarEndpoint.IOHandler = carrier1;
                rtcp      = carrier2.Socket;
                rtcpPort  = carrier2.NearPort;
                ppNATRTCP = (NATTraversalProtocol)ProtocolFactoryManager.CreateProtocolChain(Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy);
                if (ppNATRTCP == null)
                {
                    FATAL("Unable to create the protocol chain {0}", Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL);
                    ppNATData.EnqueueForDelete();
                    return(false);
                }
                carrier2.Protocol = ppNATRTCP.FarEndpoint;
                ppNATRTCP.FarEndpoint.IOHandler = carrier2;
                return(true);
            }
            if (carrier1 != null)
            {
                carrier1.Dispose();
                carrier1 = null;
            }
            if (carrier2 != null)
            {
                carrier2.Dispose();
                carrier2 = null;
            }
            socket   = null;
            port     = 0;
            rtcp     = null;
            rtcpPort = 0;
            return(false);
        }
        public bool InitializePorts(out Socket socket,out int port,ref NATTraversalProtocol ppNATData,out Socket rtcp,out int rtcpPort,ref NATTraversalProtocol ppNATRTCP)
        {
            UDPCarrier carrier1 = null;
            UDPCarrier carrier2 = null;
            for (int i = 0; i < 10; i++)
            {
                if (carrier1 != null)
                {
                    carrier1.Dispose();
                    carrier1 = null;
                }
                if (carrier2 != null)
                {
                    carrier2.Dispose();
                    carrier2 = null;
                }

                carrier1 = UDPCarrier.Create("0.0.0.0", 0);
                if (carrier1 == null)
                {
                    WARN("Unable to create UDP carrier for RTP");
                    continue;
                }

                carrier2 = (carrier1.NearPort % 2) == 0 ? UDPCarrier.Create("0.0.0.0", carrier1.NearPort + 1) : UDPCarrier.Create("0.0.0.0", carrier1.NearPort - 1);

                if (carrier2 == null)
                {
                    WARN("Unable to create UDP carrier for RTCP");
                    continue;
                }

                if (carrier1.NearPort > carrier2.NearPort)
                {
                    WARN("Switch carriers");
                    UDPCarrier pTemp = carrier1;
                    carrier1 = carrier2;
                    carrier2 = pTemp;
                }

                Variant dummy = Variant.Get();
                socket = carrier1.Socket;
                port = carrier1.NearPort;
                ppNATData = (NATTraversalProtocol)ProtocolFactoryManager.CreateProtocolChain(Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy);
                if (ppNATData == null)
                {
                    rtcp = null;
                    rtcpPort = 0;
                    FATAL("Unable to create the protocol chain {0}", Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL);
                    return false;
                }
                carrier1.Protocol = ppNATData.FarEndpoint;
                ppNATData.FarEndpoint.IOHandler = carrier1;
                rtcp = carrier2.Socket;
                rtcpPort = carrier2.NearPort;
                ppNATRTCP = (NATTraversalProtocol)ProtocolFactoryManager.CreateProtocolChain(Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy);
                if (ppNATRTCP == null)
                {
                    FATAL("Unable to create the protocol chain {0}", Defines.CONF_PROTOCOL_RTP_NAT_TRAVERSAL);
                    ppNATData.EnqueueForDelete();
                    return false;
                }
                carrier2.Protocol = ppNATRTCP.FarEndpoint;
                ppNATRTCP.FarEndpoint.IOHandler = carrier2;
                return true;
            }
            if (carrier1 != null)
            {
                carrier1.Dispose();
                carrier1 = null;
            }
            if (carrier2 != null)
            {
                carrier2.Dispose();
                carrier2 = null;
            }
            socket = null;
            port = 0;
            rtcp = null;
            rtcpPort = 0;
            return false;
        }
        public override BaseProtocol SpawnProtocol(ulong type, Variant parameters)
        {
            BaseProtocol pResult = null;
            switch (type)
            {
                case ProtocolTypes.PT_TCP:
                    pResult = new TCPProtocol();
                    break;
                case ProtocolTypes.PT_UDP:
                    pResult = new UDPProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_SSL:
                    pResult = new InboundSSLProtocol();
                    break;
                case ProtocolTypes.PT_OUTBOUND_SSL:
                    pResult = new OutboundSSLProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_RTMP:
                    pResult = new InboundRTMPProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_RTMPS_DISC:
                    break;
                case ProtocolTypes.PT_OUTBOUND_RTMP:
                    pResult = new OutboundRTMPProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_RTMFP:
                    pResult = new InboundRTMFPProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_CLUSTER:
                    pResult = new InboundClusterProtocol();
                    break;
                case ProtocolTypes.PT_OUTBOUND_CLUSTER:
                    pResult = new OutboundClusterProtocol();
                    break;
                case ProtocolTypes.PT_RTSP:
                    pResult = new RtspProtocol();
                    break;
                case ProtocolTypes.PT_RTP_NAT_TRAVERSAL:
                    pResult = new NATTraversalProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_RTP:
                    pResult = new InboundRtpProtocol();
                    break;
                case ProtocolTypes.PT_RTCP:
                    pResult = new RtcpProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_WEBSOCKET:
                    pResult = new WebSocketProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_WEBRTC_SIGNAL:
                    pResult = new WebRtcSignalProtocol();
                    break;
                case ProtocolTypes.PT_INBOUND_MP4:
                    pResult = new Mp4Protocol();
                    break;
                default:
                    Logger.FATAL("Spawning protocol {0} not yet implemented",
                        type.TagToString());
                    break;
            }
            if (pResult != null)
            {
                if (!pResult.Initialize(parameters))
                {
                    Logger.FATAL("Unable to initialize protocol {0}",
                            type.TagToString());

                    pResult = null;
                }
            }
            return pResult;
        }