diff options
Diffstat (limited to 'toxav')
-rw-r--r-- | toxav/rtp.c | 63 | ||||
-rw-r--r-- | toxav/rtp.h | 15 |
2 files changed, 38 insertions, 40 deletions
diff --git a/toxav/rtp.c b/toxav/rtp.c index ca4a4a7b..61297937 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c | |||
@@ -35,13 +35,11 @@ | |||
35 | #include "../toxcore/mono_time.h" | 35 | #include "../toxcore/mono_time.h" |
36 | #include "../toxcore/util.h" | 36 | #include "../toxcore/util.h" |
37 | 37 | ||
38 | enum { | 38 | /** |
39 | /** | 39 | * The number of milliseconds we want to keep a keyframe in the buffer for, |
40 | * The number of milliseconds we want to keep a keyframe in the buffer for, | 40 | * even though there are no free slots for incoming frames. |
41 | * even though there are no free slots for incoming frames. | 41 | */ |
42 | */ | 42 | #define VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS 15 |
43 | VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS = 15, | ||
44 | }; | ||
45 | 43 | ||
46 | // allocate_len is NOT including header! | 44 | // allocate_len is NOT including header! |
47 | static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data, | 45 | static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data, |
@@ -60,16 +58,15 @@ static struct RTPMessage *new_message(const struct RTPHeader *header, size_t all | |||
60 | return msg; | 58 | return msg; |
61 | } | 59 | } |
62 | 60 | ||
63 | enum { | 61 | /** |
64 | /** | 62 | * Instruct the caller to clear slot 0. |
65 | * Instruct the caller to clear slot 0. | 63 | */ |
66 | */ | 64 | #define GET_SLOT_RESULT_DROP_OLDEST_SLOT (-1) |
67 | GET_SLOT_RESULT_DROP_OLDEST_SLOT = -1, | 65 | |
68 | /** | 66 | /** |
69 | * Instruct the caller to drop the incoming packet. | 67 | * Instruct the caller to drop the incoming packet. |
70 | */ | 68 | */ |
71 | GET_SLOT_RESULT_DROP_INCOMING = -2, | 69 | #define GET_SLOT_RESULT_DROP_INCOMING (-2) |
72 | }; | ||
73 | 70 | ||
74 | /** | 71 | /** |
75 | * Find the next free slot in work_buffer for the incoming data packet. | 72 | * Find the next free slot in work_buffer for the incoming data packet. |
@@ -89,7 +86,7 @@ static int8_t get_slot(const Logger *log, struct RTPWorkBufferList *wkbl, bool i | |||
89 | if (is_multipart) { | 86 | if (is_multipart) { |
90 | // This RTP message is part of a multipart frame, so we try to find an | 87 | // This RTP message is part of a multipart frame, so we try to find an |
91 | // existing slot with the previous parts of the frame in it. | 88 | // existing slot with the previous parts of the frame in it. |
92 | for (uint8_t i = 0; i < wkbl->next_free_entry; i++) { | 89 | for (uint8_t i = 0; i < wkbl->next_free_entry; ++i) { |
93 | const struct RTPWorkBuffer *slot = &wkbl->work_buffer[i]; | 90 | const struct RTPWorkBuffer *slot = &wkbl->work_buffer[i]; |
94 | 91 | ||
95 | if ((slot->buf->header.sequnum == header->sequnum) && (slot->buf->header.timestamp == header->timestamp)) { | 92 | if ((slot->buf->header.sequnum == header->sequnum) && (slot->buf->header.timestamp == header->timestamp)) { |
@@ -228,14 +225,14 @@ static struct RTPMessage *process_frame(const Logger *log, struct RTPWorkBufferL | |||
228 | if (slot_id != wkbl->next_free_entry - 1) { | 225 | if (slot_id != wkbl->next_free_entry - 1) { |
229 | // The slot is not the last slot, so we created a gap. We move all the | 226 | // The slot is not the last slot, so we created a gap. We move all the |
230 | // entries after it one step up. | 227 | // entries after it one step up. |
231 | for (uint8_t i = slot_id; i < wkbl->next_free_entry - 1; i++) { | 228 | for (uint8_t i = slot_id; i < wkbl->next_free_entry - 1; ++i) { |
232 | // Move entry (i+1) into entry (i). | 229 | // Move entry (i+1) into entry (i). |
233 | wkbl->work_buffer[i] = wkbl->work_buffer[i + 1]; | 230 | wkbl->work_buffer[i] = wkbl->work_buffer[i + 1]; |
234 | } | 231 | } |
235 | } | 232 | } |
236 | 233 | ||
237 | // We now have a free entry at the end of the array. | 234 | // We now have a free entry at the end of the array. |
238 | wkbl->next_free_entry--; | 235 | --wkbl->next_free_entry; |
239 | 236 | ||
240 | // Clear the newly freed entry. | 237 | // Clear the newly freed entry. |
241 | const struct RTPWorkBuffer empty = {0}; | 238 | const struct RTPWorkBuffer empty = {0}; |
@@ -290,7 +287,7 @@ static bool fill_data_into_slot(const Logger *log, struct RTPWorkBufferList *wkb | |||
290 | slot->received_len = 0; | 287 | slot->received_len = 0; |
291 | 288 | ||
292 | assert(wkbl->next_free_entry < USED_RTP_WORKBUFFER_COUNT); | 289 | assert(wkbl->next_free_entry < USED_RTP_WORKBUFFER_COUNT); |
293 | wkbl->next_free_entry++; | 290 | ++wkbl->next_free_entry; |
294 | } | 291 | } |
295 | 292 | ||
296 | // We already checked this when we received the packet, but we rely on it | 293 | // We already checked this when we received the packet, but we rely on it |
@@ -317,7 +314,7 @@ static bool fill_data_into_slot(const Logger *log, struct RTPWorkBufferList *wkb | |||
317 | static void update_bwc_values(const Logger *log, RTPSession *session, const struct RTPMessage *msg) | 314 | static void update_bwc_values(const Logger *log, RTPSession *session, const struct RTPMessage *msg) |
318 | { | 315 | { |
319 | if (session->first_packets_counter < DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT) { | 316 | if (session->first_packets_counter < DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT) { |
320 | session->first_packets_counter++; | 317 | ++session->first_packets_counter; |
321 | } else { | 318 | } else { |
322 | uint32_t data_length_full = msg->header.data_length_full; // without header | 319 | uint32_t data_length_full = msg->header.data_length_full; // without header |
323 | uint32_t received_length_full = msg->header.received_length_full; // without header | 320 | uint32_t received_length_full = msg->header.received_length_full; // without header |
@@ -586,12 +583,14 @@ NEW_MULTIPARTED: | |||
586 | size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) | 583 | size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) |
587 | { | 584 | { |
588 | uint8_t *p = rdata; | 585 | uint8_t *p = rdata; |
589 | *p++ = (header->ve & 3) << 6 | 586 | *p = (header->ve & 3) << 6 |
590 | | (header->pe & 1) << 5 | 587 | | (header->pe & 1) << 5 |
591 | | (header->xe & 1) << 4 | 588 | | (header->xe & 1) << 4 |
592 | | (header->cc & 0xf); | 589 | | (header->cc & 0xf); |
593 | *p++ = (header->ma & 1) << 7 | 590 | ++p; |
594 | | (header->pt & 0x7f); | 591 | *p = (header->ma & 1) << 7 |
592 | | (header->pt & 0x7f); | ||
593 | ++p; | ||
595 | 594 | ||
596 | p += net_pack_u16(p, header->sequnum); | 595 | p += net_pack_u16(p, header->sequnum); |
597 | p += net_pack_u32(p, header->timestamp); | 596 | p += net_pack_u32(p, header->timestamp); |
@@ -601,7 +600,7 @@ size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) | |||
601 | p += net_pack_u32(p, header->data_length_full); | 600 | p += net_pack_u32(p, header->data_length_full); |
602 | p += net_pack_u32(p, header->received_length_full); | 601 | p += net_pack_u32(p, header->received_length_full); |
603 | 602 | ||
604 | for (size_t i = 0; i < RTP_PADDING_FIELDS; i++) { | 603 | for (size_t i = 0; i < RTP_PADDING_FIELDS; ++i) { |
605 | p += net_pack_u32(p, 0); | 604 | p += net_pack_u32(p, 0); |
606 | } | 605 | } |
607 | 606 | ||
@@ -640,10 +639,8 @@ size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header) | |||
640 | return p - data; | 639 | return p - data; |
641 | } | 640 | } |
642 | 641 | ||
643 | |||
644 | RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, | 642 | RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, |
645 | BWController *bwc, void *cs, | 643 | BWController *bwc, void *cs, rtp_m_cb *mcb) |
646 | int (*mcb)(void *, struct RTPMessage *)) | ||
647 | { | 644 | { |
648 | assert(mcb != nullptr); | 645 | assert(mcb != nullptr); |
649 | assert(cs != nullptr); | 646 | assert(cs != nullptr); |
@@ -851,6 +848,6 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, | |||
851 | } | 848 | } |
852 | } | 849 | } |
853 | 850 | ||
854 | session->sequnum ++; | 851 | ++session->sequnum; |
855 | return 0; | 852 | return 0; |
856 | } | 853 | } |
diff --git a/toxav/rtp.h b/toxav/rtp.h index e1cf7950..225f4c03 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h | |||
@@ -45,16 +45,16 @@ extern "C" { | |||
45 | /** | 45 | /** |
46 | * Payload type identifier. Also used as rtp callback prefix. | 46 | * Payload type identifier. Also used as rtp callback prefix. |
47 | */ | 47 | */ |
48 | enum { | 48 | typedef enum RTP_Type { |
49 | RTP_TYPE_AUDIO = 192, | 49 | RTP_TYPE_AUDIO = 192, |
50 | RTP_TYPE_VIDEO = 193, | 50 | RTP_TYPE_VIDEO = 193, |
51 | }; | 51 | } RTP_Type; |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * A bit mask (up to 64 bits) specifying features of the current frame affecting | 54 | * A bit mask (up to 64 bits) specifying features of the current frame affecting |
55 | * the behaviour of the decoder. | 55 | * the behaviour of the decoder. |
56 | */ | 56 | */ |
57 | enum RTPFlags { | 57 | typedef enum RTPFlags { |
58 | /** | 58 | /** |
59 | * Support frames larger than 64KiB. The full 32 bit length and offset are | 59 | * Support frames larger than 64KiB. The full 32 bit length and offset are |
60 | * set in \ref RTPHeader::data_length_full and \ref RTPHeader::offset_full. | 60 | * set in \ref RTPHeader::data_length_full and \ref RTPHeader::offset_full. |
@@ -64,7 +64,7 @@ enum RTPFlags { | |||
64 | * Whether the packet is part of a key frame. | 64 | * Whether the packet is part of a key frame. |
65 | */ | 65 | */ |
66 | RTP_KEY_FRAME = 1 << 1, | 66 | RTP_KEY_FRAME = 1 << 1, |
67 | }; | 67 | } RTPFlags; |
68 | 68 | ||
69 | 69 | ||
70 | struct RTPHeader { | 70 | struct RTPHeader { |
@@ -159,6 +159,8 @@ struct RTPWorkBufferList { | |||
159 | 159 | ||
160 | #define DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT 10 | 160 | #define DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT 10 |
161 | 161 | ||
162 | typedef int rtp_m_cb(void *cs, struct RTPMessage *msg); | ||
163 | |||
162 | /** | 164 | /** |
163 | * RTP control session. | 165 | * RTP control session. |
164 | */ | 166 | */ |
@@ -175,7 +177,7 @@ typedef struct RTPSession { | |||
175 | uint32_t friend_number; | 177 | uint32_t friend_number; |
176 | BWController *bwc; | 178 | BWController *bwc; |
177 | void *cs; | 179 | void *cs; |
178 | int (*mcb)(void *, struct RTPMessage *msg); | 180 | rtp_m_cb *mcb; |
179 | } RTPSession; | 181 | } RTPSession; |
180 | 182 | ||
181 | 183 | ||
@@ -198,8 +200,7 @@ size_t rtp_header_pack(uint8_t *rdata, const struct RTPHeader *header); | |||
198 | size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header); | 200 | size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header); |
199 | 201 | ||
200 | RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, | 202 | RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, |
201 | BWController *bwc, void *cs, | 203 | BWController *bwc, void *cs, rtp_m_cb *mcb); |
202 | int (*mcb)(void *, struct RTPMessage *)); | ||
203 | void rtp_kill(RTPSession *session); | 204 | void rtp_kill(RTPSession *session); |
204 | int rtp_allow_receiving(RTPSession *session); | 205 | int rtp_allow_receiving(RTPSession *session); |
205 | int rtp_stop_receiving(RTPSession *session); | 206 | int rtp_stop_receiving(RTPSession *session); |