[ekiga] Call: Added new RTCP-based statistics subsystem.



commit 983d88105ed64303d2dae269c4c7ae3f67a4f53e
Author: Damien Sandras <dsandras seconix com>
Date:   Sat Jan 3 17:16:13 2015 +0100

    Call: Added new RTCP-based statistics subsystem.
    
    The main new thing is that we also display remote statistics like the
    remote jitter (if provided in the RTCP data).

 lib/engine/components/opal/opal-call.cpp |  162 +++++++++++++++---------------
 lib/engine/components/opal/opal-call.h   |   57 ++---------
 lib/engine/protocol/call.h               |   45 +--------
 lib/engine/protocol/rtcp-statistics.h    |   73 +++++++++++++
 4 files changed, 167 insertions(+), 170 deletions(-)
---
diff --git a/lib/engine/components/opal/opal-call.cpp b/lib/engine/components/opal/opal-call.cpp
index 8f9c69a..3d8e751 100644
--- a/lib/engine/components/opal/opal-call.cpp
+++ b/lib/engine/components/opal/opal-call.cpp
@@ -49,6 +49,7 @@
 #include "notification-core.h"
 #include "call-core.h"
 #include "runtime.h"
+#include "known-codecs.h"
 
 using namespace Opal;
 
@@ -98,21 +99,8 @@ private:
 Opal::Call::Call (Opal::CallManager& _manager,
                  const std::string& uri)
   : OpalCall (_manager), Ekiga::Call (), manager(_manager), remote_uri (uri),
-    call_setup(false), jitter(0), outgoing(false)
-{
-  re_a_bytes = tr_a_bytes = re_v_bytes = tr_v_bytes = 0.0;
-  last_v_tick = last_a_tick = PTime ();
-  total_a =
-    total_v =
-    lost_a =
-    too_late_a =
-    out_of_order_a =
-    lost_v =
-    too_late_v =
-    out_of_order_v = 0;
-  lost_packets = late_packets = out_of_order_packets = 0.0;
-  re_a_bw = tr_a_bw = re_v_bw = tr_v_bw = 0.0;
-
+    call_setup(false), outgoing(false)
+{
   NoAnswerTimer.SetNotifier (PCREATE_NOTIFIER (OnNoAnswerTimeout));
 
   add_action (Ekiga::ActionPtr (new Ekiga::Action ("hangup", _("Hangup"),
@@ -350,6 +338,85 @@ Opal::Call::get_start_time () const
 }
 
 
+const RTCPStatistics &
+Opal::Call::get_statistics ()
+{
+  PSafePtr<OpalConnection> connection = get_remote_connection ();
+  if (connection == NULL)
+    return statistics;
+
+  OpalMediaStatistics re_a_statistics;
+  OpalMediaStatistics tr_a_statistics;
+  OpalMediaStatistics re_v_statistics;
+  OpalMediaStatistics tr_v_statistics;
+
+  OpalMediaStreamPtr stream = connection->GetMediaStream (OpalMediaType::Audio (), false); // Transmission
+  if (stream)
+    stream->GetStatistics (tr_a_statistics);
+  stream = connection->GetMediaStream (OpalMediaType::Audio (), true); // Reception
+  if (stream)
+    stream->GetStatistics (re_a_statistics);
+  stream = connection->GetMediaStream (OpalMediaType::Video (), false); // Transmission
+  if (stream)
+    stream->GetStatistics (tr_v_statistics);
+  stream = connection->GetMediaStream (OpalMediaType::Video (), true); // Reception
+  if (stream)
+    stream->GetStatistics (re_v_statistics);
+
+  for (PINDEX i = 0 ; KnownCodecs[i][0] ; i++) {
+    if (tr_a_statistics.m_mediaFormat == KnownCodecs[i][0])
+      statistics.transmitted_audio_codec = gettext (KnownCodecs[i][1]);
+    if (re_a_statistics.m_mediaFormat == KnownCodecs[i][0])
+      statistics.received_audio_codec = gettext (KnownCodecs[i][1]);
+    if (tr_v_statistics.m_mediaFormat == KnownCodecs[i][0])
+      statistics.transmitted_video_codec = gettext (KnownCodecs[i][1]);
+    if (re_v_statistics.m_mediaFormat == KnownCodecs[i][0])
+      statistics.received_video_codec = gettext (KnownCodecs[i][1]);
+  }
+
+  if (tr_a_statistics.m_startTime.IsValid ()) {
+    PTimeInterval t = (PTime () - tr_a_statistics.m_startTime);
+    if (t.GetSeconds () > 0)
+      statistics.transmitted_audio_bandwidth  = tr_a_statistics.m_totalBytes / t.GetSeconds () * 8 / 1024;
+    statistics.jitter = tr_a_statistics.m_averageJitter;
+  }
+
+  if (re_a_statistics.m_startTime.IsValid ()) {
+    PTimeInterval t = (PTime () - re_a_statistics.m_startTime);
+    if (t.GetSeconds () > 0)
+      statistics.received_audio_bandwidth  = re_a_statistics.m_totalBytes / t.GetSeconds () * 8 / 1024;
+    statistics.remote_jitter = re_a_statistics.m_averageJitter;
+  }
+
+  if (tr_v_statistics.m_startTime.IsValid ()) {
+    PTimeInterval t = (PTime () - tr_v_statistics.m_startTime);
+    if (t.GetSeconds () > 0) {
+      statistics.transmitted_video_bandwidth  = tr_v_statistics.m_totalBytes / t.GetSeconds () * 8 / 1024;
+      statistics.transmitted_fps = tr_v_statistics.m_totalFrames / t.GetSeconds ();
+    }
+  }
+
+  if (re_v_statistics.m_startTime.IsValid ()) {
+    PTimeInterval t = (PTime () - re_v_statistics.m_startTime);
+    if (t.GetSeconds () > 0) {
+      statistics.received_video_bandwidth  = re_v_statistics.m_totalBytes / t.GetSeconds () * 8 / 1024;
+      statistics.received_fps = re_v_statistics.m_totalFrames / t.GetSeconds ();
+    }
+  }
+
+  unsigned tr_total_packets = tr_a_statistics.m_totalPackets + tr_v_statistics.m_totalPackets;
+  unsigned tr_lost_packets = tr_a_statistics.m_packetsLost + tr_v_statistics.m_packetsLost;
+  unsigned re_total_packets = re_a_statistics.m_totalPackets + re_v_statistics.m_totalPackets;
+  unsigned re_lost_packets = re_a_statistics.m_packetsLost + re_v_statistics.m_packetsLost;
+
+  if (tr_total_packets > 0 && tr_total_packets > tr_lost_packets)
+    statistics.lost_packets = (unsigned) (100 * tr_lost_packets / tr_total_packets);
+  if (re_total_packets > 0 && re_total_packets > re_lost_packets)
+    statistics.lost_packets = (unsigned) (100 * re_lost_packets / re_total_packets);
+  return statistics;
+}
+
+
 bool
 Opal::Call::is_outgoing () const
 {
@@ -440,10 +507,7 @@ Opal::Call::OnEstablished (OpalConnection & connection)
 
       session = (OpalRTPSession*)PDownCast (OpalRTPConnection, &connection)->GetMediaSession 
(stream->GetSessionID ());
       if (session) {
-
         session->SetIgnorePayloadTypeChanges (TRUE);
-        session->SetRxStatisticsInterval(50);
-        session->SetTxStatisticsInterval(50);
       }
     }
 
@@ -452,10 +516,7 @@ Opal::Call::OnEstablished (OpalConnection & connection)
 
       session = (OpalRTPSession*)PDownCast (OpalRTPConnection, &connection)->GetMediaSession 
(stream->GetSessionID ());
       if (session) {
-
         session->SetIgnorePayloadTypeChanges (TRUE);
-        session->SetRxStatisticsInterval(50);
-        session->SetTxStatisticsInterval(50);
       }
     }
   }
@@ -671,65 +732,6 @@ Opal::Call::OnClosedMediaStream (OpalMediaStream & stream)
 
 
 void
-Opal::Call::OnRTPStatistics2 (const OpalConnection & /* connection */,
-                            const OpalRTPSession & session)
-{
-  PWaitAndSignal m(stats_mutex); // The stats are computed from two different threads
-
-  if (session.IsAudio ()) {
-
-    PTimeInterval t = PTime () - last_a_tick;
-    if (t.GetMilliSeconds () < 500)
-      return;
-
-    unsigned elapsed_seconds = max ((unsigned long) t.GetMilliSeconds (), (unsigned long) 1);
-    double octets_received = session.GetOctetsReceived ();
-    double octets_sent = session.GetOctetsSent ();
-
-    re_a_bw = max ((octets_received - re_a_bytes) / elapsed_seconds, 0.0);
-    tr_a_bw = max ((octets_sent - tr_a_bytes) / elapsed_seconds, 0.0);
-
-    re_a_bytes = octets_received;
-    tr_a_bytes = octets_sent;
-    last_a_tick = PTime ();
-
-    total_a = session.GetPacketsReceived ();
-    lost_a = session.GetPacketsLost ();
-    too_late_a = session.GetPacketsTooLate ();
-    out_of_order_a = session.GetPacketsOutOfOrder ();
-
-    jitter = session.GetJitterBufferSize () / max ((unsigned) session.GetJitterTimeUnits (), (unsigned) 8);
-  }
-  else {
-
-    PTimeInterval t = PTime () - last_v_tick;
-    if (t.GetMilliSeconds () < 500)
-      return;
-
-    unsigned elapsed_seconds = max ((unsigned long) t.GetMilliSeconds (), (unsigned long) 1);
-    double octets_received = session.GetOctetsReceived ();
-    double octets_sent = session.GetOctetsSent ();
-
-    re_v_bw = max ((octets_received - re_v_bytes) / elapsed_seconds, 0.0);
-    tr_v_bw = max ((octets_sent - tr_v_bytes) / elapsed_seconds, 0.0);
-
-    re_v_bytes = octets_received;
-    tr_v_bytes = octets_sent;
-    last_v_tick = PTime ();
-
-    total_v = session.GetPacketsReceived ();
-    lost_v = session.GetPacketsLost ();
-    too_late_v = session.GetPacketsTooLate ();
-    out_of_order_v = session.GetPacketsOutOfOrder ();
-  }
-
-  lost_packets = (lost_a + lost_v) / max ((unsigned long)(total_a + total_v), (unsigned long) 1);
-  late_packets = (too_late_a + too_late_v) / max ((unsigned long)(total_a + total_v), (unsigned long) 1);
-  out_of_order_packets = (out_of_order_a + out_of_order_v) / max ((unsigned long)(total_a + total_v), 
(unsigned long) 1);
-}
-
-
-void
 Opal::Call::DoSetUp (OpalConnection & connection)
 {
   OpalCall::OnSetUp (connection);
diff --git a/lib/engine/components/opal/opal-call.h b/lib/engine/components/opal/opal-call.h
index 431eec3..72badfc 100644
--- a/lib/engine/components/opal/opal-call.h
+++ b/lib/engine/components/opal/opal-call.h
@@ -35,6 +35,9 @@
  */
 
 
+#ifndef __OPAL_CALL_H__
+#define __OPAL_CALL_H__
+
 #include <opal/opal.h>
 #include <opal/call.h>
 #include <ep/pcss.h>
@@ -44,8 +47,6 @@
 #include "notification-core.h"
 #include "form-request-simple.h"
 
-#ifndef __OPAL_CALL_H__
-#define __OPAL_CALL_H__
 
 namespace Ekiga {
   class CallCore;
@@ -164,16 +165,9 @@ public:
 
     /* Implementation of inherited methods
     */
-
     bool is_outgoing () const;
-    double get_received_audio_bandwidth () const { return re_a_bw; }
-    double get_transmitted_audio_bandwidth () const { return tr_a_bw; }
-    double get_received_video_bandwidth () const { return re_v_bw; }
-    double get_transmitted_video_bandwidth () const { return tr_v_bw; }
-    unsigned get_jitter_size () const { return jitter; }
-    double get_lost_packets () const { return lost_packets; }
-    double get_late_packets () const { return late_packets; }
-    double get_out_of_order_packets () const { return out_of_order_packets; }
+
+    const RTCPStatistics & get_statistics ();
 
 
     /*
@@ -185,8 +179,6 @@ public:
 
     void OnClosedMediaStream (OpalMediaStream & stream);
 
-    void OnRTPStatistics2 (const OpalConnection & connection, const OpalRTPSession & session);
-
     void DoSetUp (OpalConnection & connection);
 
 private:
@@ -249,42 +241,6 @@ private:
 
     std::string forward_uri;
 
-    double re_a_bw;
-    double tr_a_bw;
-    double re_v_bw;
-    double tr_v_bw;
-    unsigned re_v_fps;
-    unsigned tr_v_fps;
-    unsigned tr_width;
-    unsigned tr_height;
-    unsigned re_width;
-    unsigned re_height;
-
-    unsigned jitter;
-
-    double lost_packets;
-    double late_packets;
-    double out_of_order_packets;
-
-    PMutex stats_mutex;
-    double re_a_bytes;
-    double tr_a_bytes;
-    double re_v_bytes;
-    double tr_v_bytes;
-
-    PTime last_a_tick;
-    PTime last_v_tick;
-    PTime start_time;
-
-    unsigned lost_a;
-    unsigned too_late_a;
-    unsigned out_of_order_a;
-    unsigned total_a;
-    unsigned lost_v;
-    unsigned too_late_v;
-    unsigned out_of_order_v;
-    unsigned total_v;
-
     bool outgoing;
 
 private:
@@ -296,6 +252,9 @@ private:
     void emit_ringing_in_main ();
     void emit_held_in_main ();
     void emit_retrieved_in_main ();
+
+    PTime start_time;
+    RTCPStatistics statistics;
   };
 };
 
diff --git a/lib/engine/protocol/call.h b/lib/engine/protocol/call.h
index 2a131c3..4b04238 100644
--- a/lib/engine/protocol/call.h
+++ b/lib/engine/protocol/call.h
@@ -46,6 +46,7 @@
 
 #include "actor.h"
 #include "live-object.h"
+#include "rtcp-statistics.h"
 
 namespace Ekiga
 {
@@ -155,47 +156,10 @@ namespace Ekiga
        */
       virtual bool is_outgoing () const = 0;
 
-      /** Return the received audio bandwidth
-       * @return the received audio bandwidth in kbytes/s
+      /** Return call statistics
+       * @return RTCPStatistcs
        */
-      virtual double get_received_audio_bandwidth () const = 0;
-
-      /** Return the transmitted audio bandwidth
-       * @return the transmitted audio bandwidth in kbytes/s
-       */
-      virtual double get_transmitted_audio_bandwidth () const = 0;
-
-      /** Return the received video bandwidth
-       * @return the received video bandwidth in kbytes/s
-       */
-      virtual double get_received_video_bandwidth () const = 0;
-
-      /** Return the transmitted video bandwidth
-       * @return the transmitted video bandwidth in kbytes/s
-       */
-      virtual double get_transmitted_video_bandwidth () const = 0;
-
-      /** Return the jitter size
-       * @return the jitter size in ms
-       */
-      virtual unsigned get_jitter_size () const = 0;
-
-      /** Return the lost packets information
-       * @return the lost packets percentage
-       */
-      virtual double get_lost_packets () const = 0;
-
-      /** Return the late packets information
-       * @return the late packets percentage
-       */
-      virtual double get_late_packets () const = 0;
-
-      /** Return the out of order packets information
-       * @return the out of order packets percentage
-       */
-      virtual double get_out_of_order_packets () const = 0;
-
-
+      virtual const RTCPStatistics & get_statistics () = 0;
 
       /*
        * Signals
@@ -266,7 +230,6 @@ namespace Ekiga
       /** This signal is emitted when the Call is removed.
        */
       boost::signals2::signal<void(void)> removed;
-     
     };
 
 /**
diff --git a/lib/engine/protocol/rtcp-statistics.h b/lib/engine/protocol/rtcp-statistics.h
new file mode 100644
index 0000000..d08c0bf
--- /dev/null
+++ b/lib/engine/protocol/rtcp-statistics.h
@@ -0,0 +1,73 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2015 Damien Sandras <dsandras seconix com>
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         rtp-statistics.h  -  description
+ *                         ------------------------------------------
+ *   begin                : Written in 2015 by Damien Sandras
+ *   copyright            : (c) 2015 by Damien Sandras
+ *   description          : Declaration of minimal statistics all components
+ *                          must support.
+ *
+ */
+
+
+#ifndef __RTCP_STATISTICS_H__
+#define __RTCP_STATISTICS_H__
+
+class RTCPStatistics {
+
+public:
+    RTCPStatistics () :
+        jitter (0),
+        remote_jitter (0),
+        received_fps (0),
+        transmitted_fps (0),
+        lost_packets (0),
+        remote_lost_packets (0) {};
+
+    /* Audio */
+    std::string transmitted_audio_codec;
+    unsigned transmitted_audio_bandwidth; // in kbits/s
+    std::string received_audio_codec;
+    unsigned received_audio_bandwidth; // in kbits/s
+    unsigned jitter; // in ms
+    unsigned remote_jitter; // in ms
+
+    /* Video */
+    std::string transmitted_video_codec;
+    unsigned transmitted_video_bandwidth; // in kbits/s
+    std::string received_video_codec;
+    unsigned received_video_bandwidth; // in kbits/s
+    unsigned received_fps;
+    unsigned transmitted_fps;
+
+    /* Total */
+    unsigned lost_packets;        // as a percentage
+    unsigned remote_lost_packets; // as a percentage
+};
+
+#endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]