Ejemplo n.º 1
0
        //SUpparioucly thought that the last frame would remain in a not final state so one should check that the Goodbye has not been received when processing the event...
        //Shows what happpens when packets get out of order too badely..
        public void TestFrameChangedEvents()
        {
            using (Rtp.RtpClient rtpClient = new Rtp.RtpClient())
            {
                //Fire Frames with single packets and order = 3, 1, 2.
                //Each have marker

                //What is the expected order(3 final, 1 final, 2 final)? and count (3)!

                int count = 0, fcount = 0;

                Rtp.RtpClient.TransportContext tc = new Rtp.RtpClient.TransportContext(0, 1, 0);

                //Needed to resolve packet payload and avoid exception when validating packet... :(
                tc.MediaDescription = new Sdp.MediaDescription(Sdp.MediaType.unknown, 0, "RTP", 0);

                rtpClient.AddContext(tc);

                rtpClient.FrameChangedEventsEnabled = true;

                rtpClient.RtpFrameChanged += (s, z, t, f) =>
                {
                    ++count;

                    if (f)
                    {
                        ++fcount;
                    }

                    Console.WriteLine("RtpFrameChanged=>" + z.HighestSequenceNumber + z.HasMarker + f);
                };

                Console.WriteLine("Count: " + count);

                Console.WriteLine("Final Count: " + fcount);

                int tests = 4;

                Rtp.RtpPacket rtpPacket           = new Rtp.RtpPacket(12)
                {
                    Timestamp      = tests * 1000,
                    SequenceNumber = tests,
                    Marker         = true
                };

                for (int i = tests; i >= 0; --i)
                {
                    rtpPacket.Timestamp -= tests * 1000;

                    rtpPacket.SequenceNumber = i;

                    rtpClient.HandleIncomingRtpPacket(null, rtpPacket, tc);
                }

                //8 Frame Changes only 3 are final...
                if (count != tests || fcount != tests)
                {
                    throw new Exception();
                }

                count = fcount = 0;

                rtpPacket.SequenceNumber = 4;
                rtpPacket.Timestamp      = 4000;

                rtpClient.HandleIncomingRtpPacket(null, rtpPacket, tc);

                rtpPacket.SequenceNumber = 1;
                rtpPacket.Timestamp      = 1000;

                rtpClient.HandleIncomingRtpPacket(null, rtpPacket, tc);

                rtpPacket.SequenceNumber = 3;
                rtpPacket.Timestamp      = 3000;

                rtpClient.HandleIncomingRtpPacket(null, rtpPacket, tc);

                rtpPacket.SequenceNumber = 2;
                rtpPacket.Timestamp      = 2000;

                rtpClient.HandleIncomingRtpPacket(null, rtpPacket, tc);

                if (count != tests || fcount != tests)
                {
                    throw new Exception();
                }
            }
        }
Ejemplo n.º 2
0
        public void TestBroadcast()
        {
            string testVector = @"v=0 
o=sip 1247 1247 IN IP4 255.255.255.255 
s=Talk 
c=IN IP4 255.255.255.255 
t=0 0 
m=video 5550 RTP/AVP 99 
a=rtpmap:99 H264/90000 
a=sendonly";

            //Parse the sdp
            using (var sdp = new Media.Sdp.SessionDescription(testVector))
            {
                //Verify the parsing
                if (false.Equals(sdp.Lines.Count().Equals(8)))
                {
                    throw new System.Exception("Did not parse all lines");
                }

                //Verify that a RtpClient can be created, since no ports are specified the default for rtp and rtcp are used.
                //Initialize fails on the attempt to hole punch and ports are set to 0.
                using (Rtp.RtpClient test = Rtp.RtpClient.FromSessionDescription(sdp))
                {
                    //Verify that there are the expected amount of context's
                    if (false.Equals(test.GetTransportContexts().Count().Equals(1)))
                    {
                        throw new System.Exception("Unexpected amount of TransportContext's");
                    }

                    Rtp.RtpClient.TransportContext firstContext = test.GetTransportContexts().First();

                    System.Net.IPEndPoint localEndPoint = firstContext.RtpSocket.Connected ? firstContext.RtpSocket.LocalEndPoint as System.Net.IPEndPoint : firstContext.LocalRtp as System.Net.IPEndPoint;

                    //Verify our address addresses
                    if (true.Equals(localEndPoint == null))
                    {
                        throw new System.Exception("Unexpected LocalRtp or RtpSocket.LocalEndPoint");
                    }

                    if (false.Equals(Common.Extensions.IPAddress.IPAddressExtensions.IsMulticast(localEndPoint.Address)))
                    {
                        throw new System.Exception("Unexpected IPAddress type for LocalEndPoint");
                    }

                    //Get the first MulticastIPAddress on the system and ensure that it is equal to the IPAddress which would be used locally by the RtpClient
                    //This may be different depending on the network which is being connected to in a real application.

                    if (false.Equals(Common.Extensions.Socket.SocketExtensions.GetFirstMulticastIPAddress(localEndPoint.AddressFamily).Equals(localEndPoint.Address)))
                    {
                        throw new System.Exception("Unexpected RtpSocket.LocalEndPoint.IPAddress");
                    }

                    //Verify their address
                    System.Net.IPEndPoint remoteEndPoint = firstContext.RtpSocket.Connected ? firstContext.RtpSocket.RemoteEndPoint as System.Net.IPEndPoint as System.Net.IPEndPoint : firstContext.RemoteRtp as System.Net.IPEndPoint;

                    if (true.Equals(remoteEndPoint == null))
                    {
                        throw new System.Exception("Unexpected RemoteRtp or RtpSocket.RemoteEndPoint");
                    }

                    if (false.Equals(System.Net.IPAddress.Broadcast.Equals(remoteEndPoint.Address)) && false.Equals(Common.Extensions.IPAddress.IPAddressExtensions.IsMulticast(remoteEndPoint.Address)))
                    {
                        throw new System.Exception("Unexpected IPAddress for RemoteEndPoint");
                    }
                }
            }
        }
Ejemplo n.º 3
0
        //Needs to only send packets and not worry about updating the frame, that should be done by ImageSource

        internal override void SendPackets()
        {
            m_RtpClient.FrameChangedEventsEnabled = false;

            while (State == StreamState.Started)
            {
                try
                {
                    if (m_Frames.Count == 0)
                    {
                        m_RtpClient.m_WorkerThread.Priority = System.Threading.ThreadPriority.Lowest;

                        System.Threading.Thread.Sleep(clockRate);

                        continue;
                    }

                    int period = (clockRate * 1000 / m_Frames.Count);

                    //Dequeue a frame or die
                    Rtp.RtpFrame frame = m_Frames.Dequeue();

                    if (frame == null || frame.IsDisposed)
                    {
                        continue;
                    }

                    //Get the transportChannel for the packet
                    Rtp.RtpClient.TransportContext transportContext = RtpClient.GetContextBySourceId(frame.SynchronizationSourceIdentifier);

                    //If there is a context
                    if (transportContext != null)
                    {
                        //Increase priority
                        m_RtpClient.m_WorkerThread.Priority = System.Threading.ThreadPriority.AboveNormal;

                        transportContext.RtpTimestamp += period;

                        foreach (Rtp.RtpPacket packet in frame)
                        {
                            //Copy the values before we signal the server
                            //packet.Channel = transportContext.DataChannel;
                            packet.SynchronizationSourceIdentifier = (int)sourceId;
                            packet.Timestamp = (int)transportContext.RtpTimestamp;

                            //Increment the sequence number on the transportChannel and assign the result to the packet
                            packet.SequenceNumber = ++transportContext.SequenceNumber;

                            //Fire an event so the server sends a packet to all clients connected to this source
                            if (false == m_RtpClient.FrameChangedEventsEnabled)
                            {
                                RtpClient.OnRtpPacketReceieved(packet);
                            }
                        }

                        //Modified packet is no longer complete because SequenceNumbers were modified

                        //Fire a frame changed event manually
                        if (m_RtpClient.FrameChangedEventsEnabled)
                        {
                            RtpClient.OnRtpFrameChanged(frame);
                        }

                        unchecked { ++m_FramesPerSecondCounter; }
                    }

                    //If we are to loop images then add it back at the end
                    if (Loop)
                    {
                        m_Frames.Enqueue(frame);
                    }

                    System.Threading.Thread.Sleep(clockRate);
                }
                catch (Exception ex)
                {
                    if (ex is System.Threading.ThreadAbortException)
                    {
                        //Handle the abort
                        System.Threading.Thread.ResetAbort();

                        Stop();

                        return;
                    }
                    continue;
                }
            }
        }