James Kuszmaul | 82f6c04 | 2021-01-17 11:30:16 -0800 | [diff] [blame^] | 1 | /** |
| 2 | * @file re_rtp.h Interface to Real-time Transport Protocol and RTCP |
| 3 | * |
| 4 | * Copyright (C) 2010 Creytiv.com |
| 5 | */ |
| 6 | |
| 7 | |
| 8 | /** RTP protocol values */ |
| 9 | enum { |
| 10 | RTP_VERSION = 2, /**< Defines the RTP version we support */ |
| 11 | RTCP_VERSION = 2, /**< Supported RTCP Version */ |
| 12 | RTP_HEADER_SIZE = 12 /**< Number of bytes in RTP Header */ |
| 13 | }; |
| 14 | |
| 15 | |
| 16 | /** Defines the RTP header */ |
| 17 | struct rtp_header { |
| 18 | uint8_t ver; /**< RTP version number */ |
| 19 | bool pad; /**< Padding bit */ |
| 20 | bool ext; /**< Extension bit */ |
| 21 | uint8_t cc; /**< CSRC count */ |
| 22 | bool m; /**< Marker bit */ |
| 23 | uint8_t pt; /**< Payload type */ |
| 24 | uint16_t seq; /**< Sequence number */ |
| 25 | uint32_t ts; /**< Timestamp */ |
| 26 | uint32_t ssrc; /**< Synchronization source */ |
| 27 | uint32_t csrc[16]; /**< Contributing sources */ |
| 28 | struct { |
| 29 | uint16_t type; /**< Defined by profile */ |
| 30 | uint16_t len; /**< Number of 32-bit words */ |
| 31 | } x; |
| 32 | }; |
| 33 | |
| 34 | /** RTCP Packet Types */ |
| 35 | enum rtcp_type { |
| 36 | RTCP_FIR = 192, /**< Full INTRA-frame Request (RFC 2032) */ |
| 37 | RTCP_NACK = 193, /**< Negative Acknowledgement (RFC 2032) */ |
| 38 | RTCP_SR = 200, /**< Sender Report */ |
| 39 | RTCP_RR = 201, /**< Receiver Report */ |
| 40 | RTCP_SDES = 202, /**< Source Description */ |
| 41 | RTCP_BYE = 203, /**< Goodbye */ |
| 42 | RTCP_APP = 204, /**< Application-defined */ |
| 43 | RTCP_RTPFB = 205, /**< Transport layer FB message (RFC 4585) */ |
| 44 | RTCP_PSFB = 206, /**< Payload-specific FB message (RFC 4585) */ |
| 45 | RTCP_XR = 207, /**< Extended Report (RFC 3611) */ |
| 46 | RTCP_AVB = 208, /**< AVB RTCP Packet (IEEE1733) */ |
| 47 | }; |
| 48 | |
| 49 | /** SDES Types */ |
| 50 | enum rtcp_sdes_type { |
| 51 | RTCP_SDES_END = 0, /**< End of SDES list */ |
| 52 | RTCP_SDES_CNAME = 1, /**< Canonical name */ |
| 53 | RTCP_SDES_NAME = 2, /**< User name */ |
| 54 | RTCP_SDES_EMAIL = 3, /**< User's electronic mail address */ |
| 55 | RTCP_SDES_PHONE = 4, /**< User's phone number */ |
| 56 | RTCP_SDES_LOC = 5, /**< Geographic user location */ |
| 57 | RTCP_SDES_TOOL = 6, /**< Name of application or tool */ |
| 58 | RTCP_SDES_NOTE = 7, /**< Notice about the source */ |
| 59 | RTCP_SDES_PRIV = 8 /**< Private extension */ |
| 60 | }; |
| 61 | |
| 62 | /** Transport Layer Feedback Messages */ |
| 63 | enum rtcp_rtpfb { |
| 64 | RTCP_RTPFB_GNACK = 1 /**< Generic NACK */ |
| 65 | }; |
| 66 | |
| 67 | /** Payload-Specific Feedback Messages */ |
| 68 | enum rtcp_psfb { |
| 69 | RTCP_PSFB_PLI = 1, /**< Picture Loss Indication (PLI) */ |
| 70 | RTCP_PSFB_SLI = 2, /**< Slice Loss Indication (SLI) */ |
| 71 | RTCP_PSFB_AFB = 15, /**< Application layer Feedback Messages */ |
| 72 | }; |
| 73 | |
| 74 | /** Reception report block */ |
| 75 | struct rtcp_rr { |
| 76 | uint32_t ssrc; /**< Data source being reported */ |
| 77 | unsigned int fraction:8; /**< Fraction lost since last SR/RR */ |
| 78 | int lost:24; /**< Cumul. no. pkts lost (signed!) */ |
| 79 | uint32_t last_seq; /**< Extended last seq. no. received */ |
| 80 | uint32_t jitter; /**< Interarrival jitter */ |
| 81 | uint32_t lsr; /**< Last SR packet from this source */ |
| 82 | uint32_t dlsr; /**< Delay since last SR packet */ |
| 83 | }; |
| 84 | |
| 85 | /** SDES item */ |
| 86 | struct rtcp_sdes_item { |
| 87 | enum rtcp_sdes_type type; /**< Type of item (enum rtcp_sdes_type) */ |
| 88 | uint8_t length; /**< Length of item (in octets) */ |
| 89 | char *data; /**< Text, not null-terminated */ |
| 90 | }; |
| 91 | |
| 92 | /** One RTCP Message */ |
| 93 | struct rtcp_msg { |
| 94 | /** RTCP Header */ |
| 95 | struct rtcp_hdr { |
| 96 | unsigned int version:2; /**< Protocol version */ |
| 97 | unsigned int p:1; /**< Padding flag */ |
| 98 | unsigned int count:5; /**< Varies by packet type */ |
| 99 | unsigned int pt:8; /**< RTCP packet type */ |
| 100 | uint16_t length; /**< Packet length in words */ |
| 101 | } hdr; |
| 102 | union { |
| 103 | /** Sender report (SR) */ |
| 104 | struct { |
| 105 | uint32_t ssrc; /**< Sender generating report */ |
| 106 | uint32_t ntp_sec; /**< NTP timestamp - seconds */ |
| 107 | uint32_t ntp_frac; /**< NTP timestamp - fractions */ |
| 108 | uint32_t rtp_ts; /**< RTP timestamp */ |
| 109 | uint32_t psent; /**< RTP packets sent */ |
| 110 | uint32_t osent; /**< RTP octets sent */ |
| 111 | struct rtcp_rr *rrv; /**< Reception report blocks */ |
| 112 | } sr; |
| 113 | |
| 114 | /** Reception report (RR) */ |
| 115 | struct { |
| 116 | uint32_t ssrc; /**< Receiver generating report*/ |
| 117 | struct rtcp_rr *rrv; /**< Reception report blocks */ |
| 118 | } rr; |
| 119 | |
| 120 | /** Source Description (SDES) */ |
| 121 | struct rtcp_sdes { |
| 122 | uint32_t src; /**< First SSRC/CSRC */ |
| 123 | struct rtcp_sdes_item *itemv; /**< SDES items */ |
| 124 | uint32_t n; /**< Number of SDES items */ |
| 125 | } *sdesv; |
| 126 | |
| 127 | /** BYE */ |
| 128 | struct { |
| 129 | uint32_t *srcv; /**< List of sources */ |
| 130 | char *reason; /**< Reason for leaving (opt.) */ |
| 131 | } bye; |
| 132 | |
| 133 | /** Application-defined (APP) */ |
| 134 | struct { |
| 135 | uint32_t src; /**< SSRC/CSRC */ |
| 136 | char name[4]; /**< Name (ASCII) */ |
| 137 | uint8_t *data; /**< Application data (32 bits) */ |
| 138 | size_t data_len; /**< Number of data bytes */ |
| 139 | } app; |
| 140 | |
| 141 | /** Full INTRA-frame Request (FIR) packet */ |
| 142 | struct { |
| 143 | uint32_t ssrc; /**< SSRC for sender of this packet */ |
| 144 | } fir; |
| 145 | |
| 146 | /** Negative ACKnowledgements (NACK) packet */ |
| 147 | struct { |
| 148 | uint32_t ssrc; /**< SSRC for sender of this packet */ |
| 149 | uint16_t fsn; /**< First Sequence Number lost */ |
| 150 | uint16_t blp; /**< Bitmask of lost packets */ |
| 151 | } nack; |
| 152 | |
| 153 | /** Feedback (RTPFB or PSFB) packet */ |
| 154 | struct { |
| 155 | uint32_t ssrc_packet; |
| 156 | uint32_t ssrc_media; |
| 157 | uint32_t n; |
| 158 | /** Feedback Control Information (FCI) */ |
| 159 | union { |
| 160 | struct gnack { |
| 161 | uint16_t pid; |
| 162 | uint16_t blp; |
| 163 | } *gnackv; |
| 164 | struct sli { |
| 165 | uint16_t first; |
| 166 | uint16_t number; |
| 167 | uint8_t picid; |
| 168 | } *sliv; |
| 169 | struct mbuf *afb; |
| 170 | void *p; |
| 171 | } fci; |
| 172 | } fb; |
| 173 | } r; |
| 174 | }; |
| 175 | |
| 176 | /** RTCP Statistics */ |
| 177 | struct rtcp_stats { |
| 178 | struct { |
| 179 | uint32_t sent; /**< Tx RTP Packets */ |
| 180 | int lost; /**< Tx RTP Packets Lost */ |
| 181 | uint32_t jit; /**< Tx Inter-arrival Jitter in [us] */ |
| 182 | } tx; |
| 183 | struct { |
| 184 | uint32_t sent; /**< Rx RTP Packets */ |
| 185 | int lost; /**< Rx RTP Packets Lost */ |
| 186 | uint32_t jit; /**< Rx Inter-Arrival Jitter in [us] */ |
| 187 | } rx; |
| 188 | uint32_t rtt; /**< Current Round-Trip Time in [us] */ |
| 189 | }; |
| 190 | |
| 191 | struct sa; |
| 192 | struct re_printf; |
| 193 | struct rtp_sock; |
| 194 | |
| 195 | typedef void (rtp_recv_h)(const struct sa *src, const struct rtp_header *hdr, |
| 196 | struct mbuf *mb, void *arg); |
| 197 | typedef void (rtcp_recv_h)(const struct sa *src, struct rtcp_msg *msg, |
| 198 | void *arg); |
| 199 | |
| 200 | /* RTP api */ |
| 201 | int rtp_alloc(struct rtp_sock **rsp); |
| 202 | int rtp_listen(struct rtp_sock **rsp, int proto, const struct sa *ip, |
| 203 | uint16_t min_port, uint16_t max_port, bool enable_rtcp, |
| 204 | rtp_recv_h *recvh, rtcp_recv_h *rtcph, void *arg); |
| 205 | int rtp_hdr_encode(struct mbuf *mb, const struct rtp_header *hdr); |
| 206 | int rtp_hdr_decode(struct rtp_header *hdr, struct mbuf *mb); |
| 207 | int rtp_encode(struct rtp_sock *rs, bool ext, bool marker, uint8_t pt, |
| 208 | uint32_t ts, struct mbuf *mb); |
| 209 | int rtp_decode(struct rtp_sock *rs, struct mbuf *mb, struct rtp_header *hdr); |
| 210 | int rtp_send(struct rtp_sock *rs, const struct sa *dst, bool ext, |
| 211 | bool marker, uint8_t pt, uint32_t ts, struct mbuf *mb); |
| 212 | int rtp_debug(struct re_printf *pf, const struct rtp_sock *rs); |
| 213 | void *rtp_sock(const struct rtp_sock *rs); |
| 214 | uint32_t rtp_sess_ssrc(const struct rtp_sock *rs); |
| 215 | const struct sa *rtp_local(const struct rtp_sock *rs); |
| 216 | |
| 217 | /* RTCP session api */ |
| 218 | void rtcp_start(struct rtp_sock *rs, const char *cname, |
| 219 | const struct sa *peer); |
| 220 | void rtcp_enable_mux(struct rtp_sock *rs, bool enabled); |
| 221 | void rtcp_set_srate(struct rtp_sock *rs, uint32_t sr_tx, uint32_t sr_rx); |
| 222 | void rtcp_set_srate_tx(struct rtp_sock *rs, uint32_t srate_tx); |
| 223 | void rtcp_set_srate_rx(struct rtp_sock *rs, uint32_t srate_rx); |
| 224 | int rtcp_send_app(struct rtp_sock *rs, const char name[4], |
| 225 | const uint8_t *data, size_t len); |
| 226 | int rtcp_send_fir(struct rtp_sock *rs, uint32_t ssrc); |
| 227 | int rtcp_send_nack(struct rtp_sock *rs, uint16_t fsn, uint16_t blp); |
| 228 | int rtcp_send_pli(struct rtp_sock *rs, uint32_t fb_ssrc); |
| 229 | int rtcp_debug(struct re_printf *pf, const struct rtp_sock *rs); |
| 230 | void *rtcp_sock(const struct rtp_sock *rs); |
| 231 | int rtcp_stats(struct rtp_sock *rs, uint32_t ssrc, struct rtcp_stats *stats); |
| 232 | |
| 233 | /* RTCP utils */ |
| 234 | int rtcp_encode(struct mbuf *mb, enum rtcp_type type, uint32_t count, ...); |
| 235 | int rtcp_decode(struct rtcp_msg **msgp, struct mbuf *mb); |
| 236 | int rtcp_msg_print(struct re_printf *pf, const struct rtcp_msg *msg); |
| 237 | int rtcp_sdes_encode(struct mbuf *mb, uint32_t src, uint32_t itemc, ...); |
| 238 | const char *rtcp_type_name(enum rtcp_type type); |
| 239 | const char *rtcp_sdes_name(enum rtcp_sdes_type sdes); |