Example #1
0
        /// <summary>
        /// Called by RtcpSender when it is time to collect Rtcp data
        /// </summary>
        /// <returns>A CompoundPacketBuilder</returns>
        CompoundPacketBuilder RtcpSender.IRtpSession.RtcpReportIntervalReached()
        {
            // Limit the frequency of the cleanup in order to avoid participants and streams being
            // inappropriately designated as stale.  This can happen if we start up a lot of senders at once.
            // Each sender triggers an RTCP packet which without the frequency limitation could 
            // increment the stale counter to its limit and cause the participant or stream to be removed.
            bool cleanUpNow = false;
            if (DateTime.Now > this.lastCleanUp.AddSeconds(5)) {
                cleanUpNow = true;
                this.lastCleanUp = DateTime.Now;
            }

            // A stale participant is one who is not sending Rtcp data
            if (cleanUpNow)
                CheckForStaleParticipants();

            // Add participant data
            Debug.Assert(participant.SSRC != 0);
            cpb.ParticipantData(participant);

            // Add Rtp data
            if(rtpTraffic)
            {
                // A stale stream is one not sending Rtp traffic
                if (cleanUpNow)
                    CheckForStaleStreams();

                // Collect SenderReportPackets and SDESReports from each Sender
                lock(rtpSenders)
                {

                    foreach(RtpSender sender in rtpSenders.Values)
                    {
                        // this adds the SR and SDES packets
                        sender.UpdateRtcpData();
                    }
                }

                // add a sdes (source description)
                //cpb.Add_SDESReport(participant.SSRC, participant);

                // Collect ReceiverReports from each of the streams
                lock(streamsAndIPs)
                {
                    foreach(IPStreamPairHashtable.IPStreamPair ipsp in streamsAndIPs.Values)
                    {
                        if( ipsp.stream != null )
                        {
                            ipsp.stream.AddReceiverReport(cpb);
                        }
                    }
                }
            }



#if USE_APP_PACKET
            // andrew: Add an app packet that reflects the time and the current venue...
            if ((VenueName != null) && (this.groupEP != null))
            {
                string appPayload = VenueName + "#" + this.groupEP.Address.ToString();
                long time = DateTime.Now.Ticks;
                // 8  bytes for time + venue name
                int count = 8 + utf8.GetByteCount(appPayload);

                // count must be 4-byte alligned
                int mod = count % 4;
                if (mod != 0)
                {
                    count += (4 - mod);
                }

                BufferChunk buffer = new BufferChunk(count);
                buffer.Reset(0, count);
                buffer.Clear();

                buffer.SetInt64(0, time);
                buffer.SetUTF8String(8, appPayload);
                byte[] rawBytes = buffer.Buffer;

                cpb.Add_APPReport(participant.SSRC, Rtcp.APP_PACKET_NAME, Rtcp.VENUE_APP_PACKET_SUBTYPE, rawBytes);
            }
#endif
            return cpb;
        }