[ekiga] Call: Added new RTCP-based statistics subsystem.
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga] Call: Added new RTCP-based statistics subsystem.
- Date: Sat, 3 Jan 2015 16:32:39 +0000 (UTC)
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]