summaryrefslogtreecommitdiff
path: root/toxav
diff options
context:
space:
mode:
Diffstat (limited to 'toxav')
-rw-r--r--toxav/rtp.c63
-rw-r--r--toxav/rtp.h15
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
38enum { 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!
47static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data, 45static 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
63enum { 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
317static void update_bwc_values(const Logger *log, RTPSession *session, const struct RTPMessage *msg) 314static 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:
586size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) 583size_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
644RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, 642RTPSession *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 */
48enum { 48typedef 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 */
57enum RTPFlags { 57typedef 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
70struct RTPHeader { 70struct 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
162typedef 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);
198size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header); 200size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header);
199 201
200RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, 202RTPSession *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 *));
203void rtp_kill(RTPSession *session); 204void rtp_kill(RTPSession *session);
204int rtp_allow_receiving(RTPSession *session); 205int rtp_allow_receiving(RTPSession *session);
205int rtp_stop_receiving(RTPSession *session); 206int rtp_stop_receiving(RTPSession *session);