1 /* SPDX-License-Identifier: GPL-3.0-or-later
2  * Copyright © 2016-2018 The TokTok team.
3  * Copyright © 2013-2015 Tox project.
4  */
5 #ifndef C_TOXCORE_TOXAV_RTP_H
6 #define C_TOXCORE_TOXAV_RTP_H
7 
8 #include "bwcontroller.h"
9 
10 #include "../toxcore/Messenger.h"
11 #include "../toxcore/logger.h"
12 
13 #include <stdbool.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 #ifndef TOX_DEFINED
20 #define TOX_DEFINED
21 typedef struct Tox Tox;
22 #endif /* TOX_DEFINED */
23 
24 /**
25  * RTPHeader serialised size in bytes.
26  */
27 #define RTP_HEADER_SIZE 80
28 
29 /**
30  * Number of 32 bit padding fields between \ref RTPHeader::offset_lower and
31  * everything before it.
32  */
33 #define RTP_PADDING_FIELDS 11
34 
35 /**
36  * Payload type identifier. Also used as rtp callback prefix.
37  */
38 typedef enum RTP_Type {
39     RTP_TYPE_AUDIO = 192,
40     RTP_TYPE_VIDEO = 193,
41 } RTP_Type;
42 
43 /**
44  * A bit mask (up to 64 bits) specifying features of the current frame affecting
45  * the behaviour of the decoder.
46  */
47 typedef enum RTPFlags {
48     /**
49      * Support frames larger than 64KiB. The full 32 bit length and offset are
50      * set in \ref RTPHeader::data_length_full and \ref RTPHeader::offset_full.
51      */
52     RTP_LARGE_FRAME = 1 << 0,
53     /**
54      * Whether the packet is part of a key frame.
55      */
56     RTP_KEY_FRAME = 1 << 1,
57 } RTPFlags;
58 
59 
60 struct RTPHeader {
61     /* Standard RTP header */
62     unsigned ve: 2; /* Version has only 2 bits! */
63     unsigned pe: 1; /* Padding */
64     unsigned xe: 1; /* Extra header */
65     unsigned cc: 4; /* Contributing sources count */
66 
67     unsigned ma: 1; /* Marker */
68     unsigned pt: 7; /* Payload type */
69 
70     uint16_t sequnum;
71     uint32_t timestamp;
72     uint32_t ssrc;
73 
74     /* Non-standard Tox-specific fields */
75 
76     /**
77      * Bit mask of \ref RTPFlags setting features of the current frame.
78      */
79     uint64_t flags;
80 
81     /**
82      * The full 32 bit data offset of the current data chunk. The \ref
83      * offset_lower data member contains the lower 16 bits of this value. For
84      * frames smaller than 64KiB, \ref offset_full and \ref offset_lower are
85      * equal.
86      */
87     uint32_t offset_full;
88     /**
89      * The full 32 bit payload length without header and packet id.
90      */
91     uint32_t data_length_full;
92     /**
93      * Only the receiver uses this field (why do we have this?).
94      */
95     uint32_t received_length_full;
96 
97     /**
98      * Data offset of the current part (lower bits).
99      */
100     uint16_t offset_lower;
101     /**
102      * Total message length (lower bits).
103      */
104     uint16_t data_length_lower;
105 };
106 
107 
108 struct RTPMessage {
109     /**
110      * This is used in the old code that doesn't deal with large frames, i.e.
111      * the audio code or receiving code for old 16 bit messages. We use it to
112      * record the number of bytes received so far in a multi-part message. The
113      * multi-part message in the old code is stored in \ref RTPSession::mp.
114      */
115     uint16_t len;
116 
117     struct RTPHeader header;
118     uint8_t data[];
119 };
120 
121 #define USED_RTP_WORKBUFFER_COUNT 3
122 
123 /**
124  * One slot in the work buffer list. Represents one frame that is currently
125  * being assembled.
126  */
127 struct RTPWorkBuffer {
128     /**
129      * Whether this slot contains a key frame. This is true iff
130      * `buf->header.flags & RTP_KEY_FRAME`.
131      */
132     bool is_keyframe;
133     /**
134      * The number of bytes received so far, regardless of which pieces. I.e. we
135      * could have received the first 1000 bytes and the last 1000 bytes with
136      * 4000 bytes in the middle still to come, and this number would be 2000.
137      */
138     uint32_t received_len;
139     /**
140      * The message currently being assembled.
141      */
142     struct RTPMessage *buf;
143 };
144 
145 struct RTPWorkBufferList {
146     int8_t next_free_entry;
147     struct RTPWorkBuffer work_buffer[USED_RTP_WORKBUFFER_COUNT];
148 };
149 
150 #define DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT 10
151 
152 typedef int rtp_m_cb(Mono_Time *mono_time, void *cs, struct RTPMessage *msg);
153 
154 /**
155  * RTP control session.
156  */
157 typedef struct RTPSession {
158     uint8_t  payload_type;
159     uint16_t sequnum;      /* Sending sequence number */
160     uint16_t rsequnum;     /* Receiving sequence number */
161     uint32_t rtimestamp;
162     uint32_t ssrc; //  this seems to be unused!?
163     struct RTPMessage *mp; /* Expected parted message */
164     struct RTPWorkBufferList *work_buffer_list;
165     uint8_t  first_packets_counter; /* dismiss first few lost video packets */
166     Messenger *m;
167     Tox *tox;
168     uint32_t friend_number;
169     BWController *bwc;
170     void *cs;
171     rtp_m_cb *mcb;
172 } RTPSession;
173 
174 
175 /**
176  * Serialise an RTPHeader to bytes to be sent over the network.
177  *
178  * @param rdata A byte array of length RTP_HEADER_SIZE. Does not need to be
179  *   initialised. All RTP_HEADER_SIZE bytes will be initialised after a call
180  *   to this function.
181  * @param header The RTPHeader to serialise.
182  */
183 size_t rtp_header_pack(uint8_t *rdata, const struct RTPHeader *header);
184 
185 /**
186  * Deserialise an RTPHeader from bytes received over the network.
187  *
188  * @param data A byte array of length RTP_HEADER_SIZE.
189  * @param header The RTPHeader to write the unpacked values to.
190  */
191 size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header);
192 
193 RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnumber,
194                     BWController *bwc, void *cs, rtp_m_cb *mcb);
195 void rtp_kill(RTPSession *session);
196 int rtp_allow_receiving(RTPSession *session);
197 int rtp_stop_receiving(RTPSession *session);
198 /**
199  * Send a frame of audio or video data, chunked in \ref RTPMessage instances.
200  *
201  * @param session The A/V session to send the data for.
202  * @param data A byte array of length \p length.
203  * @param length The number of bytes to send from @p data.
204  * @param is_keyframe Whether this video frame is a key frame. If it is an
205  *   audio frame, this parameter is ignored.
206  */
207 int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
208                   bool is_keyframe, const Logger *log);
209 
210 #ifdef __cplusplus
211 }  // extern "C"
212 #endif
213 
214 #endif // C_TOXCORE_TOXAV_RTP_H
215