Coverage Report

Created: 2024-01-26 01:52

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