コード例 #1
0
ファイル: RTPConnection.cs プロジェクト: zhujingcheng/CP3
 public RTPSendConnection(IPEndPoint ipe)
 {
     this.m_Participant = new RtpParticipant(Guid.NewGuid().ToString(), "Classroom Playback");
     this.m_Session     = new RtpSession(ipe, this.m_Participant, true, false);
     this.m_Sender      = this.m_Session.CreateRtpSenderFec("Classroom Presenter", PayloadType.dynamicPresentation, null, 0, 100);
     this.m_Queue       = new SendingQueue(this);
 }
コード例 #2
0
 protected override void Dispose(bool disposing)
 {
     base.Dispose(disposing);
     if (disposing)
     {
         m_Disposing = true;
         m_SendQueueWait.Set();
         this.m_BeaconService.Dispose();
         if (m_RtpSender != null)
         {
             m_RtpSender.Dispose();
             m_RtpSender = null;
         }
         if (m_RtpSession != null)
         {
             try {
                 m_RtpSession.Dispose();
             }
             catch { }
             m_RtpSession = null;
         }
         m_RtpParticipant = null;
         if (m_SendThread != null)
         {
             if (!m_SendThread.Join(5000))
             {
                 m_SendThread.Abort();
             }
         }
     }
 }
コード例 #3
0
        static void Main(string[] args)
        {
            RtpParticipant part = new RtpParticipant("*****@*****.**", "SENDER");

            RtpSession session = new RtpSession(ip, part, true, true);

            session.PacketTransform = new EncryptionTransform("You are a big freak!");
            //session.PacketTransform = new XorTransform();


            RtpSender sender = session.CreateRtpSender("My sender", PayloadType.Test, null);

            Stream fs     = File.OpenRead("data.txt");
            int    length = (int)fs.Length;

            Console.Out.WriteLine("Opening file of length: " + length);

            byte[] buffer = new byte[length];

            int bytesRead = 0;

            while (bytesRead < length)
            {
                bytesRead += fs.Read(buffer, bytesRead, Math.Min(16384, (length - bytesRead)));
            }

            for (int i = 0; i < 5; i++)
            {
                Console.Out.WriteLine("Sending buffer to address: " + ip);

                sender.Send(buffer);

                Thread.Sleep(1000);
            }
        }
コード例 #4
0
        /// <summary>
        /// Starts recording a conference. Sets up the conference data and then records all streams received until told to stop.
        /// </summary>
        public void RecordConference(string conferenceDescription, string venueIdentifier, IPEndPoint venue)
        {
            if (conferenceDescription.Length >= Constants.MaxDBStringSize || venueIdentifier.Length >= Constants.MaxDBStringSize)
            {
                throw new ArgumentException("String longer than accepted by database.");
            }

            recording = true;
            venueIPE  = venue;

            streams      = new Hashtable(Constants.InitialStreams);
            participants = new Hashtable();

            conferenceID = DBHelper.CreateConference(conferenceDescription, venueIdentifier, DateTime.Now);

            // Store info about this conference to the instance, for debugging reference (mostly)
            this.conferenceDescription = conferenceDescription;
            this.venueIdentifier       = venueIdentifier;
            this.venue = venue;

            // Create our performance counter
            perfCounter = new ConferenceRecorderPC(venueIdentifier + " : " + conferenceDescription);

            // Set up RTCP properties
            RtpEvents.RtpParticipantAdded += new MSR.LST.Net.Rtp.RtpEvents.RtpParticipantAddedEventHandler(this.OnNewRtpParticipant);
            RtpEvents.RtpStreamAdded      += new MSR.LST.Net.Rtp.RtpEvents.RtpStreamAddedEventHandler(this.OnNewRtpStream);
            RtpEvents.RtpStreamRemoved    += new MSR.LST.Net.Rtp.RtpEvents.RtpStreamRemovedEventHandler(this.OnRtpStreamRemoved);

            // Start listening
            RtpParticipant rtpMe = new RtpParticipant(Constants.PersistenceCName, Constants.PersistenceName + " (RECORDING)");

            rtpSession = new RtpSession(venue, rtpMe, true, true);
        }
コード例 #5
0
ファイル: RTPConnection.cs プロジェクト: zhujingcheng/CP3
 public RTPReceiveConnection(IPEndPoint ip, NetworkArchiver na)
 {
     RtpEvents.RtpStreamAdded   += new MSR.LST.Net.Rtp.RtpEvents.RtpStreamAddedEventHandler(this.handleRtpStreamAdded);
     RtpEvents.RtpStreamRemoved += new MSR.LST.Net.Rtp.RtpEvents.RtpStreamRemovedEventHandler(this.handleRtpStreamRemoved);
     this.m_Participant          = new RtpParticipant("Recorder", "Recorder");
     this.m_Session              = new RtpSession(ip, this.m_Participant, true, true);
     this.m_archiver             = na;
 }
コード例 #6
0
        public SimpleTest()
        {
            // Create participant
            RtpParticipant rtpParticipant = null;

            //rtpParticipant.SetTool(true);

            // Create session with Participant and Rtp data
            rtpSession = new RtpSession(new IPEndPoint(IPAddress.Parse(addr), rtpPort),
                                        rtpParticipant, false, true);
        }
コード例 #7
0
ファイル: RTPMessageSender.cs プロジェクト: zhujingcheng/CP3
            /// <summary>
            /// Creates a <see cref="ParticipantModel"/> and <see cref="RTPMessageReceiver"/>
            /// whenever a new stream is connected to the venue.  The <see cref="ParticipantModel"/>
            /// is added to the current <see cref="ClassroomModel"/>.
            /// </summary>
            private void HandleStreamAdded(object sender, RtpEvents.RtpStreamEventArgs args)
            {
                using (Synchronizer.Lock(this.m_Sender.m_Classroom.SyncRoot)) {
                    using (Synchronizer.Lock(this)) {
                        if (this.m_Disposed)
                        {
                            throw new ObjectDisposedException("RTPMessageSender");
                        }

                        RtpStream stream = args.RtpStream;

                        // Ignore streams that are not part of our session.
                        if (this.m_Sender.m_RtpSession.ContainsStream(stream))
                        {
                            // Ignore streams that are not DynamicPresentations.
                            if (stream.PayloadType == PayloadType.dynamicPresentation)
                            {
                                // Ignore our own stream, but create a listener for all others.
                                if (stream.SSRC != this.m_Sender.m_RtpSender.SSRC)
                                {
                                    // If we've not seen this client before, create a new ParticipantModel,
                                    // identified by the participant's CName, which, if the participant
                                    // is running Classroom Presenter, is a Guid string.
                                    string cname = stream.Properties.CName;

                                    // It's possible for a participant to generate more than one Rtp stream,
                                    // so we need to keep a different table for m_Participants than m_Receivers.
                                    ParticipantModel participant = ((ParticipantModel)this.m_Participants[cname]);
                                    if (participant == null)
                                    {
                                        // Also get the remote client's HumanName from the participant data.
                                        RtpParticipant client = this.m_Sender.m_RtpSession.Participants[cname];
                                        participant = new ParticipantModel(new Guid(cname), client.Name);
                                        // Add the participant to our table.
                                        this.m_Participants.Add(cname, participant);
                                    }

                                    // Add the participant to the classroom if it is not already a member.
                                    if (!this.m_Sender.m_Classroom.Participants.Contains(participant))
                                    {
                                        this.m_Sender.m_Classroom.Participants.Add(participant);
                                    }

                                    // Create a receiver for this specific stream (there may be more than one stream per participant)
                                    // and add it to the table of receivers so it can be disposed when the stream is removed.
                                    RTPMessageReceiver receiver = new RTPMessageReceiver(this.m_Sender, stream,
                                                                                         this.m_Sender.m_Model, this.m_Sender.m_Classroom, participant);
                                    this.m_Receivers.Add(stream, receiver);
                                }
                            }
                        }
                    }
                }
            }
コード例 #8
0
        public UnicastToMulticastBridge(PresenterModel model)
        {
            GetConfig();

            //Prepare for RTP sending
            m_RtpParticipant = new RtpParticipant(m_Cname, m_Name);
            try {
                m_RtpSession = new RtpSession(m_MulticastEndpoint, m_RtpParticipant, true, false);
            }
            catch (Exception e) {
                Trace.WriteLine(e.ToString());
                m_RtpSession     = null;
                m_RtpParticipant = null;
                return;
            }

            try {
                /// Notes about FEC:  There are two types supported by the MSR RTP stack:  Frame-based and Packet-based.
                /// Setting cDataPx to zero forces frame-based.  In this case cFecPx is a percentage.  It must be greater than zero, but can be
                /// very large, eg. 1000.  Frame-based FEC appears to be better for large frames (which the stack splits into multiple packets)
                /// possibly because the FEC packets for the frame are not interlaced in time sequence with the frame packets.
                /// If cDataPx is not zero, packet-based FEC is used.  In this mode cDataPx and cFecPx are a ratio of data packets to fec packets.
                /// For single packet frames, 1:1 and 0:100 are identical.  Single packet frames are frames smaller than
                /// the MTU which is normally 1500 bytes.  Presenter's Chunk encoder creates frames up to 16kbytes.  Many frames are smaller
                /// than this, but only a few are below the MTU.  For this reason we will always use Frame-based FEC.  Usful values are expected to
                /// be from around 10 up to around 100.  More than 100 might be good in some cases, but might impact performance.
                /// More than 500 would probably never be advised.
                m_RtpSender = m_RtpSession.CreateRtpSenderFec("Classroom Presenter Unicast to Multicast Bridge", PayloadType.dynamicPresentation, null, 0, m_Fec);
                m_RtpSender.DelayBetweenPackets = m_InterpacketDelay;
            }
            catch (Exception e) {
                Trace.WriteLine(e.ToString());
                try {
                    m_RtpSession.Dispose();
                }
                catch { }
                m_RtpParticipant = null;
                m_RtpSession     = null;
                m_RtpSender      = null;
                return;
            }

            //Prepare the beacon
            this.m_ChunkSequence = 0;
            this.m_Encoder       = new Chunk.ChunkEncoder();
            this.m_BeaconService = new Beacons.BridgeBeaconService(this, model);

            //Prepare the queue and sending thread
            m_Disposing     = false;
            m_SendQueueWait = new EventWaitHandle(false, EventResetMode.AutoReset);
            m_SendQueue     = new PriorityQueue <BridgeMessage>();
            m_SendThread    = new Thread(new ThreadStart(SendThread));
            m_SendThread.Start();
        }
コード例 #9
0
        internal void Receive(object data, RtpParticipant rtpParticipant)
        {
            //Drop messages received from the local node
            if (this.m_Capability.RtpSender.RtcpProperties.CName.Equals(rtpParticipant.CName))
            {
                return;
            }

            //If this is the first message from a given node, attempt to create the receiver for it.
            if (!this.m_Receivers.ContainsKey(rtpParticipant.CName))
            {
                if (data is CapabilityMessageWrapper)
                {
                    Guid             sender_id            = ((CapabilityMessageWrapper)data).SenderId;
                    bool             sender_is_instructor = ((CapabilityMessageWrapper)data).SenderIsInstructor;
                    ParticipantModel participant          = new ParticipantModel(sender_id, rtpParticipant.Name);
                    m_Participants.Add(rtpParticipant.CName, participant);

                    //Add to classroom if the local node is instructor
                    if (m_Capability.IsSender)
                    {
                        using (Synchronizer.Lock(m_Classroom.SyncRoot)) {
                            this.m_Classroom.Participants.Add(participant);
                        }
                    }
                    this.m_SsrcToSenderId.Add(rtpParticipant.SSRC, sender_id);
                    this.m_Receivers.Add(rtpParticipant.CName, new CXPCapabilityMessageReceiver(this, rtpParticipant.SSRC, m_Model, m_Classroom, participant));

                    //Set the Network Association only if local node is not an instructor, and the remote node is Instructor.
                    if ((!m_Capability.IsSender) && (sender_is_instructor))
                    {
                        m_AssociationCname = rtpParticipant.CName;
                        using (Synchronizer.Lock(this.m_Model.Network.SyncRoot)) {
                            this.m_Model.Network.Association = participant;
                        }
                    }

                    //Debug.WriteLine("Created new receiver on message receipt: ssrc=" + rtpParticipant.SSRC.ToString() + ";cname=" + rtpParticipant.CName);
                }
                else
                {
                    //Trace.WriteLine("Dropping message of type " + data.GetType().ToString() + " from " + rtpParticipant.CName + " because we don't yet have the sender's Guid.");
                    return;
                }
            }
            this.m_Receivers[rtpParticipant.CName].Receive(data);
        }
コード例 #10
0
        static void Main(string[] args)
        {
            RtpEvents.RtpStreamAdded += new RtpEvents.RtpStreamAddedEventHandler(OnNewRtpStream);


            RtpParticipant part = new RtpParticipant("*****@*****.**", "Receiver");

            session = new RtpSession(ip, part, true, true);
            //session.PacketTransform = new XorTransform();
            session.PacketTransform = new EncryptionTransform("You are a big freak!");

            // make sure this thing doesn't terminate
            while (true)
            {
                Thread.Sleep(10000);
            }
        }
コード例 #11
0
        /// <summary>
        /// Create a listener if there isn't already one for this endpoint.
        /// If we fail, write eventlog entry and return null.
        /// </summary>
        /// <param name="other">The other (possible) listener</param>
        /// <param name="venue">New IP endpoint to use</param>
        private RtpSession CreateListener(RtpSession other, UWVenue venue)
        {
            if (other != null)
            {
                if (CompareIPEndPoints(other.RtpEndPoint, venue.IpEndpoint))
                {
                    return(other);
                }
            }

            RtpParticipant p = new RtpParticipant(myCname, myFriendlyName);
            RtpSession     s;
            IPEndPoint     refEP;

            if (this.reflectorEnabled)
            {
                try
                {
                    refEP       = new IPEndPoint(System.Net.Dns.GetHostEntry(this.reflectorAddress).AddressList[0], this.reflectorPort);
                    s           = new RtpSession(venue.IpEndpoint, p, true, true, refEP);
                    s.VenueName = venue.Name;
                }
                catch (Exception e)
                {
                    eventLog.WriteEntry("Failed to create RtpSession with Reflector enabled. " + e.ToString(), EventLogEntryType.Error, 1002);
                    s = null;
                }
            }
            else
            {
                try
                {
                    s           = new RtpSession(venue.IpEndpoint, p, true, true);
                    s.VenueName = venue.Name;
                }
                catch (Exception e)
                {
                    eventLog.WriteEntry("Failed to create RtpSession. " + e.ToString(), EventLogEntryType.Error, 1002);
                    s = null;
                }
            }
            return(s);
        }
コード例 #12
0
ファイル: RTPMessageSender.cs プロジェクト: zhujingcheng/CP3
            private void HandleStreamRemoved(object sender, MSR.LST.Net.Rtp.RtpEvents.RtpStreamEventArgs args)
            {
                using (Synchronizer.Lock(this.m_Sender.m_Classroom.SyncRoot)) {
                    using (Synchronizer.Lock(this)) {
                        // Do not check (or care) whether the RTPMessageSender has been disposed,
                        // because we will get lots of RtpStreamRemoved events when the RtpSession is closed.

                        RtpStream stream = args.RtpStream;

                        RTPMessageReceiver receiver = ((RTPMessageReceiver)this.m_Receivers[stream]);
                        if (receiver != null)
                        {
                            receiver.Dispose();
                            this.m_Receivers.Remove(stream);
                        }

                        // Discard all pending Nacks so the NackManager doesn't keep nacking them forever.
                        this.m_Sender.NackManager.Discard(stream.SSRC, Range.UNIVERSE);

                        // If this was the last stream for the participant, unregister the ParticipantModel
                        // and remove it from the classroom.
                        string         cname  = stream.Properties.CName;
                        RtpParticipant client = this.m_Sender.m_RtpSession.Participants[cname];
                        if (client == null || client.SSRCs.Count <= 0)
                        {
                            ParticipantModel participant = ((ParticipantModel)this.m_Participants[cname]);
                            if (participant != null)
                            {
                                // Remove the participant from the classroom.
                                if (this.m_Sender.m_Classroom.Participants.Contains(participant))
                                {
                                    this.m_Sender.m_Classroom.Participants.Remove(participant);
                                }
                            }

                            // Remove the participant from the table.
                            this.m_Participants.Remove(cname);
                        }
                    }
                }
            }
コード例 #13
0
        private void OnNewRtpParticipant(object sender, RtpEvents.RtpParticipantEventArgs ea)
        {
            if (this.rtpSession != sender)
            {
                return;
            }

            RtpParticipant participant = ea.RtpParticipant;

            Trace.WriteLine("New participant: " + participant.CName);

            // we want to ignore ourselves
            if (participant.CName != Constants.PersistenceCName)
            {
                // Make sure this isn't someone who briefly lost connectivity.
                if (!participants.ContainsKey(participant.CName))
                {
                    string newPartName = participant.Name;
                    if (newPartName == null || newPartName == String.Empty)
                    {
                        newPartName = participant.CName;
                    }

                    int participantID = DBHelper.CreateParticipant(
                        conferenceID,
                        participant.CName,
                        newPartName);

                    participants.Add(participant.CName, new ParticipantWrapper(participant, participantID));
                }

                foreach (uint ssrc in participant.SSRCs)
                {
                    OnNewRtpStream(sender, new RtpEvents.RtpStreamEventArgs(rtpSession.Streams[ssrc]));
                }
            }
        }
コード例 #14
0
        private void OnNewRtpParticipant(object sender, RtpEvents.RtpParticipantEventArgs ea)
        {
            try {
                RtpParticipant participant = ea.RtpParticipant;

                eventLog.WriteEntry("OnNewRtpParticipant: " + participant.CName,
                                    EventLogEntryType.Information, ArchiveServiceEventLog.ID.Information);

                if (this.rtpSession != sender)
                {
                    eventLog.WriteEntry("OnNewRtpParticipant: this.rtpSession and sender don't match.",
                                        EventLogEntryType.Information, ArchiveServiceEventLog.ID.Information);
                    if (this.rtpSession == null)
                    {
                        //Note this can happen because participants are added during the rtpSession constructor!!
                        eventLog.WriteEntry("OnNewRtpParticipant: this.rtpSession is null.",
                                            EventLogEntryType.Information, ArchiveServiceEventLog.ID.Information);
                    }
                    if (sender == null)
                    {
                        eventLog.WriteEntry("OnNewRtpParticipant: sender is null.",
                                            EventLogEntryType.Information, ArchiveServiceEventLog.ID.Information);
                    }
                    //return;
                }

                //eventLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "New participant: {0}", participant.CName));

                // we want to ignore ourselves
                if (participant.CName != Constants.PersistenceCName)
                {
                    // Make sure this isn't someone who briefly lost connectivity.
                    if (!participants.ContainsKey(participant.CName))
                    {
                        string newPartName = participant.Name;
                        if (newPartName == null || newPartName == String.Empty)
                        {
                            newPartName = participant.CName;
                        }

                        int participantID = DBHelper.CreateParticipant(
                            conferenceID,
                            participant.CName,
                            newPartName);

                        participants.Add(participant.CName, new ParticipantWrapper(participant, participantID));

                        eventLog.WriteEntry("OnNewRtpParticipant completed participant Add.",
                                            EventLogEntryType.Information, ArchiveServiceEventLog.ID.Information);
                    }
                    else
                    {
                        eventLog.WriteEntry("OnNewRtpParticipant already in participants hashtable ",
                                            EventLogEntryType.Information, ArchiveServiceEventLog.ID.Information);
                    }

                    foreach (uint ssrc in participant.SSRCs)
                    {
                        if (this.rtpSession == null)
                        {
                            eventLog.WriteEntry("OnNewRtpParticipant: Failed to add streams because this.rtpSession is null.",
                                                EventLogEntryType.Warning, ArchiveServiceEventLog.ID.Warning);
                        }
                        else
                        {
                            OnNewRtpStream(this.rtpSession, new RtpEvents.RtpStreamEventArgs(rtpSession.Streams[ssrc]));
                        }
                    }
                }
                else
                {
                    eventLog.WriteEntry("OnNewRtpParticipant ignoring ourself. ",
                                        EventLogEntryType.Information, ArchiveServiceEventLog.ID.Information);
                }
            }
            catch (Exception e) {
                eventLog.WriteEntry("OnNewRtpParticipant exception: " + e.ToString(),
                                    EventLogEntryType.Warning, ArchiveServiceEventLog.ID.Warning);
            }
        }
コード例 #15
0
        public void Play(IPEndPoint venue, int[] streams, bool receiveData)
        {
            if (this.playing)
            {
                throw new InvalidOperationException(Strings.PlayerAlreadyPlayingError);
            }
            if (streams == null)
            {
                throw new ArgumentNullException(Strings.StreamsCannotBeNull);
            }

            venueIPE = venue;

            // Create an RtpSession
            RtpParticipant me = new RtpParticipant(Constants.PersistenceCName,
                                                   string.Format(CultureInfo.CurrentCulture, Strings.Playing, Constants.PersistenceName));

            rtpSession = new RtpSession(venue, me, true, receiveData);

            // andrew: connect to diagnostic server
            rtpSession.VenueName = "Archived: " + venue.ToString();

            // Hook the static stream-ended event
            StreamPlayer.EndOfStreamReached += new EventHandler(EndOfStreamReached);

            // Create a new perf counter for this ConferencePlayer instance
            this.perfCounter = new ConferencePlayerPC(venue.ToString());

            // Keep track of the streamPlayers
            ArrayList avStreams    = new ArrayList();
            ArrayList otherStreams = new ArrayList();

            // Find the first stored ticks of all the streams while creating them...
            this.firstStoredTick = long.MaxValue;

            // Create all of our StreamPlayers (one per stream...)
            for (int i = 0; i < streams.Length; i++)
            {
                StreamPlayer newStream = null;

                try
                {
                    newStream = new StreamPlayer(rtpSession, streams[i], perfCounter);
                }
                catch (Exception ex)
                {
                    eventLog.WriteEntry(String.Format(CultureInfo.CurrentCulture, Strings.StreamWithBadDataReached,
                                                      streams[i], ex.ToString()), EventLogEntryType.Warning,
                                        ArchiveServiceEventLog.ID.BadStreamInDB);
                }

                if (newStream != null)
                {
                    perfCounter.AddInstanceForCollection(newStream);

                    if (newStream.FirstStreamsTicks < this.firstStoredTick)
                    {
                        this.firstStoredTick = newStream.FirstStreamsTicks;
                    }

                    // Add the new StreamPlayer to the right collection
                    // Pri3: Consider other methods here.  Maybe a smarter detection of large frame sizes,
                    //  or initializing the stream so it has enough packets ahead of time?
                    if (newStream.Payload == PayloadType.dynamicAudio || newStream.Payload == PayloadType.dynamicVideo)
                    {
                        avStreams.Add(newStream);
                    }
                    else // RTDocs stream or other large-payload stream, most likely
                    {
                        otherStreams.Add(newStream);
                    }
                }
            }

            // Start the StreamsGroupPlayers
            // Pri2: Change this to be compatable with use of the "playback speed" feature.
            long startTime = DateTime.Now.Ticks + 1500 * Constants.TicksPerMs; // we'll start in 1.5 seconds (for init time)

            // Create the StreamsGroupPlayer(s)
            avPlayer    = new StreamsGroupPlayer(avStreams, this.firstStoredTick, startTime);
            otherPlayer = new StreamsGroupPlayer(otherStreams, this.firstStoredTick, startTime);

            this.playing = true;
        }
コード例 #16
0
        private void JoinRtpSession()
        {
            RtpParticipant participant = new RtpParticipant("Video" + pb1.Handle.ToInt32(), "Video");

            rtpSession = new RtpSession(ep, participant, true, true);
        }
コード例 #17
0
 public ParticipantWrapper(RtpParticipant participant, int id)
 {
     this.participant = participant;
     participantID    = id;
 }