SdesData structure, used extensively among Rtcp and Rtp objects to describe the common properties associated with the Rtp data / Rtcp Participant. See RFC 3550 for definitions on the data it contains.
상속: RtcpData
예제 #1
0
        /// <summary>
        /// Called when an SdesPacket arrives with an ID (CNAME) that no other session Participant has
        /// </summary>
        /// <param name="rtcp">SdesData containing the information for the participant</param>
        /// <param name="ipAddress">IpAddress this participant originates from</param>
        internal RtpParticipant(SdesData data, IPAddress ipAddress) 
            : base(data)
        {
            this.ipAddress = ipAddress;
            this.ssrcs = new List<uint>();
            this.stale = 0;

            SetPrivateExtension(Rtcp.PEP_SOURCE, Rtcp.PED_PARTICIPANT);
        }
예제 #2
0
        /// <summary>
        /// Constructs an SdesData instance by reading its properties from another instance 
        /// </summary>
        /// <param name="data"></param>
        public SdesData(SdesData sdes)
        {
            // Skip the first index - see comments for member variable 'data'
            for (int i = 1; i < sdes.data.Length; i++)
            {
                byte[] data = sdes.data[i];

                if (data != null)
                {
                    byte[] copy = new byte[data.Length];
                    data.CopyTo(copy, 0);
                    data = copy;
                }

                this.data[i] = data;
            }

            foreach (DictionaryEntry de in sdes.privs)
            {
                SetPrivateExtension((byte[])de.Key, (byte[])de.Value);
            }

        }
예제 #3
0
 internal SdesReport(uint ssrc, SdesData sdes)
 {
     this.ssrc = ssrc;
     this.sdes = sdes;
 }
예제 #4
0
        /// <summary>
        /// This method is called to update the local data from another SdesData
        /// </summary>
        /// <param name="data">what we want to update our data to</param>
        /// <returns>true if the local data was updated, otherwise false</returns>
        internal bool UpdateData(SdesData sdes)
        {
            bool ret = false;

            // Well-known properties
            // CName can never be updated, so start with Name
            for (int id = (int)SDESType.NAME; id <= (int)SDESType.NOTE; id++)
            {
                if (!data[id].Compare(sdes.data[id]))
                {
                    data[id] = sdes.data[id].Copy();
                    ret = true;
                }
            }

            // Write private properties
            foreach (DictionaryEntry de in sdes.privs)
            {
                byte[] key = (byte[])de.Key;
                byte[] data = (byte[])de.Value;

                if (!privs.Contains(key) || !data.Compare(privs[key]))
                {
                    privs[key.Copy()] = data.Copy();
                    ret = true;
                }
            }

            return ret;
        }
예제 #5
0
 internal RtpStreamFec(RtpListener rtpListener, uint ssrc, SdesData sdes, PayloadType pt)
     : base(rtpListener.ReturnBufferCallback, ssrc, sdes, pt)
 {
     this.getBufferHandler = rtpListener.GetBufferCallback;
 }
예제 #6
0
 internal RtpStreamFFec(RtpListener rtpListener, uint ssrc, SdesData sdes, PayloadType pt, ushort fecPxExp)
     : base(rtpListener, ssrc, sdes, pt)
 {
     fecPercent = fecPxExp;
     pcFecType = 2;
 }
예제 #7
0
        internal RtpStreamCFec(RtpListener rtpListener, uint ssrc, SdesData sdes, PayloadType pt, ushort dataPxExp, ushort fecPxExp)
            : base(rtpListener, ssrc, sdes, pt)
        {
            pcFecType = 1;

            this.dataPxExp = dataPxExp;
            this.fecPxExp = fecPxExp;

            SetDecoder();
            InitializeDCRStorage();
        }
예제 #8
0
 private void AddSdes(uint ssrc, SdesData sdes)
 {
     cpb.Add_SDESReport(ssrc, sdes);
 }
예제 #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);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Called to create a stream via Rtcp and have all the "links" created
        /// 
        /// CXP always stores the Participant ssrc/SdesData first in the SdesPacket.  So a
        /// participant should always exist before the stream is created in this code.
        /// 
        /// AddStream is called by the RtcpListener thread via ProcessSdesPacket
        /// </summary>
        private void AddOrUpdateStream(uint ssrc, SdesData sdes)
        {
            lock(participants)
            {
                lock(streamsAndIPs)
                {
                    RtpParticipant participant = participants[sdes.CName];
                    if(participants[sdes.CName] == null)
                    {
                        Debug.Assert(false);
                        throw new InvalidOperationException(Strings.CantCreateAStreamNoParticipant);
                    }

                    IPStreamPair ipsp = streamsAndIPs[ssrc];
                    Debug.Assert(ipsp != null);

                    if(ipsp.stream == null)
                    {
                        ipsp.stream = RtpStream.CreateStream(rtpListener, ssrc, sdes);

                        ssrcToParticipant[ssrc] = participant;
                        participant.AddSSRC(ssrc);

                        RaiseRtpStreamAddedEvent(ipsp.stream);
                    }
                    else // Update
                    {
                        ipsp.stream.Stale = 0;
                        ipsp.stream.Properties.UpdateData(sdes);
                    }
                }
            }
        }
예제 #11
0
 void RtpSender.IRtpSession.AddSdes(uint ssrc, SdesData sdes)
 {
     AddSdes(ssrc, sdes);
 }
예제 #12
0
 /// <summary>
 /// Raises the ParticipantStatusChanged event if the data changed
 /// </summary>
 /// <param name="data"></param>
 internal new void UpdateData(SdesData data)
 {
     if(base.UpdateData(data))
     {
         object[] args = {this, new RtpEvents.RtpParticipantEventArgs(this)};
         EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(RtpEvents.RaiseRtpParticipantDataChangedEvent), args);
     }
 }