Revision as of 10:09, December 13, 2018 by Xavier (talk | contribs)
Jump to: navigation, search

Audio statistics and MOS Calculation

This page describes the API to get audio statistics for current or recently completed call, what is included into that statistics, and how the derived metrics (such as MOS) are calculated.

typedef struct gs_call_statistics {
  int got_local_stat; // true if next 5 fields are valid (local stat available)
  float local_fraction_lost; // fraction of lost packets (not locally received)
  int      local_total_lost; // total lost packaged (calculated per RFC 3550)
  unsigned local_jitter;     // interarrival jitter
  unsigned local_PktCount;   // local packet count (number of RTP packets sent)
  unsigned local_OctCount;   // local octet count (number of bytes sent)
  int got_remote_SR; // true if next 2 fields valid (got remote Sender Report)
  unsigned remote_PktCount;  // remote packet count
  unsigned remote_OctCount;  // remote octet count
  int got_remote_RR; // true if next 3 fields valid (got remote Receiver Report)
  float remote_fraction_lost; // fraction of lost pkts (not received by remote)
  int      remote_total_lost; // total lost packaged (calculated per RFC 3550)
  unsigned remote_jitter;     // interarrival jitter
  int rttMs; // Round-trip time in milliseconds.
  float local_MOS;      // local MOS for entire call segment (added in 9.0.005)
  float local_interMOS; // local MOS for the last interval
  //
  // added in 9.0.009 (all decoded_10ms_xxx values are numbers of 10ms frames):
  //
  int got_neteq_stat; // true if next 6 fields are valid (NetEQ stat available)
  int     local_pkt_received; // total number of RTP packets received locally
  pgtime_t last_pkt_received; // timestamp of last RTP or RTCP packet received
  int decoded_10ms_normal;    // AudioDecodingStats - normal (decoded from RTP)
  int decoded_10ms_plc;       // - Packet Loss Concealment
  int decoded_10ms_cng;       // - Comfort Noise Generation
  int decoded_10ms_silence;   // - dead silence
  //
  // information about current (or last used) codec, added in 9.0.012:
  //
  int got_codec_info; // true if next 2 fields valid (codec info is available)
  int         codec_rtp_pt;   // payload type used for sending RTP packets
  const char *codec_sdp_name; // codec name (as appears in SDP)
}
gs_call_statistics;

The following methods are defined in GSSessionService protocol to get audio statistics:

  @protocol GSSessionService <NSObject>
  /**
   Get audio statistics for particular session
   @param session object.
   @returns GSStatistics with audio statistics content.
   */
  - (GSStatistics*) audioStatisticsForSession:(id<GSSession>) session;
  - (GSStatistics*) audioStatisticsForSessionId:(int) sessionId;

where GSStatistics is an object with the following properties (closely matching internal C++ structure, just with names formatted using standard objective-C convention):

  @property (nonatomic) int gotLocalStat;
  @property (nonatomic) float localFractionLost;
  @property (nonatomic) int localTotalLost;
  @property (nonatomic) unsigned localJitter;
  @property (nonatomic) unsigned localPktCount;
  @property (nonatomic) unsigned localOctCount;
  @property (nonatomic) int gotRemoteSR;
  @property (nonatomic) unsigned remotePktCount;
  @property (nonatomic) unsigned remoteOctCount;
  @property (nonatomic) int gotRemoteRR;
  @property (nonatomic) float remoteFractionLost;
  @property (nonatomic) int remoteTotalLost;
  @property (nonatomic) unsigned remoteJitter;
  @property (nonatomic) int rttMs;
  @property (nonatomic) float vqLocalMOS;
  @property (nonatomic) float vqLocalIntervalMOS;
  @property (nonatomic) int gotNeteqStat;
  @property (nonatomic) int localPktReceived;
  @property (nonatomic) struct timeval lastPktReceived;
  @property (nonatomic) int decoded10msNormal;
  @property (nonatomic) int decoded10msPlc;
  @property (nonatomic) int decoded10msCng;
  @property (nonatomic) int decoded10msSilence;

The following method is defined in ICallControl interface to get audio statistics for specific session ID:

  Dictionary<String^,Object^>^ GetAudioStatistics(int sessionId);

where the returned dictionary is created from internal gs_call_statistics structure as following:

  virtual Dictionary<String^, Object^>^ GetAudioStatistics(int sessionId)
  {
    Dictionary<String^,Object^>^ res = gcnew Dictionary<String^,Object^>();
    gs_call_statistics gst = this->endpoint->getAudioStatistics(sessionId);
    res->Add("Got Local Stat ", gst.got_local_stat);
    res->Add("Local Frac Lost", gst.local_fraction_lost);
    res->Add("Local TotalLost", gst.local_total_lost);
    res->Add("Local Jitter   ", gst.local_jitter);
    res->Add("Local Pkt Count", gst.local_PktCount);
    res->Add("Local Oct Count", gst.local_OctCount);
    res->Add("Got Remote SR  ", gst.got_remote_SR);
    res->Add("Remote PktCount", gst.remote_PktCount);
    res->Add("Remote OctCount", gst.remote_OctCount);
    res->Add("Got Remote RR  ", gst.got_remote_RR);
    res->Add("Remote FracLost", gst.remote_fraction_lost);
    res->Add("Remote TotaLost", gst.remote_total_lost);
    res->Add("Remote Jitter  ", gst.remote_jitter);
    res->Add("Round Trip Time",      gst.rttMs);
    res->Add("VQ Local MOS",         gst.local_MOS);
    res->Add("VQ Local IntervalMOS", gst.local_interMOS);
    res->Add("GotNeteqStat",       gst.got_neteq_stat);
    res->Add("LocalPktReceived",   gst.local_pkt_received);
    res->Add("LastPktReceived",    gst.last_pkt_received);
    res->Add("Decoded10msNormal",  gst.decoded_10ms_normal);
    res->Add("Decoded10msPlc",     gst.decoded_10ms_plc);
    res->Add("Decoded10msCng",     gst.decoded_10ms_cng);
    res->Add("Decoded10msSilence", gst.decoded_10ms_silence);
    return res;
  }


Comments or questions about this documentation? Contact us for support!