blob: fb204852abcfb1ea82c976638b8bfee79f224a5a [file] [log] [blame]
/* $Id$ */
/*
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __PJMEDIA_RTCP_XR_H__
#define __PJMEDIA_RTCP_XR_H__
/**
* @file rtcp_xr.h
* @brief RTCP XR implementation.
*/
#include <pjmedia/types.h>
#include <pj/math.h>
PJ_BEGIN_DECL
/**
* @defgroup PJMED_RTCP_XR RTCP Extended Report (XR) - RFC 3611
* @ingroup PJMEDIA_SESSION
* @brief RTCP XR extension to RTCP session
* @{
*
* PJMEDIA implements subsets of RTCP XR specification (RFC 3611) to monitor
* the quality of the real-time media (audio/video) transmission.
*/
/**
* Enumeration of report types of RTCP XR. Useful for user to enable varying
* combinations of RTCP XR report blocks.
*/
typedef enum {
PJMEDIA_RTCP_XR_LOSS_RLE = (1 << 0),
PJMEDIA_RTCP_XR_DUP_RLE = (1 << 1),
PJMEDIA_RTCP_XR_RCPT_TIMES = (1 << 2),
PJMEDIA_RTCP_XR_RR_TIME = (1 << 3),
PJMEDIA_RTCP_XR_DLRR = (1 << 4),
PJMEDIA_RTCP_XR_STATS = (1 << 5),
PJMEDIA_RTCP_XR_VOIP_METRICS = (1 << 6)
} pjmedia_rtcp_xr_type;
/**
* Enumeration of info need to be updated manually to RTCP XR. Most info
* could be updated automatically each time RTP received.
*/
typedef enum {
PJMEDIA_RTCP_XR_INFO_SIGNAL_LVL = 1,
PJMEDIA_RTCP_XR_INFO_NOISE_LVL = 2,
PJMEDIA_RTCP_XR_INFO_RERL = 3,
PJMEDIA_RTCP_XR_INFO_R_FACTOR = 4,
PJMEDIA_RTCP_XR_INFO_MOS_LQ = 5,
PJMEDIA_RTCP_XR_INFO_MOS_CQ = 6,
PJMEDIA_RTCP_XR_INFO_CONF_PLC = 7,
PJMEDIA_RTCP_XR_INFO_CONF_JBA = 8,
PJMEDIA_RTCP_XR_INFO_CONF_JBR = 9,
PJMEDIA_RTCP_XR_INFO_JB_NOM = 10,
PJMEDIA_RTCP_XR_INFO_JB_MAX = 11,
PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX = 12
} pjmedia_rtcp_xr_info;
/**
* Enumeration of PLC types definitions for RTCP XR report.
*/
typedef enum {
PJMEDIA_RTCP_XR_PLC_UNK = 0,
PJMEDIA_RTCP_XR_PLC_DIS = 1,
PJMEDIA_RTCP_XR_PLC_ENH = 2,
PJMEDIA_RTCP_XR_PLC_STD = 3
} pjmedia_rtcp_xr_plc_type;
/**
* Enumeration of jitter buffer types definitions for RTCP XR report.
*/
typedef enum {
PJMEDIA_RTCP_XR_JB_UNKNOWN = 0,
PJMEDIA_RTCP_XR_JB_FIXED = 2,
PJMEDIA_RTCP_XR_JB_ADAPTIVE = 3
} pjmedia_rtcp_xr_jb_type;
#pragma pack(1)
/**
* This type declares RTCP XR Report Header.
*/
typedef struct pjmedia_rtcp_xr_rb_header
{
pj_uint8_t bt; /**< Block type. */
pj_uint8_t specific; /**< Block specific data. */
pj_uint16_t length; /**< Block length. */
} pjmedia_rtcp_xr_rb_header;
/**
* This type declares RTCP XR Receiver Reference Time Report Block.
*/
typedef struct pjmedia_rtcp_xr_rb_rr_time
{
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
pj_uint32_t ntp_sec; /**< NTP time, seconds part. */
pj_uint32_t ntp_frac; /**< NTP time, fractions part. */
} pjmedia_rtcp_xr_rb_rr_time;
/**
* This type declares RTCP XR DLRR Report Sub-block
*/
typedef struct pjmedia_rtcp_xr_rb_dlrr_item
{
pj_uint32_t ssrc; /**< receiver SSRC */
pj_uint32_t lrr; /**< last receiver report */
pj_uint32_t dlrr; /**< delay since last receiver
report */
} pjmedia_rtcp_xr_rb_dlrr_item;
/**
* This type declares RTCP XR DLRR Report Block
*/
typedef struct pjmedia_rtcp_xr_rb_dlrr
{
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
pjmedia_rtcp_xr_rb_dlrr_item item; /**< Block contents,
variable length list */
} pjmedia_rtcp_xr_rb_dlrr;
/**
* This type declares RTCP XR Statistics Summary Report Block
*/
typedef struct pjmedia_rtcp_xr_rb_stats
{
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
pj_uint32_t ssrc; /**< Receiver SSRC */
pj_uint16_t begin_seq; /**< Begin RTP sequence reported */
pj_uint16_t end_seq; /**< End RTP sequence reported */
pj_uint32_t lost; /**< Number of packet lost in this
interval */
pj_uint32_t dup; /**< Number of duplicated packet in
this interval */
pj_uint32_t jitter_min; /**< Minimum jitter in this interval */
pj_uint32_t jitter_max; /**< Maximum jitter in this interval */
pj_uint32_t jitter_mean; /**< Average jitter in this interval */
pj_uint32_t jitter_dev; /**< Jitter deviation in this
interval */
pj_uint32_t toh_min:8; /**< Minimum ToH in this interval */
pj_uint32_t toh_max:8; /**< Maximum ToH in this interval */
pj_uint32_t toh_mean:8; /**< Average ToH in this interval */
pj_uint32_t toh_dev:8; /**< ToH deviation in this interval */
} pjmedia_rtcp_xr_rb_stats;
/**
* This type declares RTCP XR VoIP Metrics Report Block
*/
typedef struct pjmedia_rtcp_xr_rb_voip_mtc
{
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
pj_uint32_t ssrc; /**< Receiver SSRC */
pj_uint8_t loss_rate; /**< Packet loss rate */
pj_uint8_t discard_rate; /**< Packet discarded rate */
pj_uint8_t burst_den; /**< Burst density */
pj_uint8_t gap_den; /**< Gap density */
pj_uint16_t burst_dur; /**< Burst duration */
pj_uint16_t gap_dur; /**< Gap duration */
pj_uint16_t rnd_trip_delay;/**< Round trip delay */
pj_uint16_t end_sys_delay; /**< End system delay */
pj_uint8_t signal_lvl; /**< Signal level */
pj_uint8_t noise_lvl; /**< Noise level */
pj_uint8_t rerl; /**< Residual Echo Return Loss */
pj_uint8_t gmin; /**< The gap threshold */
pj_uint8_t r_factor; /**< Voice quality metric carried
over this RTP session */
pj_uint8_t ext_r_factor; /**< Voice quality metric carried
outside of this RTP session*/
pj_uint8_t mos_lq; /**< Mean Opinion Score for
Listening Quality */
pj_uint8_t mos_cq; /**< Mean Opinion Score for
Conversation Quality */
pj_uint8_t rx_config; /**< Receiver configuration */
pj_uint8_t reserved2; /**< Not used */
pj_uint16_t jb_nom; /**< Current delay by jitter
buffer */
pj_uint16_t jb_max; /**< Maximum delay by jitter
buffer */
pj_uint16_t jb_abs_max; /**< Maximum possible delay by
jitter buffer */
} pjmedia_rtcp_xr_rb_voip_mtc;
/**
* Constant of RTCP-XR content size.
*/
#define PJMEDIA_RTCP_XR_BUF_SIZE \
sizeof(pjmedia_rtcp_xr_rb_rr_time) + \
sizeof(pjmedia_rtcp_xr_rb_dlrr) + \
sizeof(pjmedia_rtcp_xr_rb_stats) + \
sizeof(pjmedia_rtcp_xr_rb_voip_mtc)
/**
* This structure declares RTCP XR (Extended Report) packet.
*/
typedef struct pjmedia_rtcp_xr_pkt
{
struct {
#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
unsigned version:2; /**< packet type */
unsigned p:1; /**< padding flag */
unsigned count:5; /**< varies by payload type */
unsigned pt:8; /**< payload type */
#else
unsigned count:5; /**< varies by payload type */
unsigned p:1; /**< padding flag */
unsigned version:2; /**< packet type */
unsigned pt:8; /**< payload type */
#endif
unsigned length:16; /**< packet length */
pj_uint32_t ssrc; /**< SSRC identification */
} common;
pj_int8_t buf[PJMEDIA_RTCP_XR_BUF_SIZE];
/**< Content buffer */
} pjmedia_rtcp_xr_pkt;
#pragma pack()
/**
* This structure describes RTCP XR statitic.
*/
typedef struct pjmedia_rtcp_xr_stream_stat
{
struct {
pj_time_val update; /**< Time of last update. */
pj_uint32_t begin_seq; /**< Begin # seq of this interval. */
pj_uint32_t end_seq; /**< End # seq of this interval. */
unsigned count; /**< Number of packets. */
/**
* Flags represent whether the such report is valid/updated
*/
unsigned l:1; /**< Lost flag */
unsigned d:1; /**< Duplicated flag */
unsigned j:1; /**< Jitter flag */
unsigned t:2; /**< TTL or Hop Limit,
0=none, 1=TTL, 2=HL */
unsigned lost; /**< Number of packets lost */
unsigned dup; /**< Number of duplicated packets */
pj_math_stat jitter; /**< Jitter statistics (in usec) */
pj_math_stat toh; /**< TTL of hop limit statistics. */
} stat_sum;
struct {
pj_time_val update; /**< Time of last update. */
pj_uint8_t loss_rate; /**< Packet loss rate */
pj_uint8_t discard_rate; /**< Packet discarded rate */
pj_uint8_t burst_den; /**< Burst density */
pj_uint8_t gap_den; /**< Gap density */
pj_uint16_t burst_dur; /**< Burst duration */
pj_uint16_t gap_dur; /**< Gap duration */
pj_uint16_t rnd_trip_delay; /**< Round trip delay */
pj_uint16_t end_sys_delay; /**< End system delay */
pj_int8_t signal_lvl; /**< Signal level */
pj_int8_t noise_lvl; /**< Noise level */
pj_uint8_t rerl; /**< Residual Echo Return Loss */
pj_uint8_t gmin; /**< The gap threshold */
pj_uint8_t r_factor; /**< Voice quality metric carried
over this RTP session */
pj_uint8_t ext_r_factor; /**< Voice quality metric carried
outside of this RTP session*/
pj_uint8_t mos_lq; /**< Mean Opinion Score for
Listening Quality */
pj_uint8_t mos_cq; /**< Mean Opinion Score for
Conversation Quality */
pj_uint8_t rx_config; /**< Receiver configuration */
pj_uint16_t jb_nom; /**< Current delay by jitter
buffer */
pj_uint16_t jb_max; /**< Maximum delay by jitter
buffer */
pj_uint16_t jb_abs_max; /**< Maximum possible delay by
jitter buffer */
} voip_mtc;
} pjmedia_rtcp_xr_stream_stat;
typedef struct pjmedia_rtcp_xr_stat
{
pjmedia_rtcp_xr_stream_stat rx; /**< Decoding direction statistics. */
pjmedia_rtcp_xr_stream_stat tx; /**< Encoding direction statistics. */
pj_math_stat rtt; /**< Round-trip delay stat (in usec)
the value is calculated from
receiver side. */
} pjmedia_rtcp_xr_stat;
/**
* Forward declaration of RTCP session
*/
struct pjmedia_rtcp_session;
/**
* RTCP session is used to monitor the RTP session of one endpoint. There
* should only be one RTCP session for a bidirectional RTP streams.
*/
struct pjmedia_rtcp_xr_session
{
char *name; /**< Name identification. */
pjmedia_rtcp_xr_pkt pkt; /**< Cached RTCP XR packet. */
pj_uint32_t rx_lrr; /**< NTP ts in last RR received. */
pj_timestamp rx_lrr_time;/**< Time when last RR is received. */
pj_uint32_t rx_last_rr; /**< # pkt received since last
sending RR time. */
pjmedia_rtcp_xr_stat stat; /**< RTCP XR statistics. */
/* The reference sequence number is an extended sequence number
* that serves as the basis for determining whether a new 16 bit
* sequence number comes earlier or later in the 32 bit sequence
* space.
*/
pj_uint32_t src_ref_seq;
pj_bool_t uninitialized_src_ref_seq;
/* This structure contains variables needed for calculating
* burst metrics.
*/
struct {
pj_uint32_t pkt;
pj_uint32_t lost;
pj_uint32_t loss_count;
pj_uint32_t discard_count;
pj_uint32_t c11;
pj_uint32_t c13;
pj_uint32_t c14;
pj_uint32_t c22;
pj_uint32_t c23;
pj_uint32_t c33;
} voip_mtc_stat;
unsigned ptime; /**< Packet time. */
unsigned frames_per_packet; /**< # frames per packet. */
struct pjmedia_rtcp_session *rtcp_session;
/**< Parent/RTCP session. */
};
typedef struct pjmedia_rtcp_xr_session pjmedia_rtcp_xr_session;
/**
* Build an RTCP XR packet which contains one or more RTCP XR report blocks.
* There are seven report types as defined in RFC 3611.
*
* @param session The RTCP XR session.
* @param rpt_types Report types to be included in the packet, report types
* are defined in pjmedia_rtcp_xr_type, set this to zero
* will make this function build all reports appropriately.
* @param rtcp_pkt Upon return, it will contain pointer to the RTCP XR packet.
* @param len Upon return, it will indicate the size of the generated
* RTCP XR packet.
*/
PJ_DECL(void) pjmedia_rtcp_build_rtcp_xr( pjmedia_rtcp_xr_session *session,
unsigned rpt_types,
void **rtcp_pkt, int *len);
/**
* Call this function to manually update some info needed by RTCP XR to
* generate report which could not be populated directly when receiving
* RTP.
*
* @param session The RTCP XR session.
* @param info Info type to be updated, @see pjmedia_rtcp_xr_info.
* @param val Value.
*/
PJ_DECL(pj_status_t) pjmedia_rtcp_xr_update_info(
pjmedia_rtcp_xr_session *session,
unsigned info,
pj_int32_t val);
/*
* Private APIs:
*/
/**
* This function is called internally by RTCP session when RTCP XR is enabled
* to initialize the RTCP XR session.
*
* @param session RTCP XR session.
* @param r_session RTCP session.
* @param gmin Gmin value (defined in RFC 3611), set to 0 for default (16).
* @param frames_per_packet
Number of frames per packet.
*/
void pjmedia_rtcp_xr_init( pjmedia_rtcp_xr_session *session,
struct pjmedia_rtcp_session *r_session,
pj_uint8_t gmin,
unsigned frames_per_packet);
/**
* This function is called internally by RTCP session to destroy
* the RTCP XR session.
*
* @param session RTCP XR session.
*/
void pjmedia_rtcp_xr_fini( pjmedia_rtcp_xr_session *session );
/**
* This function is called internally by RTCP session when it receives
* incoming RTCP XR packets.
*
* @param session RTCP XR session.
* @param rtcp_pkt The received RTCP XR packet.
* @param size Size of the incoming packet.
*/
void pjmedia_rtcp_xr_rx_rtcp_xr( pjmedia_rtcp_xr_session *session,
const void *rtcp_pkt,
pj_size_t size);
/**
* This function is called internally by RTCP session whenever an RTP packet
* is received or lost to let the RTCP XR session update its statistics.
* Data passed to this function is a result of analyzation by RTCP and the
* jitter buffer. Whenever some info is available, the value should be zero
* or more (no negative info), otherwise if info is not available the info
* should be -1 so no update will be done for this info in the RTCP XR session.
*
* @param session RTCP XR session.
* @param seq Sequence number of RTP packet.
* @param lost Info if this packet is lost.
* @param dup Info if this packet is a duplication.
* @param discarded Info if this packet is discarded
* (not because of duplication).
* @param jitter Info jitter of this packet.
* @param toh Info Time To Live or Hops Limit of this packet.
* @param toh_ipv4 Set PJ_TRUE if packet is transported over IPv4.
*/
void pjmedia_rtcp_xr_rx_rtp( pjmedia_rtcp_xr_session *session,
unsigned seq,
int lost,
int dup,
int discarded,
int jitter,
int toh, pj_bool_t toh_ipv4);
/**
* This function is called internally by RTCP session whenever an RTP
* packet is sent to let the RTCP XR session do its internal calculations.
*
* @param session RTCP XR session.
* @param ptsize Size of RTP payload being sent.
*/
void pjmedia_rtcp_xr_tx_rtp( pjmedia_rtcp_xr_session *session,
unsigned ptsize );
/**
* @}
*/
PJ_END_DECL
#endif /* __PJMEDIA_RTCP_XR_H__ */