Tristan Matthews | 0a329cc | 2013-07-17 13:20:14 -0400 | [diff] [blame] | 1 | /* $Id$ */ |
| 2 | /* |
| 3 | * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
| 4 | * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ |
| 20 | #ifndef __PJMEDIA_RTP_H__ |
| 21 | #define __PJMEDIA_RTP_H__ |
| 22 | |
| 23 | |
| 24 | /** |
| 25 | * @file rtp.h |
| 26 | * @brief RTP packet and RTP session declarations. |
| 27 | */ |
| 28 | #include <pjmedia/types.h> |
| 29 | |
| 30 | |
| 31 | PJ_BEGIN_DECL |
| 32 | |
| 33 | |
| 34 | /** |
| 35 | * @defgroup PJMED_RTP RTP Session and Encapsulation (RFC 3550) |
| 36 | * @ingroup PJMEDIA_SESSION |
| 37 | * @brief RTP format and session management |
| 38 | * @{ |
| 39 | * |
| 40 | * The RTP module is designed to be dependent only to PJLIB, it does not depend |
| 41 | * on any other parts of PJMEDIA library. The RTP module does not even depend |
| 42 | * on any transports (sockets), to promote even more use, such as in DSP |
| 43 | * development (where transport may be handled by different processor). |
| 44 | * |
| 45 | * An RTCP implementation is available, in separate module. Please see |
| 46 | * @ref PJMED_RTCP. |
| 47 | * |
| 48 | * The functions that are provided by this module: |
| 49 | * - creating RTP header for each outgoing packet. |
| 50 | * - decoding RTP packet into RTP header and payload. |
| 51 | * - provide simple RTP session management (sequence number, etc.) |
| 52 | * |
| 53 | * The RTP module does not use any dynamic memory at all. |
| 54 | * |
| 55 | * \section P1 How to Use the RTP Module |
| 56 | * |
| 57 | * First application must call #pjmedia_rtp_session_init() to initialize the RTP |
| 58 | * session. |
| 59 | * |
| 60 | * When application wants to send RTP packet, it needs to call |
| 61 | * #pjmedia_rtp_encode_rtp() to build the RTP header. Note that this WILL NOT build |
| 62 | * the complete RTP packet, but instead only the header. Application can |
| 63 | * then either concatenate the header with the payload, or send the two |
| 64 | * fragments (the header and the payload) using scatter-gather transport API |
| 65 | * (e.g. \a sendv()). |
| 66 | * |
| 67 | * When application receives an RTP packet, first it should call |
| 68 | * #pjmedia_rtp_decode_rtp to decode RTP header and payload, then it should call |
| 69 | * #pjmedia_rtp_session_update to check whether we can process the RTP payload, |
| 70 | * and to let the RTP session updates its internal status. The decode function |
| 71 | * is guaranteed to point the payload to the correct position regardless of |
| 72 | * any options present in the RTP packet. |
| 73 | * |
| 74 | */ |
| 75 | |
| 76 | #ifdef _MSC_VER |
| 77 | # pragma warning(disable:4214) // bit field types other than int |
| 78 | #endif |
| 79 | |
| 80 | |
| 81 | /** |
| 82 | * RTP packet header. Note that all RTP functions here will work with this |
| 83 | * header in network byte order. |
| 84 | */ |
| 85 | #pragma pack(1) |
| 86 | struct pjmedia_rtp_hdr |
| 87 | { |
| 88 | #if defined(PJ_IS_BIG_ENDIAN) && (PJ_IS_BIG_ENDIAN!=0) |
| 89 | pj_uint16_t v:2; /**< packet type/version */ |
| 90 | pj_uint16_t p:1; /**< padding flag */ |
| 91 | pj_uint16_t x:1; /**< extension flag */ |
| 92 | pj_uint16_t cc:4; /**< CSRC count */ |
| 93 | pj_uint16_t m:1; /**< marker bit */ |
| 94 | pj_uint16_t pt:7; /**< payload type */ |
| 95 | #else |
| 96 | pj_uint16_t cc:4; /**< CSRC count */ |
| 97 | pj_uint16_t x:1; /**< header extension flag */ |
| 98 | pj_uint16_t p:1; /**< padding flag */ |
| 99 | pj_uint16_t v:2; /**< packet type/version */ |
| 100 | pj_uint16_t pt:7; /**< payload type */ |
| 101 | pj_uint16_t m:1; /**< marker bit */ |
| 102 | #endif |
| 103 | pj_uint16_t seq; /**< sequence number */ |
| 104 | pj_uint32_t ts; /**< timestamp */ |
| 105 | pj_uint32_t ssrc; /**< synchronization source */ |
| 106 | }; |
| 107 | #pragma pack() |
| 108 | |
| 109 | /** |
| 110 | * @see pjmedia_rtp_hdr |
| 111 | */ |
| 112 | typedef struct pjmedia_rtp_hdr pjmedia_rtp_hdr; |
| 113 | |
| 114 | |
| 115 | /** |
| 116 | * RTP extendsion header. |
| 117 | */ |
| 118 | struct pjmedia_rtp_ext_hdr |
| 119 | { |
| 120 | pj_uint16_t profile_data; /**< Profile data. */ |
| 121 | pj_uint16_t length; /**< Length. */ |
| 122 | }; |
| 123 | |
| 124 | /** |
| 125 | * @see pjmedia_rtp_ext_hdr |
| 126 | */ |
| 127 | typedef struct pjmedia_rtp_ext_hdr pjmedia_rtp_ext_hdr; |
| 128 | |
| 129 | |
| 130 | #pragma pack(1) |
| 131 | |
| 132 | /** |
| 133 | * Declaration for DTMF telephony-events (RFC2833). |
| 134 | */ |
| 135 | struct pjmedia_rtp_dtmf_event |
| 136 | { |
| 137 | pj_uint8_t event; /**< Event type ID. */ |
| 138 | pj_uint8_t e_vol; /**< Event volume. */ |
| 139 | pj_uint16_t duration; /**< Event duration. */ |
| 140 | }; |
| 141 | |
| 142 | /** |
| 143 | * @see pjmedia_rtp_dtmf_event |
| 144 | */ |
| 145 | typedef struct pjmedia_rtp_dtmf_event pjmedia_rtp_dtmf_event; |
| 146 | |
| 147 | #pragma pack() |
| 148 | |
| 149 | |
| 150 | /** |
| 151 | * A generic sequence number management, used by both RTP and RTCP. |
| 152 | */ |
| 153 | struct pjmedia_rtp_seq_session |
| 154 | { |
| 155 | pj_uint16_t max_seq; /**< Highest sequence number heard */ |
| 156 | pj_uint32_t cycles; /**< Shifted count of seq number cycles */ |
| 157 | pj_uint32_t base_seq; /**< Base seq number */ |
| 158 | pj_uint32_t bad_seq; /**< Last 'bad' seq number + 1 */ |
| 159 | pj_uint32_t probation; /**< Sequ. packets till source is valid */ |
| 160 | }; |
| 161 | |
| 162 | /** |
| 163 | * @see pjmedia_rtp_seq_session |
| 164 | */ |
| 165 | typedef struct pjmedia_rtp_seq_session pjmedia_rtp_seq_session; |
| 166 | |
| 167 | |
| 168 | /** |
| 169 | * RTP session descriptor. |
| 170 | */ |
| 171 | struct pjmedia_rtp_session |
| 172 | { |
| 173 | pjmedia_rtp_hdr out_hdr; /**< Saved hdr for outgoing pkts. */ |
| 174 | pjmedia_rtp_seq_session seq_ctrl; /**< Sequence number management. */ |
| 175 | pj_uint16_t out_pt; /**< Default outgoing payload type. */ |
| 176 | pj_uint32_t out_extseq; /**< Outgoing extended seq #. */ |
| 177 | pj_uint32_t peer_ssrc; /**< Peer SSRC. */ |
| 178 | pj_uint32_t received; /**< Number of received packets. */ |
| 179 | }; |
| 180 | |
| 181 | /** |
| 182 | * @see pjmedia_rtp_session |
| 183 | */ |
| 184 | typedef struct pjmedia_rtp_session pjmedia_rtp_session; |
| 185 | |
| 186 | |
| 187 | /** |
| 188 | * This structure is used to receive additional information about the |
| 189 | * state of incoming RTP packet. |
| 190 | */ |
| 191 | struct pjmedia_rtp_status |
| 192 | { |
| 193 | union { |
| 194 | struct flag { |
| 195 | int bad:1; /**< General flag to indicate that sequence is |
| 196 | bad, and application should not process |
| 197 | this packet. More information will be given |
| 198 | in other flags. */ |
| 199 | int badpt:1; /**< Bad payload type. */ |
| 200 | int badssrc:1; /**< Bad SSRC */ |
| 201 | int dup:1; /**< Indicates duplicate packet */ |
| 202 | int outorder:1; /**< Indicates out of order packet */ |
| 203 | int probation:1;/**< Indicates that session is in probation |
| 204 | until more packets are received. */ |
| 205 | int restart:1; /**< Indicates that sequence number has made |
| 206 | a large jump, and internal base sequence |
| 207 | number has been adjusted. */ |
| 208 | } flag; /**< Status flags. */ |
| 209 | |
| 210 | pj_uint16_t value; /**< Status value, to conveniently address all |
| 211 | flags. */ |
| 212 | |
| 213 | } status; /**< Status information union. */ |
| 214 | |
| 215 | pj_uint16_t diff; /**< Sequence number difference from previous |
| 216 | packet. Normally the value should be 1. |
| 217 | Value greater than one may indicate packet |
| 218 | loss. If packet with lower sequence is |
| 219 | received, the value will be set to zero. |
| 220 | If base sequence has been restarted, the |
| 221 | value will be one. */ |
| 222 | }; |
| 223 | |
| 224 | |
| 225 | /** |
| 226 | * RTP session settings. |
| 227 | */ |
| 228 | typedef struct pjmedia_rtp_session_setting |
| 229 | { |
| 230 | pj_uint8_t flags; /**< Bitmask flags to specify whether such |
| 231 | field is set. Bitmask contents are: |
| 232 | (bit #0 is LSB) |
| 233 | bit #0: default payload type |
| 234 | bit #1: sender SSRC |
| 235 | bit #2: sequence |
| 236 | bit #3: timestamp */ |
| 237 | int default_pt; /**< Default payload type. */ |
| 238 | pj_uint32_t sender_ssrc; /**< Sender SSRC. */ |
| 239 | pj_uint16_t seq; /**< Sequence. */ |
| 240 | pj_uint32_t ts; /**< Timestamp. */ |
| 241 | } pjmedia_rtp_session_setting; |
| 242 | |
| 243 | |
| 244 | /** |
| 245 | * @see pjmedia_rtp_status |
| 246 | */ |
| 247 | typedef struct pjmedia_rtp_status pjmedia_rtp_status; |
| 248 | |
| 249 | |
| 250 | /** |
| 251 | * This function will initialize the RTP session according to given parameters. |
| 252 | * |
| 253 | * @param ses The session. |
| 254 | * @param default_pt Default payload type. |
| 255 | * @param sender_ssrc SSRC used for outgoing packets, in host byte order. |
| 256 | * |
| 257 | * @return PJ_SUCCESS if successfull. |
| 258 | */ |
| 259 | PJ_DECL(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses, |
| 260 | int default_pt, |
| 261 | pj_uint32_t sender_ssrc ); |
| 262 | |
| 263 | /** |
| 264 | * This function will initialize the RTP session according to given parameters |
| 265 | * defined in RTP session settings. |
| 266 | * |
| 267 | * @param ses The session. |
| 268 | * @param settings RTP session settings. |
| 269 | * |
| 270 | * @return PJ_SUCCESS if successfull. |
| 271 | */ |
| 272 | PJ_DECL(pj_status_t) pjmedia_rtp_session_init2( |
| 273 | pjmedia_rtp_session *ses, |
| 274 | pjmedia_rtp_session_setting settings); |
| 275 | |
| 276 | |
| 277 | /** |
| 278 | * Create the RTP header based on arguments and current state of the RTP |
| 279 | * session. |
| 280 | * |
| 281 | * @param ses The session. |
| 282 | * @param pt Payload type. |
| 283 | * @param m Marker flag. |
| 284 | * @param payload_len Payload length in bytes. |
| 285 | * @param ts_len Timestamp length. |
| 286 | * @param rtphdr Upon return will point to RTP packet header. |
| 287 | * @param hdrlen Upon return will indicate the size of RTP packet header |
| 288 | * |
| 289 | * @return PJ_SUCCESS if successfull. |
| 290 | */ |
| 291 | PJ_DECL(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses, |
| 292 | int pt, int m, |
| 293 | int payload_len, int ts_len, |
| 294 | const void **rtphdr, |
| 295 | int *hdrlen ); |
| 296 | |
| 297 | /** |
| 298 | * This function decodes incoming packet into RTP header and payload. |
| 299 | * The decode function is guaranteed to point the payload to the correct |
| 300 | * position regardless of any options present in the RTP packet. |
| 301 | * |
| 302 | * Note that this function does not modify the returned RTP header to |
| 303 | * host byte order. |
| 304 | * |
| 305 | * @param ses The session. |
| 306 | * @param pkt The received RTP packet. |
| 307 | * @param pkt_len The length of the packet. |
| 308 | * @param hdr Upon return will point to the location of the RTP |
| 309 | * header inside the packet. Note that the RTP header |
| 310 | * will be given back as is, meaning that the fields |
| 311 | * will be in network byte order. |
| 312 | * @param payload Upon return will point to the location of the |
| 313 | * payload inside the packet. |
| 314 | * @param payloadlen Upon return will indicate the size of the payload. |
| 315 | * |
| 316 | * @return PJ_SUCCESS if successfull. |
| 317 | */ |
| 318 | PJ_DECL(pj_status_t) pjmedia_rtp_decode_rtp( pjmedia_rtp_session *ses, |
| 319 | const void *pkt, int pkt_len, |
| 320 | const pjmedia_rtp_hdr **hdr, |
| 321 | const void **payload, |
| 322 | unsigned *payloadlen); |
| 323 | |
| 324 | /** |
| 325 | * Call this function everytime an RTP packet is received to check whether |
| 326 | * the packet can be received and to let the RTP session performs its internal |
| 327 | * calculations. |
| 328 | * |
| 329 | * @param ses The session. |
| 330 | * @param hdr The RTP header of the incoming packet. The header must |
| 331 | * be given with fields in network byte order. |
| 332 | * @param seq_st Optional structure to receive the status of the RTP packet |
| 333 | * processing. |
| 334 | */ |
| 335 | PJ_DECL(void) pjmedia_rtp_session_update( pjmedia_rtp_session *ses, |
| 336 | const pjmedia_rtp_hdr *hdr, |
| 337 | pjmedia_rtp_status *seq_st); |
| 338 | |
| 339 | |
| 340 | /** |
| 341 | * Call this function everytime an RTP packet is received to check whether |
| 342 | * the packet can be received and to let the RTP session performs its internal |
| 343 | * calculations. |
| 344 | * |
| 345 | * @param ses The session. |
| 346 | * @param hdr The RTP header of the incoming packet. The header must |
| 347 | * be given with fields in network byte order. |
| 348 | * @param seq_st Optional structure to receive the status of the RTP packet |
| 349 | * processing. |
| 350 | * @param check_pt Flag to indicate whether payload type needs to be validate. |
| 351 | * |
| 352 | * @see pjmedia_rtp_session_update() |
| 353 | */ |
| 354 | PJ_DECL(void) pjmedia_rtp_session_update2(pjmedia_rtp_session *ses, |
| 355 | const pjmedia_rtp_hdr *hdr, |
| 356 | pjmedia_rtp_status *seq_st, |
| 357 | pj_bool_t check_pt); |
| 358 | |
| 359 | |
| 360 | /* |
| 361 | * INTERNAL: |
| 362 | */ |
| 363 | |
| 364 | /** |
| 365 | * Internal function for creating sequence number control, shared by RTCP |
| 366 | * implementation. |
| 367 | * |
| 368 | * @param seq_ctrl The sequence control instance. |
| 369 | * @param seq Sequence number to initialize. |
| 370 | */ |
| 371 | void pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *seq_ctrl, |
| 372 | pj_uint16_t seq); |
| 373 | |
| 374 | |
| 375 | /** |
| 376 | * Internal function update sequence control, shared by RTCP implementation. |
| 377 | * |
| 378 | * @param seq_ctrl The sequence control instance. |
| 379 | * @param seq Sequence number to update. |
| 380 | * @param seq_status Optional structure to receive additional information |
| 381 | * about the packet. |
| 382 | */ |
| 383 | void pjmedia_rtp_seq_update( pjmedia_rtp_seq_session *seq_ctrl, |
| 384 | pj_uint16_t seq, |
| 385 | pjmedia_rtp_status *seq_status); |
| 386 | |
| 387 | /** |
| 388 | * @} |
| 389 | */ |
| 390 | |
| 391 | PJ_END_DECL |
| 392 | |
| 393 | |
| 394 | #endif /* __PJMEDIA_RTP_H__ */ |