RtpParticipant is the object shared between Rtp and Rtcp for describing a participant. Most of the public properties are a thin wrapper around the SdesData used in Rtcp. This class was created in order to shield the user from needing to understand Rtcp/Sdes, and give them a familiar concept that is easy to understand. The most important aspect of a participant is their uniqueName. It needs to be unique within the context of a session in order to differentiate them from other participants. A domain account, email, GUID, etc. would be good unique names. The participant also contains some other properties, such as the IPAddress the participant originates from, as well as all the streams the participant "owns" (is sending).
Inheritance: SdesData
Esempio n. 1
0
        public MultiSession(string uniqueSessionName)
        {
            fUniqueSessionName = uniqueSessionName;

            // Step 1
            HookRtpEvents();

            // Step 2
            RtpParticipant participant = new RtpParticipant(fUniqueSessionName, fUniqueSessionName);
            fRtpSession = new RtpSession(gSessionEndPoint, participant, true, true);

            // Wait for channels to be added
        }
Esempio n. 2
0
        ConferenceSession(IPEndPoint endPoint, string uniqueName, string friendlyName, bool rtpTraffic, bool receiveData, IPEndPoint reflector)
            : base()
        {
            fModel = new ShowItModel(this);


            // Step 1
            fLocalParticipant = new RtpParticipant(uniqueName, friendlyName);

            if (null == reflector)
                Session = new RtpSession(endPoint, fLocalParticipant, true, true);
            else
                Session = new RtpSession(endPoint, fLocalParticipant, true, true, reflector);

            HookRtpEvents();


            // After everything is setup, initialize the session, which will
            // start the network messages flowing.
            Session.Initialize();

        
            // Create the three channels that are used in the conference
            fDesktopChannel = CreateChannel(PayloadType.xApplication2);
            fDesktopChannel.FrameReceivedEvent += new RtpStream.FrameReceivedEventHandler(ReceiveDesktopFrame);
            
            fAudioChannel = CreateChannel(PayloadType.xApplication3);
            fAudioChannel.FrameReceivedEvent += new RtpStream.FrameReceivedEventHandler(ReceiveAudioFrame);
            
            fVideoChannel = CreateChannel(PayloadType.xApplication4);
            fVideoChannel.FrameReceivedEvent += new RtpStream.FrameReceivedEventHandler(ReceiveVideoFrame);

            // Wait until the channels are ready
            // to send before proceeding
            do
            {
                Thread.Sleep(10);
            } while (!fDesktopChannel.IsReadyToSend && !fAudioChannel.IsReadyToSend && !fVideoChannel.IsReadyToSend);

        }
Esempio n. 3
0
        public ConferenceAttendee(ConferenceSession session, RtpParticipant participant)
        {
            fSession = session;
            fParticipant = participant;

            // Create the equipment the attendee controls
            // Personal desktop capture
            fDesktopCapture = new DesktopCapture(this);

            // Personal video Capture
            int camIndex = 0;
            int numSources = VideoCaptureDevice.GetNumberOfInputDevices();
            if (numSources > 4)
                camIndex = 4;

            fCaptureCamera = new AttendeeCamera(this, camIndex);
            fCaptureCamera.Start();

            // Personal audio capture

            // Desk Set
            fDeskSet = session.Model.CreateDeskSet(this);
        }
Esempio n. 4
0
 public RtpParticipantEventArgs(RtpParticipant participant)
 {
     RtpParticipant = participant;
 }
Esempio n. 5
0
 protected virtual void JoinRtpSession(string ID, string name)
 {
     fSessionParticipant = new RtpParticipant(ID, name);
     fSession = new RtpSession(gSessionEndPoint, fSessionParticipant, true, true);
 }
Esempio n. 6
0
 protected virtual void JoinRtpSession(string name)
 {
     RtpParticipant participant = new RtpParticipant(name, name);
     rtpSession = new RtpSession(gSessionEndPoint, participant, true, true);
 }
Esempio n. 7
0
        /// <summary>
        /// Removes a participant and does all the necessary cleanup of streams and associations
        /// </summary>
        /// <param name="participant"></param>
        private void RemoveParticipant(RtpParticipant participant)
        {
            lock(participants)
            {
                if(participants.ContainsKey(participant.CName))
                {
                    foreach(uint ssrc in participant.SSRCs)
                    {
                        if(streamsAndIPs[ssrc].stream != null)
                        {
                            RemoveSSRC(ssrc);
                        }

                        participant.RemoveSSRC(ssrc);
                        ssrcToParticipant.Remove(ssrc);
                    }

                    participants.Remove(participant.CName);
                    ssrcToParticipant.Remove(participant.SSRC);

                    RaiseParticipantRemovedEvent(participant);
                }
            }
        }
Esempio n. 8
0
        private void AddParticipant(uint ssrc, RtpParticipant participant)
        {
            lock(participants)
            {
                // Update collections
                participants.Add(participant.CName, participant);
                participant.SSRC = ssrc;
                ssrcToParticipant.Add(ssrc, participant);

                // Raise event
                RaiseParticipantAddedEvent(participant);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// AddOrUpdateParticipant is called by the RtpSession ctor for adding the local participant and
        /// by ProcessSdesPacket when an SDES packet arrives on the RtcpListener thread
        /// 
        /// If the participant does not exist in the session, we add them
        /// If the participant does exist in the session, we make sure there is no CName conflict
        /// </summary>
        /// <param name="ssrc">Unique identifier of the stream</param>
        /// <param name="sdes">CName, Name, Email, etc from which to create the Participant</param>
        /// <param name="ip">Originating IP address of the ssrc and SdesData</param>
        private void AddOrUpdateParticipant(uint ssrc, SdesData sdes, IPAddress ip)
        {
            lock(participants)
            {
                string cName = sdes.CName;
                RtpParticipant participant = null;
                if (participants.ContainsKey(cName))
                    participant = participants[cName];

                // Participant does not exist
                if(null == participant)
                {
                    // Create a new participant
                    AddParticipant(ssrc, new RtpParticipant(sdes, ip));
                }
                else // Participant exists
                {
                    CheckForCNameConflict(cName, new IPAddress[]{participant.IPAddress, ip});
                    
                    participant.Stale = 0;
                    participant.UpdateData(sdes);
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// This constructor is the same as "RtpSession(IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData)",
        /// except that it is capable of using a Unicast-Multicast reflector.
        /// </summary>
        /// <param name="multicastEP"></param>
        /// <param name="participant"></param>
        /// <param name="rtpTraffic"></param>
        /// <param name="reflectorEPArg">The IP address and port number of the reflector</param>
        public RtpSession(IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData, IPEndPoint reflectorEP)
        {
            fEvents = new RtpEvents();

            #region Parameter Validation

            if(multicastEP == null)
            {
                throw new ArgumentNullException("multicastEP");
            }

            // A null participant is a special state for diagnostic purposes
            // The rtpTraffic flag must be false in order to be consistent
            if(participant == null && rtpTraffic)
            {
                throw new ArgumentException(Strings.IncompatibleArgumentsStatus);
            }

            if(!receiveData && (participant != null || !rtpTraffic))
            {
                throw new ArgumentException(Strings.IncompatibleArgumentsMessageShort);
            }

            #endregion Parameter Validation

            Utility.multicastIP = multicastEP.Address;

            if (null != reflectorEP)
                this.multicastEP = reflectorEP; // Use the reflector as a Unicast EndPoint
            else
                this.multicastEP = multicastEP;

            // Same as the "old" three argument constructor ...
            this.participant = participant;
            this.rtpTraffic = rtpTraffic;
            this.receiveData = receiveData;
                       
            // Initialize threads, perf counters, network, etc.
            //Initialize();
        }
Esempio n. 11
0
 /// <summary>
 /// The RtpSession can be in 1 of 4 states:
 /// 
 /// 1. Sending/Receiving Rtp + Rtcp traffic - this is what most users want
 /// 2. Sending/Receiving Rtcp traffic - used mainly by diagnostic tools for discovery of 
 ///     people while also announcing the local user
 /// 3. Receiving Rtcp traffic only - a special diagnostic case used by Pipecleaner to 
 ///     discover if an Agent is already running.
 /// 4. Sending Rtp + Rtcp traffic - a rare case only used for sending test data or
 ///     for "playback" of data in a scenario where SSRC and CNAME conflicts aren't of
 ///     interest to the sender.  THIS SHOULD ONLY BE USED IN EXCEPTIONAL CASES.
 /// 
 /// -If no participant is provided (null), then RtpSession cannot send Rtp or Rtcp data (state 3)
 /// -Else a valid participant is provided and Rtcp traffic can be sent (states 1, 2, or 4)
 ///    -If rtpTraffic is true, then Rtp traffic is sent and/or received (state 1 or 4)
 ///       -If receiveData is true, then Rtp traffic is received as well as sent (state 1)
 ///       -Else Rtp and Rtcp traffic are not received (state 4)
 ///    -Else rtpTraffic is neither sent nor received (state 2)
 /// </summary>
 /// <remarks>
 /// Note that receiving Rtp data without sending Rtcp data is seen as a privacy concern and is not allowed.
 /// </remarks>
 /// <param name="multicastEP">Rtp endpoint, Rtcp endpoint will be derived from it</param>
 /// <param name="participant">Person joining the session</param>
 /// <param name="rtpTraffic">Flag indicating whether or not to monitor or allow sending of Rtp traffic</param>
 /// <param name="receiveData">Flag indicating whether or not to monitor any incoming data</param>
 public RtpSession(IPEndPoint multicastEP, RtpParticipant participant, bool rtpTraffic, bool receiveData)
     : this(multicastEP, participant, rtpTraffic, receiveData, null)
 {
 }
Esempio n. 12
0
 private void RaiseParticipantTimeoutEvent(RtpParticipant participant)
 {
     object[] args = {this, new RtpEvents.RtpParticipantEventArgs(participant)};
     EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(Events.RaiseRtpParticipantTimeoutEvent), args);
 }
Esempio n. 13
0
 internal void RaiseParticipantRemovedEvent(RtpParticipant participant)
 {
     object[] args = {this, new RtpEvents.RtpParticipantEventArgs(participant)};
     EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(Events.RaiseRtpParticipantRemovedEvent), args);
 }
Esempio n. 14
0
 public void AddPendingParticipant(RtpParticipant participant)
 {
     fPendingParticipants.Enqueue(participant);
 }