Esempio n. 1
0
        internal void AddReceiverReport(CompoundPacketBuilder cpb)
        {
            // Update the values
            rr.SSRC         = ssrc;
            rr.PacketsLost  = packetsLost;
            rr.FractionLost = (byte)((float)packetsLost / (float)(packetsReceived + packetsLost) * 100F);

            // TODO - figure out how to calculate / interpret these values, especially Seq - JVE
//            rr.Jitter = ?;
//            rr.LastSenderReport = ?;
//            rr.DelaySinceLastSenderReport = ?;
//            rr.ExtendedHighestSequence = ?;

            cpb.Add_ReceiverReport(rr);
        }
Esempio n. 2
0
        internal void AddReceiverReport(CompoundPacketBuilder cpb)
        {
            // Update the values
            rr.SSRC        = ssrc;
            rr.PacketsLost = packetsLost;

            // andrew: this is obviously not what the spec says, but it's easier to compute and
            //  to use for diagnostics...
            rr.ExtendedHighestSequence = packetsReceived;

            // andrew: this also is incorrect: the spec says this should be calculated per
            // interval rather than per session
            rr.FractionLost = (byte)((float)packetsLost / (float)(packetsReceived + packetsLost) * 100F);

            // TODO - figure out how to calculate / interpret these values, especially Seq - JVE
//            rr.Jitter = ?;
//            rr.LastSenderReport = ?;
//            rr.DelaySinceLastSenderReport = ?;
//            rr.ExtendedHighestSequence = ?;

            cpb.Add_ReceiverReport(rr);
        }
Esempio n. 3
0
        /// <summary>
        /// Collects the Rtcp data from the session, assembles it into CompoundPackets (via the
        /// CompoundPacketBuilder) and sends the packets
        ///
        /// The current design has a "forced" Send occurring on the thread that makes the call, and
        /// a normal Send occurring on the dedicated RtcpSender thread.
        ///
        /// To make sure that multiple threads aren't making the call at the same time, which can
        /// lead to data access exceptions (e.g. Queue empty), we lock here.
        /// </summary>
        /// <param name="forced">Is Send being called due to timing rules, or forced?</param>
        private void Send(bool forced)
        {
            lock (this)
            {
                try
                {
                    // We're Sending despite timing rules
                    if (forced)
                    {
                        lastSendForced = true;
                    }
                    else // We're Sending due to timing rules
                    {
                        // The timing rules may now be in conflict with a previous forced Send
                        // Ask the timing rules to reconsider again before Sending
                        if (lastSendForced)
                        {
                            lastSendForced = false;
                            return;
                        }
                    }

                    CompoundPacketBuilder cpb = rtpSession.RtcpReportIntervalReached();
                    cpb.BuildCompoundPackets();

                    Debug.Assert(cpb.PacketCount > 0);

                    // Send all compound packets (in case there is more than 1)
                    short packetCount = cpb.PacketCount;
                    int   bytes       = 0;

                    foreach (CompoundPacket cp in cpb)
                    {
                        BufferChunk data = cp.Data;
                        bytes += data.Length;
                        rtcpNetworkSender.Send(data);

                        if (diagnosticSender != null)
                        {
                            // andrew: send a "carbon-copy" to the diagnostic server
                            // this is done over unicast to avoid entangling diagnosis with multicast
                            diagnosticSender.Send(data);
                        }
                    }

                    // How long between the last send time and now
                    TimeSpan interval = DateTime.Now - lastSendTime;

                    // Update lastSendTime
                    lastSendTime = DateTime.Now;

                    // Update performance data
                    // Packets before bytes, since packets doesn't have any dependencies
                    // but BytesPerPacket requires a correct reading on the packet count
                    UpdatePerformancePackets(packetCount);
                    UpdatePerformanceBytes(bytes);
                    UpdatePerformanceInterval(interval, forced);
                }
                catch (ThreadAbortException) {}
                catch (Exception e)
                {
                    // AAA debugging only
                    System.Console.WriteLine(e.StackTrace);

                    if (e is System.Net.Sockets.SocketException)
                    {
                        Object[] args = new Object[] { this, new RtpEvents.HiddenSocketExceptionEventArgs((RtpSession)rtpSession,
                                                                                                          (System.Net.Sockets.SocketException)e) };
                        EventThrower.QueueUserWorkItem(new RtpEvents.RaiseEvent(RtpEvents.RaiseHiddenSocketExceptionEvent), args);
                    }

                    rtpSession.LogEvent("RtcpSender", e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error);
                }
            }
        }