/* $Id$ */ /* * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) * Copyright (C) 2003-2008 Benny Prijono * * 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 #include 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__ */