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 }
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); }
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); }
public RtpParticipantEventArgs(RtpParticipant participant) { RtpParticipant = participant; }
protected virtual void JoinRtpSession(string ID, string name) { fSessionParticipant = new RtpParticipant(ID, name); fSession = new RtpSession(gSessionEndPoint, fSessionParticipant, true, true); }
protected virtual void JoinRtpSession(string name) { RtpParticipant participant = new RtpParticipant(name, name); rtpSession = new RtpSession(gSessionEndPoint, participant, true, true); }
/// <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); } } }
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); } }
/// <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); } } }
/// <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(); }
/// <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) { }
private void RaiseParticipantTimeoutEvent(RtpParticipant participant) { object[] args = {this, new RtpEvents.RtpParticipantEventArgs(participant)}; EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(Events.RaiseRtpParticipantTimeoutEvent), args); }
internal void RaiseParticipantRemovedEvent(RtpParticipant participant) { object[] args = {this, new RtpEvents.RtpParticipantEventArgs(participant)}; EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(Events.RaiseRtpParticipantRemovedEvent), args); }
public void AddPendingParticipant(RtpParticipant participant) { fPendingParticipants.Enqueue(participant); }