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