chenqiyang
2021-08-16 d98a16782ce455ebf4624c6d29e4311598b7eead
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * Copyright (c) 2010-2019 Belledonne Communications SARL.
 *
 * This file is part of oRTP.
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */
 
 
#ifndef RTP_H
#define RTP_H
 
#include <ortp/port.h>
#include <ortp/str_utils.h>
 
#define IPMAXLEN 20
#define UDP_MAX_SIZE 1500
#define RTP_FIXED_HEADER_SIZE 12
#define RTP_DEFAULT_JITTER_TIME 80    /*miliseconds*/
#define RTP_DEFAULT_MULTICAST_TTL 5    /*hops*/
#define RTP_DEFAULT_MULTICAST_LOOPBACK 0  /*false*/
#define RTP_DEFAULT_DSCP 0x00  /*best effort*/
 
 
 
typedef struct rtp_header
{
#ifdef ORTP_BIGENDIAN
    uint16_t version:2;
    uint16_t padbit:1;
    uint16_t extbit:1;
    uint16_t cc:4;
    uint16_t markbit:1;
    uint16_t paytype:7;
#else
    uint16_t cc:4;
    uint16_t extbit:1;
    uint16_t padbit:1;
    uint16_t version:2;
    uint16_t paytype:7;
    uint16_t markbit:1;
#endif
    uint16_t seq_number;
    uint32_t timestamp;
    uint32_t ssrc;
    uint32_t csrc[16];
} rtp_header_t;
 
/* MAX is 15 because we use 1-byte header */
typedef enum {
    RTP_EXTENSION_NONE = 0,
    RTP_EXTENSION_MID = 1,
    RTP_EXTENSION_MAX = 15
} rtp_extension_type_t;
 
typedef struct rtp_stats
{
    uint64_t packet_sent;        /*number of outgoing packets */
    uint64_t packet_dup_sent;    /*number of outgoing duplicate packets */
    uint64_t sent;                /* outgoing total bytes (excluding IP header) */
    uint64_t packet_recv;        /* number of incoming packets */
    uint64_t packet_dup_recv;    /* number of incoming duplicate packets */
    uint64_t recv;                /* incoming bytes of payload and delivered in time to the application */
    uint64_t hw_recv;            /* incoming bytes of payload */
    uint64_t outoftime;            /* number of incoming packets that were received too late */
    int64_t  cum_packet_loss;    /* cumulative number of incoming packet lost */
    uint64_t bad;                /* incoming packets that did not appear to be RTP */
    uint64_t discarded;            /* incoming packets discarded because the queue exceeds its max size */
    uint64_t sent_rtcp_packets;    /* outgoing RTCP packets counter (only packets that embed a report block are considered) */
    uint64_t recv_rtcp_packets;    /* incoming RTCP packets counter (only packets that embed a report block are considered) */
} rtp_stats_t;
 
 
typedef struct jitter_stats
{
    uint32_t jitter;            /* interarrival jitter at last emitted sender report */
    uint32_t max_jitter;        /* biggest interarrival jitter (value in stream clock unit) */
    uint64_t sum_jitter;        /* sum of all interarrival jitter (value in stream clock unit) */
    uint64_t max_jitter_ts;        /* date (in ms since Epoch) of the biggest interarrival jitter */
    float jitter_buffer_size_ms;/* mean jitter buffer size in milliseconds.*/
} jitter_stats_t;
 
#define RTP_TIMESTAMP_IS_NEWER_THAN(ts1, ts2) \
    ((uint32_t)((uint32_t)(ts1) - (uint32_t)(ts2)) < ((uint32_t)1 << 31))
 
#define RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(ts1, ts2) \
    (((uint32_t)((uint32_t)(ts1) - (uint32_t)(ts2)) < ((uint32_t)1 << 31)) && (ts1) != (ts2))
 
#define RTP_SEQ_IS_STRICTLY_GREATER_THAN(seq1, seq2) \
    (((uint16_t)((uint16_t)(seq1) - (uint16_t)(seq2)) < ((uint16_t)1 << 15)) && (seq1) != (seq2))
 
#define TIME_IS_NEWER_THAN(t1,t2) RTP_TIMESTAMP_IS_NEWER_THAN(t1,t2)
 
#define TIME_IS_STRICTLY_NEWER_THAN(t1,t2) RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(t1,t2)
 
 
#ifdef __cplusplus
extern "C"{
#endif
 
/* packet api */
/* the first argument is a mblk_t. The header is supposed to be not splitted  */
#define rtp_set_markbit(mp,value)    ((rtp_header_t*)((mp)->b_rptr))->markbit=(value)
#define rtp_set_extbit(mp,value)    ((rtp_header_t*)((mp)->b_rptr))->extbit=(value)
#define rtp_set_seqnumber(mp,seq)    ((rtp_header_t*)((mp)->b_rptr))->seq_number=(seq)
#define rtp_set_timestamp(mp,ts)    ((rtp_header_t*)((mp)->b_rptr))->timestamp=(ts)
#define rtp_set_ssrc(mp,_ssrc)        ((rtp_header_t*)((mp)->b_rptr))->ssrc=(_ssrc)
ORTP_PUBLIC void rtp_add_csrc(mblk_t *mp ,uint32_t csrc);
#define rtp_set_payload_type(mp,pt)    ((rtp_header_t*)((mp)->b_rptr))->paytype=(pt)
 
#define rtp_get_version(mp)    (((rtp_header_t*)((mp)->b_rptr))->version)
#define rtp_get_markbit(mp)    (((rtp_header_t*)((mp)->b_rptr))->markbit)
#define rtp_get_extbit(mp)    (((rtp_header_t*)((mp)->b_rptr))->extbit)
#define rtp_get_timestamp(mp)    (((rtp_header_t*)((mp)->b_rptr))->timestamp)
#define rtp_get_seqnumber(mp)    (((rtp_header_t*)((mp)->b_rptr))->seq_number)
#define rtp_get_payload_type(mp)    (((rtp_header_t*)((mp)->b_rptr))->paytype)
#define rtp_get_ssrc(mp)        (((rtp_header_t*)((mp)->b_rptr))->ssrc)
#define rtp_get_cc(mp)        (((rtp_header_t*)((mp)->b_rptr))->cc)
#define rtp_get_csrc(mp, idx)        (((rtp_header_t*)((mp)->b_rptr))->csrc[idx])
 
ORTP_PUBLIC int rtp_get_payload(mblk_t *packet, unsigned char **start);
ORTP_PUBLIC int rtp_get_extheader(mblk_t *packet, uint16_t *profile, uint8_t **start_ext);
 
/* Extension header api */
ORTP_PUBLIC void rtp_add_extension_header(mblk_t *packet, int id, size_t size, uint8_t *data);
ORTP_PUBLIC int rtp_get_extension_header(mblk_t *packet, int id, uint8_t **data);
 
#ifdef __cplusplus
}
#endif
 
#endif