示例#1
0
        private void AddByeReports(CompoundPacket cp)
        {
            while(!cpComplete && byeReports.Count > 0)
            {
                bool byepComplete = false;
                bool addedReport = false;

                ByePacket byep = new ByePacket();
        
                // Remove the size of the header + ssrc
                if(space >= byep.Size)
                {
                    space -= byep.Size;

                    // Add the rest
                    while(space >= Rtp.SSRC_SIZE && byeReports.Count > 0)
                    {
                        try
                        {
                            uint ssrc = (uint)byeReports.Peek();
                            byep.AddSSRC(ssrc);
                            byeReports.Dequeue();
                            
                            space -= Rtp.SSRC_SIZE;
                            addedReport = true;
                        }
                        catch(RtcpPacket.InsufficientItemSpaceException)
                        {
                            // No more room in bp for reports
                            byepComplete = true;
                            break;
                        }
                    }
                }

                // We broke out of the loop for one of 3 reasons
                // 1. There were no more byeReports
                // 2. There was no more room in bp
                // 3. There was no more room in cp (cpComplete)

                // If we added a report to bp, add bp to cp
                if(addedReport)
                {
                    int start = cp.Buffer.Length;
                    cp.AddPacket(byep);
                    int end = cp.Buffer.Length;

                    Debug.Assert( (end-start) == byep.Size ); // math check
                }

                // Figure out if we exited because cp is complete
                if(byeReports.Count > 0 && byepComplete == false)
                {
                    cpComplete = true;
                }
            }
        }
示例#2
0
 /// <summary>
 /// A ByePacket can contain multiple SSRCs so we need to process them in a loop
 /// </summary>
 /// <param name="packet">ByePacket</param>
 /// <param name="ipAddress">IPAddress packet was received from</param>
 private void ProcessBYEPacket(ByePacket packet, IPAddress ipAddress)
 {
     // Remove stream does a special form of AddSsrcToIp
     // to try and prevent mischievous programming
     foreach(uint ssrc in packet.SSRCs)
     {
         RemoveSSRC(ssrc, ipAddress);
     }
 }
示例#3
0
       private void Start()
       {
            //BufferChunk chunk = new BufferChunk(2048);
            CompoundPacket compoundPacket = new CompoundPacket();
            EndPoint endPoint = null;

            while (isRunning)
            {
                try
                {
                     compoundPacket.Reset();
                   udpListener.ReceiveFrom(compoundPacket.Buffer, out endPoint);

                    compoundPacket.ParseBuffer();
                    //IPAddress ipAddress = ((IPEndPoint)endPoint).Address;
                    IPEndPoint ipEndpoint = (IPEndPoint)endPoint;

                    // The compound packet enumerator destroys its list during enumeration,
                    // so we keep track of packets that have yet to be processed
                    IList<RtcpPacket> yetToBeProcessed = new List<RtcpPacket>();


                    String venueName = null;
                    //uint ssrc = 0;
                    long when = 0; // in units of "ticks"

                    // scan through the compound packet, looking for key pieces of meta-data
                    // first, look for the app packet that specifies the venue
                    // also, obtain the ssrc and the time stamp
                    
                    foreach (RtcpPacket packet in compoundPacket)
                    {
                        if (packet.PacketType == (byte)Rtcp.PacketType.APP)
                        {
                            AppPacket appPacket = new AppPacket(packet);
                            if (appPacket.Name.Equals(Rtcp.APP_PACKET_NAME) &&
                                appPacket.Subtype == Rtcp.VENUE_APP_PACKET_SUBTYPE)
                            {

                                BufferChunk chunk = new BufferChunk(appPacket.Data);
                                when = chunk.NextInt64();
                                venueName = chunk.NextUtf8String(chunk.Length);
                                int padIndex = venueName.IndexOf((char)0);
                                if (padIndex > 0)
                                    venueName = venueName.Substring(0, padIndex);
                            }
                        }
                        else
                        {
                            yetToBeProcessed.Add(packet);
                        }
                    }

                    if (venueName == null)
                        continue; // can't do anything if we don't know the venue for this packet
                    if (when == 0)
                        continue; // need a timestamp
                    
                    VenueState venueState = null;
                    
                    // compound operations must always be locked...
                    lock (venueStateMap)
                    {
                        if (!venueStateMap.ContainsKey(venueName))
                            venueState = new VenueState(venueName);
                        else venueState = venueStateMap[venueName];
                    }


                    // scan again, this time processing the RTCP packets
                    foreach (RtcpPacket packet in yetToBeProcessed)
                    {

                        switch (packet.PacketType)
                        {
                            case (byte)Rtcp.PacketType.SR:
                                {
                                    SrPacket sr = new SrPacket(packet);
                                    
                                    SenderData senderData = venueState.GetSenderState(sr.SSRC);
                                    senderData.Source = ipEndpoint;

                                    senderData.updateSenderState(sr.SenderReport, when);

                                    // this "refreshes" the host state (so that it won't expire)
                                    venueState.SenderData[sr.SSRC] = senderData;
                                    break;
                                }

                            case (byte)Rtcp.PacketType.RR:
                                {
                                    RrPacket rr = new RrPacket(packet);
                                    ReceiverData receiverData = venueState.GetReceiverData (ipEndpoint);

                                    // currently, we replace all receiver summaries with the data
                                    // from a single RR packet
                                    receiverData.updateReceiverState(rr.ReceiverReports, when, venueState);
                                        

                                    // this "refreshes" the host state (so that it won't expire)
                                    venueState.ReceiverData[ipEndpoint] = receiverData;
                                    break;
                                }

                            case (byte)Rtcp.PacketType.SDES:
                                {
                                    SdesPacket sdp = new SdesPacket(packet);                                   

                                    foreach(SdesReport report in sdp.Reports())
                                    {
                                        SenderData senderData = venueState.GetSenderState(report.SSRC);
                                        senderData.CName = report.SdesData.CName;
                                        senderData.Source = ipEndpoint;

                                        // this "refreshes" the host state (so that it won't expire)
                                        venueState.SenderData[report.SSRC] = senderData;

                                        ReceiverData receiverData = 
                                            venueState.GetReceiverDataWithoutCreating(ipEndpoint);

                                        if (receiverData != null)
                                            receiverData.CName = report.SdesData.CName;
                                    }
                                    break;
                                }

                            case (byte)Rtcp.PacketType.BYE:
                                {
                                    //BYE packets occur when capabilities stop.  Clean out sender data only for the
                                    //ssrc's affected.  We leave receiver reports alone for now.
                                    ByePacket byePacket = new ByePacket(packet);
                                    foreach (uint ssrc in byePacket.SSRCs) {
                                        venueState.SenderData.Remove(ssrc);
                                    }
                                    //Set a flag to cause the matrix for this venue to be rebuilt on the next request.
                                    venueState.ParticipantChange = true;
                                    continue;
                                }

                            case (byte)Rtcp.PacketType.APP:
                                {
                                    // ignored

                                    break;
                                }
                        }
                     }  // foreach packet...

                    // refresh the venue state
                     venueStateMap[venueName] = venueState;
                 }
                catch (Exception e)
                {
                    Console.Out.WriteLine("Exception : " + e.ToString());

                    writeEventLog("Exception in receive thread: " + e.ToString(), EventLogEntryType.Warning);
                }
            } // loop forever...
        }