summaryrefslogtreecommitdiffstats
path: root/tinyRTP/src/rtcp
diff options
context:
space:
mode:
Diffstat (limited to 'tinyRTP/src/rtcp')
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_header.c133
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_packet.c379
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_rblock.c167
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_report.c6
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_report_bye.c319
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_report_fb.c1101
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_report_rr.c337
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_report_sdes.c271
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_report_sr.c407
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_report_xr.c6
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_sdes_chunck.c224
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_sdes_item.c171
-rwxr-xr-xtinyRTP/src/rtcp/trtp_rtcp_session.c2421
13 files changed, 3051 insertions, 2891 deletions
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_header.c b/tinyRTP/src/rtcp/trtp_rtcp_header.c
index e93772a..d11d32f 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_header.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_header.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -35,73 +35,73 @@ header |V=2|P| RC | PT=SR=200 | length |
trtp_rtcp_header_t* trtp_rtcp_header_create_null()
{
- return tsk_object_new(trtp_rtcp_header_def_t);
+ return tsk_object_new(trtp_rtcp_header_def_t);
}
trtp_rtcp_header_t* trtp_rtcp_header_create(uint8_t version, uint8_t padding, uint8_t rc, trtp_rtcp_packet_type_t type, uint16_t length_in_bytes)
{
- trtp_rtcp_header_t* header;
- if((header = trtp_rtcp_header_create_null())){
- header->version = version;
- header->padding = padding;
- header->rc = rc;
- header->type = type;
- header->length_in_words_minus1 = ((length_in_bytes >> 2) - 1);
- header->length_in_bytes = length_in_bytes;
- }
+ trtp_rtcp_header_t* header;
+ if((header = trtp_rtcp_header_create_null())) {
+ header->version = version;
+ header->padding = padding;
+ header->rc = rc;
+ header->type = type;
+ header->length_in_words_minus1 = ((length_in_bytes >> 2) - 1);
+ header->length_in_bytes = length_in_bytes;
+ }
- return header;
+ return header;
}
int trtp_rtcp_header_serialize_to(const trtp_rtcp_header_t *self, void* data, tsk_size_t size)
{
- uint8_t* pdata = (uint8_t*)data;
- if(!self || !data || size < TRTP_RTCP_HEADER_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- // Octet-0: version(2), Padding(1), RC(5)
- pdata[0] = ((uint8_t)self->version)<<6 |
- ((uint8_t)self->padding)<<5 |
- ((uint8_t)self->rc);
- // Octet-1: PT(8)
- pdata[1] = self->type;
- // Octet-2 and Octet3: length (16)
- pdata[2] = self->length_in_words_minus1 >> 8;
- pdata[3] = self->length_in_words_minus1 & 0xFF;
- return 0;
+ uint8_t* pdata = (uint8_t*)data;
+ if(!self || !data || size < TRTP_RTCP_HEADER_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ // Octet-0: version(2), Padding(1), RC(5)
+ pdata[0] = ((uint8_t)self->version)<<6 |
+ ((uint8_t)self->padding)<<5 |
+ ((uint8_t)self->rc);
+ // Octet-1: PT(8)
+ pdata[1] = self->type;
+ // Octet-2 and Octet3: length (16)
+ pdata[2] = self->length_in_words_minus1 >> 8;
+ pdata[3] = self->length_in_words_minus1 & 0xFF;
+ return 0;
}
trtp_rtcp_header_t* trtp_rtcp_header_deserialize(const void *data, tsk_size_t size)
{
- trtp_rtcp_header_t* header = tsk_null;
- if(trtp_rtcp_header_deserialize_to(&header, data, size) != 0){
- TSK_DEBUG_ERROR("Failed to deserialize the rtcp header");
- TSK_OBJECT_SAFE_FREE(header);
- }
- return header;
+ trtp_rtcp_header_t* header = tsk_null;
+ if(trtp_rtcp_header_deserialize_to(&header, data, size) != 0) {
+ TSK_DEBUG_ERROR("Failed to deserialize the rtcp header");
+ TSK_OBJECT_SAFE_FREE(header);
+ }
+ return header;
}
int trtp_rtcp_header_deserialize_to(trtp_rtcp_header_t** self, const void *data, tsk_size_t size)
{
- const uint8_t* pdata = (uint8_t*)data;
- if(!self || !data || size < TRTP_RTCP_HEADER_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(!*self && !(*self = trtp_rtcp_header_create_null())){
- TSK_DEBUG_ERROR("Failed to create new rtcp header");
- return -3;
- }
- (*self)->version = pdata[0] >> 6;
- (*self)->padding = (pdata[0] >> 5) & 0x01;
- (*self)->rc = (pdata[0] & 0x1f);
- (*self)->type = (enum trtp_rtcp_packet_type_e)pdata[1];
- (*self)->length_in_words_minus1 = tnet_ntohs_2(&pdata[2]);
- (*self)->length_in_bytes = ((*self)->length_in_words_minus1 + 1) << 2;
+ const uint8_t* pdata = (uint8_t*)data;
+ if(!self || !data || size < TRTP_RTCP_HEADER_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- return 0;
+ if(!*self && !(*self = trtp_rtcp_header_create_null())) {
+ TSK_DEBUG_ERROR("Failed to create new rtcp header");
+ return -3;
+ }
+ (*self)->version = pdata[0] >> 6;
+ (*self)->padding = (pdata[0] >> 5) & 0x01;
+ (*self)->rc = (pdata[0] & 0x1f);
+ (*self)->type = (enum trtp_rtcp_packet_type_e)pdata[1];
+ (*self)->length_in_words_minus1 = tnet_ntohs_2(&pdata[2]);
+ (*self)->length_in_bytes = ((*self)->length_in_words_minus1 + 1) << 2;
+
+ return 0;
}
//=================================================================================================
@@ -109,26 +109,25 @@ int trtp_rtcp_header_deserialize_to(trtp_rtcp_header_t** self, const void *data,
//
static tsk_object_t* trtp_rtcp_header_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_header_t *header = self;
- if(header){
- }
- return self;
+ trtp_rtcp_header_t *header = self;
+ if(header) {
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_header_dtor(tsk_object_t * self)
-{
- trtp_rtcp_header_t *header = self;
- if(header){
- }
+{
+ trtp_rtcp_header_t *header = self;
+ if(header) {
+ }
- return self;
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_header_def_s =
-{
- sizeof(trtp_rtcp_header_t),
- trtp_rtcp_header_ctor,
- trtp_rtcp_header_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_header_def_s = {
+ sizeof(trtp_rtcp_header_t),
+ trtp_rtcp_header_ctor,
+ trtp_rtcp_header_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_header_def_t = &trtp_rtcp_header_def_s;
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_packet.c b/tinyRTP/src/rtcp/trtp_rtcp_packet.c
index d2ec856..d5614b8 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_packet.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_packet.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -32,224 +32,255 @@
static tsk_object_t* trtp_rtcp_packet_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_packet_t *packet = self;
- if(packet){
- }
- return self;
+ trtp_rtcp_packet_t *packet = self;
+ if(packet) {
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_packet_dtor(tsk_object_t * self)
-{
- trtp_rtcp_packet_t *packet = self;
- if(packet){
+{
+ trtp_rtcp_packet_t *packet = self;
+ if(packet) {
- }
+ }
- return self;
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_packet_def_s =
-{
- sizeof(trtp_rtcp_packet_t),
- trtp_rtcp_packet_ctor,
- trtp_rtcp_packet_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_packet_def_s = {
+ sizeof(trtp_rtcp_packet_t),
+ trtp_rtcp_packet_ctor,
+ trtp_rtcp_packet_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_packet_def_t = &trtp_rtcp_packet_def_s;
trtp_rtcp_packet_t* trtp_rtcp_packet_create(struct trtp_rtcp_header_s* header)
{
- trtp_rtcp_packet_t* packet;
- if((packet = tsk_object_new(trtp_rtcp_packet_def_t)) && header){
- packet->header = tsk_object_ref(header);
- }
- return packet;
+ trtp_rtcp_packet_t* packet;
+ if((packet = tsk_object_new(trtp_rtcp_packet_def_t)) && header) {
+ packet->header = tsk_object_ref(header);
+ }
+ return packet;
}
int trtp_rtcp_packet_init(trtp_rtcp_packet_t* self, uint8_t version, uint8_t padding, uint8_t rc, trtp_rtcp_packet_type_t type, uint16_t length_in_bytes)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(!self->header){
- self->header = trtp_rtcp_header_create(version, padding, rc, type, length_in_bytes);
- }
- else{
- self->header->version = version;
- self->header->padding = padding;
- self->header->rc = rc;
- self->header->type = type;
- self->header->length_in_bytes = length_in_bytes;
- self->header->length_in_words_minus1 = ((length_in_bytes >> 2) - 1);
- }
- return 0;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if(!self->header) {
+ self->header = trtp_rtcp_header_create(version, padding, rc, type, length_in_bytes);
+ }
+ else {
+ self->header->version = version;
+ self->header->padding = padding;
+ self->header->rc = rc;
+ self->header->type = type;
+ self->header->length_in_bytes = length_in_bytes;
+ self->header->length_in_words_minus1 = ((length_in_bytes >> 2) - 1);
+ }
+ return 0;
}
trtp_rtcp_packet_t* trtp_rtcp_packet_deserialize(const void* data, tsk_size_t size)
{
- trtp_rtcp_packet_type_t type;
-
- if(!data || size < TRTP_RTCP_HEADER_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- type = (trtp_rtcp_packet_type_t)((const uint8_t*)data)[1];
-
- switch(type){
- case trtp_rtcp_packet_type_rr: return (trtp_rtcp_packet_t*)trtp_rtcp_report_rr_deserialize(data, size);
- case trtp_rtcp_packet_type_sr: return (trtp_rtcp_packet_t*)trtp_rtcp_report_sr_deserialize(data, size);
- case trtp_rtcp_packet_type_sdes: return (trtp_rtcp_packet_t*)trtp_rtcp_report_sdes_deserialize(data, size);
- case trtp_rtcp_packet_type_bye: return (trtp_rtcp_packet_t*)trtp_rtcp_report_bye_deserialize(data, size);
- case trtp_rtcp_packet_type_rtpfb: return (trtp_rtcp_packet_t*)trtp_rtcp_report_rtpfb_deserialize(data, size);
- case trtp_rtcp_packet_type_psfb: return (trtp_rtcp_packet_t*)trtp_rtcp_report_psfb_deserialize(data, size);
- default:
- {
- // returns abstract RTCP packet
- trtp_rtcp_header_t* header;
- TSK_DEBUG_ERROR("%d not recognized as valid RTCP packet type", (int)type);
- if((header = trtp_rtcp_header_deserialize(data, size))){
- trtp_rtcp_packet_t* packet = trtp_rtcp_packet_create(header);
- TSK_OBJECT_SAFE_FREE(header);
- return packet;
- }
- break;
- }
- }
-
- return tsk_null;
+ trtp_rtcp_packet_type_t type;
+
+ if(!data || size < TRTP_RTCP_HEADER_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+
+ type = (trtp_rtcp_packet_type_t)((const uint8_t*)data)[1];
+
+ switch(type) {
+ case trtp_rtcp_packet_type_rr:
+ return (trtp_rtcp_packet_t*)trtp_rtcp_report_rr_deserialize(data, size);
+ case trtp_rtcp_packet_type_sr:
+ return (trtp_rtcp_packet_t*)trtp_rtcp_report_sr_deserialize(data, size);
+ case trtp_rtcp_packet_type_sdes:
+ return (trtp_rtcp_packet_t*)trtp_rtcp_report_sdes_deserialize(data, size);
+ case trtp_rtcp_packet_type_bye:
+ return (trtp_rtcp_packet_t*)trtp_rtcp_report_bye_deserialize(data, size);
+ case trtp_rtcp_packet_type_rtpfb:
+ return (trtp_rtcp_packet_t*)trtp_rtcp_report_rtpfb_deserialize(data, size);
+ case trtp_rtcp_packet_type_psfb:
+ return (trtp_rtcp_packet_t*)trtp_rtcp_report_psfb_deserialize(data, size);
+ default: {
+ // returns abstract RTCP packet
+ trtp_rtcp_header_t* header;
+ TSK_DEBUG_ERROR("%d not recognized as valid RTCP packet type", (int)type);
+ if((header = trtp_rtcp_header_deserialize(data, size))) {
+ trtp_rtcp_packet_t* packet = trtp_rtcp_packet_create(header);
+ TSK_OBJECT_SAFE_FREE(header);
+ return packet;
+ }
+ break;
+ }
+ }
+
+ return tsk_null;
}
int trtp_rtcp_packet_serialize_to(const trtp_rtcp_packet_t* self, void* data, tsk_size_t size)
{
- if(!self || !self->header || !data || !size){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- switch(self->header->type){
- case trtp_rtcp_packet_type_rr: return trtp_rtcp_report_rr_serialize_to((const trtp_rtcp_report_rr_t*)self, data, size);
- case trtp_rtcp_packet_type_sr: return trtp_rtcp_report_sr_serialize_to((const trtp_rtcp_report_sr_t*)self, data, size);
- case trtp_rtcp_packet_type_sdes: return trtp_rtcp_report_sdes_serialize_to((const trtp_rtcp_report_sdes_t*)self, data, size);
- case trtp_rtcp_packet_type_bye: return trtp_rtcp_report_bye_serialize_to((const trtp_rtcp_report_bye_t*)self, data, size);
- case trtp_rtcp_packet_type_psfb: return trtp_rtcp_report_psfb_serialize_to((const trtp_rtcp_report_psfb_t*)self, data, size);
- case trtp_rtcp_packet_type_rtpfb: return trtp_rtcp_report_rtpfb_serialize_to((const trtp_rtcp_report_rtpfb_t*)self, data, size);
- default:
- {
- TSK_DEBUG_ERROR("%d not recognized as valid RTCP packet type", (int)self->header->type);
- return -2;
- }
- }
+ if(!self || !self->header || !data || !size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ switch(self->header->type) {
+ case trtp_rtcp_packet_type_rr:
+ return trtp_rtcp_report_rr_serialize_to((const trtp_rtcp_report_rr_t*)self, data, size);
+ case trtp_rtcp_packet_type_sr:
+ return trtp_rtcp_report_sr_serialize_to((const trtp_rtcp_report_sr_t*)self, data, size);
+ case trtp_rtcp_packet_type_sdes:
+ return trtp_rtcp_report_sdes_serialize_to((const trtp_rtcp_report_sdes_t*)self, data, size);
+ case trtp_rtcp_packet_type_bye:
+ return trtp_rtcp_report_bye_serialize_to((const trtp_rtcp_report_bye_t*)self, data, size);
+ case trtp_rtcp_packet_type_psfb:
+ return trtp_rtcp_report_psfb_serialize_to((const trtp_rtcp_report_psfb_t*)self, data, size);
+ case trtp_rtcp_packet_type_rtpfb:
+ return trtp_rtcp_report_rtpfb_serialize_to((const trtp_rtcp_report_rtpfb_t*)self, data, size);
+ default: {
+ TSK_DEBUG_ERROR("%d not recognized as valid RTCP packet type", (int)self->header->type);
+ return -2;
+ }
+ }
}
tsk_buffer_t* trtp_rtcp_packet_serialize(const trtp_rtcp_packet_t* self, tsk_size_t num_bytes_pad)
{
- tsk_size_t size = trtp_rtcp_packet_get_size(self);
- if(self && size){
- tsk_buffer_t* buffer;
- const tsk_size_t _size = (size + num_bytes_pad);
- if((buffer = tsk_buffer_create(tsk_null, _size))){
- if(trtp_rtcp_packet_serialize_to(self, buffer->data, size) != 0){
- TSK_OBJECT_SAFE_FREE(buffer);
- }
- else buffer->size = size;
- return buffer;
- }
- }
- return tsk_null;
+ tsk_size_t size = trtp_rtcp_packet_get_size(self);
+ if(self && size) {
+ tsk_buffer_t* buffer;
+ const tsk_size_t _size = (size + num_bytes_pad);
+ if((buffer = tsk_buffer_create(tsk_null, _size))) {
+ if(trtp_rtcp_packet_serialize_to(self, buffer->data, size) != 0) {
+ TSK_OBJECT_SAFE_FREE(buffer);
+ }
+ else {
+ buffer->size = size;
+ }
+ return buffer;
+ }
+ }
+ return tsk_null;
}
int trtp_rtcp_packet_add_packet(trtp_rtcp_packet_t* self, trtp_rtcp_packet_t* packet, tsk_bool_t front)
{
- trtp_rtcp_packets_L_t* packets = tsk_null;
- if(!self || !self->header || !packet){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- switch(self->header->type){
- case trtp_rtcp_packet_type_rr: packets = ((trtp_rtcp_report_rr_t*)self)->packets; break;
- case trtp_rtcp_packet_type_sr: packets = ((trtp_rtcp_report_sr_t*)self)->packets; break;
- case trtp_rtcp_packet_type_bye: packets = ((trtp_rtcp_report_bye_t*)self)->packets; break;
- default: TSK_DEBUG_ERROR("not valid operation for packet type %d", (int)self->header->type); return -2;
- }
-
- if(packets){
- //tsk_size_t packet_size = trtp_rtcp_packet_get_size(packet);
- packet = tsk_object_ref(packet);
- // self->header->length_in_bytes += packet_size;
- // self->header->length_in_words_minus1 = ((self->header->length_in_bytes >> 2) - 1) +
- // ((self->header->length_in_bytes & 0x03) ? 1 : 0);
- tsk_list_push_data(packets, (void**)&packet, !front);
- }
-
- return 0;
+ trtp_rtcp_packets_L_t* packets = tsk_null;
+ if(!self || !self->header || !packet) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ switch(self->header->type) {
+ case trtp_rtcp_packet_type_rr:
+ packets = ((trtp_rtcp_report_rr_t*)self)->packets;
+ break;
+ case trtp_rtcp_packet_type_sr:
+ packets = ((trtp_rtcp_report_sr_t*)self)->packets;
+ break;
+ case trtp_rtcp_packet_type_bye:
+ packets = ((trtp_rtcp_report_bye_t*)self)->packets;
+ break;
+ default:
+ TSK_DEBUG_ERROR("not valid operation for packet type %d", (int)self->header->type);
+ return -2;
+ }
+
+ if(packets) {
+ //tsk_size_t packet_size = trtp_rtcp_packet_get_size(packet);
+ packet = tsk_object_ref(packet);
+ // self->header->length_in_bytes += packet_size;
+ // self->header->length_in_words_minus1 = ((self->header->length_in_bytes >> 2) - 1) +
+ // ((self->header->length_in_bytes & 0x03) ? 1 : 0);
+ tsk_list_push_data(packets, (void**)&packet, !front);
+ }
+
+ return 0;
}
const trtp_rtcp_packet_t* trtp_rtcp_packet_get_at(const trtp_rtcp_packet_t* self, trtp_rtcp_packet_type_t type, tsk_size_t index)
{
- const tsk_list_item_t *item;
- const trtp_rtcp_packets_L_t* packets = tsk_null;
- tsk_size_t i;
-
- if(!self || !self->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
- if(self->header->type == type && index == 0){
- return self;
- }
- switch(self->header->type){
- case trtp_rtcp_packet_type_rr: packets = ((const trtp_rtcp_report_rr_t*)self)->packets; break;
- case trtp_rtcp_packet_type_sr: packets = ((const trtp_rtcp_report_sr_t*)self)->packets; break;
- case trtp_rtcp_packet_type_bye: packets = ((const trtp_rtcp_report_bye_t*)self)->packets; break;
- default: break;
- }
-
- i = 0;
- tsk_list_foreach(item, packets){
- if(TRTP_RTCP_PACKET(item->data)->header->type == type && i++ >= index){
- return TRTP_RTCP_PACKET(item->data);
- }
- }
- return tsk_null;
+ const tsk_list_item_t *item;
+ const trtp_rtcp_packets_L_t* packets = tsk_null;
+ tsk_size_t i;
+
+ if(!self || !self->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+ if(self->header->type == type && index == 0) {
+ return self;
+ }
+ switch(self->header->type) {
+ case trtp_rtcp_packet_type_rr:
+ packets = ((const trtp_rtcp_report_rr_t*)self)->packets;
+ break;
+ case trtp_rtcp_packet_type_sr:
+ packets = ((const trtp_rtcp_report_sr_t*)self)->packets;
+ break;
+ case trtp_rtcp_packet_type_bye:
+ packets = ((const trtp_rtcp_report_bye_t*)self)->packets;
+ break;
+ default:
+ break;
+ }
+
+ i = 0;
+ tsk_list_foreach(item, packets) {
+ if(TRTP_RTCP_PACKET(item->data)->header->type == type && i++ >= index) {
+ return TRTP_RTCP_PACKET(item->data);
+ }
+ }
+ return tsk_null;
}
const trtp_rtcp_packet_t* trtp_rtcp_packet_get(const trtp_rtcp_packet_t* self, trtp_rtcp_packet_type_t type)
{
- return trtp_rtcp_packet_get_at(self, type, 0);
+ return trtp_rtcp_packet_get_at(self, type, 0);
}
tsk_size_t trtp_rtcp_packet_get_size(const trtp_rtcp_packet_t* self)
{
- if(!self || !self->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- switch(self->header->type){
- case trtp_rtcp_packet_type_rr: return trtp_rtcp_report_rr_get_size((const trtp_rtcp_report_rr_t*)self);
- case trtp_rtcp_packet_type_sr: return trtp_rtcp_report_sr_get_size((const trtp_rtcp_report_sr_t*)self);
- case trtp_rtcp_packet_type_sdes: return trtp_rtcp_report_sdes_get_size((const trtp_rtcp_report_sdes_t*)self);
- case trtp_rtcp_packet_type_bye: return trtp_rtcp_report_bye_get_size((const trtp_rtcp_report_bye_t*)self);
- case trtp_rtcp_packet_type_rtpfb: return trtp_rtcp_report_rtpfb_get_size((const trtp_rtcp_report_rtpfb_t*)self);
- case trtp_rtcp_packet_type_psfb: return trtp_rtcp_report_psfb_get_size((const trtp_rtcp_report_psfb_t*)self);
- default:
- {
- TSK_DEBUG_ERROR("%d not recognized as valid RTCP packet type", (int)self->header->type);
- return self->header->length_in_bytes;
- }
- }
+ if(!self || !self->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+
+ switch(self->header->type) {
+ case trtp_rtcp_packet_type_rr:
+ return trtp_rtcp_report_rr_get_size((const trtp_rtcp_report_rr_t*)self);
+ case trtp_rtcp_packet_type_sr:
+ return trtp_rtcp_report_sr_get_size((const trtp_rtcp_report_sr_t*)self);
+ case trtp_rtcp_packet_type_sdes:
+ return trtp_rtcp_report_sdes_get_size((const trtp_rtcp_report_sdes_t*)self);
+ case trtp_rtcp_packet_type_bye:
+ return trtp_rtcp_report_bye_get_size((const trtp_rtcp_report_bye_t*)self);
+ case trtp_rtcp_packet_type_rtpfb:
+ return trtp_rtcp_report_rtpfb_get_size((const trtp_rtcp_report_rtpfb_t*)self);
+ case trtp_rtcp_packet_type_psfb:
+ return trtp_rtcp_report_psfb_get_size((const trtp_rtcp_report_psfb_t*)self);
+ default: {
+ TSK_DEBUG_ERROR("%d not recognized as valid RTCP packet type", (int)self->header->type);
+ return self->header->length_in_bytes;
+ }
+ }
}
int trtp_rtcp_packet_deinit(trtp_rtcp_packet_t* self)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- TSK_OBJECT_SAFE_FREE(self->header);
- return 0;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ TSK_OBJECT_SAFE_FREE(self->header);
+ return 0;
}
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_rblock.c b/tinyRTP/src/rtcp/trtp_rtcp_rblock.c
index 9a85b4b..3c9bc51 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_rblock.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_rblock.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -42,112 +42,111 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static tsk_object_t* trtp_rtcp_rblock_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_rblock_t *block = self;
- if(block){
- }
- return self;
+ trtp_rtcp_rblock_t *block = self;
+ if(block) {
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_rblock_dtor(tsk_object_t * self)
-{
- trtp_rtcp_rblock_t *block = self;
- if(block){
- }
+{
+ trtp_rtcp_rblock_t *block = self;
+ if(block) {
+ }
- return self;
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_rblock_def_s =
-{
- sizeof(trtp_rtcp_rblock_t),
- trtp_rtcp_rblock_ctor,
- trtp_rtcp_rblock_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_rblock_def_s = {
+ sizeof(trtp_rtcp_rblock_t),
+ trtp_rtcp_rblock_ctor,
+ trtp_rtcp_rblock_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_rblock_def_t = &trtp_rtcp_rblock_def_s;
trtp_rtcp_rblock_t* trtp_rtcp_rblock_create_null()
{
- return tsk_object_new(trtp_rtcp_rblock_def_t);
+ return tsk_object_new(trtp_rtcp_rblock_def_t);
}
trtp_rtcp_rblock_t* trtp_rtcp_rblock_deserialize(const void* data, tsk_size_t size)
{
- trtp_rtcp_rblock_t* rblock = tsk_null;
- const uint8_t* pdata = (const uint8_t*)data;
- if(!data || size < TRTP_RTCP_RBLOCK_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
- if((rblock = trtp_rtcp_rblock_create_null())){
- rblock->ssrc = (uint32_t)tnet_ntohl_2(pdata);
- rblock->fraction = pdata[4];
- rblock->cumulative_no_lost = (tnet_ntohl_2(&pdata[5]) >> 8) & 0xFFFFFF;
- rblock->last_seq = (uint32_t)tnet_ntohl_2(&pdata[8]);
- rblock->jitter = (uint32_t)tnet_ntohl_2(&pdata[12]);
- rblock->lsr = (uint32_t)tnet_ntohl_2(&pdata[16]);
- rblock->dlsr = (uint32_t)tnet_ntohl_2(&pdata[20]);
- }
- else{
- TSK_DEBUG_ERROR("Failed to create report block object");
- }
+ trtp_rtcp_rblock_t* rblock = tsk_null;
+ const uint8_t* pdata = (const uint8_t*)data;
+ if(!data || size < TRTP_RTCP_RBLOCK_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+ if((rblock = trtp_rtcp_rblock_create_null())) {
+ rblock->ssrc = (uint32_t)tnet_ntohl_2(pdata);
+ rblock->fraction = pdata[4];
+ rblock->cumulative_no_lost = (tnet_ntohl_2(&pdata[5]) >> 8) & 0xFFFFFF;
+ rblock->last_seq = (uint32_t)tnet_ntohl_2(&pdata[8]);
+ rblock->jitter = (uint32_t)tnet_ntohl_2(&pdata[12]);
+ rblock->lsr = (uint32_t)tnet_ntohl_2(&pdata[16]);
+ rblock->dlsr = (uint32_t)tnet_ntohl_2(&pdata[20]);
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to create report block object");
+ }
- return rblock;
+ return rblock;
}
// Up to the
int trtp_rtcp_rblock_deserialize_list(const void* data, tsk_size_t _size, trtp_rtcp_rblocks_L_t* dest_list)
{
- int32_t size = (int32_t)_size;
- const uint8_t* pdata = (const uint8_t*)data;
- trtp_rtcp_rblock_t* rblock;
+ int32_t size = (int32_t)_size;
+ const uint8_t* pdata = (const uint8_t*)data;
+ trtp_rtcp_rblock_t* rblock;
- if(!data || !size || !dest_list){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if(!data || !size || !dest_list) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- while(size >= TRTP_RTCP_RBLOCK_SIZE){
- if((rblock = trtp_rtcp_rblock_deserialize(pdata, size))){
- tsk_list_push_back_data(dest_list, (void**)&rblock);
- }
- if((size -= TRTP_RTCP_RBLOCK_SIZE) > 0){
- pdata += TRTP_RTCP_RBLOCK_SIZE;
- }
- }
- return 0;
+ while(size >= TRTP_RTCP_RBLOCK_SIZE) {
+ if((rblock = trtp_rtcp_rblock_deserialize(pdata, size))) {
+ tsk_list_push_back_data(dest_list, (void**)&rblock);
+ }
+ if((size -= TRTP_RTCP_RBLOCK_SIZE) > 0) {
+ pdata += TRTP_RTCP_RBLOCK_SIZE;
+ }
+ }
+ return 0;
}
int trtp_rtcp_rblock_serialize_to(const trtp_rtcp_rblock_t* self, void* data, tsk_size_t size)
{
- uint8_t* pdata = (uint8_t*)data;
- if(!self || !data || size < TRTP_RTCP_RBLOCK_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ uint8_t* pdata = (uint8_t*)data;
+ if(!self || !data || size < TRTP_RTCP_RBLOCK_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- pdata[0] = self->ssrc >> 24;
- pdata[1] = (self->ssrc >> 16) & 0xFF;
- pdata[2] = (self->ssrc >> 8) & 0xFF;
- pdata[3] = (self->ssrc & 0xFF);
- pdata[4] = self->fraction;
- pdata[5] = (self->cumulative_no_lost >> 16) & 0xFF;
- pdata[6] = (self->cumulative_no_lost >> 8) & 0xFF;
- pdata[7] = (self->cumulative_no_lost & 0xFF);
- pdata[8] = self->last_seq >> 24;
- pdata[9] = (self->last_seq >> 16) & 0xFF;
- pdata[10] = (self->last_seq >> 8) & 0xFF;
- pdata[11] = (self->last_seq & 0xFF);
- pdata[12] = self->jitter >> 24;
- pdata[13] = (self->jitter >> 16) & 0xFF;
- pdata[14] = (self->jitter >> 8) & 0xFF;
- pdata[15] = (self->jitter & 0xFF);
- pdata[16] = self->lsr >> 24;
- pdata[17] = (self->lsr >> 16) & 0xFF;
- pdata[18] = (self->lsr >> 8) & 0xFF;
- pdata[19] = (self->lsr & 0xFF);
- pdata[20] = self->dlsr >> 24;
- pdata[21] = (self->dlsr >> 16) & 0xFF;
- pdata[22] = (self->dlsr >> 8) & 0xFF;
- pdata[23] = (self->dlsr & 0xFF);
+ pdata[0] = self->ssrc >> 24;
+ pdata[1] = (self->ssrc >> 16) & 0xFF;
+ pdata[2] = (self->ssrc >> 8) & 0xFF;
+ pdata[3] = (self->ssrc & 0xFF);
+ pdata[4] = self->fraction;
+ pdata[5] = (self->cumulative_no_lost >> 16) & 0xFF;
+ pdata[6] = (self->cumulative_no_lost >> 8) & 0xFF;
+ pdata[7] = (self->cumulative_no_lost & 0xFF);
+ pdata[8] = self->last_seq >> 24;
+ pdata[9] = (self->last_seq >> 16) & 0xFF;
+ pdata[10] = (self->last_seq >> 8) & 0xFF;
+ pdata[11] = (self->last_seq & 0xFF);
+ pdata[12] = self->jitter >> 24;
+ pdata[13] = (self->jitter >> 16) & 0xFF;
+ pdata[14] = (self->jitter >> 8) & 0xFF;
+ pdata[15] = (self->jitter & 0xFF);
+ pdata[16] = self->lsr >> 24;
+ pdata[17] = (self->lsr >> 16) & 0xFF;
+ pdata[18] = (self->lsr >> 8) & 0xFF;
+ pdata[19] = (self->lsr & 0xFF);
+ pdata[20] = self->dlsr >> 24;
+ pdata[21] = (self->dlsr >> 16) & 0xFF;
+ pdata[22] = (self->dlsr >> 8) & 0xFF;
+ pdata[23] = (self->dlsr & 0xFF);
- return 0;
+ return 0;
} \ No newline at end of file
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_report.c b/tinyRTP/src/rtcp/trtp_rtcp_report.c
index 5fb2697..41e177b 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_report.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_report.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_report_bye.c b/tinyRTP/src/rtcp/trtp_rtcp_report_bye.c
index 0f44608..9085160 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_report_bye.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_report_bye.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -31,195 +31,194 @@
static tsk_object_t* trtp_rtcp_report_bye_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_report_bye_t *bye = self;
- if(bye){
- bye->packets = tsk_list_create();
- }
- return self;
+ trtp_rtcp_report_bye_t *bye = self;
+ if(bye) {
+ bye->packets = tsk_list_create();
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_report_bye_dtor(tsk_object_t * self)
-{
- trtp_rtcp_report_bye_t *bye = self;
- if(bye){
- // deinit self
- TSK_OBJECT_SAFE_FREE(bye->packets);
- TSK_FREE(bye->ssrc_list);
- // deinit base
- trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(bye));
- }
-
- return self;
+{
+ trtp_rtcp_report_bye_t *bye = self;
+ if(bye) {
+ // deinit self
+ TSK_OBJECT_SAFE_FREE(bye->packets);
+ TSK_FREE(bye->ssrc_list);
+ // deinit base
+ trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(bye));
+ }
+
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_report_bye_def_s =
-{
- sizeof(trtp_rtcp_report_bye_t),
- trtp_rtcp_report_bye_ctor,
- trtp_rtcp_report_bye_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_report_bye_def_s = {
+ sizeof(trtp_rtcp_report_bye_t),
+ trtp_rtcp_report_bye_ctor,
+ trtp_rtcp_report_bye_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_report_bye_def_t = &trtp_rtcp_report_bye_def_s;
trtp_rtcp_report_bye_t* trtp_rtcp_report_bye_create_null()
{
- trtp_rtcp_report_bye_t* bye;
- if((bye = (trtp_rtcp_report_bye_t*)tsk_object_new(trtp_rtcp_report_bye_def_t))){
- trtp_rtcp_packet_init(TRTP_RTCP_PACKET(bye), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_bye, TRTP_RTCP_HEADER_SIZE);
- }
- return bye;
+ trtp_rtcp_report_bye_t* bye;
+ if((bye = (trtp_rtcp_report_bye_t*)tsk_object_new(trtp_rtcp_report_bye_def_t))) {
+ trtp_rtcp_packet_init(TRTP_RTCP_PACKET(bye), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_bye, TRTP_RTCP_HEADER_SIZE);
+ }
+ return bye;
}
trtp_rtcp_report_bye_t* trtp_rtcp_report_bye_create(struct trtp_rtcp_header_s* header)
{
- trtp_rtcp_report_bye_t* bye;
- if((bye = (trtp_rtcp_report_bye_t*)tsk_object_new(trtp_rtcp_report_bye_def_t))){
- TRTP_RTCP_PACKET(bye)->header = tsk_object_ref(header);
- }
- return bye;
+ trtp_rtcp_report_bye_t* bye;
+ if((bye = (trtp_rtcp_report_bye_t*)tsk_object_new(trtp_rtcp_report_bye_def_t))) {
+ TRTP_RTCP_PACKET(bye)->header = tsk_object_ref(header);
+ }
+ return bye;
}
trtp_rtcp_report_bye_t* trtp_rtcp_report_bye_create_2(uint32_t ssrc)
{
- uint32_t* ssrc_list = tsk_malloc(sizeof(uint32_t));
- if(ssrc_list){
- trtp_rtcp_report_bye_t* bye;
- if((bye = (trtp_rtcp_report_bye_t*)tsk_object_new(trtp_rtcp_report_bye_def_t))){
- trtp_rtcp_packet_init(TRTP_RTCP_PACKET(bye), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_bye, (TRTP_RTCP_HEADER_SIZE + 4));
- TRTP_RTCP_PACKET(bye)->header->rc = 1;
- *ssrc_list = ssrc, bye->ssrc_list = ssrc_list, ssrc_list = tsk_null;
- }
- TSK_FREE(ssrc_list);
- return bye;
- }
- return tsk_null;
+ uint32_t* ssrc_list = tsk_malloc(sizeof(uint32_t));
+ if(ssrc_list) {
+ trtp_rtcp_report_bye_t* bye;
+ if((bye = (trtp_rtcp_report_bye_t*)tsk_object_new(trtp_rtcp_report_bye_def_t))) {
+ trtp_rtcp_packet_init(TRTP_RTCP_PACKET(bye), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_bye, (TRTP_RTCP_HEADER_SIZE + 4));
+ TRTP_RTCP_PACKET(bye)->header->rc = 1;
+ *ssrc_list = ssrc, bye->ssrc_list = ssrc_list, ssrc_list = tsk_null;
+ }
+ TSK_FREE(ssrc_list);
+ return bye;
+ }
+ return tsk_null;
}
trtp_rtcp_report_bye_t* trtp_rtcp_report_bye_deserialize(const void* data, tsk_size_t _size)
{
- trtp_rtcp_report_bye_t* bye = tsk_null;
- trtp_rtcp_header_t* header = tsk_null;
- const uint8_t* pdata = (const uint8_t*)data;
- int32_t size = (int32_t)_size;
-
- if(!data || size < TRTP_RTCP_PACKET_BYE_MIN_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- if(!(header = trtp_rtcp_header_deserialize(pdata, size))){
- TSK_DEBUG_ERROR("Failed to deserialize the header");
- goto bail;
- }
- if(header->length_in_bytes < TRTP_RTCP_PACKET_BYE_MIN_SIZE){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
-
- if(!(bye = trtp_rtcp_report_bye_create(header))){
- TSK_DEBUG_ERROR("Failed to create object");
- goto bail;
- }
-
- pdata += (TRTP_RTCP_HEADER_SIZE);
- size -= (TRTP_RTCP_HEADER_SIZE);
-
- // SSRCs
- if(header->rc > 0){
- tsk_size_t i;
- if((int32_t)(header->rc * sizeof(uint32_t)) > size){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
- if(!(bye->ssrc_list = tsk_calloc(header->rc, sizeof(uint32_t)))){
- goto bail;
- }
- for(i = 0; i < header->rc; ++i){
- bye->ssrc_list[i] = (uint32_t)tnet_ntohl_2(&pdata[0]);
- pdata += sizeof(uint32_t);
- size -= sizeof(uint32_t);
- }
- }
-
- // Other Packets
- while(size > TRTP_RTCP_HEADER_SIZE){
- trtp_rtcp_packet_t* packet;
-
- if((packet = trtp_rtcp_packet_deserialize(pdata, size))){
- if((size -= packet->header->length_in_bytes) > 0){
- pdata += packet->header->length_in_bytes;
- }
- tsk_list_push_back_data(bye->packets, (void**)&packet);
- continue;
- }
- break;
- }
+ trtp_rtcp_report_bye_t* bye = tsk_null;
+ trtp_rtcp_header_t* header = tsk_null;
+ const uint8_t* pdata = (const uint8_t*)data;
+ int32_t size = (int32_t)_size;
+
+ if(!data || size < TRTP_RTCP_PACKET_BYE_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+
+ if(!(header = trtp_rtcp_header_deserialize(pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to deserialize the header");
+ goto bail;
+ }
+ if(header->length_in_bytes < TRTP_RTCP_PACKET_BYE_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+
+ if(!(bye = trtp_rtcp_report_bye_create(header))) {
+ TSK_DEBUG_ERROR("Failed to create object");
+ goto bail;
+ }
+
+ pdata += (TRTP_RTCP_HEADER_SIZE);
+ size -= (TRTP_RTCP_HEADER_SIZE);
+
+ // SSRCs
+ if(header->rc > 0) {
+ tsk_size_t i;
+ if((int32_t)(header->rc * sizeof(uint32_t)) > size) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+ if(!(bye->ssrc_list = tsk_calloc(header->rc, sizeof(uint32_t)))) {
+ goto bail;
+ }
+ for(i = 0; i < header->rc; ++i) {
+ bye->ssrc_list[i] = (uint32_t)tnet_ntohl_2(&pdata[0]);
+ pdata += sizeof(uint32_t);
+ size -= sizeof(uint32_t);
+ }
+ }
+
+ // Other Packets
+ while(size > TRTP_RTCP_HEADER_SIZE) {
+ trtp_rtcp_packet_t* packet;
+
+ if((packet = trtp_rtcp_packet_deserialize(pdata, size))) {
+ if((size -= packet->header->length_in_bytes) > 0) {
+ pdata += packet->header->length_in_bytes;
+ }
+ tsk_list_push_back_data(bye->packets, (void**)&packet);
+ continue;
+ }
+ break;
+ }
bail:
- TSK_OBJECT_SAFE_FREE(header);
- return bye;
+ TSK_OBJECT_SAFE_FREE(header);
+ return bye;
}
int trtp_rtcp_report_bye_serialize_to(const trtp_rtcp_report_bye_t* self, void* data, tsk_size_t size)
{
- int ret;
- tsk_size_t i;
- uint8_t* pdata = (uint8_t*)data;
- const tsk_list_item_t* item;
-
- if(!self || !data || size < trtp_rtcp_report_bye_get_size(self)){
- return -1;
- }
-
- if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize the header");
- return ret;
- }
-
- pdata += (TRTP_RTCP_HEADER_SIZE);
- size -= (TRTP_RTCP_HEADER_SIZE);
-
- for(i = 0; i < TRTP_RTCP_PACKET(self)->header->rc; ++i){
- pdata[0] = self->ssrc_list[i] >> 24;
- pdata[1] = (self->ssrc_list[i] >> 16) & 0xFF;
- pdata[2] = (self->ssrc_list[i] >> 8) & 0xFF;
- pdata[3] = (self->ssrc_list[i] & 0xFF);
- pdata += 4;
- size -= 4;
- }
-
- tsk_list_foreach(item, self->packets){
- if(!item->data){
- continue;
- }
- if((ret = trtp_rtcp_packet_serialize_to(TRTP_RTCP_PACKET(item->data), pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize packet");
- goto bail;
- }
- pdata += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- size -= TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- }
+ int ret;
+ tsk_size_t i;
+ uint8_t* pdata = (uint8_t*)data;
+ const tsk_list_item_t* item;
+
+ if(!self || !data || size < trtp_rtcp_report_bye_get_size(self)) {
+ return -1;
+ }
+
+ if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize the header");
+ return ret;
+ }
+
+ pdata += (TRTP_RTCP_HEADER_SIZE);
+ size -= (TRTP_RTCP_HEADER_SIZE);
+
+ for(i = 0; i < TRTP_RTCP_PACKET(self)->header->rc; ++i) {
+ pdata[0] = self->ssrc_list[i] >> 24;
+ pdata[1] = (self->ssrc_list[i] >> 16) & 0xFF;
+ pdata[2] = (self->ssrc_list[i] >> 8) & 0xFF;
+ pdata[3] = (self->ssrc_list[i] & 0xFF);
+ pdata += 4;
+ size -= 4;
+ }
+
+ tsk_list_foreach(item, self->packets) {
+ if(!item->data) {
+ continue;
+ }
+ if((ret = trtp_rtcp_packet_serialize_to(TRTP_RTCP_PACKET(item->data), pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize packet");
+ goto bail;
+ }
+ pdata += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ size -= TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ }
bail:
- return ret;
+ return ret;
}
tsk_size_t trtp_rtcp_report_bye_get_size(const trtp_rtcp_report_bye_t* self)
{
- tsk_size_t size;
- const tsk_list_item_t* item;
-
- if(!self || !TRTP_RTCP_PACKET(self)->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- size = TRTP_RTCP_PACKET(self)->header->length_in_bytes;
- tsk_list_foreach(item, self->packets){
- if(item->data && TRTP_RTCP_PACKET(item->data)->header){
- size += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- }
- }
-
- return size;
+ tsk_size_t size;
+ const tsk_list_item_t* item;
+
+ if(!self || !TRTP_RTCP_PACKET(self)->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+
+ size = TRTP_RTCP_PACKET(self)->header->length_in_bytes;
+ tsk_list_foreach(item, self->packets) {
+ if(item->data && TRTP_RTCP_PACKET(item->data)->header) {
+ size += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ }
+ }
+
+ return size;
}
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_report_fb.c b/tinyRTP/src/rtcp/trtp_rtcp_report_fb.c
index bbc80b1..bb6690e 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_report_fb.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_report_fb.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WArtpfbANTY; without even the implied wartpfbanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -35,270 +35,274 @@
static int _trtp_rtcp_report_fb_deserialize(const void* data, tsk_size_t _size, trtp_rtcp_header_t** header, uint32_t* ssrc_sender, uint32_t* ssrc_media_src)
{
- const uint8_t* pdata = data;
- if(!data || !header || _size < TRTP_RTCP_PACKET_FB_MIN_SIZE || (_size & 0x03)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(!(*header = trtp_rtcp_header_deserialize(pdata, _size))){
- TSK_DEBUG_ERROR("Failed to deserialize the header");
- return -3;
- }
- if((*header)->length_in_bytes < TRTP_RTCP_PACKET_FB_MIN_SIZE){
- TSK_DEBUG_ERROR("Too short");
- return -4;
- }
- else if((*header)->length_in_bytes > _size){
- TSK_DEBUG_ERROR("Too long");
- return -5;
- }
-
- *ssrc_sender = (uint32_t)tnet_ntohl_2(&pdata[4]);
- *ssrc_media_src = (uint32_t)tnet_ntohl_2(&pdata[8]);
- return 0;
+ const uint8_t* pdata = data;
+ if(!data || !header || _size < TRTP_RTCP_PACKET_FB_MIN_SIZE || (_size & 0x03)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if(!(*header = trtp_rtcp_header_deserialize(pdata, _size))) {
+ TSK_DEBUG_ERROR("Failed to deserialize the header");
+ return -3;
+ }
+ if((*header)->length_in_bytes < TRTP_RTCP_PACKET_FB_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Too short");
+ return -4;
+ }
+ else if((*header)->length_in_bytes > _size) {
+ TSK_DEBUG_ERROR("Too long");
+ return -5;
+ }
+
+ *ssrc_sender = (uint32_t)tnet_ntohl_2(&pdata[4]);
+ *ssrc_media_src = (uint32_t)tnet_ntohl_2(&pdata[8]);
+ return 0;
}
static int _trtp_rtcp_report_fb_serialize_to(const trtp_rtcp_report_fb_t* self, void* data, tsk_size_t size)
{
- int ret;
- uint8_t* pdata = (uint8_t*)data;
-
- if(!self || !data || size < TRTP_RTCP_PACKET_FB_MIN_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize the header");
- return ret;
- }
-
- pdata[TRTP_RTCP_HEADER_SIZE] = self->ssrc_sender >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 1] = (self->ssrc_sender >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 2] = (self->ssrc_sender >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 3] = (self->ssrc_sender & 0xFF);
- pdata[TRTP_RTCP_HEADER_SIZE + 4] = self->ssrc_media >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 5] = (self->ssrc_media >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 6] = (self->ssrc_media >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 7] = (self->ssrc_media & 0xFF);
-
- return 0;
+ int ret;
+ uint8_t* pdata = (uint8_t*)data;
+
+ if(!self || !data || size < TRTP_RTCP_PACKET_FB_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize the header");
+ return ret;
+ }
+
+ pdata[TRTP_RTCP_HEADER_SIZE] = self->ssrc_sender >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 1] = (self->ssrc_sender >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 2] = (self->ssrc_sender >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 3] = (self->ssrc_sender & 0xFF);
+ pdata[TRTP_RTCP_HEADER_SIZE + 4] = self->ssrc_media >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 5] = (self->ssrc_media >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 6] = (self->ssrc_media >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 7] = (self->ssrc_media & 0xFF);
+
+ return 0;
}
static tsk_object_t* trtp_rtcp_report_rtpfb_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_report_rtpfb_t *rtpfb = self;
- if(rtpfb){
-
- }
- return self;
+ trtp_rtcp_report_rtpfb_t *rtpfb = self;
+ if(rtpfb) {
+
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_report_rtpfb_dtor(tsk_object_t * self)
-{
- trtp_rtcp_report_rtpfb_t *rtpfb = self;
- if(rtpfb){
- // deinit self
- switch(rtpfb->fci_type){
- case trtp_rtcp_rtpfb_fci_type_nack:
- {
- TSK_FREE(rtpfb->nack.pid);
- TSK_FREE(rtpfb->nack.blp);
- break;
- }
- case trtp_rtcp_rtpfb_fci_type_tmmbn:
- {
- TSK_FREE(rtpfb->tmmbn.ssrc);
- TSK_FREE(rtpfb->tmmbn.MxTBR_Exp);
- TSK_FREE(rtpfb->tmmbn.MxTBR_Mantissa);
- TSK_FREE(rtpfb->tmmbn.MeasuredOverhead);
- break;
- }
- }
- // deinit base
- trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(rtpfb));
- }
-
- return self;
-}
-static const tsk_object_def_t trtp_rtcp_report_rtpfb_def_s =
{
- sizeof(trtp_rtcp_report_rtpfb_t),
- trtp_rtcp_report_rtpfb_ctor,
- trtp_rtcp_report_rtpfb_dtor,
- tsk_null,
+ trtp_rtcp_report_rtpfb_t *rtpfb = self;
+ if(rtpfb) {
+ // deinit self
+ switch(rtpfb->fci_type) {
+ case trtp_rtcp_rtpfb_fci_type_nack: {
+ TSK_FREE(rtpfb->nack.pid);
+ TSK_FREE(rtpfb->nack.blp);
+ break;
+ }
+ case trtp_rtcp_rtpfb_fci_type_tmmbn: {
+ TSK_FREE(rtpfb->tmmbn.ssrc);
+ TSK_FREE(rtpfb->tmmbn.MxTBR_Exp);
+ TSK_FREE(rtpfb->tmmbn.MxTBR_Mantissa);
+ TSK_FREE(rtpfb->tmmbn.MeasuredOverhead);
+ break;
+ }
+ }
+ // deinit base
+ trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(rtpfb));
+ }
+
+ return self;
+}
+static const tsk_object_def_t trtp_rtcp_report_rtpfb_def_s = {
+ sizeof(trtp_rtcp_report_rtpfb_t),
+ trtp_rtcp_report_rtpfb_ctor,
+ trtp_rtcp_report_rtpfb_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_report_rtpfb_def_t = &trtp_rtcp_report_rtpfb_def_s;
trtp_rtcp_report_rtpfb_t* trtp_rtcp_report_rtpfb_create_null()
{
- trtp_rtcp_report_rtpfb_t* rtpfb;
- if((rtpfb = (trtp_rtcp_report_rtpfb_t*)tsk_object_new(trtp_rtcp_report_rtpfb_def_t))){
- trtp_rtcp_packet_init(TRTP_RTCP_PACKET(rtpfb), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_rtpfb, TRTP_RTCP_PACKET_FB_MIN_SIZE);
- }
- return rtpfb;
+ trtp_rtcp_report_rtpfb_t* rtpfb;
+ if((rtpfb = (trtp_rtcp_report_rtpfb_t*)tsk_object_new(trtp_rtcp_report_rtpfb_def_t))) {
+ trtp_rtcp_packet_init(TRTP_RTCP_PACKET(rtpfb), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_rtpfb, TRTP_RTCP_PACKET_FB_MIN_SIZE);
+ }
+ return rtpfb;
}
trtp_rtcp_report_rtpfb_t* trtp_rtcp_report_rtpfb_create(trtp_rtcp_header_t* header)
{
- trtp_rtcp_report_rtpfb_t* rtpfb;
- if((rtpfb = (trtp_rtcp_report_rtpfb_t*)tsk_object_new(trtp_rtcp_report_rtpfb_def_t))){
- TRTP_RTCP_PACKET(rtpfb)->header = tsk_object_ref(header);
- }
- return rtpfb;
+ trtp_rtcp_report_rtpfb_t* rtpfb;
+ if((rtpfb = (trtp_rtcp_report_rtpfb_t*)tsk_object_new(trtp_rtcp_report_rtpfb_def_t))) {
+ TRTP_RTCP_PACKET(rtpfb)->header = tsk_object_ref(header);
+ }
+ return rtpfb;
}
trtp_rtcp_report_rtpfb_t* trtp_rtcp_report_rtpfb_create_2(trtp_rtcp_rtpfb_fci_type_t fci_type, uint32_t ssrc_sender, uint32_t ssrc_media_src)
{
- trtp_rtcp_report_rtpfb_t* rtpfb;
- if((rtpfb = trtp_rtcp_report_rtpfb_create_null())){
- rtpfb->fci_type = TRTP_RTCP_PACKET(rtpfb)->header->rc = fci_type;
- TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_sender = ssrc_sender;
- TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_media = ssrc_media_src;
- }
- return rtpfb;
+ trtp_rtcp_report_rtpfb_t* rtpfb;
+ if((rtpfb = trtp_rtcp_report_rtpfb_create_null())) {
+ rtpfb->fci_type = TRTP_RTCP_PACKET(rtpfb)->header->rc = fci_type;
+ TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_sender = ssrc_sender;
+ TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_media = ssrc_media_src;
+ }
+ return rtpfb;
}
// seq_nums[n] must be in [seq_nums[0], seq_nums[0] + 16] and > seq_nums[n - 1]
trtp_rtcp_report_rtpfb_t* trtp_rtcp_report_rtpfb_create_nack(uint32_t ssrc_sender, uint32_t ssrc_media_src, const uint16_t* seq_nums, tsk_size_t count)
{
- trtp_rtcp_report_rtpfb_t* rtpfb;
- if(!seq_nums || !count){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
- if((rtpfb = trtp_rtcp_report_rtpfb_create_2(trtp_rtcp_rtpfb_fci_type_nack, ssrc_sender, ssrc_media_src))){
- tsk_size_t i, j;
- rtpfb->nack.count = 1; // max = 16
- rtpfb->nack.blp = tsk_malloc(sizeof(uint16_t));
- rtpfb->nack.pid = tsk_malloc(sizeof(uint16_t));
- if(!rtpfb->nack.blp || !rtpfb->nack.pid){
- TSK_OBJECT_SAFE_FREE(rtpfb);
- return tsk_null;
- }
- rtpfb->nack.pid[0] = seq_nums[0];
- rtpfb->nack.blp[0] = 0;
- for(i = 1; i <= 16 && i < count; ++i){
- j = seq_nums[i] - rtpfb->nack.pid[0];
- rtpfb->nack.blp[0] |= (1 << (j - 1));
- }
-
- TRTP_RTCP_PACKET(rtpfb)->header->length_in_bytes += (uint32_t)(rtpfb->nack.count << 2);
- TRTP_RTCP_PACKET(rtpfb)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(rtpfb)->header->length_in_bytes >> 2) - 1);
- }
- return rtpfb;
+ trtp_rtcp_report_rtpfb_t* rtpfb;
+ if(!seq_nums || !count) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+ if((rtpfb = trtp_rtcp_report_rtpfb_create_2(trtp_rtcp_rtpfb_fci_type_nack, ssrc_sender, ssrc_media_src))) {
+ tsk_size_t i, j;
+ rtpfb->nack.count = 1; // max = 16
+ rtpfb->nack.blp = tsk_malloc(sizeof(uint16_t));
+ rtpfb->nack.pid = tsk_malloc(sizeof(uint16_t));
+ if(!rtpfb->nack.blp || !rtpfb->nack.pid) {
+ TSK_OBJECT_SAFE_FREE(rtpfb);
+ return tsk_null;
+ }
+ rtpfb->nack.pid[0] = seq_nums[0];
+ rtpfb->nack.blp[0] = 0;
+ for(i = 1; i <= 16 && i < count; ++i) {
+ j = seq_nums[i] - rtpfb->nack.pid[0];
+ rtpfb->nack.blp[0] |= (1 << (j - 1));
+ }
+
+ TRTP_RTCP_PACKET(rtpfb)->header->length_in_bytes += (uint32_t)(rtpfb->nack.count << 2);
+ TRTP_RTCP_PACKET(rtpfb)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(rtpfb)->header->length_in_bytes >> 2) - 1);
+ }
+ return rtpfb;
}
trtp_rtcp_report_rtpfb_t* trtp_rtcp_report_rtpfb_deserialize(const void* data, tsk_size_t _size)
{
- trtp_rtcp_report_rtpfb_t* rtpfb = tsk_null;
- trtp_rtcp_header_t* header = tsk_null;
- uint32_t ssrc_sender, ssrc_media_src;
-
- if(_trtp_rtcp_report_fb_deserialize(data, _size, &header, &ssrc_sender, &ssrc_media_src) == 0){
- if((rtpfb = trtp_rtcp_report_rtpfb_create(header))){
- const uint8_t* pdata = ((const uint8_t*)data) + TRTP_RTCP_PACKET_FB_MIN_SIZE;
- tsk_size_t size = (header->length_in_bytes - TRTP_RTCP_PACKET_FB_MIN_SIZE), i;
-
- TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_sender = ssrc_sender;
- TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_media = ssrc_media_src;
-
- switch(rtpfb->fci_type = (trtp_rtcp_rtpfb_fci_type_t)header->rc){
- case trtp_rtcp_rtpfb_fci_type_nack:
- {
- if((rtpfb->nack.count = (size >> 2)) > 0){
- rtpfb->nack.pid = tsk_realloc(rtpfb->nack.pid, (rtpfb->nack.count * sizeof(uint16_t)));
- rtpfb->nack.blp = tsk_realloc(rtpfb->nack.blp, (rtpfb->nack.count * sizeof(uint16_t)));
- for(i = 0; i < rtpfb->nack.count; ++i){
- if(rtpfb->nack.pid) rtpfb->nack.pid[i] = tnet_ntohs_2(&pdata[0]);
- if(rtpfb->nack.blp) rtpfb->nack.blp[i] = tnet_ntohs_2(&pdata[2]);
- pdata += 4;
- }
- }
- break;
- }
- case trtp_rtcp_rtpfb_fci_type_tmmbn:
- {
- TSK_DEBUG_INFO("TMMBN");
- if((rtpfb->tmmbn.count = (size >> 3)) > 0){
- uint32_t u32;
- rtpfb->tmmbn.ssrc = tsk_realloc(rtpfb->tmmbn.ssrc, (rtpfb->tmmbn.count * sizeof(uint32_t)));
- rtpfb->tmmbn.MxTBR_Exp = tsk_realloc(rtpfb->tmmbn.MxTBR_Exp, (rtpfb->tmmbn.count * sizeof(uint16_t)));
- rtpfb->tmmbn.MxTBR_Mantissa = tsk_realloc(rtpfb->tmmbn.MxTBR_Mantissa, (rtpfb->tmmbn.count * sizeof(uint32_t)));
- rtpfb->tmmbn.MeasuredOverhead = tsk_realloc(rtpfb->tmmbn.MeasuredOverhead, (rtpfb->tmmbn.count * sizeof(uint16_t)));
- for(i = 0; i < rtpfb->tmmbn.count; ++i){
- if(rtpfb->tmmbn.ssrc) rtpfb->tmmbn.ssrc[i] = (uint32_t)tnet_ntohl_2(&pdata[0]);
- u32 = (uint32_t)tnet_ntohl_2(&pdata[4]);
- if(rtpfb->tmmbn.MxTBR_Exp) rtpfb->tmmbn.MxTBR_Exp[i] = (u32 >> 26);
- if(rtpfb->tmmbn.MxTBR_Mantissa) rtpfb->tmmbn.MxTBR_Mantissa[i] = ((u32 >> 9) & 0x1FFFF);
- if(rtpfb->tmmbn.MeasuredOverhead) rtpfb->tmmbn.MeasuredOverhead[i] = (u32 & 0x1FF);
- pdata += 8;
- }
- }
- break;
- }
-
- default:
- {
- TSK_DEBUG_ERROR("Unsupported Feedback message type %d", (int)rtpfb->fci_type);
- break;
- }
- }
- }
- }
-
- TSK_OBJECT_SAFE_FREE(header);
- return rtpfb;
+ trtp_rtcp_report_rtpfb_t* rtpfb = tsk_null;
+ trtp_rtcp_header_t* header = tsk_null;
+ uint32_t ssrc_sender, ssrc_media_src;
+
+ if(_trtp_rtcp_report_fb_deserialize(data, _size, &header, &ssrc_sender, &ssrc_media_src) == 0) {
+ if((rtpfb = trtp_rtcp_report_rtpfb_create(header))) {
+ const uint8_t* pdata = ((const uint8_t*)data) + TRTP_RTCP_PACKET_FB_MIN_SIZE;
+ tsk_size_t size = (header->length_in_bytes - TRTP_RTCP_PACKET_FB_MIN_SIZE), i;
+
+ TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_sender = ssrc_sender;
+ TRTP_RTCP_REPORT_FB(rtpfb)->ssrc_media = ssrc_media_src;
+
+ switch(rtpfb->fci_type = (trtp_rtcp_rtpfb_fci_type_t)header->rc) {
+ case trtp_rtcp_rtpfb_fci_type_nack: {
+ if((rtpfb->nack.count = (size >> 2)) > 0) {
+ rtpfb->nack.pid = tsk_realloc(rtpfb->nack.pid, (rtpfb->nack.count * sizeof(uint16_t)));
+ rtpfb->nack.blp = tsk_realloc(rtpfb->nack.blp, (rtpfb->nack.count * sizeof(uint16_t)));
+ for(i = 0; i < rtpfb->nack.count; ++i) {
+ if(rtpfb->nack.pid) {
+ rtpfb->nack.pid[i] = tnet_ntohs_2(&pdata[0]);
+ }
+ if(rtpfb->nack.blp) {
+ rtpfb->nack.blp[i] = tnet_ntohs_2(&pdata[2]);
+ }
+ pdata += 4;
+ }
+ }
+ break;
+ }
+ case trtp_rtcp_rtpfb_fci_type_tmmbn: {
+ TSK_DEBUG_INFO("TMMBN");
+ if((rtpfb->tmmbn.count = (size >> 3)) > 0) {
+ uint32_t u32;
+ rtpfb->tmmbn.ssrc = tsk_realloc(rtpfb->tmmbn.ssrc, (rtpfb->tmmbn.count * sizeof(uint32_t)));
+ rtpfb->tmmbn.MxTBR_Exp = tsk_realloc(rtpfb->tmmbn.MxTBR_Exp, (rtpfb->tmmbn.count * sizeof(uint16_t)));
+ rtpfb->tmmbn.MxTBR_Mantissa = tsk_realloc(rtpfb->tmmbn.MxTBR_Mantissa, (rtpfb->tmmbn.count * sizeof(uint32_t)));
+ rtpfb->tmmbn.MeasuredOverhead = tsk_realloc(rtpfb->tmmbn.MeasuredOverhead, (rtpfb->tmmbn.count * sizeof(uint16_t)));
+ for(i = 0; i < rtpfb->tmmbn.count; ++i) {
+ if(rtpfb->tmmbn.ssrc) {
+ rtpfb->tmmbn.ssrc[i] = (uint32_t)tnet_ntohl_2(&pdata[0]);
+ }
+ u32 = (uint32_t)tnet_ntohl_2(&pdata[4]);
+ if(rtpfb->tmmbn.MxTBR_Exp) {
+ rtpfb->tmmbn.MxTBR_Exp[i] = (u32 >> 26);
+ }
+ if(rtpfb->tmmbn.MxTBR_Mantissa) {
+ rtpfb->tmmbn.MxTBR_Mantissa[i] = ((u32 >> 9) & 0x1FFFF);
+ }
+ if(rtpfb->tmmbn.MeasuredOverhead) {
+ rtpfb->tmmbn.MeasuredOverhead[i] = (u32 & 0x1FF);
+ }
+ pdata += 8;
+ }
+ }
+ break;
+ }
+
+ default: {
+ TSK_DEBUG_ERROR("Unsupported Feedback message type %d", (int)rtpfb->fci_type);
+ break;
+ }
+ }
+ }
+ }
+
+ TSK_OBJECT_SAFE_FREE(header);
+ return rtpfb;
}
int trtp_rtcp_report_rtpfb_serialize_to(const trtp_rtcp_report_rtpfb_t* self, void* data, tsk_size_t size)
{
- int ret;
- uint8_t* pdata = (uint8_t*)data;
-
- if(!self || !data || size < trtp_rtcp_report_rtpfb_get_size(self)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if((ret = _trtp_rtcp_report_fb_serialize_to(TRTP_RTCP_REPORT_FB(self), pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize FB message");
- return ret;
- }
- pdata += TRTP_RTCP_PACKET_FB_MIN_SIZE;
- size -= TRTP_RTCP_PACKET_FB_MIN_SIZE;
-
- switch(self->fci_type){
- case trtp_rtcp_rtpfb_fci_type_nack:
- {
- tsk_size_t i;
- for(i = 0; i < self->nack.count; ++i){
- pdata[0] = self->nack.pid[i] >> 8;
- pdata[1] = (self->nack.pid[i] & 0xFF);
- pdata[2] = self->nack.blp[i] >> 8;
- pdata[3] = (self->nack.blp[i] & 0xFF);
- pdata += 4;
- }
- break;
- }
- default:
- {
- TSK_DEBUG_ERROR("Not implemented");
- return -2;
- }
- }
- return 0;
+ int ret;
+ uint8_t* pdata = (uint8_t*)data;
+
+ if(!self || !data || size < trtp_rtcp_report_rtpfb_get_size(self)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if((ret = _trtp_rtcp_report_fb_serialize_to(TRTP_RTCP_REPORT_FB(self), pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize FB message");
+ return ret;
+ }
+ pdata += TRTP_RTCP_PACKET_FB_MIN_SIZE;
+ size -= TRTP_RTCP_PACKET_FB_MIN_SIZE;
+
+ switch(self->fci_type) {
+ case trtp_rtcp_rtpfb_fci_type_nack: {
+ tsk_size_t i;
+ for(i = 0; i < self->nack.count; ++i) {
+ pdata[0] = self->nack.pid[i] >> 8;
+ pdata[1] = (self->nack.pid[i] & 0xFF);
+ pdata[2] = self->nack.blp[i] >> 8;
+ pdata[3] = (self->nack.blp[i] & 0xFF);
+ pdata += 4;
+ }
+ break;
+ }
+ default: {
+ TSK_DEBUG_ERROR("Not implemented");
+ return -2;
+ }
+ }
+ return 0;
}
tsk_size_t trtp_rtcp_report_rtpfb_get_size(const trtp_rtcp_report_rtpfb_t* self)
{
- if(!self || !TRTP_RTCP_PACKET(self)->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
- return TRTP_RTCP_PACKET(self)->header->length_in_bytes;
+ if(!self || !TRTP_RTCP_PACKET(self)->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+ return TRTP_RTCP_PACKET(self)->header->length_in_bytes;
}
@@ -311,341 +315,406 @@ tsk_size_t trtp_rtcp_report_rtpfb_get_size(const trtp_rtcp_report_rtpfb_t* self)
static tsk_object_t* trtp_rtcp_report_psfb_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_report_psfb_t *psfb = self;
- if(psfb){
-
- }
- return self;
+ trtp_rtcp_report_psfb_t *psfb = self;
+ if(psfb) {
+
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_report_psfb_dtor(tsk_object_t * self)
-{
- trtp_rtcp_report_psfb_t *psfb = self;
- if(psfb){
- // deinit self
- switch(psfb->fci_type){
- case trtp_rtcp_psfb_fci_type_pli:
- break;
- case trtp_rtcp_psfb_fci_type_sli:
- TSK_FREE(psfb->sli.first);
- TSK_FREE(psfb->sli.number);
- TSK_FREE(psfb->sli.pic_id);
- break;
- case trtp_rtcp_psfb_fci_type_rpsi:
- TSK_FREE(psfb->rpsi.bytes);
- break;
- case trtp_rtcp_psfb_fci_type_fir:
- TSK_FREE(psfb->fir.ssrc);
- TSK_FREE(psfb->fir.seq_num);
- break;
- case trtp_rtcp_psfb_fci_type_afb:
- switch(psfb->afb.type){
- case trtp_rtcp_psfb_afb_type_none:
- TSK_FREE(psfb->afb.none.bytes);
- break;
- case trtp_rtcp_psfb_afb_type_remb:
- TSK_FREE(psfb->afb.remb.ssrc_feedbacks);
- break;
- }
- break;
- }
- // deinit base
- trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(psfb));
- }
-
- return self;
-}
-static const tsk_object_def_t trtp_rtcp_report_psfb_def_s =
{
- sizeof(trtp_rtcp_report_psfb_t),
- trtp_rtcp_report_psfb_ctor,
- trtp_rtcp_report_psfb_dtor,
- tsk_null,
+ trtp_rtcp_report_psfb_t *psfb = self;
+ if(psfb) {
+ // deinit self
+ switch(psfb->fci_type) {
+ case trtp_rtcp_psfb_fci_type_pli:
+ break;
+ case trtp_rtcp_psfb_fci_type_sli:
+ TSK_FREE(psfb->sli.first);
+ TSK_FREE(psfb->sli.number);
+ TSK_FREE(psfb->sli.pic_id);
+ break;
+ case trtp_rtcp_psfb_fci_type_rpsi:
+ TSK_FREE(psfb->rpsi.bytes);
+ break;
+ case trtp_rtcp_psfb_fci_type_fir:
+ TSK_FREE(psfb->fir.ssrc);
+ TSK_FREE(psfb->fir.seq_num);
+ break;
+ case trtp_rtcp_psfb_fci_type_afb:
+ switch(psfb->afb.type) {
+ case trtp_rtcp_psfb_afb_type_none:
+ TSK_FREE(psfb->afb.none.bytes);
+ break;
+ case trtp_rtcp_psfb_afb_type_remb:
+ TSK_FREE(psfb->afb.remb.ssrc_feedbacks);
+ break;
+ case trtp_rtcp_psfb_afb_type_jcng:
+ TSK_FREE(psfb->afb.jcng.ssrc_feedbacks);
+ break;
+ }
+ break;
+ }
+ // deinit base
+ trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(psfb));
+ }
+
+ return self;
+}
+static const tsk_object_def_t trtp_rtcp_report_psfb_def_s = {
+ sizeof(trtp_rtcp_report_psfb_t),
+ trtp_rtcp_report_psfb_ctor,
+ trtp_rtcp_report_psfb_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_report_psfb_def_t = &trtp_rtcp_report_psfb_def_s;
trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_create_null()
{
- trtp_rtcp_report_psfb_t* psfb;
- if((psfb = (trtp_rtcp_report_psfb_t*)tsk_object_new(trtp_rtcp_report_psfb_def_t))){
- trtp_rtcp_packet_init(TRTP_RTCP_PACKET(psfb), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_psfb, TRTP_RTCP_PACKET_FB_MIN_SIZE);
- }
- return psfb;
+ trtp_rtcp_report_psfb_t* psfb;
+ if ((psfb = (trtp_rtcp_report_psfb_t*)tsk_object_new(trtp_rtcp_report_psfb_def_t))) {
+ trtp_rtcp_packet_init(TRTP_RTCP_PACKET(psfb), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_psfb, TRTP_RTCP_PACKET_FB_MIN_SIZE);
+ }
+ return psfb;
}
trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_create(trtp_rtcp_header_t* header)
{
- trtp_rtcp_report_psfb_t* psfb;
- if((psfb = (trtp_rtcp_report_psfb_t*)tsk_object_new(trtp_rtcp_report_psfb_def_t))){
- TRTP_RTCP_PACKET(psfb)->header = tsk_object_ref(header);
- }
- return psfb;
+ trtp_rtcp_report_psfb_t* psfb;
+ if ((psfb = (trtp_rtcp_report_psfb_t*)tsk_object_new(trtp_rtcp_report_psfb_def_t))) {
+ TRTP_RTCP_PACKET(psfb)->header = tsk_object_ref(header);
+ }
+ return psfb;
}
trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_t fci_type, uint32_t ssrc_sender, uint32_t ssrc_media_src)
{
- trtp_rtcp_report_psfb_t* psfb;
- if((psfb = trtp_rtcp_report_psfb_create_null())){
- TRTP_RTCP_PACKET(psfb)->header->rc = psfb->fci_type = fci_type;
- TRTP_RTCP_REPORT_FB(psfb)->ssrc_sender = ssrc_sender;
- TRTP_RTCP_REPORT_FB(psfb)->ssrc_media = ssrc_media_src;
- }
- return psfb;
+ trtp_rtcp_report_psfb_t* psfb;
+ if ((psfb = trtp_rtcp_report_psfb_create_null())) {
+ TRTP_RTCP_PACKET(psfb)->header->rc = psfb->fci_type = fci_type;
+ TRTP_RTCP_REPORT_FB(psfb)->ssrc_sender = ssrc_sender;
+ TRTP_RTCP_REPORT_FB(psfb)->ssrc_media = ssrc_media_src;
+ }
+ return psfb;
}
trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_create_pli(uint32_t ssrc_sender, uint32_t ssrc_media_src)
{
- return trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_pli, ssrc_sender, ssrc_media_src);
+ return trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_pli, ssrc_sender, ssrc_media_src);
}
trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_create_fir(uint8_t seq_num, uint32_t ssrc_sender, uint32_t ssrc_media_src)
{
- trtp_rtcp_report_psfb_t* psfb;
- if((psfb = trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_fir, ssrc_sender, ssrc_media_src))){
- psfb->fir.ssrc = tsk_malloc(sizeof(uint32_t));
- psfb->fir.seq_num = tsk_malloc(sizeof(uint8_t));
- if(!psfb->fir.ssrc || !psfb->fir.seq_num){
- TSK_OBJECT_SAFE_FREE(psfb);
- return tsk_null;
- }
- psfb->fir.count = 1;
- psfb->fir.seq_num[0] = seq_num;
- psfb->fir.ssrc[0] = ssrc_media_src;
- TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += (uint32_t)(psfb->fir.count << 3);
- TRTP_RTCP_PACKET(psfb)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(psfb)->header->length_in_bytes >> 2) - 1);
- }
- return psfb;
+ trtp_rtcp_report_psfb_t* psfb;
+ if ((psfb = trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_fir, ssrc_sender, ssrc_media_src))) {
+ psfb->fir.ssrc = tsk_malloc(sizeof(uint32_t));
+ psfb->fir.seq_num = tsk_malloc(sizeof(uint8_t));
+ if (!psfb->fir.ssrc || !psfb->fir.seq_num) {
+ TSK_OBJECT_SAFE_FREE(psfb);
+ return tsk_null;
+ }
+ psfb->fir.count = 1;
+ psfb->fir.seq_num[0] = seq_num;
+ psfb->fir.ssrc[0] = ssrc_media_src;
+ TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += (uint32_t)(psfb->fir.count << 3);
+ TRTP_RTCP_PACKET(psfb)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(psfb)->header->length_in_bytes >> 2) - 1);
+ }
+ return psfb;
}
trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_create_afb_remb(uint32_t ssrc_sender, const uint32_t* ssrc_media_src_list, uint32_t ssrc_media_src_list_count, uint32_t bitrate/*in bps*/)
{
- trtp_rtcp_report_psfb_t* psfb;
- // draft-alvestrand-rmcat-remb-02 2.2: SSRC media source always equal to zero
- if((psfb = trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_afb, ssrc_sender, 0))){
- static const uint32_t __max_mantissa = 131072;
- psfb->afb.type = trtp_rtcp_psfb_afb_type_remb;
- psfb->afb.remb.exp = 0;
- if(bitrate <= __max_mantissa){
- psfb->afb.remb.mantissa = bitrate;
- }
- else{
- while(bitrate >= (__max_mantissa << psfb->afb.remb.exp) && psfb->afb.remb.exp < 63) ++psfb->afb.remb.exp;
- psfb->afb.remb.mantissa = (bitrate >> psfb->afb.remb.exp);
- }
- if(ssrc_media_src_list && ssrc_media_src_list_count > 0 && (psfb->afb.remb.ssrc_feedbacks = (uint32_t*)tsk_malloc(ssrc_media_src_list_count << 2))){
- uint32_t i;
- psfb->afb.remb.num_ssrc = ssrc_media_src_list_count;
- for(i = 0; i < ssrc_media_src_list_count; ++i){
- psfb->afb.remb.ssrc_feedbacks[i] = ssrc_media_src_list[i];
- }
- }
- TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += 8; /*'R' 'E' 'M' 'B', Num SSRC, BR Exp, BR Mantissa */
- TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += (psfb->afb.remb.num_ssrc << 2);
- TRTP_RTCP_PACKET(psfb)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(psfb)->header->length_in_bytes >> 2) - 1);
- }
- return psfb;
+ trtp_rtcp_report_psfb_t* psfb;
+ // draft-alvestrand-rmcat-remb-02 2.2: SSRC media source always equal to zero
+ if ((psfb = trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_afb, ssrc_sender, 0))) {
+ static const uint32_t __max_mantissa = 131072;
+ psfb->afb.type = trtp_rtcp_psfb_afb_type_remb;
+ psfb->afb.remb.exp = 0;
+ if (bitrate <= __max_mantissa) {
+ psfb->afb.remb.mantissa = bitrate;
+ }
+ else {
+ while (bitrate >= (__max_mantissa << psfb->afb.remb.exp) && psfb->afb.remb.exp < 63) {
+ ++psfb->afb.remb.exp;
+ }
+ psfb->afb.remb.mantissa = (bitrate >> psfb->afb.remb.exp);
+ }
+ if (ssrc_media_src_list && ssrc_media_src_list_count > 0 && (psfb->afb.remb.ssrc_feedbacks = (uint32_t*)tsk_malloc(ssrc_media_src_list_count << 2))) {
+ uint32_t i;
+ psfb->afb.remb.num_ssrc = ssrc_media_src_list_count;
+ for (i = 0; i < ssrc_media_src_list_count; ++i) {
+ psfb->afb.remb.ssrc_feedbacks[i] = ssrc_media_src_list[i];
+ }
+ }
+ TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += 8; /*'R' 'E' 'M' 'B', Num SSRC, BR Exp, BR Mantissa */
+ TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += (psfb->afb.remb.num_ssrc << 2);
+ TRTP_RTCP_PACKET(psfb)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(psfb)->header->length_in_bytes >> 2) - 1);
+ }
+ return psfb;
+}
+
+trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_create_afb_jcng(uint32_t ssrc_sender, const uint32_t* ssrc_media_src_list, uint32_t ssrc_media_src_list_count, float jcng_q/*in quality metric*/)
+{
+ trtp_rtcp_report_psfb_t* psfb;
+ // SSRC media source always equal to zero
+ if ((psfb = trtp_rtcp_report_psfb_create_2(trtp_rtcp_psfb_fci_type_afb, ssrc_sender, 0))) {
+ psfb->afb.type = trtp_rtcp_psfb_afb_type_jcng;
+ psfb->afb.jcng.q = (uint8_t)(jcng_q * 255.f);
+ if (ssrc_media_src_list && ssrc_media_src_list_count > 0 && (psfb->afb.jcng.ssrc_feedbacks = (uint32_t*)tsk_malloc(ssrc_media_src_list_count << 2))) {
+ uint32_t i;
+ psfb->afb.jcng.num_ssrc = ssrc_media_src_list_count;
+ for (i = 0; i < ssrc_media_src_list_count; ++i) {
+ psfb->afb.jcng.ssrc_feedbacks[i] = ssrc_media_src_list[i];
+ }
+ }
+ TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += 8; /*'J' 'C' 'N' 'G', Num SSRC, Q, Reserverd */
+ TRTP_RTCP_PACKET(psfb)->header->length_in_bytes += (psfb->afb.jcng.num_ssrc << 2);
+ TRTP_RTCP_PACKET(psfb)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(psfb)->header->length_in_bytes >> 2) - 1);
+ }
+ return psfb;
}
trtp_rtcp_report_psfb_t* trtp_rtcp_report_psfb_deserialize(const void* data, tsk_size_t _size)
{
- trtp_rtcp_report_psfb_t* psfb = tsk_null;
- trtp_rtcp_header_t* header = tsk_null;
- uint32_t ssrc_sender, ssrc_media_src;
-
- if(_trtp_rtcp_report_fb_deserialize(data, _size, &header, &ssrc_sender, &ssrc_media_src) == 0){
- if((psfb = trtp_rtcp_report_psfb_create(header))){
- const uint8_t* pdata = ((const uint8_t*)data) + TRTP_RTCP_PACKET_FB_MIN_SIZE;
- tsk_size_t size = (header->length_in_bytes - TRTP_RTCP_PACKET_FB_MIN_SIZE);
-
- TRTP_RTCP_REPORT_FB(psfb)->ssrc_sender = ssrc_sender;
- TRTP_RTCP_REPORT_FB(psfb)->ssrc_media = ssrc_media_src;
-
- switch((psfb->fci_type = header->rc)/* FMT for RTCP-FB messages */){
- case trtp_rtcp_psfb_fci_type_pli:
- {
- // No FCI in PLI
- // TSK_DEBUG_INFO("PLI");
- break;
- }
- case trtp_rtcp_psfb_fci_type_sli:
- {
- tsk_size_t sli_count = (size >> 2), i;
- uint32_t u32;
- if(sli_count == 0){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
- psfb->sli.first = tsk_realloc(psfb->sli.first, (sli_count * sizeof(uint16_t)));
- psfb->sli.number = tsk_realloc(psfb->sli.number, (sli_count * sizeof(uint16_t)));
- psfb->sli.pic_id = tsk_realloc(psfb->sli.pic_id, (sli_count * sizeof(uint16_t)));
- for(i = 0; i < sli_count; ++i){
- u32 = (uint32_t)tnet_ntohl_2(&pdata[i >> 2]);
- if(psfb->sli.first) psfb->sli.first[i] = (u32 >> 19);
- if(psfb->sli.number) psfb->sli.number[i] = (u32 >> 6) & 0x1FFF;
- if(psfb->sli.pic_id) psfb->sli.pic_id[i] = u32 & 0x3F;
- }
-
- break;
- }
- case trtp_rtcp_psfb_fci_type_rpsi:
- {
- uint16_t u16;
- if(size < 2){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
- u16 = tnet_ntohs_2(&pdata[0]);
- psfb->rpsi.pb = (u16 >> 8);
- psfb->rpsi.pt = (u16 & 0x7F);
- if((psfb->rpsi.bytes = tsk_calloc((size - 2), sizeof(uint8_t)))){
- memcpy(psfb->rpsi.bytes, &pdata[2], (size - 2));
- }
- break;
- }
- case trtp_rtcp_psfb_fci_type_fir:
- {
- tsk_size_t fir_count = (size >> 3), i;
- if(fir_count == 0){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
- psfb->fir.count = fir_count;
- psfb->fir.ssrc = tsk_realloc(psfb->fir.seq_num, (fir_count * sizeof(uint32_t)));
- psfb->fir.seq_num = tsk_realloc(psfb->fir.seq_num, (fir_count * sizeof(uint8_t)));
- for(i = 0; i < fir_count; ++i){
- if(psfb->fir.ssrc) psfb->fir.ssrc[i] = (uint32_t)tnet_ntohl_2(&pdata[0]);
- if(psfb->fir.seq_num) psfb->fir.seq_num[i] = pdata[4];
- pdata+=8;
- }
- break;
- }
- case trtp_rtcp_psfb_fci_type_afb:
- {
- if(size > 0){
- psfb->afb.type = trtp_rtcp_psfb_afb_type_none;
- // REMB (http://tools.ietf.org/html/draft-alvestrand-rmcat-remb-02) ?
- if(size > 4 && tsk_strniequals(pdata, "REMB", 4)){
- uint32_t _u32;
- if(size < 8){ // REMB, Num SSRC, BR Exp, BR Mantissa
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
- psfb->afb.type = trtp_rtcp_psfb_afb_type_remb;
- _u32 = (uint32_t)tnet_ntohl_2(&pdata[4]);
- psfb->afb.remb.num_ssrc = ((_u32 >> 24) & 0xFF);
- if((psfb->afb.remb.num_ssrc << 2) != (size - 8)){
- TSK_DEBUG_ERROR("Invalid size");
- psfb->afb.remb.num_ssrc = 0;
- goto bail;
- }
- psfb->afb.remb.exp = ((_u32 >> 18) & 0x3F);
- psfb->afb.remb.mantissa = (_u32 & 0x3FFFF);
- if((psfb->afb.remb.ssrc_feedbacks = tsk_malloc(psfb->afb.remb.num_ssrc << 2))){
- for(_u32 = 0; _u32 < psfb->afb.remb.num_ssrc; ++_u32){
- psfb->afb.remb.ssrc_feedbacks[_u32] = (uint32_t)tnet_ntohl_2(&pdata[8 + (_u32 << 2)]);
- }
- }
- }
- else{
- if((psfb->afb.none.bytes = tsk_calloc(size, sizeof(uint8_t)))){
- memcpy(psfb->afb.none.bytes, &pdata[0], size);
- }
- }
- }
- break;
- }
- default:
- {
- TSK_DEBUG_ERROR("%d not a valid FCI", psfb->fci_type);
- goto bail;
- }
- }
- }
- }
+ trtp_rtcp_report_psfb_t* psfb = tsk_null;
+ trtp_rtcp_header_t* header = tsk_null;
+ uint32_t ssrc_sender, ssrc_media_src;
+
+ if(_trtp_rtcp_report_fb_deserialize(data, _size, &header, &ssrc_sender, &ssrc_media_src) == 0) {
+ if((psfb = trtp_rtcp_report_psfb_create(header))) {
+ const uint8_t* pdata = ((const uint8_t*)data) + TRTP_RTCP_PACKET_FB_MIN_SIZE;
+ tsk_size_t size = (header->length_in_bytes - TRTP_RTCP_PACKET_FB_MIN_SIZE);
+
+ TRTP_RTCP_REPORT_FB(psfb)->ssrc_sender = ssrc_sender;
+ TRTP_RTCP_REPORT_FB(psfb)->ssrc_media = ssrc_media_src;
+
+ switch((psfb->fci_type = header->rc)/* FMT for RTCP-FB messages */) {
+ case trtp_rtcp_psfb_fci_type_pli: {
+ // No FCI in PLI
+ // TSK_DEBUG_INFO("PLI");
+ break;
+ }
+ case trtp_rtcp_psfb_fci_type_sli: {
+ tsk_size_t sli_count = (size >> 2), i;
+ uint32_t u32;
+ if(sli_count == 0) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+ psfb->sli.first = tsk_realloc(psfb->sli.first, (sli_count * sizeof(uint16_t)));
+ psfb->sli.number = tsk_realloc(psfb->sli.number, (sli_count * sizeof(uint16_t)));
+ psfb->sli.pic_id = tsk_realloc(psfb->sli.pic_id, (sli_count * sizeof(uint16_t)));
+ for(i = 0; i < sli_count; ++i) {
+ u32 = (uint32_t)tnet_ntohl_2(&pdata[i >> 2]);
+ if(psfb->sli.first) {
+ psfb->sli.first[i] = (u32 >> 19);
+ }
+ if(psfb->sli.number) {
+ psfb->sli.number[i] = (u32 >> 6) & 0x1FFF;
+ }
+ if(psfb->sli.pic_id) {
+ psfb->sli.pic_id[i] = u32 & 0x3F;
+ }
+ }
+
+ break;
+ }
+ case trtp_rtcp_psfb_fci_type_rpsi: {
+ uint16_t u16;
+ if(size < 2) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+ u16 = tnet_ntohs_2(&pdata[0]);
+ psfb->rpsi.pb = (u16 >> 8);
+ psfb->rpsi.pt = (u16 & 0x7F);
+ if((psfb->rpsi.bytes = tsk_calloc((size - 2), sizeof(uint8_t)))) {
+ memcpy(psfb->rpsi.bytes, &pdata[2], (size - 2));
+ }
+ break;
+ }
+ case trtp_rtcp_psfb_fci_type_fir: {
+ tsk_size_t fir_count = (size >> 3), i;
+ if(fir_count == 0) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+ psfb->fir.count = fir_count;
+ psfb->fir.ssrc = tsk_realloc(psfb->fir.seq_num, (fir_count * sizeof(uint32_t)));
+ psfb->fir.seq_num = tsk_realloc(psfb->fir.seq_num, (fir_count * sizeof(uint8_t)));
+ for(i = 0; i < fir_count; ++i) {
+ if(psfb->fir.ssrc) {
+ psfb->fir.ssrc[i] = (uint32_t)tnet_ntohl_2(&pdata[0]);
+ }
+ if(psfb->fir.seq_num) {
+ psfb->fir.seq_num[i] = pdata[4];
+ }
+ pdata+=8;
+ }
+ break;
+ }
+ case trtp_rtcp_psfb_fci_type_afb: {
+ if(size > 0) {
+ psfb->afb.type = trtp_rtcp_psfb_afb_type_none;
+ // REMB (http://tools.ietf.org/html/draft-alvestrand-rmcat-remb-02) or jitter buffer congestion estimation message?
+ if (size > 4 && tsk_strniequals(pdata, "REMB", 4)) {
+ uint32_t _u32;
+ if (size < 8) { // REMB, Num SSRC, BR Exp, BR Mantissa
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+ psfb->afb.type = trtp_rtcp_psfb_afb_type_remb;
+ _u32 = (uint32_t)tnet_ntohl_2(&pdata[4]);
+ psfb->afb.remb.num_ssrc = ((_u32 >> 24) & 0xFF);
+ if ((psfb->afb.remb.num_ssrc << 2) != (size - 8)) {
+ TSK_DEBUG_ERROR("Invalid size");
+ psfb->afb.remb.num_ssrc = 0;
+ goto bail;
+ }
+ psfb->afb.remb.exp = ((_u32 >> 18) & 0x3F);
+ psfb->afb.remb.mantissa = (_u32 & 0x3FFFF);
+ if ((psfb->afb.remb.ssrc_feedbacks = tsk_malloc(psfb->afb.remb.num_ssrc << 2))) {
+ for (_u32 = 0; _u32 < psfb->afb.remb.num_ssrc; ++_u32) {
+ psfb->afb.remb.ssrc_feedbacks[_u32] = (uint32_t)tnet_ntohl_2(&pdata[8 + (_u32 << 2)]);
+ }
+ }
+ }
+ else if (size > 4 && tsk_strniequals(pdata, "JCNG", 4)) {
+ uint32_t _u32;
+ if (size < 8) { // JCNG, Num SSRC, Q, Reserved
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+ psfb->afb.type = trtp_rtcp_psfb_afb_type_jcng;
+ _u32 = (uint32_t)tnet_ntohl_2(&pdata[4]);
+ psfb->afb.jcng.num_ssrc = ((_u32 >> 24) & 0xFF);
+ if ((psfb->afb.jcng.num_ssrc << 2) != (size - 8)) {
+ TSK_DEBUG_ERROR("Invalid size");
+ psfb->afb.jcng.num_ssrc = 0;
+ goto bail;
+ }
+ psfb->afb.jcng.q = ((_u32 >> 16) & 0xFF);
+ if ((psfb->afb.jcng.ssrc_feedbacks = tsk_malloc(psfb->afb.jcng.num_ssrc << 2))) {
+ for (_u32 = 0; _u32 < psfb->afb.jcng.num_ssrc; ++_u32) {
+ psfb->afb.jcng.ssrc_feedbacks[_u32] = (uint32_t)tnet_ntohl_2(&pdata[8 + (_u32 << 2)]);
+ }
+ }
+ }
+ else {
+ if ((psfb->afb.none.bytes = tsk_calloc(size, sizeof(uint8_t)))) {
+ memcpy(psfb->afb.none.bytes, &pdata[0], size);
+ }
+ }
+ }
+ break;
+ }
+ default: {
+ TSK_DEBUG_ERROR("%d not a valid FCI", psfb->fci_type);
+ goto bail;
+ }
+ }
+ }
+ }
bail:
- TSK_OBJECT_SAFE_FREE(header);
- return psfb;
+ TSK_OBJECT_SAFE_FREE(header);
+ return psfb;
}
int trtp_rtcp_report_psfb_serialize_to(const trtp_rtcp_report_psfb_t* self, void* data, tsk_size_t size)
{
- int ret;
- uint8_t* pdata = (uint8_t*)data;
-
- if(!self || !data || size < trtp_rtcp_report_psfb_get_size(self)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if((ret = _trtp_rtcp_report_fb_serialize_to(TRTP_RTCP_REPORT_FB(self), pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize FB message");
- return ret;
- }
- pdata += TRTP_RTCP_PACKET_FB_MIN_SIZE;
- size -= TRTP_RTCP_PACKET_FB_MIN_SIZE;
-
- switch(self->fci_type){
- case trtp_rtcp_psfb_fci_type_pli:
- {
- // No FCI in PLI
- break;
- }
- case trtp_rtcp_psfb_fci_type_fir:
- {
- tsk_size_t i;
- for(i = 0; i < self->fir.count; ++i){
- pdata[0] = self->fir.ssrc[i] >> 24;
- pdata[1] = (self->fir.ssrc[i] >> 16) & 0xFF;
- pdata[2] = (self->fir.ssrc[i] >> 8) & 0xFF;
- pdata[3] = (self->fir.ssrc[i] & 0xFF);
- pdata[4] = self->fir.seq_num[i];
- pdata += 8; // SSRC (4), Seq nr(1), Reserved(3)
- }
- break;
- }
- case trtp_rtcp_psfb_fci_type_afb:
- {
- if(self->afb.type == trtp_rtcp_psfb_afb_type_remb){
- tsk_size_t i;
- // 'R' 'E' 'M' 'B'
- pdata[0] = 'R', pdata[1] = 'E', pdata[2] = 'M', pdata[3] = 'B';
- // | Num SSRC | BR Exp | BR Mantissa
- pdata[4] = self->afb.remb.num_ssrc; // 8bits
- pdata[5] = (self->afb.remb.exp << 2) & 0xFC;// 6bits
- // 18bits
- pdata[5] |= (self->afb.remb.mantissa >> 16) & 0x3;
- pdata[6] = (self->afb.remb.mantissa >> 8) & 0xFF;
- pdata[7] = (self->afb.remb.mantissa & 0xFF);
- if(self->afb.remb.ssrc_feedbacks){
- for(i = 0; i < self->afb.remb.num_ssrc; ++i){
- pdata[8 + (i<<2)] = self->afb.remb.ssrc_feedbacks[i] >> 24;
- pdata[8 + (i<<2) + 1] = (self->afb.remb.ssrc_feedbacks[i] >> 16) & 0xFF;
- pdata[8 + (i<<2) + 2] = (self->afb.remb.ssrc_feedbacks[i] >> 8) & 0xFF;
- pdata[8 + (i<<2) + 3] = (self->afb.remb.ssrc_feedbacks[i] & 0xFF);
- }
- }
- }
- else{
- TSK_DEBUG_ERROR("Not implemented yet");
- return -1;
- }
- break;
- }
- default:
- {
- TSK_DEBUG_ERROR("Not implemented yet");
- return -1;
- }
- }
-
- return ret;
+ int ret;
+ uint8_t* pdata = (uint8_t*)data;
+
+ if(!self || !data || size < trtp_rtcp_report_psfb_get_size(self)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if((ret = _trtp_rtcp_report_fb_serialize_to(TRTP_RTCP_REPORT_FB(self), pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize FB message");
+ return ret;
+ }
+ pdata += TRTP_RTCP_PACKET_FB_MIN_SIZE;
+ size -= TRTP_RTCP_PACKET_FB_MIN_SIZE;
+
+ switch(self->fci_type) {
+ case trtp_rtcp_psfb_fci_type_pli: {
+ // No FCI in PLI
+ break;
+ }
+ case trtp_rtcp_psfb_fci_type_fir: {
+ tsk_size_t i;
+ for(i = 0; i < self->fir.count; ++i) {
+ pdata[0] = self->fir.ssrc[i] >> 24;
+ pdata[1] = (self->fir.ssrc[i] >> 16) & 0xFF;
+ pdata[2] = (self->fir.ssrc[i] >> 8) & 0xFF;
+ pdata[3] = (self->fir.ssrc[i] & 0xFF);
+ pdata[4] = self->fir.seq_num[i];
+ pdata += 8; // SSRC (4), Seq nr(1), Reserved(3)
+ }
+ break;
+ }
+ case trtp_rtcp_psfb_fci_type_afb: {
+ if (self->afb.type == trtp_rtcp_psfb_afb_type_remb) {
+ tsk_size_t i;
+ // 'R' 'E' 'M' 'B'
+ pdata[0] = 'R', pdata[1] = 'E', pdata[2] = 'M', pdata[3] = 'B';
+ // | Num SSRC | BR Exp | BR Mantissa
+ pdata[4] = self->afb.remb.num_ssrc; // 8bits
+ pdata[5] = (self->afb.remb.exp << 2) & 0xFC;// 6bits
+ // 18bits
+ pdata[5] |= (self->afb.remb.mantissa >> 16) & 0x3;
+ pdata[6] = (self->afb.remb.mantissa >> 8) & 0xFF;
+ pdata[7] = (self->afb.remb.mantissa & 0xFF);
+ if (self->afb.remb.ssrc_feedbacks) {
+ for (i = 0; i < self->afb.remb.num_ssrc; ++i) {
+ pdata[8 + (i<<2)] = self->afb.remb.ssrc_feedbacks[i] >> 24;
+ pdata[8 + (i<<2) + 1] = (self->afb.remb.ssrc_feedbacks[i] >> 16) & 0xFF;
+ pdata[8 + (i<<2) + 2] = (self->afb.remb.ssrc_feedbacks[i] >> 8) & 0xFF;
+ pdata[8 + (i<<2) + 3] = (self->afb.remb.ssrc_feedbacks[i] & 0xFF);
+ }
+ }
+ }
+ else if (self->afb.type == trtp_rtcp_psfb_afb_type_jcng) {
+ tsk_size_t i;
+ // 'J' 'C' 'N' 'G'
+ pdata[0] = 'J', pdata[1] = 'C', pdata[2] = 'N', pdata[3] = 'G';
+ // | Num SSRC | Q | Reserved
+ pdata[4] = self->afb.jcng.num_ssrc; // 8bits
+ pdata[5] = self->afb.jcng.q;// 8bits
+ // 16bits, reserved, zeros
+ pdata[6] = 0x00;
+ pdata[7] = 0x00;
+ if (self->afb.jcng.ssrc_feedbacks) {
+ for (i = 0; i < self->afb.jcng.num_ssrc; ++i) {
+ pdata[8 + (i<<2)] = self->afb.jcng.ssrc_feedbacks[i] >> 24;
+ pdata[8 + (i<<2) + 1] = (self->afb.jcng.ssrc_feedbacks[i] >> 16) & 0xFF;
+ pdata[8 + (i<<2) + 2] = (self->afb.jcng.ssrc_feedbacks[i] >> 8) & 0xFF;
+ pdata[8 + (i<<2) + 3] = (self->afb.jcng.ssrc_feedbacks[i] & 0xFF);
+ }
+ }
+ }
+ else {
+ TSK_DEBUG_ERROR("Not implemented yet");
+ return -1;
+ }
+ break;
+ }
+ default: {
+ TSK_DEBUG_ERROR("Not implemented yet");
+ return -1;
+ }
+ }
+
+ return ret;
}
tsk_size_t trtp_rtcp_report_psfb_get_size(const trtp_rtcp_report_psfb_t* self)
{
- if(!self || !TRTP_RTCP_PACKET(self)->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
- return TRTP_RTCP_PACKET(self)->header->length_in_bytes;
+ if(!self || !TRTP_RTCP_PACKET(self)->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+ return TRTP_RTCP_PACKET(self)->header->length_in_bytes;
} \ No newline at end of file
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_report_rr.c b/tinyRTP/src/rtcp/trtp_rtcp_report_rr.c
index 2a38a4c..0842921 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_report_rr.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_report_rr.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -30,203 +30,202 @@
static tsk_object_t* trtp_rtcp_report_rr_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_report_rr_t *rr = self;
- if(rr){
- rr->packets = tsk_list_create();
- rr->blocks = tsk_list_create();
- }
- return self;
+ trtp_rtcp_report_rr_t *rr = self;
+ if(rr) {
+ rr->packets = tsk_list_create();
+ rr->blocks = tsk_list_create();
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_report_rr_dtor(tsk_object_t * self)
-{
- trtp_rtcp_report_rr_t *rr = self;
- if(rr){
- // deinit self
- TSK_OBJECT_SAFE_FREE(rr->packets);
- TSK_OBJECT_SAFE_FREE(rr->blocks);
- // deinit base
- trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(rr));
- }
-
- return self;
-}
-static const tsk_object_def_t trtp_rtcp_report_rr_def_s =
{
- sizeof(trtp_rtcp_report_rr_t),
- trtp_rtcp_report_rr_ctor,
- trtp_rtcp_report_rr_dtor,
- tsk_null,
+ trtp_rtcp_report_rr_t *rr = self;
+ if(rr) {
+ // deinit self
+ TSK_OBJECT_SAFE_FREE(rr->packets);
+ TSK_OBJECT_SAFE_FREE(rr->blocks);
+ // deinit base
+ trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(rr));
+ }
+
+ return self;
+}
+static const tsk_object_def_t trtp_rtcp_report_rr_def_s = {
+ sizeof(trtp_rtcp_report_rr_t),
+ trtp_rtcp_report_rr_ctor,
+ trtp_rtcp_report_rr_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_report_rr_def_t = &trtp_rtcp_report_rr_def_s;
trtp_rtcp_report_rr_t* trtp_rtcp_report_rr_create_null()
{
- trtp_rtcp_report_rr_t* rr;
- if((rr = (trtp_rtcp_report_rr_t*)tsk_object_new(trtp_rtcp_report_rr_def_t))){
- trtp_rtcp_packet_init(TRTP_RTCP_PACKET(rr), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_rr, (TRTP_RTCP_HEADER_SIZE + 4));
- }
- return rr;
+ trtp_rtcp_report_rr_t* rr;
+ if((rr = (trtp_rtcp_report_rr_t*)tsk_object_new(trtp_rtcp_report_rr_def_t))) {
+ trtp_rtcp_packet_init(TRTP_RTCP_PACKET(rr), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_rr, (TRTP_RTCP_HEADER_SIZE + 4));
+ }
+ return rr;
}
trtp_rtcp_report_rr_t* trtp_rtcp_report_rr_create(trtp_rtcp_header_t* header)
{
- trtp_rtcp_report_rr_t* rr;
- if((rr = (trtp_rtcp_report_rr_t*)tsk_object_new(trtp_rtcp_report_rr_def_t))){
- TRTP_RTCP_PACKET(rr)->header = tsk_object_ref(header);
- }
- return rr;
+ trtp_rtcp_report_rr_t* rr;
+ if((rr = (trtp_rtcp_report_rr_t*)tsk_object_new(trtp_rtcp_report_rr_def_t))) {
+ TRTP_RTCP_PACKET(rr)->header = tsk_object_ref(header);
+ }
+ return rr;
}
trtp_rtcp_report_rr_t* trtp_rtcp_report_rr_create_2(uint32_t ssrc)
{
- trtp_rtcp_report_rr_t* rr;
- if((rr = trtp_rtcp_report_rr_create_null())){
- rr->ssrc = ssrc;
- }
- return rr;
+ trtp_rtcp_report_rr_t* rr;
+ if((rr = trtp_rtcp_report_rr_create_null())) {
+ rr->ssrc = ssrc;
+ }
+ return rr;
}
trtp_rtcp_report_rr_t* trtp_rtcp_report_rr_deserialize(const void* data, tsk_size_t _size)
{
- trtp_rtcp_report_rr_t* rr = tsk_null;
- trtp_rtcp_header_t* header = tsk_null;
- const uint8_t* pdata = (const uint8_t*)data;
- int32_t size = (int32_t)_size;
-
- if(!data || size < TRTP_RTCP_PACKET_RR_MIN_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- if(!(header = trtp_rtcp_header_deserialize(pdata, size))){
- TSK_DEBUG_ERROR("Failed to deserialize the header");
- goto bail;
- }
- if(header->length_in_bytes < TRTP_RTCP_PACKET_RR_MIN_SIZE){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
-
- if(!(rr = trtp_rtcp_report_rr_create(header))){
- TSK_DEBUG_ERROR("Failed to create object");
- goto bail;
- }
-
- rr->ssrc = (uint32_t)tnet_ntohl_2(&pdata[4]);
-
- pdata += (TRTP_RTCP_HEADER_SIZE + 4);
- size -= (TRTP_RTCP_HEADER_SIZE + 4);
-
- // Blocks
- if(header->rc > 0){
- tsk_size_t i = 0;
- trtp_rtcp_rblock_t* rblock;
-
- while(i++ < header->rc && size >= TRTP_RTCP_RBLOCK_SIZE){
- if((rblock = trtp_rtcp_rblock_deserialize(pdata, size))){
- tsk_list_push_back_data(rr->blocks, (void**)&rblock);
- }
- pdata += TRTP_RTCP_RBLOCK_SIZE;
- size -= TRTP_RTCP_RBLOCK_SIZE;
- }
- }
-
- // Other Packets
- while(size > TRTP_RTCP_HEADER_SIZE){
- trtp_rtcp_packet_t* packet;
-
- if((packet = trtp_rtcp_packet_deserialize(pdata, size))){
- if((size -= packet->header->length_in_bytes) > 0){
- pdata += packet->header->length_in_bytes;
- }
- tsk_list_push_back_data(rr->packets, (void**)&packet);
- continue;
- }
- break;
- }
+ trtp_rtcp_report_rr_t* rr = tsk_null;
+ trtp_rtcp_header_t* header = tsk_null;
+ const uint8_t* pdata = (const uint8_t*)data;
+ int32_t size = (int32_t)_size;
+
+ if(!data || size < TRTP_RTCP_PACKET_RR_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+
+ if(!(header = trtp_rtcp_header_deserialize(pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to deserialize the header");
+ goto bail;
+ }
+ if(header->length_in_bytes < TRTP_RTCP_PACKET_RR_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+
+ if(!(rr = trtp_rtcp_report_rr_create(header))) {
+ TSK_DEBUG_ERROR("Failed to create object");
+ goto bail;
+ }
+
+ rr->ssrc = (uint32_t)tnet_ntohl_2(&pdata[4]);
+
+ pdata += (TRTP_RTCP_HEADER_SIZE + 4);
+ size -= (TRTP_RTCP_HEADER_SIZE + 4);
+
+ // Blocks
+ if(header->rc > 0) {
+ tsk_size_t i = 0;
+ trtp_rtcp_rblock_t* rblock;
+
+ while(i++ < header->rc && size >= TRTP_RTCP_RBLOCK_SIZE) {
+ if((rblock = trtp_rtcp_rblock_deserialize(pdata, size))) {
+ tsk_list_push_back_data(rr->blocks, (void**)&rblock);
+ }
+ pdata += TRTP_RTCP_RBLOCK_SIZE;
+ size -= TRTP_RTCP_RBLOCK_SIZE;
+ }
+ }
+
+ // Other Packets
+ while(size > TRTP_RTCP_HEADER_SIZE) {
+ trtp_rtcp_packet_t* packet;
+
+ if((packet = trtp_rtcp_packet_deserialize(pdata, size))) {
+ if((size -= packet->header->length_in_bytes) > 0) {
+ pdata += packet->header->length_in_bytes;
+ }
+ tsk_list_push_back_data(rr->packets, (void**)&packet);
+ continue;
+ }
+ break;
+ }
bail:
- TSK_OBJECT_SAFE_FREE(header);
- return rr;
+ TSK_OBJECT_SAFE_FREE(header);
+ return rr;
}
int trtp_rtcp_report_rr_serialize_to(const trtp_rtcp_report_rr_t* self, void* data, tsk_size_t size)
{
- int ret;
- const tsk_list_item_t* item;
- uint8_t* pdata = (uint8_t*)data;
-
- if(!self || !data || size < trtp_rtcp_report_rr_get_size(self)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize the header");
- return ret;
- }
-
- pdata[TRTP_RTCP_HEADER_SIZE] = self->ssrc >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 1] = (self->ssrc >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 2] = (self->ssrc >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 3] = (self->ssrc & 0xFF);
-
- pdata += (TRTP_RTCP_HEADER_SIZE + 4);
- size -= (TRTP_RTCP_HEADER_SIZE + 4);
-
- if(TRTP_RTCP_PACKET(self)->header->rc > 0){
- tsk_list_foreach(item, self->blocks){
- if(!item->data){
- continue;
- }
- if((ret = trtp_rtcp_rblock_serialize_to(TRTP_RTCP_RBLOCK(item->data), pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize the rblock");
- goto bail;
- }
- pdata += TRTP_RTCP_RBLOCK_SIZE;
- size -= TRTP_RTCP_RBLOCK_SIZE;
- }
- }
-
- tsk_list_foreach(item, self->packets){
- if(!item->data){
- continue;
- }
- if((ret = trtp_rtcp_packet_serialize_to(TRTP_RTCP_PACKET(item->data), pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize packet");
- goto bail;
- }
- pdata += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- size -= TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- }
+ int ret;
+ const tsk_list_item_t* item;
+ uint8_t* pdata = (uint8_t*)data;
+
+ if(!self || !data || size < trtp_rtcp_report_rr_get_size(self)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize the header");
+ return ret;
+ }
+
+ pdata[TRTP_RTCP_HEADER_SIZE] = self->ssrc >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 1] = (self->ssrc >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 2] = (self->ssrc >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 3] = (self->ssrc & 0xFF);
+
+ pdata += (TRTP_RTCP_HEADER_SIZE + 4);
+ size -= (TRTP_RTCP_HEADER_SIZE + 4);
+
+ if(TRTP_RTCP_PACKET(self)->header->rc > 0) {
+ tsk_list_foreach(item, self->blocks) {
+ if(!item->data) {
+ continue;
+ }
+ if((ret = trtp_rtcp_rblock_serialize_to(TRTP_RTCP_RBLOCK(item->data), pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize the rblock");
+ goto bail;
+ }
+ pdata += TRTP_RTCP_RBLOCK_SIZE;
+ size -= TRTP_RTCP_RBLOCK_SIZE;
+ }
+ }
+
+ tsk_list_foreach(item, self->packets) {
+ if(!item->data) {
+ continue;
+ }
+ if((ret = trtp_rtcp_packet_serialize_to(TRTP_RTCP_PACKET(item->data), pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize packet");
+ goto bail;
+ }
+ pdata += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ size -= TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ }
bail:
- return ret;
+ return ret;
}
tsk_size_t trtp_rtcp_report_rr_get_size(const trtp_rtcp_report_rr_t* self)
{
- tsk_size_t size;
- const tsk_list_item_t* item;
-
- if(!self || !TRTP_RTCP_PACKET(self)->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- size = TRTP_RTCP_PACKET(self)->header->length_in_bytes;
- if(TRTP_RTCP_PACKET(self)->header->rc > 0){
- tsk_list_foreach(item, self->blocks){
- if(item->data){
- size += TRTP_RTCP_RBLOCK_SIZE;
- }
- }
- }
- tsk_list_foreach(item, self->packets){
- if(item->data && TRTP_RTCP_PACKET(item->data)->header){
- size += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- }
- }
-
- return size;
+ tsk_size_t size;
+ const tsk_list_item_t* item;
+
+ if(!self || !TRTP_RTCP_PACKET(self)->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+
+ size = TRTP_RTCP_PACKET(self)->header->length_in_bytes;
+ if(TRTP_RTCP_PACKET(self)->header->rc > 0) {
+ tsk_list_foreach(item, self->blocks) {
+ if(item->data) {
+ size += TRTP_RTCP_RBLOCK_SIZE;
+ }
+ }
+ }
+ tsk_list_foreach(item, self->packets) {
+ if(item->data && TRTP_RTCP_PACKET(item->data)->header) {
+ size += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ }
+ }
+
+ return size;
} \ No newline at end of file
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_report_sdes.c b/tinyRTP/src/rtcp/trtp_rtcp_report_sdes.c
index 4f5e944..8013509 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_report_sdes.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_report_sdes.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -26,7 +26,7 @@
/*
6.5 SDES: Source Description RTCP Packet
- 0 1 2
+ 0 1 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P| SC | PT=SDES=202 | length |
@@ -45,170 +45,169 @@ chunk | SSRC/CSRC_2 |
static tsk_object_t* trtp_rtcp_report_sdes_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_report_sdes_t *sdes = self;
- if(sdes){
- sdes->chuncks = tsk_list_create();
- }
- return self;
+ trtp_rtcp_report_sdes_t *sdes = self;
+ if(sdes) {
+ sdes->chuncks = tsk_list_create();
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_report_sdes_dtor(tsk_object_t * self)
-{
- trtp_rtcp_report_sdes_t *sdes = self;
- if(sdes){
- // deinit base
- trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(sdes));
- // deinit self
- TSK_OBJECT_SAFE_FREE(sdes->chuncks);
- }
-
- return self;
-}
-static const tsk_object_def_t trtp_rtcp_report_sdes_def_s =
{
- sizeof(trtp_rtcp_report_sdes_t),
- trtp_rtcp_report_sdes_ctor,
- trtp_rtcp_report_sdes_dtor,
- tsk_null,
+ trtp_rtcp_report_sdes_t *sdes = self;
+ if(sdes) {
+ // deinit base
+ trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(sdes));
+ // deinit self
+ TSK_OBJECT_SAFE_FREE(sdes->chuncks);
+ }
+
+ return self;
+}
+static const tsk_object_def_t trtp_rtcp_report_sdes_def_s = {
+ sizeof(trtp_rtcp_report_sdes_t),
+ trtp_rtcp_report_sdes_ctor,
+ trtp_rtcp_report_sdes_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_report_sdes_def_t = &trtp_rtcp_report_sdes_def_s;
trtp_rtcp_report_sdes_t* trtp_rtcp_report_sdes_create_null()
{
- trtp_rtcp_report_sdes_t* sdes;
- if((sdes = (trtp_rtcp_report_sdes_t*)tsk_object_new(trtp_rtcp_report_sdes_def_t))){
- trtp_rtcp_packet_init(TRTP_RTCP_PACKET(sdes), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_sdes, TRTP_RTCP_HEADER_SIZE);
- }
- return sdes;
+ trtp_rtcp_report_sdes_t* sdes;
+ if((sdes = (trtp_rtcp_report_sdes_t*)tsk_object_new(trtp_rtcp_report_sdes_def_t))) {
+ trtp_rtcp_packet_init(TRTP_RTCP_PACKET(sdes), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_sdes, TRTP_RTCP_HEADER_SIZE);
+ }
+ return sdes;
}
trtp_rtcp_report_sdes_t* trtp_rtcp_report_sdes_create(trtp_rtcp_header_t* header)
{
- trtp_rtcp_report_sdes_t* sdes;
- if((sdes = (trtp_rtcp_report_sdes_t*)tsk_object_new(trtp_rtcp_report_sdes_def_t))){
- TRTP_RTCP_PACKET(sdes)->header = tsk_object_ref(header);
- }
- return sdes;
+ trtp_rtcp_report_sdes_t* sdes;
+ if((sdes = (trtp_rtcp_report_sdes_t*)tsk_object_new(trtp_rtcp_report_sdes_def_t))) {
+ TRTP_RTCP_PACKET(sdes)->header = tsk_object_ref(header);
+ }
+ return sdes;
}
trtp_rtcp_report_sdes_t* trtp_rtcp_report_sdes_deserialize(const void* data, tsk_size_t _size)
{
- trtp_rtcp_report_sdes_t* sdes = tsk_null;
- trtp_rtcp_header_t* header = tsk_null;
- const uint8_t* pdata = (const uint8_t*)data;
- int32_t size = (int32_t)_size;
-
- if(!data || size < TRTP_RTCP_HEADER_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- if(!(header = trtp_rtcp_header_deserialize(pdata, size))){
- TSK_DEBUG_ERROR("Failed to deserialize the header");
- goto bail;
- }
- if(header->length_in_bytes < (TRTP_RTCP_HEADER_SIZE + 4)){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
-
- if(!(sdes = trtp_rtcp_report_sdes_create(header))){
- TSK_DEBUG_ERROR("Failed to create object");
- goto bail;
- }
-
- pdata += TRTP_RTCP_HEADER_SIZE;
- size -= TRTP_RTCP_HEADER_SIZE;
-
- // Chuncks
- if(header->rc > 0){
- tsk_size_t i = 0, chunck_size;
- trtp_rtcp_sdes_chunck_t* chunck;
- while(i++ < header->rc && size > TRTP_RTCP_SDES_CHUNCK_MIN_SIZE){
- if((chunck = trtp_rtcp_sdes_chunck_deserialize(pdata, size))){
- chunck_size = trtp_rtcp_sdes_chunck_get_size(chunck);
- if((size -= (int32_t)chunck_size)){
- pdata += chunck_size;
- }
- tsk_list_push_ascending_data(sdes->chuncks, (void**)&chunck);
- continue;
- }
- break;
- }
- }
+ trtp_rtcp_report_sdes_t* sdes = tsk_null;
+ trtp_rtcp_header_t* header = tsk_null;
+ const uint8_t* pdata = (const uint8_t*)data;
+ int32_t size = (int32_t)_size;
+
+ if(!data || size < TRTP_RTCP_HEADER_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+
+ if(!(header = trtp_rtcp_header_deserialize(pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to deserialize the header");
+ goto bail;
+ }
+ if(header->length_in_bytes < (TRTP_RTCP_HEADER_SIZE + 4)) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+
+ if(!(sdes = trtp_rtcp_report_sdes_create(header))) {
+ TSK_DEBUG_ERROR("Failed to create object");
+ goto bail;
+ }
+
+ pdata += TRTP_RTCP_HEADER_SIZE;
+ size -= TRTP_RTCP_HEADER_SIZE;
+
+ // Chuncks
+ if(header->rc > 0) {
+ tsk_size_t i = 0, chunck_size;
+ trtp_rtcp_sdes_chunck_t* chunck;
+ while(i++ < header->rc && size > TRTP_RTCP_SDES_CHUNCK_MIN_SIZE) {
+ if((chunck = trtp_rtcp_sdes_chunck_deserialize(pdata, size))) {
+ chunck_size = trtp_rtcp_sdes_chunck_get_size(chunck);
+ if((size -= (int32_t)chunck_size)) {
+ pdata += chunck_size;
+ }
+ tsk_list_push_ascending_data(sdes->chuncks, (void**)&chunck);
+ continue;
+ }
+ break;
+ }
+ }
bail:
- TSK_OBJECT_SAFE_FREE(header);
- return sdes;
+ TSK_OBJECT_SAFE_FREE(header);
+ return sdes;
}
int trtp_rtcp_report_sdes_serialize_to(const trtp_rtcp_report_sdes_t* self, void* data, tsk_size_t size)
{
- int ret;
- uint8_t* pdata = (uint8_t*)data;
- if(!self || !data || size < trtp_rtcp_report_sdes_get_size(self)){
- return -1;
- }
-
- if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize the header");
- return ret;
- }
-
- pdata += (TRTP_RTCP_HEADER_SIZE);
- size -= (TRTP_RTCP_HEADER_SIZE);
-
- if(TRTP_RTCP_PACKET(self)->header->rc > 0){
- const tsk_list_item_t* item;
- tsk_size_t chunck_size;
- const trtp_rtcp_sdes_chunck_t* chunck;
- tsk_list_foreach(item, self->chuncks){
- if(!(chunck = item->data)){
- continue;
- }
- if((ret = trtp_rtcp_sdes_chunck_serialize_to(chunck, pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize SDES chunck");
- goto bail;
- }
- chunck_size = trtp_rtcp_sdes_chunck_get_size(chunck);
- pdata += chunck_size;
- size -= chunck_size;
- }
- }
+ int ret;
+ uint8_t* pdata = (uint8_t*)data;
+ if(!self || !data || size < trtp_rtcp_report_sdes_get_size(self)) {
+ return -1;
+ }
+
+ if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize the header");
+ return ret;
+ }
+
+ pdata += (TRTP_RTCP_HEADER_SIZE);
+ size -= (TRTP_RTCP_HEADER_SIZE);
+
+ if(TRTP_RTCP_PACKET(self)->header->rc > 0) {
+ const tsk_list_item_t* item;
+ tsk_size_t chunck_size;
+ const trtp_rtcp_sdes_chunck_t* chunck;
+ tsk_list_foreach(item, self->chuncks) {
+ if(!(chunck = item->data)) {
+ continue;
+ }
+ if((ret = trtp_rtcp_sdes_chunck_serialize_to(chunck, pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize SDES chunck");
+ goto bail;
+ }
+ chunck_size = trtp_rtcp_sdes_chunck_get_size(chunck);
+ pdata += chunck_size;
+ size -= chunck_size;
+ }
+ }
bail:
- return ret;
+ return ret;
}
int trtp_rtcp_report_sdes_add_chunck(trtp_rtcp_report_sdes_t* self, trtp_rtcp_sdes_chunck_t* chunck)
{
- if(!self || !self->chuncks || !chunck){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- chunck = tsk_object_ref(chunck);
- TRTP_RTCP_PACKET(self)->header->length_in_bytes += (uint32_t)trtp_rtcp_sdes_chunck_get_size(chunck);
- TRTP_RTCP_PACKET(self)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(self)->header->length_in_bytes >> 2) - 1)
- + ((TRTP_RTCP_PACKET(self)->header->length_in_bytes & 0x03) ? 1 : 0);
- ++TRTP_RTCP_PACKET(self)->header->rc;
- tsk_list_push_back_data(self->chuncks, (void**)&chunck);
- return 0;
+ if(!self || !self->chuncks || !chunck) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ chunck = tsk_object_ref(chunck);
+ TRTP_RTCP_PACKET(self)->header->length_in_bytes += (uint32_t)trtp_rtcp_sdes_chunck_get_size(chunck);
+ TRTP_RTCP_PACKET(self)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(self)->header->length_in_bytes >> 2) - 1)
+ + ((TRTP_RTCP_PACKET(self)->header->length_in_bytes & 0x03) ? 1 : 0);
+ ++TRTP_RTCP_PACKET(self)->header->rc;
+ tsk_list_push_back_data(self->chuncks, (void**)&chunck);
+ return 0;
}
tsk_size_t trtp_rtcp_report_sdes_get_size(const trtp_rtcp_report_sdes_t* self)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
- else{
- tsk_size_t size = TRTP_RTCP_HEADER_SIZE;
- const tsk_list_item_t* item;
- tsk_list_foreach(item, self->chuncks){
- size += trtp_rtcp_sdes_chunck_get_size(TRTP_RTCP_SDES_CHUNCK(item->data));
- }
- return size;
- }
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+ else {
+ tsk_size_t size = TRTP_RTCP_HEADER_SIZE;
+ const tsk_list_item_t* item;
+ tsk_list_foreach(item, self->chuncks) {
+ size += trtp_rtcp_sdes_chunck_get_size(TRTP_RTCP_SDES_CHUNCK(item->data));
+ }
+ return size;
+ }
}
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_report_sr.c b/tinyRTP/src/rtcp/trtp_rtcp_report_sr.c
index 5d8ceda..e807f17 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_report_sr.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_report_sr.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -30,241 +30,240 @@
static tsk_object_t* trtp_rtcp_report_sr_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_report_sr_t *sr = self;
- if(sr){
- sr->blocks = tsk_list_create();
- sr->packets = tsk_list_create();
- }
- return self;
+ trtp_rtcp_report_sr_t *sr = self;
+ if(sr) {
+ sr->blocks = tsk_list_create();
+ sr->packets = tsk_list_create();
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_report_sr_dtor(tsk_object_t * self)
-{
- trtp_rtcp_report_sr_t *sr = self;
- if(sr){
- // deinit self
- TSK_OBJECT_SAFE_FREE(sr->blocks);
- TSK_OBJECT_SAFE_FREE(sr->packets);
- // deinit base
- trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(sr));
- }
-
- return self;
+{
+ trtp_rtcp_report_sr_t *sr = self;
+ if(sr) {
+ // deinit self
+ TSK_OBJECT_SAFE_FREE(sr->blocks);
+ TSK_OBJECT_SAFE_FREE(sr->packets);
+ // deinit base
+ trtp_rtcp_packet_deinit(TRTP_RTCP_PACKET(sr));
+ }
+
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_report_sr_def_s =
-{
- sizeof(trtp_rtcp_report_sr_t),
- trtp_rtcp_report_sr_ctor,
- trtp_rtcp_report_sr_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_report_sr_def_s = {
+ sizeof(trtp_rtcp_report_sr_t),
+ trtp_rtcp_report_sr_ctor,
+ trtp_rtcp_report_sr_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_report_sr_def_t = &trtp_rtcp_report_sr_def_s;
trtp_rtcp_report_sr_t* trtp_rtcp_report_sr_create_null()
{
- trtp_rtcp_report_sr_t* sr;
- if((sr = (trtp_rtcp_report_sr_t*)tsk_object_new(trtp_rtcp_report_sr_def_t))){
- trtp_rtcp_packet_init(TRTP_RTCP_PACKET(sr), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_sr, (TRTP_RTCP_HEADER_SIZE + 4 + 20));
- }
- return sr;
+ trtp_rtcp_report_sr_t* sr;
+ if((sr = (trtp_rtcp_report_sr_t*)tsk_object_new(trtp_rtcp_report_sr_def_t))) {
+ trtp_rtcp_packet_init(TRTP_RTCP_PACKET(sr), TRTP_RTCP_HEADER_VERSION_DEFAULT, 0, 0, trtp_rtcp_packet_type_sr, (TRTP_RTCP_HEADER_SIZE + 4 + 20));
+ }
+ return sr;
}
trtp_rtcp_report_sr_t* trtp_rtcp_report_sr_create(struct trtp_rtcp_header_s* header)
{
- trtp_rtcp_report_sr_t* sr;
- if((sr = (trtp_rtcp_report_sr_t*)tsk_object_new(trtp_rtcp_report_sr_def_t))){
- TRTP_RTCP_PACKET(sr)->header = tsk_object_ref(header);
- }
- return sr;
+ trtp_rtcp_report_sr_t* sr;
+ if((sr = (trtp_rtcp_report_sr_t*)tsk_object_new(trtp_rtcp_report_sr_def_t))) {
+ TRTP_RTCP_PACKET(sr)->header = tsk_object_ref(header);
+ }
+ return sr;
}
trtp_rtcp_report_sr_t* trtp_rtcp_report_sr_deserialize(const void* data, tsk_size_t _size)
{
- trtp_rtcp_report_sr_t* sr = tsk_null;
- trtp_rtcp_header_t* header = tsk_null;
- const uint8_t* pdata = (const uint8_t*)data;
- int32_t size = (int32_t)_size;
-
- if(!data || size < TRTP_RTCP_PACKET_SR_MIN_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- if(!(header = trtp_rtcp_header_deserialize(pdata, size))){
- TSK_DEBUG_ERROR("Failed to deserialize the header");
- goto bail;
- }
- if(header->length_in_bytes < TRTP_RTCP_PACKET_SR_MIN_SIZE){
- TSK_DEBUG_ERROR("Too short");
- goto bail;
- }
-
- if(!(sr = trtp_rtcp_report_sr_create(header))){
- TSK_DEBUG_ERROR("Failed to create object");
- goto bail;
- }
-
- sr->ssrc = (uint32_t)tnet_ntohl_2(&pdata[4]);
- pdata += (TRTP_RTCP_HEADER_SIZE + 4);
- size -= (TRTP_RTCP_HEADER_SIZE + 4);
-
- // sender info
- sr->sender_info.ntp_msw = (uint32_t)tnet_ntohl_2(&pdata[0]);
- sr->sender_info.ntp_lsw = (uint32_t)tnet_ntohl_2(&pdata[4]);
- sr->sender_info.rtp_timestamp = (uint32_t)tnet_ntohl_2(&pdata[8]);
- sr->sender_info.sender_pcount = (uint32_t)tnet_ntohl_2(&pdata[12]);
- sr->sender_info.sender_ocount = (uint32_t)tnet_ntohl_2(&pdata[16]);
- pdata += 20;
- size -= 20;
-
- // Blocks
- if(header->rc > 0){
- tsk_size_t i = 0;
- trtp_rtcp_rblock_t* rblock;
-
- while(i++ < header->rc && size >= TRTP_RTCP_RBLOCK_SIZE){
- if((rblock = trtp_rtcp_rblock_deserialize(pdata, size))){
- tsk_list_push_back_data(sr->blocks, (void**)&rblock);
- }
- pdata += TRTP_RTCP_RBLOCK_SIZE;
- size -= TRTP_RTCP_RBLOCK_SIZE;
- }
- }
-
- // Other Packets
- while(size > TRTP_RTCP_HEADER_SIZE){
- trtp_rtcp_packet_t* packet;
-
- if((packet = trtp_rtcp_packet_deserialize(pdata, size))){
- if((size -= packet->header->length_in_bytes) > 0){
- pdata += packet->header->length_in_bytes;
- }
- tsk_list_push_back_data(sr->packets, (void**)&packet);
- continue;
- }
- break;
- }
+ trtp_rtcp_report_sr_t* sr = tsk_null;
+ trtp_rtcp_header_t* header = tsk_null;
+ const uint8_t* pdata = (const uint8_t*)data;
+ int32_t size = (int32_t)_size;
+
+ if(!data || size < TRTP_RTCP_PACKET_SR_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+
+ if(!(header = trtp_rtcp_header_deserialize(pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to deserialize the header");
+ goto bail;
+ }
+ if(header->length_in_bytes < TRTP_RTCP_PACKET_SR_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Too short");
+ goto bail;
+ }
+
+ if(!(sr = trtp_rtcp_report_sr_create(header))) {
+ TSK_DEBUG_ERROR("Failed to create object");
+ goto bail;
+ }
+
+ sr->ssrc = (uint32_t)tnet_ntohl_2(&pdata[4]);
+ pdata += (TRTP_RTCP_HEADER_SIZE + 4);
+ size -= (TRTP_RTCP_HEADER_SIZE + 4);
+
+ // sender info
+ sr->sender_info.ntp_msw = (uint32_t)tnet_ntohl_2(&pdata[0]);
+ sr->sender_info.ntp_lsw = (uint32_t)tnet_ntohl_2(&pdata[4]);
+ sr->sender_info.rtp_timestamp = (uint32_t)tnet_ntohl_2(&pdata[8]);
+ sr->sender_info.sender_pcount = (uint32_t)tnet_ntohl_2(&pdata[12]);
+ sr->sender_info.sender_ocount = (uint32_t)tnet_ntohl_2(&pdata[16]);
+ pdata += 20;
+ size -= 20;
+
+ // Blocks
+ if(header->rc > 0) {
+ tsk_size_t i = 0;
+ trtp_rtcp_rblock_t* rblock;
+
+ while(i++ < header->rc && size >= TRTP_RTCP_RBLOCK_SIZE) {
+ if((rblock = trtp_rtcp_rblock_deserialize(pdata, size))) {
+ tsk_list_push_back_data(sr->blocks, (void**)&rblock);
+ }
+ pdata += TRTP_RTCP_RBLOCK_SIZE;
+ size -= TRTP_RTCP_RBLOCK_SIZE;
+ }
+ }
+
+ // Other Packets
+ while(size > TRTP_RTCP_HEADER_SIZE) {
+ trtp_rtcp_packet_t* packet;
+
+ if((packet = trtp_rtcp_packet_deserialize(pdata, size))) {
+ if((size -= packet->header->length_in_bytes) > 0) {
+ pdata += packet->header->length_in_bytes;
+ }
+ tsk_list_push_back_data(sr->packets, (void**)&packet);
+ continue;
+ }
+ break;
+ }
bail:
- TSK_OBJECT_SAFE_FREE(header);
- return sr;
+ TSK_OBJECT_SAFE_FREE(header);
+ return sr;
}
int trtp_rtcp_report_sr_serialize_to(const trtp_rtcp_report_sr_t* self, void* data, tsk_size_t size)
{
- int ret;
- const tsk_list_item_t* item;
- uint8_t* pdata = (uint8_t*)data;
-
- if(!self || !data || size < trtp_rtcp_report_sr_get_size(self)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize the header");
- return ret;
- }
-
- pdata[TRTP_RTCP_HEADER_SIZE] = self->ssrc >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 1] = (self->ssrc >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 2] = (self->ssrc >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 3] = (self->ssrc & 0xFF);
- pdata[TRTP_RTCP_HEADER_SIZE + 4] = self->sender_info.ntp_msw >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 5] = (self->sender_info.ntp_msw >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 6] = (self->sender_info.ntp_msw >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 7] = self->sender_info.ntp_msw & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 8] = self->sender_info.ntp_lsw >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 9] = (self->sender_info.ntp_lsw >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 10] = (self->sender_info.ntp_lsw >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 11] = self->sender_info.ntp_lsw & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 12] = self->sender_info.rtp_timestamp >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 13] = (self->sender_info.rtp_timestamp >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 14] = (self->sender_info.rtp_timestamp >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 15] = self->sender_info.rtp_timestamp & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 16] = self->sender_info.sender_pcount >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 17] = (self->sender_info.sender_pcount >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 18] = (self->sender_info.sender_pcount >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 19] = self->sender_info.sender_pcount & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 20] = self->sender_info.sender_ocount >> 24;
- pdata[TRTP_RTCP_HEADER_SIZE + 21] = (self->sender_info.sender_ocount >> 16) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 22] = (self->sender_info.sender_ocount >> 8) & 0xFF;
- pdata[TRTP_RTCP_HEADER_SIZE + 23] = self->sender_info.sender_ocount & 0xFF;
-
- pdata += (TRTP_RTCP_HEADER_SIZE + 4 + 20);
- size -= (TRTP_RTCP_HEADER_SIZE + 4 + 20);
-
- if(TRTP_RTCP_PACKET(self)->header->rc > 0){
- tsk_list_foreach(item, self->blocks){
- if(!item->data){
- continue;
- }
- if((ret = trtp_rtcp_rblock_serialize_to(TRTP_RTCP_RBLOCK(item->data), pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize the rblock");
- goto bail;
- }
- pdata += TRTP_RTCP_RBLOCK_SIZE;
- size -= TRTP_RTCP_RBLOCK_SIZE;
- }
- }
-
- tsk_list_foreach(item, self->packets){
- if(!item->data){
- continue;
- }
- if((ret = trtp_rtcp_packet_serialize_to(TRTP_RTCP_PACKET(item->data), pdata, size))){
- TSK_DEBUG_ERROR("Failed to serialize packet");
- goto bail;
- }
- pdata += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- size -= TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- }
+ int ret;
+ const tsk_list_item_t* item;
+ uint8_t* pdata = (uint8_t*)data;
+
+ if(!self || !data || size < trtp_rtcp_report_sr_get_size(self)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if((ret = trtp_rtcp_header_serialize_to(TRTP_RTCP_PACKET(self)->header, pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize the header");
+ return ret;
+ }
+
+ pdata[TRTP_RTCP_HEADER_SIZE] = self->ssrc >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 1] = (self->ssrc >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 2] = (self->ssrc >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 3] = (self->ssrc & 0xFF);
+ pdata[TRTP_RTCP_HEADER_SIZE + 4] = self->sender_info.ntp_msw >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 5] = (self->sender_info.ntp_msw >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 6] = (self->sender_info.ntp_msw >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 7] = self->sender_info.ntp_msw & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 8] = self->sender_info.ntp_lsw >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 9] = (self->sender_info.ntp_lsw >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 10] = (self->sender_info.ntp_lsw >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 11] = self->sender_info.ntp_lsw & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 12] = self->sender_info.rtp_timestamp >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 13] = (self->sender_info.rtp_timestamp >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 14] = (self->sender_info.rtp_timestamp >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 15] = self->sender_info.rtp_timestamp & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 16] = self->sender_info.sender_pcount >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 17] = (self->sender_info.sender_pcount >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 18] = (self->sender_info.sender_pcount >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 19] = self->sender_info.sender_pcount & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 20] = self->sender_info.sender_ocount >> 24;
+ pdata[TRTP_RTCP_HEADER_SIZE + 21] = (self->sender_info.sender_ocount >> 16) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 22] = (self->sender_info.sender_ocount >> 8) & 0xFF;
+ pdata[TRTP_RTCP_HEADER_SIZE + 23] = self->sender_info.sender_ocount & 0xFF;
+
+ pdata += (TRTP_RTCP_HEADER_SIZE + 4 + 20);
+ size -= (TRTP_RTCP_HEADER_SIZE + 4 + 20);
+
+ if(TRTP_RTCP_PACKET(self)->header->rc > 0) {
+ tsk_list_foreach(item, self->blocks) {
+ if(!item->data) {
+ continue;
+ }
+ if((ret = trtp_rtcp_rblock_serialize_to(TRTP_RTCP_RBLOCK(item->data), pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize the rblock");
+ goto bail;
+ }
+ pdata += TRTP_RTCP_RBLOCK_SIZE;
+ size -= TRTP_RTCP_RBLOCK_SIZE;
+ }
+ }
+
+ tsk_list_foreach(item, self->packets) {
+ if(!item->data) {
+ continue;
+ }
+ if((ret = trtp_rtcp_packet_serialize_to(TRTP_RTCP_PACKET(item->data), pdata, size))) {
+ TSK_DEBUG_ERROR("Failed to serialize packet");
+ goto bail;
+ }
+ pdata += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ size -= TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ }
bail:
- return ret;
+ return ret;
}
int trtp_rtcp_report_sr_add_block(trtp_rtcp_report_sr_t* self, trtp_rtcp_rblock_t* rblock)
{
- if(!self || !TRTP_RTCP_PACKET(self)->header || !rblock){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- rblock = tsk_object_ref(rblock);
- tsk_list_push_back_data(self->blocks, (void**)&rblock);
- ++TRTP_RTCP_PACKET(self)->header->rc;
- TRTP_RTCP_PACKET(self)->header->length_in_bytes += TRTP_RTCP_RBLOCK_SIZE;
- TRTP_RTCP_PACKET(self)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(self)->header->length_in_bytes >> 2) - 1) +
- ((TRTP_RTCP_PACKET(self)->header->length_in_bytes & 0x03) ? 1 : 0);
- return 0;
+ if(!self || !TRTP_RTCP_PACKET(self)->header || !rblock) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ rblock = tsk_object_ref(rblock);
+ tsk_list_push_back_data(self->blocks, (void**)&rblock);
+ ++TRTP_RTCP_PACKET(self)->header->rc;
+ TRTP_RTCP_PACKET(self)->header->length_in_bytes += TRTP_RTCP_RBLOCK_SIZE;
+ TRTP_RTCP_PACKET(self)->header->length_in_words_minus1 = ((TRTP_RTCP_PACKET(self)->header->length_in_bytes >> 2) - 1) +
+ ((TRTP_RTCP_PACKET(self)->header->length_in_bytes & 0x03) ? 1 : 0);
+ return 0;
}
tsk_size_t trtp_rtcp_report_sr_get_size(const trtp_rtcp_report_sr_t* self)
{
- tsk_size_t size;
- const tsk_list_item_t* item;
-
- if(!self || !TRTP_RTCP_PACKET(self)->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- size = TRTP_RTCP_PACKET(self)->header->length_in_bytes;
- //if(TRTP_RTCP_PACKET(self)->header->rc > 0){
- // tsk_list_foreach(item, self->blocks){
- // if(item->data){
- // size += TRTP_RTCP_RBLOCK_SIZE;
- // }
- // }
- //}
- tsk_list_foreach(item, self->packets){
- if(item->data && TRTP_RTCP_PACKET(item->data)->header){
- size += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
- }
- }
-
- return size;
+ tsk_size_t size;
+ const tsk_list_item_t* item;
+
+ if(!self || !TRTP_RTCP_PACKET(self)->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+
+ size = TRTP_RTCP_PACKET(self)->header->length_in_bytes;
+ //if(TRTP_RTCP_PACKET(self)->header->rc > 0){
+ // tsk_list_foreach(item, self->blocks){
+ // if(item->data){
+ // size += TRTP_RTCP_RBLOCK_SIZE;
+ // }
+ // }
+ //}
+ tsk_list_foreach(item, self->packets) {
+ if(item->data && TRTP_RTCP_PACKET(item->data)->header) {
+ size += TRTP_RTCP_PACKET(item->data)->header->length_in_bytes;
+ }
+ }
+
+ return size;
}
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_report_xr.c b/tinyRTP/src/rtcp/trtp_rtcp_report_xr.c
index 5fb2697..41e177b 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_report_xr.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_report_xr.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_sdes_chunck.c b/tinyRTP/src/rtcp/trtp_rtcp_sdes_chunck.c
index 9104580..f8bed63 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_sdes_chunck.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_sdes_chunck.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -44,27 +44,26 @@ Each chunk consists of an SSRC/CSRC identifier followed by a list of
static tsk_object_t* trtp_rtcp_sdes_chunck_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_sdes_chunck_t *chunck = self;
- if(chunck){
- chunck->items = tsk_list_create();
- }
- return self;
+ trtp_rtcp_sdes_chunck_t *chunck = self;
+ if(chunck) {
+ chunck->items = tsk_list_create();
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_sdes_chunck_dtor(tsk_object_t * self)
-{
- trtp_rtcp_sdes_chunck_t *chunck = self;
- if(chunck){
- TSK_OBJECT_SAFE_FREE(chunck->items);
- }
+{
+ trtp_rtcp_sdes_chunck_t *chunck = self;
+ if(chunck) {
+ TSK_OBJECT_SAFE_FREE(chunck->items);
+ }
- return self;
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_sdes_chunck_def_s =
-{
- sizeof(trtp_rtcp_sdes_chunck_t),
- trtp_rtcp_sdes_chunck_ctor,
- trtp_rtcp_sdes_chunck_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_sdes_chunck_def_s = {
+ sizeof(trtp_rtcp_sdes_chunck_t),
+ trtp_rtcp_sdes_chunck_ctor,
+ trtp_rtcp_sdes_chunck_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_sdes_chunck_def_t = &trtp_rtcp_sdes_chunck_def_s;
@@ -72,119 +71,120 @@ const tsk_object_def_t *trtp_rtcp_sdes_chunck_def_t = &trtp_rtcp_sdes_chunck_def
trtp_rtcp_sdes_chunck_t* trtp_rtcp_sdes_chunck_create_null()
{
- return tsk_object_new(trtp_rtcp_sdes_chunck_def_t);
+ return tsk_object_new(trtp_rtcp_sdes_chunck_def_t);
}
trtp_rtcp_sdes_chunck_t* trtp_rtcp_sdes_chunck_create(uint32_t ssrc)
{
- trtp_rtcp_sdes_chunck_t* chunck;
- if((chunck = trtp_rtcp_sdes_chunck_create_null())){
- chunck->ssrc = ssrc;
- }
- return chunck;
+ trtp_rtcp_sdes_chunck_t* chunck;
+ if((chunck = trtp_rtcp_sdes_chunck_create_null())) {
+ chunck->ssrc = ssrc;
+ }
+ return chunck;
}
trtp_rtcp_sdes_chunck_t* trtp_rtcp_sdes_chunck_deserialize(const void* data, tsk_size_t size)
{
- trtp_rtcp_sdes_chunck_t* chunck = tsk_null;
- const uint8_t* pdata = (uint8_t*)data;
- const uint8_t* pend;
- if(!data || size < TRTP_RTCP_SDES_CHUNCK_MIN_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- pend = (pdata + size);
- if((chunck = trtp_rtcp_sdes_chunck_create_null())){
- trtp_rtcp_sdes_item_t* item;
- tsk_bool_t is_last_item = tsk_false;
- // SSRC/CSRC
- chunck->ssrc = (uint32_t)tnet_ntohl_2(pdata);
- pdata += TRTP_RTCP_SDES_CHUNCK_SSRC_OR_CSRC_SIZE;
- while((pdata < pend) && !is_last_item){
- if((item = trtp_rtcp_sdes_item_deserialize(pdata, (pend-pdata)))){
- is_last_item = (item->type == trtp_rtcp_sdes_item_type_end);
- pdata += trtp_rtcp_sdes_item_get_size(item);
- tsk_list_push_back_data(chunck->items, (void**)&item);
- }
- else{
- TSK_DEBUG_ERROR("Failed to deserialize sdes item");
- break;
- }
- }
- }
- else{
- TSK_DEBUG_ERROR("Failed to create new sdes_chunck object");
- return tsk_null;
- }
-
- return chunck;
+ trtp_rtcp_sdes_chunck_t* chunck = tsk_null;
+ const uint8_t* pdata = (uint8_t*)data;
+ const uint8_t* pend;
+ if(!data || size < TRTP_RTCP_SDES_CHUNCK_MIN_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+
+ pend = (pdata + size);
+ if((chunck = trtp_rtcp_sdes_chunck_create_null())) {
+ trtp_rtcp_sdes_item_t* item;
+ tsk_bool_t is_last_item = tsk_false;
+ // SSRC/CSRC
+ chunck->ssrc = (uint32_t)tnet_ntohl_2(pdata);
+ pdata += TRTP_RTCP_SDES_CHUNCK_SSRC_OR_CSRC_SIZE;
+ while((pdata < pend) && !is_last_item) {
+ if((item = trtp_rtcp_sdes_item_deserialize(pdata, (pend-pdata)))) {
+ is_last_item = (item->type == trtp_rtcp_sdes_item_type_end);
+ pdata += trtp_rtcp_sdes_item_get_size(item);
+ tsk_list_push_back_data(chunck->items, (void**)&item);
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to deserialize sdes item");
+ break;
+ }
+ }
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to create new sdes_chunck object");
+ return tsk_null;
+ }
+
+ return chunck;
}
int trtp_rtcp_sdes_chunck_serialize_to(const trtp_rtcp_sdes_chunck_t* self, void* data, tsk_size_t size)
{
- uint8_t* pdata = (uint8_t*)data;
- const tsk_list_item_t* item;
- const trtp_rtcp_sdes_item_t* sdes_item;
- tsk_size_t sdes_item_size;
- int ret = 0;
-
- if(!self || !data || size < trtp_rtcp_sdes_chunck_get_size(self)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- pdata[0] = self->ssrc >> 24;
- pdata[1] = (self->ssrc >> 16) & 0xFF;
- pdata[2] = (self->ssrc >> 8) & 0xFF;
- pdata[3] = (self->ssrc & 0xFF);
- pdata += 4;
-
- tsk_list_foreach(item, self->items){
- if(!(sdes_item = TRTP_RTCP_SDES_ITEM(item->data))){
- continue;
- }
- if((ret = trtp_rtcp_sdes_item_serialize_to(sdes_item, pdata, size))){
- TSK_DEBUG_ERROR("SDES item serialization failed");
- goto bail;
- }
- sdes_item_size = trtp_rtcp_sdes_item_get_size(sdes_item);
- pdata += sdes_item_size; size -= sdes_item_size;
- }
+ uint8_t* pdata = (uint8_t*)data;
+ const tsk_list_item_t* item;
+ const trtp_rtcp_sdes_item_t* sdes_item;
+ tsk_size_t sdes_item_size;
+ int ret = 0;
+
+ if(!self || !data || size < trtp_rtcp_sdes_chunck_get_size(self)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ pdata[0] = self->ssrc >> 24;
+ pdata[1] = (self->ssrc >> 16) & 0xFF;
+ pdata[2] = (self->ssrc >> 8) & 0xFF;
+ pdata[3] = (self->ssrc & 0xFF);
+ pdata += 4;
+
+ tsk_list_foreach(item, self->items) {
+ if(!(sdes_item = TRTP_RTCP_SDES_ITEM(item->data))) {
+ continue;
+ }
+ if((ret = trtp_rtcp_sdes_item_serialize_to(sdes_item, pdata, size))) {
+ TSK_DEBUG_ERROR("SDES item serialization failed");
+ goto bail;
+ }
+ sdes_item_size = trtp_rtcp_sdes_item_get_size(sdes_item);
+ pdata += sdes_item_size;
+ size -= sdes_item_size;
+ }
bail:
- return ret;
+ return ret;
}
int trtp_rtcp_sdes_chunck_add_item(trtp_rtcp_sdes_chunck_t* self, trtp_rtcp_sdes_item_type_t type, const void* data, uint8_t length)
{
- trtp_rtcp_sdes_item_t *item;
- if(!self || !self->items){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if((item = trtp_rtcp_sdes_item_create(type, data, length))){
- tsk_list_push_back_data(self->items, (void**)&item);
- }
- return 0;
+ trtp_rtcp_sdes_item_t *item;
+ if(!self || !self->items) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if((item = trtp_rtcp_sdes_item_create(type, data, length))) {
+ tsk_list_push_back_data(self->items, (void**)&item);
+ }
+ return 0;
}
tsk_size_t trtp_rtcp_sdes_chunck_get_size(const trtp_rtcp_sdes_chunck_t* self)
{
- const tsk_list_item_t* item;
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
- else{
- tsk_size_t size = TRTP_RTCP_SDES_CHUNCK_SSRC_OR_CSRC_SIZE;
- tsk_list_foreach(item, self->items){
- size += trtp_rtcp_sdes_item_get_size(TRTP_RTCP_SDES_ITEM(item->data));
- }
- if(size & 0x03){//Each chunk starts on a 32-bit boundary
- size += (4 - (size & 0x03));
- }
- return size;
- }
+ const tsk_list_item_t* item;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+ else {
+ tsk_size_t size = TRTP_RTCP_SDES_CHUNCK_SSRC_OR_CSRC_SIZE;
+ tsk_list_foreach(item, self->items) {
+ size += trtp_rtcp_sdes_item_get_size(TRTP_RTCP_SDES_ITEM(item->data));
+ }
+ if(size & 0x03) { //Each chunk starts on a 32-bit boundary
+ size += (4 - (size & 0x03));
+ }
+ return size;
+ }
}
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_sdes_item.c b/tinyRTP/src/rtcp/trtp_rtcp_sdes_item.c
index 7f22537..6d70a46 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_sdes_item.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_sdes_item.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -32,117 +32,118 @@
static tsk_object_t* trtp_rtcp_sdes_item_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_sdes_item_t *item = self;
- if(item){
- }
- return self;
+ trtp_rtcp_sdes_item_t *item = self;
+ if(item) {
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_sdes_item_dtor(tsk_object_t * self)
-{
- trtp_rtcp_sdes_item_t *item = self;
- if(item){
- TSK_OBJECT_SAFE_FREE(item->data);
- }
+{
+ trtp_rtcp_sdes_item_t *item = self;
+ if(item) {
+ TSK_OBJECT_SAFE_FREE(item->data);
+ }
- return self;
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_sdes_item_def_s =
-{
- sizeof(trtp_rtcp_sdes_item_t),
- trtp_rtcp_sdes_item_ctor,
- trtp_rtcp_sdes_item_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_sdes_item_def_s = {
+ sizeof(trtp_rtcp_sdes_item_t),
+ trtp_rtcp_sdes_item_ctor,
+ trtp_rtcp_sdes_item_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_sdes_item_def_t = &trtp_rtcp_sdes_item_def_s;
trtp_rtcp_sdes_item_t* _trtp_rtcp_sdes_item_create_null(trtp_rtcp_sdes_item_type_t type)
{
- return tsk_object_new(trtp_rtcp_sdes_item_def_t);
+ return tsk_object_new(trtp_rtcp_sdes_item_def_t);
}
trtp_rtcp_sdes_item_t* trtp_rtcp_sdes_item_create(trtp_rtcp_sdes_item_type_t type, const void* data, uint8_t length)
{
- trtp_rtcp_sdes_item_t* item;
- if(!(item = _trtp_rtcp_sdes_item_create_null(type))){
- TSK_DEBUG_ERROR("Failed to create new SDES item");
- return tsk_null;
- }
- item->type = type;
- if(data && length){
- item->data = tsk_buffer_create(data, length);
- }
-
- return item;
+ trtp_rtcp_sdes_item_t* item;
+ if(!(item = _trtp_rtcp_sdes_item_create_null(type))) {
+ TSK_DEBUG_ERROR("Failed to create new SDES item");
+ return tsk_null;
+ }
+ item->type = type;
+ if(data && length) {
+ item->data = tsk_buffer_create(data, length);
+ }
+
+ return item;
}
trtp_rtcp_sdes_item_t* trtp_rtcp_sdes_item_deserialize(const void* data, tsk_size_t size)
{
- const uint8_t* pdata = (const uint8_t*)data;
-
- if(!data || !size){
- TSK_DEBUG_ERROR("Invlaid parameter");
- return tsk_null;
- }
-
- if(pdata[0] == trtp_rtcp_sdes_item_type_end){
- return trtp_rtcp_sdes_item_create(trtp_rtcp_sdes_item_type_end, tsk_null, 0);
- }
-
- if(size < TRTP_RTCP_SDES_ITEM_MIN_SIZE || size < (tsk_size_t)(pdata[1] + 2)){
- TSK_DEBUG_ERROR("Too short");
- return tsk_null;
- }
-
- return trtp_rtcp_sdes_item_create((trtp_rtcp_sdes_item_type_t)pdata[0], &pdata[2], pdata[1]);
+ const uint8_t* pdata = (const uint8_t*)data;
+
+ if(!data || !size) {
+ TSK_DEBUG_ERROR("Invlaid parameter");
+ return tsk_null;
+ }
+
+ if(pdata[0] == trtp_rtcp_sdes_item_type_end) {
+ return trtp_rtcp_sdes_item_create(trtp_rtcp_sdes_item_type_end, tsk_null, 0);
+ }
+
+ if(size < TRTP_RTCP_SDES_ITEM_MIN_SIZE || size < (tsk_size_t)(pdata[1] + 2)) {
+ TSK_DEBUG_ERROR("Too short");
+ return tsk_null;
+ }
+
+ return trtp_rtcp_sdes_item_create((trtp_rtcp_sdes_item_type_t)pdata[0], &pdata[2], pdata[1]);
}
tsk_buffer_t* trtp_rtcp_sdes_item_serialize(const trtp_rtcp_sdes_item_t* self)
{
- tsk_buffer_t*buffer = tsk_null;
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
- if((buffer = tsk_buffer_create(tsk_null, trtp_rtcp_sdes_item_get_size(self)))){
- if(trtp_rtcp_sdes_item_serialize_to(self, buffer->data, buffer->size) != 0){
- TSK_OBJECT_SAFE_FREE(buffer);
- }
- }
- return buffer;
+ tsk_buffer_t*buffer = tsk_null;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+ if((buffer = tsk_buffer_create(tsk_null, trtp_rtcp_sdes_item_get_size(self)))) {
+ if(trtp_rtcp_sdes_item_serialize_to(self, buffer->data, buffer->size) != 0) {
+ TSK_OBJECT_SAFE_FREE(buffer);
+ }
+ }
+ return buffer;
}
int trtp_rtcp_sdes_item_serialize_to(const trtp_rtcp_sdes_item_t* self, void* data, tsk_size_t size)
{
- if(!self || !data || (size < trtp_rtcp_sdes_item_get_size(self))){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(self->type == trtp_rtcp_sdes_item_type_end){
- ((uint8_t*)data)[0] = trtp_rtcp_sdes_item_type_end;
- }
- else{
- ((uint8_t*)data)[0] = self->type;
- if(self->data){
- ((uint8_t*)data)[1] = (uint8_t)self->data->size;
- memcpy(&((uint8_t*)data)[2], self->data->data, self->data->size);
- }
- else{
- ((uint8_t*)data)[1] = 0;
- }
- }
- return 0;
+ if(!self || !data || (size < trtp_rtcp_sdes_item_get_size(self))) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if(self->type == trtp_rtcp_sdes_item_type_end) {
+ ((uint8_t*)data)[0] = trtp_rtcp_sdes_item_type_end;
+ }
+ else {
+ ((uint8_t*)data)[0] = self->type;
+ if(self->data) {
+ ((uint8_t*)data)[1] = (uint8_t)self->data->size;
+ memcpy(&((uint8_t*)data)[2], self->data->data, self->data->size);
+ }
+ else {
+ ((uint8_t*)data)[1] = 0;
+ }
+ }
+ return 0;
}
tsk_size_t trtp_rtcp_sdes_item_get_size(const trtp_rtcp_sdes_item_t* self)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
- switch(self->type){
- case trtp_rtcp_sdes_item_type_end: return 1;
- default: return 2 + (self->data ? self->data->size : 0);
- }
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+ switch(self->type) {
+ case trtp_rtcp_sdes_item_type_end:
+ return 1;
+ default:
+ return 2 + (self->data ? self->data->size : 0);
+ }
}
diff --git a/tinyRTP/src/rtcp/trtp_rtcp_session.c b/tinyRTP/src/rtcp/trtp_rtcp_session.c
index b2f4733..226b0cd 100755
--- a/tinyRTP/src/rtcp/trtp_rtcp_session.c
+++ b/tinyRTP/src/rtcp/trtp_rtcp_session.c
@@ -2,19 +2,19 @@
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -56,8 +56,14 @@
#include <limits.h> /* INT_MAX */
#ifdef _MSC_VER
-static double drand48() { return (((double)rand()) / RAND_MAX); }
-static void srand48(long sv) { srand((unsigned int) sv); }
+static double drand48()
+{
+ return (((double)rand()) / RAND_MAX);
+}
+static void srand48(long sv)
+{
+ srand((unsigned int) sv);
+}
#endif
#define RTCP_BW (160 * 50) // FIXME: default bandwidth (octet/second)
@@ -70,19 +76,17 @@ static void srand48(long sv) { srand((unsigned int) sv); }
typedef double time_tp;
typedef void* packet_;
-typedef enum event_
-{
- EVENT_BYE,
- EVENT_REPORT,
- EVENT_RTP
+typedef enum event_ {
+ EVENT_BYE,
+ EVENT_REPORT,
+ EVENT_RTP
}
event_;
-typedef enum PacketType_
-{
- PACKET_RTCP_REPORT,
- PACKET_BYE,
- PACKET_RTP,
+typedef enum PacketType_ {
+ PACKET_RTCP_REPORT,
+ PACKET_BYE,
+ PACKET_RTP,
}
PacketType_;
@@ -90,53 +94,51 @@ PacketType_;
#define TRTP_RTCP_SOURCE(self) ((trtp_rtcp_source_t*)self)
-typedef struct trtp_rtcp_source_s
-{
- TSK_DECLARE_OBJECT;
-
- uint32_t ssrc; /* source's ssrc */
- uint16_t max_seq; /* highest seq. number seen */
- uint32_t cycles; /* shifted count of seq. number cycles */
- uint32_t base_seq; /* base seq number */
- uint32_t bad_seq; /* last 'bad' seq number + 1 */
- uint32_t probation; /* sequ. packets till source is valid */
- uint32_t received; /* packets received */
- uint32_t expected_prior; /* packet expected at last interval */
- uint32_t received_prior; /* packet received at last interval */
- uint32_t transit; /* relative trans time for prev pkt */
- double jitter; /* estimated jitter */
-
- uint32_t base_ts; /* base timestamp */
- uint32_t max_ts; /* highest timestamp number seen */
- uint32_t rate; /* codec sampling rate */
-
- uint32_t ntp_msw; /* last received NTP timestamp from RTCP sender */
- uint32_t ntp_lsw; /* last received NTP timestamp from RTCP sender */
- uint64_t dlsr; /* delay since last SR */
+typedef struct trtp_rtcp_source_s {
+ TSK_DECLARE_OBJECT;
+
+ uint32_t ssrc; /* source's ssrc */
+ uint16_t max_seq; /* highest seq. number seen */
+ uint32_t cycles; /* shifted count of seq. number cycles */
+ uint32_t base_seq; /* base seq number */
+ uint32_t bad_seq; /* last 'bad' seq number + 1 */
+ uint32_t probation; /* sequ. packets till source is valid */
+ uint32_t received; /* packets received */
+ uint32_t expected_prior; /* packet expected at last interval */
+ uint32_t received_prior; /* packet received at last interval */
+ uint32_t transit; /* relative trans time for prev pkt */
+ double jitter; /* estimated jitter */
+
+ uint32_t base_ts; /* base timestamp */
+ uint32_t max_ts; /* highest timestamp number seen */
+ uint32_t rate; /* codec sampling rate */
+
+ uint32_t ntp_msw; /* last received NTP timestamp from RTCP sender */
+ uint32_t ntp_lsw; /* last received NTP timestamp from RTCP sender */
+ uint64_t dlsr; /* delay since last SR */
}
trtp_rtcp_source_t;
typedef tsk_list_t trtp_rtcp_sources_L_t; /**< List of @ref trtp_rtcp_header_t elements */
static tsk_object_t* trtp_rtcp_source_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_source_t *source = self;
- if(source){
- }
- return self;
+ trtp_rtcp_source_t *source = self;
+ if(source) {
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_source_dtor(tsk_object_t * self)
-{
- trtp_rtcp_source_t *source = self;
- if(source){
- }
- return self;
-}
-static const tsk_object_def_t trtp_rtcp_source_def_s =
{
- sizeof(trtp_rtcp_source_t),
- trtp_rtcp_source_ctor,
- trtp_rtcp_source_dtor,
- tsk_null,
+ trtp_rtcp_source_t *source = self;
+ if(source) {
+ }
+ return self;
+}
+static const tsk_object_def_t trtp_rtcp_source_def_s = {
+ sizeof(trtp_rtcp_source_t),
+ trtp_rtcp_source_ctor,
+ trtp_rtcp_source_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_source_def_t = &trtp_rtcp_source_def_s;
@@ -145,113 +147,117 @@ static tsk_bool_t _trtp_rtcp_source_update_seq(trtp_rtcp_source_t* self, uint16_
static int __pred_find_source_by_ssrc(const tsk_list_item_t *item, const void *pssrc)
{
- if(item && item->data){
- trtp_rtcp_source_t *source = item->data;
- return source->ssrc - *((uint32_t*)pssrc);
- }
- return -1;
+ if(item && item->data) {
+ trtp_rtcp_source_t *source = item->data;
+ return source->ssrc - *((uint32_t*)pssrc);
+ }
+ return -1;
}
static trtp_rtcp_source_t* _trtp_rtcp_source_create(uint32_t ssrc, uint16_t seq, uint32_t ts)
{
- trtp_rtcp_source_t* source;
- if(!(source = tsk_object_new(trtp_rtcp_source_def_t))){
- TSK_DEBUG_ERROR("Failed to create source object");
- return tsk_null;
- }
-
- _trtp_rtcp_source_init_seq(source, seq, ts);
- source->ssrc = ssrc;
- source->max_seq = seq - 1;
- source->probation = MIN_SEQUENTIAL;
- source->rate = CODEC_RATE;//FIXME
-
- return source;
+ trtp_rtcp_source_t* source;
+ if(!(source = tsk_object_new(trtp_rtcp_source_def_t))) {
+ TSK_DEBUG_ERROR("Failed to create source object");
+ return tsk_null;
+ }
+
+ _trtp_rtcp_source_init_seq(source, seq, ts);
+ source->ssrc = ssrc;
+ source->max_seq = seq - 1;
+ source->probation = MIN_SEQUENTIAL;
+ source->rate = CODEC_RATE;//FIXME
+
+ return source;
}
static int _trtp_rtcp_source_init_seq(trtp_rtcp_source_t* self, uint16_t seq, uint32_t ts)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- self->base_seq = seq;
- self->max_seq = seq;
- self->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */
- self->cycles = 0;
- self->received = 0;
- self->received_prior = 0;
- self->expected_prior = 0;
- self->base_ts = ts;
- self->max_ts = ts;
- return 0;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ self->base_seq = seq;
+ self->max_seq = seq;
+ self->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */
+ self->cycles = 0;
+ self->received = 0;
+ self->received_prior = 0;
+ self->expected_prior = 0;
+ self->base_ts = ts;
+ self->max_ts = ts;
+ return 0;
}
static tsk_bool_t _trtp_rtcp_source_update_seq(trtp_rtcp_source_t* self, uint16_t seq, uint32_t ts)
{
- uint16_t udelta;
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_false;
- }
-
- udelta = seq - self->max_seq;
-
- /*
- * Source is not valid until MIN_SEQUENTIAL packets with
- * sequential sequence numbers have been received.
- */
- if (self->probation) {
- /* packet is in sequence */
- if (seq == self->max_seq + 1) {
- self->probation--;
- self->max_seq = seq;
- self->max_ts = ts;
- if (self->probation == 0) {
- _trtp_rtcp_source_init_seq(self, seq, ts);
- self->received++;
- return tsk_true;
- }
- } else {
- self->probation = MIN_SEQUENTIAL - 1;
- self->max_seq = seq;
- self->max_ts = ts;
- }
- return tsk_false;
- } else if (udelta < MAX_DROPOUT) {
- /* in order, with permissible gap */
- if (seq < self->max_seq) {
- /*
- * Sequence number wrapped - count another 64K cycle.
- */
- self->cycles += RTP_SEQ_MOD;
- }
- self->max_seq = seq;
- self->max_ts = ts;
- } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
- /* the sequence number made a very large jump */
- if (seq == self->bad_seq) {
- /*
- * Two sequential packets -- assume that the other side
- * restarted without telling us so just re-sync
- * (i.e., pretend this was the first packet).
- */
- _trtp_rtcp_source_init_seq(self, seq, ts);
- }
- else {
- self->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
- return tsk_false;
- }
- } else {
- /* duplicate or reordered packet */
- }
- self->received++;
- return tsk_true;
+ uint16_t udelta;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_false;
+ }
+
+ udelta = seq - self->max_seq;
+
+ /*
+ * Source is not valid until MIN_SEQUENTIAL packets with
+ * sequential sequence numbers have been received.
+ */
+ if (self->probation) {
+ /* packet is in sequence */
+ if (seq == self->max_seq + 1) {
+ self->probation--;
+ self->max_seq = seq;
+ self->max_ts = ts;
+ if (self->probation == 0) {
+ _trtp_rtcp_source_init_seq(self, seq, ts);
+ self->received++;
+ return tsk_true;
+ }
+ }
+ else {
+ self->probation = MIN_SEQUENTIAL - 1;
+ self->max_seq = seq;
+ self->max_ts = ts;
+ }
+ return tsk_false;
+ }
+ else if (udelta < MAX_DROPOUT) {
+ /* in order, with permissible gap */
+ if (seq < self->max_seq) {
+ /*
+ * Sequence number wrapped - count another 64K cycle.
+ */
+ self->cycles += RTP_SEQ_MOD;
+ }
+ self->max_seq = seq;
+ self->max_ts = ts;
+ }
+ else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
+ /* the sequence number made a very large jump */
+ if (seq == self->bad_seq) {
+ /*
+ * Two sequential packets -- assume that the other side
+ * restarted without telling us so just re-sync
+ * (i.e., pretend this was the first packet).
+ */
+ _trtp_rtcp_source_init_seq(self, seq, ts);
+ }
+ else {
+ self->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
+ return tsk_false;
+ }
+ }
+ else {
+ /* duplicate or reordered packet */
+ }
+ self->received++;
+ return tsk_true;
}
static tsk_bool_t _trtp_rtcp_source_is_probed(const trtp_rtcp_source_t* self)
{
- return (self && self->probation == 0);
+ return (self && self->probation == 0);
}
@@ -261,118 +267,120 @@ static tsk_bool_t _trtp_rtcp_source_is_probed(const trtp_rtcp_source_t* self)
typedef time_tp (*tc_f)();
-static time_tp _trtp_rtcp_session_tc() { return (time_tp)tsk_time_now(); }
-
-typedef struct trtp_rtcp_session_s
+static time_tp _trtp_rtcp_session_tc()
{
- TSK_DECLARE_OBJECT;
-
- tsk_bool_t is_started;
- tnet_fd_t local_fd;
+ return (time_tp)tsk_time_now();
+}
+
+typedef struct trtp_rtcp_session_s {
+ TSK_DECLARE_OBJECT;
+
+ tsk_bool_t is_started;
+ tnet_fd_t local_fd;
struct tnet_transport_s* transport; // not starter -> do not stop
- const struct sockaddr * remote_addr;
- struct tnet_ice_ctx_s* ice_ctx; // not starter -> do not stop
- tsk_bool_t is_ice_turn_active;
-
- const void* callback_data;
- trtp_rtcp_cb_f callback;
-
- int32_t app_bw_max_upload; // application specific (kbps)
- int32_t app_bw_max_download; // application specific (kbps)
-
- struct{
- tsk_timer_manager_handle_t* handle_global;
- tsk_timer_id_t id_report;
- tsk_timer_id_t id_bye;
- } timer;
-
- trtp_rtcp_source_t* source_local; /**< local source */
- trtp_rtcp_report_sdes_t* sdes;
- uint64_t time_start; /**< Start time in millis (NOT in NTP unit yet) */
-
- // <RTCP-FB>
- uint8_t fir_seqnr;
- // </RTCP-FB>
-
- // <sender>
- char* cname;
- uint32_t packets_count;
- uint32_t octets_count;
- // </sender>
-
- // <others>
- time_tp tp; /**< the last time an RTCP packet was transmitted; */
- tc_f tc; /**< the current time */
- time_tp tn; /**< the next scheduled transmission time of an RTCP packet */
- int32_t pmembers; /**< the estimated number of session members at the time tn was last recomputed */
- int32_t members; /**< the most current estimate for the number of session members */
- int32_t senders; /**< the most current estimate for the number of senders in the session */
- double rtcp_bw; /**< The target RTCP bandwidth, i.e., the total bandwidth
+ const struct sockaddr * remote_addr;
+ struct tnet_ice_ctx_s* ice_ctx; // not starter -> do not stop
+ tsk_bool_t is_ice_turn_active;
+
+ const void* callback_data;
+ trtp_rtcp_cb_f callback;
+
+ int32_t app_bw_max_upload; // application specific (kbps)
+ int32_t app_bw_max_download; // application specific (kbps)
+ float app_jcng_q; // application specific for jitter buffer congestion estimation (quality in [0, 1])
+
+ struct {
+ tsk_timer_manager_handle_t* handle_global;
+ tsk_timer_id_t id_report;
+ tsk_timer_id_t id_bye;
+ } timer;
+
+ trtp_rtcp_source_t* source_local; /**< local source */
+ trtp_rtcp_report_sdes_t* sdes;
+ uint64_t time_start; /**< Start time in millis (NOT in NTP unit yet) */
+
+ // <RTCP-FB>
+ uint8_t fir_seqnr;
+ // </RTCP-FB>
+
+ // <sender>
+ char* cname;
+ uint32_t packets_count;
+ uint32_t octets_count;
+ // </sender>
+
+ // <others>
+ time_tp tp; /**< the last time an RTCP packet was transmitted; */
+ tc_f tc; /**< the current time */
+ time_tp tn; /**< the next scheduled transmission time of an RTCP packet */
+ int32_t pmembers; /**< the estimated number of session members at the time tn was last recomputed */
+ int32_t members; /**< the most current estimate for the number of session members */
+ int32_t senders; /**< the most current estimate for the number of senders in the session */
+ double rtcp_bw; /**< The target RTCP bandwidth, i.e., the total bandwidth
that will be used for RTCP packets by all members of this session,
in octets per second. This will be a specified fraction of the
"session bandwidth" parameter supplied to the application at
startup*/
- tsk_bool_t we_sent; /**< Flag that is true if the application has sent data since the 2nd previous RTCP report was transmitted */
- double avg_rtcp_size; /**< The average compound RTCP packet size, in octets,
+ tsk_bool_t we_sent; /**< Flag that is true if the application has sent data since the 2nd previous RTCP report was transmitted */
+ double avg_rtcp_size; /**< The average compound RTCP packet size, in octets,
over all RTCP packets sent and received by this participant. The
size includes lower-layer transport and network protocol headers
(e.g., UDP and IP) as explained in Section 6.2*/
- tsk_bool_t initial; /**< Flag that is true if the application has not yet sent an RTCP packet */
- // </others>
+ tsk_bool_t initial; /**< Flag that is true if the application has not yet sent an RTCP packet */
+ // </others>
- trtp_rtcp_sources_L_t *sources;
+ trtp_rtcp_sources_L_t *sources;
- TSK_DECLARE_SAFEOBJ;
+ TSK_DECLARE_SAFEOBJ;
#if HAVE_SRTP
- struct{
- const srtp_t* session;
- } srtp;
+ struct {
+ const srtp_t* session;
+ } srtp;
#endif
}
trtp_rtcp_session_t;
static tsk_object_t* trtp_rtcp_session_ctor(tsk_object_t * self, va_list * app)
{
- trtp_rtcp_session_t *session = self;
- if(session){
- session->app_bw_max_upload = INT_MAX; // INT_MAX or <=0 means undefined
- session->app_bw_max_download = INT_MAX; // INT_MAX or <=0 means undefined
- session->sources = tsk_list_create();
- session->timer.id_report = TSK_INVALID_TIMER_ID;
- session->timer.id_bye = TSK_INVALID_TIMER_ID;
- session->tc = _trtp_rtcp_session_tc;
- // get a handle for the global timer manager
- session->timer.handle_global = tsk_timer_mgr_global_ref();
- tsk_safeobj_init(session);
- }
- return self;
+ trtp_rtcp_session_t *session = self;
+ if(session) {
+ session->app_bw_max_upload = INT_MAX; // INT_MAX or <=0 means undefined
+ session->app_bw_max_download = INT_MAX; // INT_MAX or <=0 means undefined
+ session->sources = tsk_list_create();
+ session->timer.id_report = TSK_INVALID_TIMER_ID;
+ session->timer.id_bye = TSK_INVALID_TIMER_ID;
+ session->tc = _trtp_rtcp_session_tc;
+ // get a handle for the global timer manager
+ session->timer.handle_global = tsk_timer_mgr_global_ref();
+ tsk_safeobj_init(session);
+ }
+ return self;
}
static tsk_object_t* trtp_rtcp_session_dtor(tsk_object_t * self)
-{
- trtp_rtcp_session_t *session = self;
- if(session){
- trtp_rtcp_session_stop(session);
-
- TSK_OBJECT_SAFE_FREE(session->sources);
- TSK_OBJECT_SAFE_FREE(session->source_local);
- TSK_OBJECT_SAFE_FREE(session->sdes);
- TSK_OBJECT_SAFE_FREE(session->ice_ctx); // not starter -> do not stop
- TSK_FREE(session->cname);
+{
+ trtp_rtcp_session_t *session = self;
+ if(session) {
+ trtp_rtcp_session_stop(session);
+
+ TSK_OBJECT_SAFE_FREE(session->sources);
+ TSK_OBJECT_SAFE_FREE(session->source_local);
+ TSK_OBJECT_SAFE_FREE(session->sdes);
+ TSK_OBJECT_SAFE_FREE(session->ice_ctx); // not starter -> do not stop
+ TSK_FREE(session->cname);
TSK_OBJECT_SAFE_FREE(session->transport); // not starter -> do not stop
- // release the handle for the global timer manager
- tsk_timer_mgr_global_unref(&session->timer.handle_global);
+ // release the handle for the global timer manager
+ tsk_timer_mgr_global_unref(&session->timer.handle_global);
- tsk_safeobj_deinit(session);
- }
- return self;
+ tsk_safeobj_deinit(session);
+ }
+ return self;
}
-static const tsk_object_def_t trtp_rtcp_session_def_s =
-{
- sizeof(trtp_rtcp_session_t),
- trtp_rtcp_session_ctor,
- trtp_rtcp_session_dtor,
- tsk_null,
+static const tsk_object_def_t trtp_rtcp_session_def_s = {
+ sizeof(trtp_rtcp_session_t),
+ trtp_rtcp_session_ctor,
+ trtp_rtcp_session_dtor,
+ tsk_null,
};
const tsk_object_def_t *trtp_rtcp_session_def_t = &trtp_rtcp_session_def_s;
@@ -394,378 +402,394 @@ static void SendBYEPacket(trtp_rtcp_session_t* session, event_ e);
trtp_rtcp_session_t* trtp_rtcp_session_create(uint32_t ssrc, const char* cname)
{
- trtp_rtcp_session_t* session;
-
- if(!(session = tsk_object_new(trtp_rtcp_session_def_t))){
- TSK_DEBUG_ERROR("Failed to create new session object");
- return tsk_null;
- }
-
- // RFC 3550 - 6.3.2 Initialization
- if(!(session->source_local = _trtp_rtcp_source_create(ssrc, 0, 0))){
- TSK_DEBUG_ERROR("Failed to create new local source");
- TSK_OBJECT_SAFE_FREE(session);
- goto bail;
- }
- _trtp_rtcp_session_add_source(session, session->source_local);
- session->initial = tsk_true;
- session->we_sent = tsk_false;
- session->senders = 1;
- session->members = 1;
- session->rtcp_bw = RTCP_BW;//FIXME: as parameter from the code, Also added possiblities to update this value
- session->cname = tsk_strdup(cname);
-
+ trtp_rtcp_session_t* session;
+
+ if(!(session = tsk_object_new(trtp_rtcp_session_def_t))) {
+ TSK_DEBUG_ERROR("Failed to create new session object");
+ return tsk_null;
+ }
+
+ // RFC 3550 - 6.3.2 Initialization
+ if(!(session->source_local = _trtp_rtcp_source_create(ssrc, 0, 0))) {
+ TSK_DEBUG_ERROR("Failed to create new local source");
+ TSK_OBJECT_SAFE_FREE(session);
+ goto bail;
+ }
+ _trtp_rtcp_session_add_source(session, session->source_local);
+ session->initial = tsk_true;
+ session->we_sent = tsk_false;
+ session->senders = 1;
+ session->members = 1;
+ session->rtcp_bw = RTCP_BW;//FIXME: as parameter from the code, Also added possiblities to update this value
+ session->cname = tsk_strdup(cname);
+
bail:
- return session;
+ return session;
}
struct trtp_rtcp_session_s* trtp_rtcp_session_create_2(struct tnet_ice_ctx_s* ice_ctx, uint32_t ssrc, const char* cname)
{
- struct trtp_rtcp_session_s* session = trtp_rtcp_session_create(ssrc, cname);
- if (session) {
- if ((session->ice_ctx = tsk_object_ref(ice_ctx))) {
- session->is_ice_turn_active = tnet_ice_ctx_is_turn_rtcp_active(session->ice_ctx);
- }
- }
- return session;
+ struct trtp_rtcp_session_s* session = trtp_rtcp_session_create(ssrc, cname);
+ if (session) {
+ if ((session->ice_ctx = tsk_object_ref(ice_ctx))) {
+ session->is_ice_turn_active = tnet_ice_ctx_is_turn_rtcp_active(session->ice_ctx);
+ }
+ }
+ return session;
}
int trtp_rtcp_session_set_callback(trtp_rtcp_session_t* self, trtp_rtcp_cb_f callback, const void* callback_data)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(self);
- self->callback = callback;
- self->callback_data = callback_data;
- tsk_safeobj_unlock(self);
- return 0;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(self);
+ self->callback = callback;
+ self->callback_data = callback_data;
+ tsk_safeobj_unlock(self);
+ return 0;
}
#if HAVE_SRTP
int trtp_rtcp_session_set_srtp_sess(trtp_rtcp_session_t* self, const srtp_t* session)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(self);
- self->srtp.session = session;
- tsk_safeobj_unlock(self);
+ tsk_safeobj_lock(self);
+ self->srtp.session = session;
+ tsk_safeobj_unlock(self);
- return 0;
+ return 0;
}
#endif
-int trtp_rtcp_session_set_app_bandwidth_max(trtp_rtcp_session_t* self, int32_t bw_upload_kbps, int32_t bw_download_kbps)
+int trtp_rtcp_session_set_app_bw_and_jcng(trtp_rtcp_session_t* self, int32_t bw_upload_kbps, int32_t bw_download_kbps, float jcng_q)
{
- trtp_rtcp_report_rr_t* rr;
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- tsk_safeobj_lock(self);
-
- self->app_bw_max_upload = bw_upload_kbps;
- self->app_bw_max_download = bw_download_kbps;
-
- if(self->is_started && self->source_local && self->app_bw_max_download > 0 && self->app_bw_max_download != INT_MAX){ // INT_MAX or <=0 means undefined
- tsk_list_item_t* item;
- uint32_t media_ssrc_list[256] = {0};
- uint32_t media_ssrc_list_count = 0;
- // retrieve sources as array
- tsk_list_foreach(item, self->sources){
- if(!item->data){
- continue;
- }
- if((media_ssrc_list_count + 1) < sizeof(media_ssrc_list)/sizeof(media_ssrc_list[0])){
- media_ssrc_list[media_ssrc_list_count++] = TRTP_RTCP_SOURCE(item->data)->ssrc;
- }
- }
- // create RTCP-RR packet and send it over the network
- if(media_ssrc_list_count > 0 && (rr = trtp_rtcp_report_rr_create_2(self->source_local->ssrc))){
- // app_bw_max_download unit is kbps while create_afb_remb() expect bps
- trtp_rtcp_report_psfb_t* psfb_afb_remb = trtp_rtcp_report_psfb_create_afb_remb(self->source_local->ssrc/*sender SSRC*/, media_ssrc_list, media_ssrc_list_count, (self->app_bw_max_download * 1024));
- if(psfb_afb_remb){
- TSK_DEBUG_INFO("Packing RTCP-AFB-REMB (bw_dwn=%d kbps) for outgoing RTCP-RR", self->app_bw_max_download);
- if(trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)rr, (trtp_rtcp_packet_t*)psfb_afb_remb, tsk_false) == 0){
- _trtp_rtcp_session_send_pkt(self, (trtp_rtcp_packet_t*)rr);
- }
- TSK_OBJECT_SAFE_FREE(psfb_afb_remb);
- }
- TSK_OBJECT_SAFE_FREE(rr);
- }
- }
-
- tsk_safeobj_unlock(self);
-
- return 0;
+ trtp_rtcp_report_rr_t* rr;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ tsk_safeobj_lock(self);
+
+ self->app_bw_max_upload = bw_upload_kbps;
+ self->app_bw_max_download = bw_download_kbps;
+ self->app_jcng_q = jcng_q;
+
+ if(self->is_started && self->source_local) { // INT_MAX or <=0 means undefined
+ tsk_list_item_t* item;
+ uint32_t media_ssrc_list[256] = {0};
+ uint32_t media_ssrc_list_count = 0;
+ // retrieve sources as array
+ tsk_list_foreach(item, self->sources) {
+ if(!item->data) {
+ continue;
+ }
+ if((media_ssrc_list_count + 1) < sizeof(media_ssrc_list)/sizeof(media_ssrc_list[0])) {
+ media_ssrc_list[media_ssrc_list_count++] = TRTP_RTCP_SOURCE(item->data)->ssrc;
+ }
+ }
+ // create RTCP-RR packet and send it over the network
+ if (media_ssrc_list_count > 0 && (rr = trtp_rtcp_report_rr_create_2(self->source_local->ssrc))) {
+ // RTCP-REMB
+ if (self->app_bw_max_download > 0 && self->app_bw_max_download != INT_MAX) {
+ // app_bw_max_download unit is kbps while create_afb_remb() expect bps
+ trtp_rtcp_report_psfb_t* psfb_afb_remb = trtp_rtcp_report_psfb_create_afb_remb(self->source_local->ssrc/*sender SSRC*/, media_ssrc_list, media_ssrc_list_count, (self->app_bw_max_download << 10));
+ if (psfb_afb_remb) {
+ TSK_DEBUG_INFO("Packing RTCP-AFB-REMB (bw_dwn=%d kbps) for outgoing RTCP-RR", self->app_bw_max_download);
+ trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)rr, (trtp_rtcp_packet_t*)psfb_afb_remb, tsk_false);
+ TSK_OBJECT_SAFE_FREE(psfb_afb_remb);
+ }
+ }
+ // RTCP-JCNG
+ if (self->app_jcng_q > 0.f && self->app_jcng_q <= 1.f) {
+ // app_bw_max_download unit is kbps while create_afb_remb() expect bps
+ trtp_rtcp_report_psfb_t* psfb_afb_jcng = trtp_rtcp_report_psfb_create_afb_jcng(self->source_local->ssrc/*sender SSRC*/, media_ssrc_list, media_ssrc_list_count, self->app_jcng_q);
+ if (psfb_afb_jcng) {
+ TSK_DEBUG_INFO("Packing RTCP-AFB-JCNG (q=%f) for outgoing RTCP-RR", self->app_jcng_q);
+ trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)rr, (trtp_rtcp_packet_t*)psfb_afb_jcng, tsk_false);
+ TSK_OBJECT_SAFE_FREE(psfb_afb_jcng);
+ }
+ }
+ // send the RR message
+ _trtp_rtcp_session_send_pkt(self, (trtp_rtcp_packet_t*)rr);
+ TSK_OBJECT_SAFE_FREE(rr);
+ }
+ }
+
+ tsk_safeobj_unlock(self);
+
+ return 0;
}
int trtp_rtcp_session_start(trtp_rtcp_session_t* self, tnet_fd_t local_fd, const struct sockaddr * remote_addr)
{
- int ret;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(self->is_started){
- TSK_DEBUG_WARN("Already started");
- return 0;
- }
-
- // start global timer manager
- if((ret = tsk_timer_manager_start(self->timer.handle_global))){
- TSK_DEBUG_ERROR("Failed to start timer");
- return ret;
- }
-
- self->local_fd = local_fd;
- self->remote_addr = remote_addr;
-
- // Send Initial RR (mandatory)
- Schedule(self, 0., EVENT_REPORT);
-
- // set start time
- self->time_start = tsk_time_now();
-
- self->is_started = tsk_true;
-
- return ret;
+ int ret;
+
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if(self->is_started) {
+ TSK_DEBUG_WARN("Already started");
+ return 0;
+ }
+
+ // start global timer manager
+ if((ret = tsk_timer_manager_start(self->timer.handle_global))) {
+ TSK_DEBUG_ERROR("Failed to start timer");
+ return ret;
+ }
+
+ self->local_fd = local_fd;
+ self->remote_addr = remote_addr;
+
+ // Send Initial RR (mandatory)
+ Schedule(self, 0., EVENT_REPORT);
+
+ // set start time
+ self->time_start = tsk_time_now();
+
+ self->is_started = tsk_true;
+
+ return ret;
}
int trtp_rtcp_session_stop(trtp_rtcp_session_t* self)
{
- int ret = 0;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(self->is_started){
- // send BYE synchronous way
- SendBYEPacket(self, EVENT_REPORT);
-
- // this is a global timer shared by many components -> stopping it won't remove
- // all scheduled items as it could continue running if still used
- tsk_safeobj_lock(self); // must
- if(TSK_TIMER_ID_IS_VALID(self->timer.id_bye)){
- tsk_timer_manager_cancel(self->timer.handle_global, self->timer.id_bye);
- self->timer.id_bye = TSK_INVALID_TIMER_ID;
- }
- if(TSK_TIMER_ID_IS_VALID(self->timer.id_report)){
- tsk_timer_manager_cancel(self->timer.handle_global, self->timer.id_report);
- self->timer.id_report = TSK_INVALID_TIMER_ID;
- }
- tsk_safeobj_unlock(self);
- self->is_started = tsk_false;
- }
-
- return ret;
+ int ret = 0;
+
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if(self->is_started) {
+ // send BYE synchronous way
+ SendBYEPacket(self, EVENT_REPORT);
+
+ // this is a global timer shared by many components -> stopping it won't remove
+ // all scheduled items as it could continue running if still used
+ tsk_safeobj_lock(self); // must
+ if(TSK_TIMER_ID_IS_VALID(self->timer.id_bye)) {
+ tsk_timer_manager_cancel(self->timer.handle_global, self->timer.id_bye);
+ self->timer.id_bye = TSK_INVALID_TIMER_ID;
+ }
+ if(TSK_TIMER_ID_IS_VALID(self->timer.id_report)) {
+ tsk_timer_manager_cancel(self->timer.handle_global, self->timer.id_report);
+ self->timer.id_report = TSK_INVALID_TIMER_ID;
+ }
+ tsk_safeobj_unlock(self);
+ self->is_started = tsk_false;
+ }
+
+ return ret;
}
int trtp_rtcp_session_process_rtp_out(trtp_rtcp_session_t* self, const trtp_rtp_packet_t* packet_rtp, tsk_size_t size)
{
- int ret = 0;
-
- if(!self || !packet_rtp || !packet_rtp->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(!self->is_started){
- TSK_DEBUG_ERROR("Not started");
- return -2;
- }
-
- tsk_safeobj_lock(self);
-
- // create local source if not already done
- // first destroy it if the ssrc don't match
- if(self->source_local && self->source_local->ssrc != packet_rtp->header->ssrc){
- tsk_bool_t removed = tsk_false;
- // local ssrc has changed: sould never happen ...but who know?
- // remove the source
- TSK_DEBUG_WARN("Not expected to be called");
- _trtp_rtcp_session_remove_source(self, self->source_local->ssrc, &removed);
- TSK_OBJECT_SAFE_FREE(self->source_local);
- TSK_OBJECT_SAFE_FREE(self->sdes);
- self->packets_count = 0;
- self->octets_count = 0;
- if(removed){
- --self->senders;
- --self->members;
- }
- }
- if(!self->source_local){
- if(!(self->source_local = _trtp_rtcp_source_create(packet_rtp->header->ssrc, packet_rtp->header->seq_num, packet_rtp->header->timestamp))){
- TSK_DEBUG_ERROR("Failed to create new local source");
- }
- // add the source (refresh the number of senders, ...)
- _trtp_rtcp_session_add_source(self, self->source_local);
- // 'members' and 'senders' were already initialized in the constructor
- }
-
- if(!self->we_sent){
- self->we_sent = tsk_true;
- }
-
- ++self->packets_count;
- self->octets_count += (uint32_t)size;
-
- tsk_safeobj_unlock(self);
-
- return ret;
+ int ret = 0;
+
+ if(!self || !packet_rtp || !packet_rtp->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if(!self->is_started) {
+ TSK_DEBUG_ERROR("Not started");
+ return -2;
+ }
+
+ tsk_safeobj_lock(self);
+
+ // create local source if not already done
+ // first destroy it if the ssrc don't match
+ if(self->source_local && self->source_local->ssrc != packet_rtp->header->ssrc) {
+ tsk_bool_t removed = tsk_false;
+ // local ssrc has changed: sould never happen ...but who know?
+ // remove the source
+ TSK_DEBUG_WARN("Not expected to be called");
+ _trtp_rtcp_session_remove_source(self, self->source_local->ssrc, &removed);
+ TSK_OBJECT_SAFE_FREE(self->source_local);
+ TSK_OBJECT_SAFE_FREE(self->sdes);
+ self->packets_count = 0;
+ self->octets_count = 0;
+ if(removed) {
+ --self->senders;
+ --self->members;
+ }
+ }
+ if(!self->source_local) {
+ if(!(self->source_local = _trtp_rtcp_source_create(packet_rtp->header->ssrc, packet_rtp->header->seq_num, packet_rtp->header->timestamp))) {
+ TSK_DEBUG_ERROR("Failed to create new local source");
+ }
+ // add the source (refresh the number of senders, ...)
+ _trtp_rtcp_session_add_source(self, self->source_local);
+ // 'members' and 'senders' were already initialized in the constructor
+ }
+
+ if(!self->we_sent) {
+ self->we_sent = tsk_true;
+ }
+
+ ++self->packets_count;
+ self->octets_count += (uint32_t)size;
+
+ tsk_safeobj_unlock(self);
+
+ return ret;
}
int trtp_rtcp_session_process_rtp_in(trtp_rtcp_session_t* self, const trtp_rtp_packet_t* packet_rtp, tsk_size_t size)
{
- int ret = 0;
- trtp_rtcp_source_t* source;
-
- if(!self || !packet_rtp || !packet_rtp->header){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(!self->is_started){
- TSK_DEBUG_INFO("RTCP session not started");
- return -2;
- }
-
- tsk_safeobj_lock(self);
- OnReceive(self, (const packet_)packet_rtp, EVENT_RTP, size);
- if((source = _trtp_rtcp_session_find_source(self, packet_rtp->header->ssrc))){
- if(_trtp_rtcp_source_update_seq(source, packet_rtp->header->seq_num, packet_rtp->header->timestamp)){
- // RFC 3550 A.8 Estimating the Interarrival Jitter
- /* uint32_t expected = (source->cycles + source->max_seq) - source->base_seq + 1; */
- double arrival = (((double)(source->max_ts - source->base_ts) / (double)source->rate) * 1000);
- int32_t transit = (int32_t)arrival - packet_rtp->header->timestamp;
- int32_t d = (transit - source->transit);
- if(d < 0) d = -d;
- source->transit = transit;
- source->jitter += (1./16.) * ((double)d - source->jitter);
- }
- TSK_OBJECT_SAFE_FREE(source);
- }
-
- tsk_safeobj_unlock(self);
-
- return ret;
+ int ret = 0;
+ trtp_rtcp_source_t* source;
+
+ if(!self || !packet_rtp || !packet_rtp->header) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if(!self->is_started) {
+ TSK_DEBUG_INFO("RTCP session not started");
+ return -2;
+ }
+
+ tsk_safeobj_lock(self);
+ OnReceive(self, (const packet_)packet_rtp, EVENT_RTP, size);
+ if((source = _trtp_rtcp_session_find_source(self, packet_rtp->header->ssrc))) {
+ if(_trtp_rtcp_source_update_seq(source, packet_rtp->header->seq_num, packet_rtp->header->timestamp)) {
+ // RFC 3550 A.8 Estimating the Interarrival Jitter
+ /* uint32_t expected = (source->cycles + source->max_seq) - source->base_seq + 1; */
+ double arrival = (((double)(source->max_ts - source->base_ts) / (double)source->rate) * 1000);
+ int32_t transit = (int32_t)arrival - packet_rtp->header->timestamp;
+ int32_t d = (transit - source->transit);
+ if(d < 0) {
+ d = -d;
+ }
+ source->transit = transit;
+ source->jitter += (1./16.) * ((double)d - source->jitter);
+ }
+ TSK_OBJECT_SAFE_FREE(source);
+ }
+
+ tsk_safeobj_unlock(self);
+
+ return ret;
}
int trtp_rtcp_session_process_rtcp_in(trtp_rtcp_session_t* self, const void* buffer, tsk_size_t size)
{
- int ret = 0;
- trtp_rtcp_packet_t* packet_rtcp = tsk_null;
-
- if(!self || !buffer || size < TRTP_RTCP_HEADER_SIZE){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(!self->is_started){
- TSK_DEBUG_ERROR("Not started");
- return -2;
- }
-
- // derialize the RTCP packet for processing
- packet_rtcp = trtp_rtcp_packet_deserialize(buffer, size);
- if(packet_rtcp){
- tsk_safeobj_lock(self);
- OnReceive(self,
- (const packet_)packet_rtcp,
- (packet_rtcp->header->type == trtp_rtcp_packet_type_bye) ? EVENT_BYE : EVENT_REPORT,
- size);
- if(packet_rtcp->header->type == trtp_rtcp_packet_type_sr){
- trtp_rtcp_source_t* source;
- const trtp_rtcp_report_sr_t* sr = (const trtp_rtcp_report_sr_t*)packet_rtcp;
- if((source = _trtp_rtcp_session_find_source(self, sr->ssrc))){
- source->ntp_lsw = sr->sender_info.ntp_lsw;
- source->ntp_msw = sr->sender_info.ntp_msw;
- source->dlsr = tsk_time_now();
- TSK_OBJECT_SAFE_FREE(source);
- }
- }
- tsk_safeobj_unlock(self); // must be before callback()
-
- if(self->callback){
- ret = self->callback(self->callback_data, packet_rtcp);
- }
- TSK_OBJECT_SAFE_FREE(packet_rtcp);
- }
-
-
- return ret;
+ int ret = 0;
+ trtp_rtcp_packet_t* packet_rtcp = tsk_null;
+
+ if(!self || !buffer || size < TRTP_RTCP_HEADER_SIZE) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if(!self->is_started) {
+ TSK_DEBUG_ERROR("Not started");
+ return -2;
+ }
+
+ // derialize the RTCP packet for processing
+ packet_rtcp = trtp_rtcp_packet_deserialize(buffer, size);
+ if(packet_rtcp) {
+ tsk_safeobj_lock(self);
+ OnReceive(self,
+ (const packet_)packet_rtcp,
+ (packet_rtcp->header->type == trtp_rtcp_packet_type_bye) ? EVENT_BYE : EVENT_REPORT,
+ size);
+ if(packet_rtcp->header->type == trtp_rtcp_packet_type_sr) {
+ trtp_rtcp_source_t* source;
+ const trtp_rtcp_report_sr_t* sr = (const trtp_rtcp_report_sr_t*)packet_rtcp;
+ if((source = _trtp_rtcp_session_find_source(self, sr->ssrc))) {
+ source->ntp_lsw = sr->sender_info.ntp_lsw;
+ source->ntp_msw = sr->sender_info.ntp_msw;
+ source->dlsr = tsk_time_now();
+ TSK_OBJECT_SAFE_FREE(source);
+ }
+ }
+ tsk_safeobj_unlock(self); // must be before callback()
+
+ if(self->callback) {
+ ret = self->callback(self->callback_data, packet_rtcp);
+ }
+ TSK_OBJECT_SAFE_FREE(packet_rtcp);
+ }
+
+
+ return ret;
}
int trtp_rtcp_session_signal_pkt_loss(trtp_rtcp_session_t* self, uint32_t ssrc_media, const uint16_t* seq_nums, tsk_size_t count)
{
- trtp_rtcp_report_rr_t* rr;
- if(!self || !self->source_local || !seq_nums || !count){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(!self->is_started){
- TSK_DEBUG_ERROR("Not started");
- return -1;
- }
-
- tsk_safeobj_lock(self);
-
- if((rr = trtp_rtcp_report_rr_create_2(self->source_local->ssrc))){
- trtp_rtcp_report_rtpfb_t* rtpfb;
- if((rtpfb = trtp_rtcp_report_rtpfb_create_nack(self->source_local->ssrc, ssrc_media, seq_nums, count))){
- trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)rr, (trtp_rtcp_packet_t*)rtpfb, tsk_false);
- _trtp_rtcp_session_send_pkt(self, (trtp_rtcp_packet_t*)rr);
- TSK_OBJECT_SAFE_FREE(rtpfb);
- }
- TSK_OBJECT_SAFE_FREE(rr);
- }
-
- tsk_safeobj_unlock(self);
-
- return 0;
+ trtp_rtcp_report_rr_t* rr;
+ if(!self || !self->source_local || !seq_nums || !count) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if(!self->is_started) {
+ TSK_DEBUG_ERROR("Not started");
+ return -1;
+ }
+
+ tsk_safeobj_lock(self);
+
+ if((rr = trtp_rtcp_report_rr_create_2(self->source_local->ssrc))) {
+ trtp_rtcp_report_rtpfb_t* rtpfb;
+ if((rtpfb = trtp_rtcp_report_rtpfb_create_nack(self->source_local->ssrc, ssrc_media, seq_nums, count))) {
+ trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)rr, (trtp_rtcp_packet_t*)rtpfb, tsk_false);
+ _trtp_rtcp_session_send_pkt(self, (trtp_rtcp_packet_t*)rr);
+ TSK_OBJECT_SAFE_FREE(rtpfb);
+ }
+ TSK_OBJECT_SAFE_FREE(rr);
+ }
+
+ tsk_safeobj_unlock(self);
+
+ return 0;
}
// Frame corrupted means the prediction chain is broken -> Send FIR
int trtp_rtcp_session_signal_frame_corrupted(trtp_rtcp_session_t* self, uint32_t ssrc_media)
{
- trtp_rtcp_report_rr_t* rr;
- if(!self || !self->source_local){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(!self->is_started){
- TSK_DEBUG_ERROR("Not started");
- return -1;
- }
-
- tsk_safeobj_lock(self);
-
- if((rr = trtp_rtcp_report_rr_create_2(self->source_local->ssrc))){
- trtp_rtcp_report_psfb_t* psfb_fir = trtp_rtcp_report_psfb_create_fir(self->fir_seqnr++, self->source_local->ssrc, ssrc_media);
- if(psfb_fir){
- trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)rr, (trtp_rtcp_packet_t*)psfb_fir, tsk_false);
- _trtp_rtcp_session_send_pkt(self, (trtp_rtcp_packet_t*)rr);
- TSK_OBJECT_SAFE_FREE(psfb_fir);
- }
- TSK_OBJECT_SAFE_FREE(rr);
- }
-
- tsk_safeobj_unlock(self);
- return 0;
+ trtp_rtcp_report_rr_t* rr;
+ if(!self || !self->source_local) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if(!self->is_started) {
+ TSK_DEBUG_ERROR("Not started");
+ return -1;
+ }
+
+ tsk_safeobj_lock(self);
+
+ if((rr = trtp_rtcp_report_rr_create_2(self->source_local->ssrc))) {
+ trtp_rtcp_report_psfb_t* psfb_fir = trtp_rtcp_report_psfb_create_fir(self->fir_seqnr++, self->source_local->ssrc, ssrc_media);
+ if(psfb_fir) {
+ trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)rr, (trtp_rtcp_packet_t*)psfb_fir, tsk_false);
+ _trtp_rtcp_session_send_pkt(self, (trtp_rtcp_packet_t*)rr);
+ TSK_OBJECT_SAFE_FREE(psfb_fir);
+ }
+ TSK_OBJECT_SAFE_FREE(rr);
+ }
+
+ tsk_safeobj_unlock(self);
+ return 0;
}
// for now send just a FIR
int trtp_rtcp_session_signal_jb_error(struct trtp_rtcp_session_s* self, uint32_t ssrc_media)
{
- return trtp_rtcp_session_signal_frame_corrupted(self, ssrc_media);
+ return trtp_rtcp_session_signal_frame_corrupted(self, ssrc_media);
}
tnet_fd_t trtp_rtcp_session_get_local_fd(const struct trtp_rtcp_session_s* self)
@@ -800,314 +824,329 @@ int trtp_rtcp_session_set_net_transport(struct trtp_rtcp_session_s* self, struct
static tsk_bool_t _trtp_rtcp_session_have_source(trtp_rtcp_session_t* self, uint32_t ssrc)
{
- tsk_list_item_t* item;
- tsk_list_foreach(item, self->sources){
- if(TRTP_RTCP_SOURCE(item->data)->ssrc == ssrc){
- return tsk_true;
- }
- }
- return tsk_false;
+ tsk_list_item_t* item;
+ tsk_list_foreach(item, self->sources) {
+ if(TRTP_RTCP_SOURCE(item->data)->ssrc == ssrc) {
+ return tsk_true;
+ }
+ }
+ return tsk_false;
}
// find source by ssrc
// the caller must release the returned object
static trtp_rtcp_source_t* _trtp_rtcp_session_find_source(trtp_rtcp_session_t* self, uint32_t ssrc)
{
- tsk_list_item_t* item;
- tsk_list_foreach(item, self->sources){
- if(TRTP_RTCP_SOURCE(item->data)->ssrc == ssrc){
- return tsk_object_ref(item->data);
- }
- }
- return tsk_null;
+ tsk_list_item_t* item;
+ tsk_list_foreach(item, self->sources) {
+ if(TRTP_RTCP_SOURCE(item->data)->ssrc == ssrc) {
+ return tsk_object_ref(item->data);
+ }
+ }
+ return tsk_null;
}
// find or add source by ssrc
// the caller must release the returned object
static trtp_rtcp_source_t* _trtp_rtcp_session_find_or_add_source(trtp_rtcp_session_t* self, uint32_t ssrc, uint16_t seq_if_add, uint32_t ts_id_add)
{
- trtp_rtcp_source_t* source;
- if((source = _trtp_rtcp_session_find_source(self, ssrc))){
- return source;
- }
-
- if((source = _trtp_rtcp_source_create(ssrc, seq_if_add, ts_id_add))){
- if((_trtp_rtcp_session_add_source(self, source)) != 0){
- TSK_DEBUG_ERROR("Failed to add source");
- TSK_OBJECT_SAFE_FREE(source);
- return tsk_null;
- }
- return tsk_object_ref(source);
- }
- return tsk_null;
+ trtp_rtcp_source_t* source;
+ if((source = _trtp_rtcp_session_find_source(self, ssrc))) {
+ return source;
+ }
+
+ if((source = _trtp_rtcp_source_create(ssrc, seq_if_add, ts_id_add))) {
+ if((_trtp_rtcp_session_add_source(self, source)) != 0) {
+ TSK_DEBUG_ERROR("Failed to add source");
+ TSK_OBJECT_SAFE_FREE(source);
+ return tsk_null;
+ }
+ return tsk_object_ref(source);
+ }
+ return tsk_null;
}
int _trtp_rtcp_session_add_source(trtp_rtcp_session_t* self, trtp_rtcp_source_t* source)
{
- if(!self || !source){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if(!self || !source) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_list_lock(self->sources);
- source = tsk_object_ref(source);
- tsk_list_push_back_data(self->sources, (void**)&source);
- tsk_list_unlock(self->sources);
+ tsk_list_lock(self->sources);
+ source = tsk_object_ref(source);
+ tsk_list_push_back_data(self->sources, (void**)&source);
+ tsk_list_unlock(self->sources);
- return 0;
+ return 0;
}
// adds a source if doesn't exist
static int _trtp_rtcp_session_add_source_2(trtp_rtcp_session_t* self, uint32_t ssrc, uint16_t seq, uint32_t ts, tsk_bool_t *added)
{
- int ret = 0;
- tsk_list_item_t* item;
- trtp_rtcp_source_t* source;
-
- tsk_list_lock(self->sources);
- tsk_list_foreach(item, self->sources){
- if(TRTP_RTCP_SOURCE(item->data)->ssrc == ssrc){
- tsk_list_unlock(self->sources);
- *added = tsk_false;
- return 0;
- }
- }
+ int ret = 0;
+ tsk_list_item_t* item;
+ trtp_rtcp_source_t* source;
+
+ tsk_list_lock(self->sources);
+ tsk_list_foreach(item, self->sources) {
+ if(TRTP_RTCP_SOURCE(item->data)->ssrc == ssrc) {
+ tsk_list_unlock(self->sources);
+ *added = tsk_false;
+ return 0;
+ }
+ }
- tsk_list_unlock(self->sources);
+ tsk_list_unlock(self->sources);
- if((source = _trtp_rtcp_source_create(ssrc, seq, ts))){
- ret = _trtp_rtcp_session_add_source(self, source);
- }
+ if((source = _trtp_rtcp_source_create(ssrc, seq, ts))) {
+ ret = _trtp_rtcp_session_add_source(self, source);
+ }
- TSK_OBJECT_SAFE_FREE(source);
+ TSK_OBJECT_SAFE_FREE(source);
- *added = tsk_true;
- return ret;
+ *added = tsk_true;
+ return ret;
}
int _trtp_rtcp_session_remove_source(trtp_rtcp_session_t* self, uint32_t ssrc, tsk_bool_t *removed)
{
- *removed = tsk_false;
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_list_lock(self->sources);
- if((*removed = tsk_list_remove_item_by_pred(self->sources, __pred_find_source_by_ssrc, &ssrc)) == tsk_true){
- // ...
- }
- tsk_list_unlock(self->sources);
- return 0;
+ *removed = tsk_false;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_list_lock(self->sources);
+ if((*removed = tsk_list_remove_item_by_pred(self->sources, __pred_find_source_by_ssrc, &ssrc)) == tsk_true) {
+ // ...
+ }
+ tsk_list_unlock(self->sources);
+ return 0;
}
static tsk_size_t _trtp_rtcp_session_send_pkt(trtp_rtcp_session_t* self, trtp_rtcp_packet_t* pkt)
{
- tsk_size_t ret = 0;
- tsk_size_t __num_bytes_pad = 0;
- tsk_buffer_t* buffer;
+ tsk_size_t ret = 0;
+ tsk_size_t __num_bytes_pad = 0;
+ tsk_buffer_t* buffer;
- if(!self->remote_addr || self->local_fd <= 0){
- TSK_DEBUG_ERROR("Invalid network settings");
- return 0;
- }
+ if(!self->remote_addr || self->local_fd <= 0) {
+ TSK_DEBUG_ERROR("Invalid network settings");
+ return 0;
+ }
#if HAVE_SRTP
- if(self->srtp.session) __num_bytes_pad = (SRTP_MAX_TRAILER_LEN + 0x4);
+ if(self->srtp.session) {
+ __num_bytes_pad = (SRTP_MAX_TRAILER_LEN + 0x4);
+ }
#endif
- // SDES
- if(!self->sdes && (self->sdes = trtp_rtcp_report_sdes_create_null())){
- trtp_rtcp_sdes_chunck_t* chunck = trtp_rtcp_sdes_chunck_create(self->source_local->ssrc);
- if(chunck){
- static const char* _name = "test@doubango.org";
- trtp_rtcp_sdes_chunck_add_item(chunck, trtp_rtcp_sdes_item_type_cname, self->cname, (uint8_t)tsk_strlen(self->cname));
- trtp_rtcp_sdes_chunck_add_item(chunck, trtp_rtcp_sdes_item_type_name, _name, (uint8_t)tsk_strlen(_name));
- trtp_rtcp_report_sdes_add_chunck(self->sdes, chunck);
- TSK_OBJECT_SAFE_FREE(chunck);
- }
- }
- if(self->sdes){
- trtp_rtcp_packet_add_packet(pkt, (trtp_rtcp_packet_t*)self->sdes, tsk_true);
- }
-
- if((buffer = trtp_rtcp_packet_serialize(pkt, __num_bytes_pad))){
- void* data = buffer->data;
- int size = (int)buffer->size;
+ // SDES
+ if(!self->sdes && (self->sdes = trtp_rtcp_report_sdes_create_null())) {
+ trtp_rtcp_sdes_chunck_t* chunck = trtp_rtcp_sdes_chunck_create(self->source_local->ssrc);
+ if(chunck) {
+ static const char* _name = "test@doubango.org";
+ trtp_rtcp_sdes_chunck_add_item(chunck, trtp_rtcp_sdes_item_type_cname, self->cname, (uint8_t)tsk_strlen(self->cname));
+ trtp_rtcp_sdes_chunck_add_item(chunck, trtp_rtcp_sdes_item_type_name, _name, (uint8_t)tsk_strlen(_name));
+ trtp_rtcp_report_sdes_add_chunck(self->sdes, chunck);
+ TSK_OBJECT_SAFE_FREE(chunck);
+ }
+ }
+ if(self->sdes) {
+ trtp_rtcp_packet_add_packet(pkt, (trtp_rtcp_packet_t*)self->sdes, tsk_true);
+ }
+
+ if((buffer = trtp_rtcp_packet_serialize(pkt, __num_bytes_pad))) {
+ void* data = buffer->data;
+ int size = (int)buffer->size;
#if HAVE_SRTP
- if(self->srtp.session){
- if(srtp_protect_rtcp(((srtp_t)*self->srtp.session), data, &size) != err_status_ok){
- TSK_DEBUG_ERROR("srtp_protect_rtcp() failed");
- }
- }
+ if(self->srtp.session) {
+ if(srtp_protect_rtcp(((srtp_t)*self->srtp.session), data, &size) != err_status_ok) {
+ TSK_DEBUG_ERROR("srtp_protect_rtcp() failed");
+ }
+ }
#endif
- ret = _trtp_rtcp_session_send_raw(self, data, size);
- TSK_OBJECT_SAFE_FREE(buffer);
- }
+ ret = _trtp_rtcp_session_send_raw(self, data, size);
+ TSK_OBJECT_SAFE_FREE(buffer);
+ }
- return ret;
+ return ret;
}
static tsk_size_t _trtp_rtcp_session_send_raw(trtp_rtcp_session_t* self, const void* data, tsk_size_t size)
{
- tsk_size_t ret = 0;
- if (!self || !data || !size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
- if (self->is_ice_turn_active) {
- ret = (tnet_ice_ctx_send_turn_rtcp(self->ice_ctx, data, size) == 0) ? size : 0; // returns #0 if ok
- }
- else {
+ tsk_size_t ret = 0;
+ if (!self || !data || !size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+ if (self->is_ice_turn_active) {
+ ret = (tnet_ice_ctx_send_turn_rtcp(self->ice_ctx, data, size) == 0) ? size : 0; // returns #0 if ok
+ }
+ else {
ret = self->transport
- ? tnet_transport_sendto(self->transport, self->local_fd, self->remote_addr, data, size)
- : tnet_sockfd_sendto(self->local_fd, self->remote_addr, data, size);
- }
- return ret;
+ ? tnet_transport_sendto(self->transport, self->local_fd, self->remote_addr, data, size)
+ : tnet_sockfd_sendto(self->local_fd, self->remote_addr, data, size);
+ }
+ return ret;
}
static int _trtp_rtcp_session_timer_callback(const void* arg, tsk_timer_id_t timer_id)
{
- trtp_rtcp_session_t* session = (trtp_rtcp_session_t*)arg;
- tsk_safeobj_lock(session); // must
- if(session->timer.id_bye == timer_id){
- session->timer.id_bye = TSK_INVALID_TIMER_ID;
- OnExpire(session, EVENT_BYE);
- }
- else if(session->timer.id_report == timer_id){
- session->timer.id_report = TSK_INVALID_TIMER_ID;
- OnExpire(session, EVENT_REPORT);
- }
- tsk_safeobj_unlock(session);
- return 0;
+ trtp_rtcp_session_t* session = (trtp_rtcp_session_t*)arg;
+ tsk_safeobj_lock(session); // must
+ if(session->timer.id_bye == timer_id) {
+ session->timer.id_bye = TSK_INVALID_TIMER_ID;
+ OnExpire(session, EVENT_BYE);
+ }
+ else if(session->timer.id_report == timer_id) {
+ session->timer.id_report = TSK_INVALID_TIMER_ID;
+ OnExpire(session, EVENT_REPORT);
+ }
+ tsk_safeobj_unlock(session);
+ return 0;
}
static tsk_bool_t IsRtpPacket(const packet_ p)
{
- return (TSK_OBJECT_HEADER(p)->__def__ == trtp_rtp_packet_def_t);
+ return (TSK_OBJECT_HEADER(p)->__def__ == trtp_rtp_packet_def_t);
}
static PacketType_ PacketType(const packet_ p)
{
- if(IsRtpPacket(p)){
- return PACKET_RTP;
- }
- else{
- switch(((const trtp_rtcp_packet_t*)p)->header->type){
- case trtp_rtcp_packet_type_bye: return PACKET_BYE;
- default: return PACKET_RTCP_REPORT;
- }
- }
+ if(IsRtpPacket(p)) {
+ return PACKET_RTP;
+ }
+ else {
+ switch(((const trtp_rtcp_packet_t*)p)->header->type) {
+ case trtp_rtcp_packet_type_bye:
+ return PACKET_BYE;
+ default:
+ return PACKET_RTCP_REPORT;
+ }
+ }
}
// Returns true if the packet is from a member or not
// also checks all csrc
static tsk_bool_t NewMember(trtp_rtcp_session_t* session, const packet_ p)
{
- uint32_t ssrc = 0;
- if(IsRtpPacket(p)){
- const trtp_rtp_packet_t* packet_rtp = (const trtp_rtp_packet_t*)p;
- tsk_size_t i;
- for(i = 0; i < packet_rtp->header->csrc_count && i < sizeof(packet_rtp->header->csrc)/sizeof(packet_rtp->header->csrc[0]); ++i){
- if(!(_trtp_rtcp_session_have_source(session, packet_rtp->header->csrc[i]))){
- return tsk_false;
- }
- }
- ssrc = packet_rtp->header->ssrc;
- }
- else{
- switch(((const trtp_rtcp_packet_t*)p)->header->type){
- case trtp_rtcp_packet_type_rr: ssrc = ((const trtp_rtcp_report_rr_t*)p)->ssrc; break;
- case trtp_rtcp_packet_type_sr: ssrc = ((const trtp_rtcp_report_sr_t*)p)->ssrc; break;
- case trtp_rtcp_packet_type_bye:
- {
- tsk_size_t i;
- const trtp_rtcp_report_bye_t* bye = (const trtp_rtcp_report_bye_t*)p;
- for(i = 0; i < TRTP_RTCP_PACKET(bye)->header->rc; ++i){
- if(!_trtp_rtcp_session_have_source(session, bye->ssrc_list[i])){
- return tsk_false;
- }
- }
- return tsk_true;
- }
- default: return tsk_false;
- }
- }
-
- return !_trtp_rtcp_session_have_source(session, ssrc);
+ uint32_t ssrc = 0;
+ if(IsRtpPacket(p)) {
+ const trtp_rtp_packet_t* packet_rtp = (const trtp_rtp_packet_t*)p;
+ tsk_size_t i;
+ for(i = 0; i < packet_rtp->header->csrc_count && i < sizeof(packet_rtp->header->csrc)/sizeof(packet_rtp->header->csrc[0]); ++i) {
+ if(!(_trtp_rtcp_session_have_source(session, packet_rtp->header->csrc[i]))) {
+ return tsk_false;
+ }
+ }
+ ssrc = packet_rtp->header->ssrc;
+ }
+ else {
+ switch(((const trtp_rtcp_packet_t*)p)->header->type) {
+ case trtp_rtcp_packet_type_rr:
+ ssrc = ((const trtp_rtcp_report_rr_t*)p)->ssrc;
+ break;
+ case trtp_rtcp_packet_type_sr:
+ ssrc = ((const trtp_rtcp_report_sr_t*)p)->ssrc;
+ break;
+ case trtp_rtcp_packet_type_bye: {
+ tsk_size_t i;
+ const trtp_rtcp_report_bye_t* bye = (const trtp_rtcp_report_bye_t*)p;
+ for(i = 0; i < TRTP_RTCP_PACKET(bye)->header->rc; ++i) {
+ if(!_trtp_rtcp_session_have_source(session, bye->ssrc_list[i])) {
+ return tsk_false;
+ }
+ }
+ return tsk_true;
+ }
+ default:
+ return tsk_false;
+ }
+ }
+
+ return !_trtp_rtcp_session_have_source(session, ssrc);
}
#define NewSender(session, p) NewMember((session), (p))
static tsk_size_t AddMemberUsingRTCPPacket(trtp_rtcp_session_t* session, const trtp_rtcp_packet_t* p, tsk_bool_t sender)
{
- trtp_rtcp_packets_L_t* packets = tsk_null;
- trtp_rtcp_rblocks_L_t* blocks = tsk_null;
- tsk_bool_t added = tsk_false;
- tsk_size_t count = 0;
-
- switch(p->header->type){
- case trtp_rtcp_packet_type_rr:
- {
- const trtp_rtcp_report_rr_t* rr = (const trtp_rtcp_report_rr_t*)p;
- _trtp_rtcp_session_add_source_2(session, ((const trtp_rtcp_report_rr_t*)p)->ssrc, 0, 0, &added);
- if(added) ++count;
-
- packets = rr->packets;
- blocks = rr->blocks;
- break;
- }
- case trtp_rtcp_packet_type_sr:
- {
- const trtp_rtcp_report_sr_t* sr = (const trtp_rtcp_report_sr_t*)p;
- _trtp_rtcp_session_add_source_2(session, ((const trtp_rtcp_report_sr_t*)p)->ssrc, 0, 0, &added);
- if(added) ++count;
- packets = sr->packets;
- blocks = sr->blocks;
- break;
- }
- default:
- {
- break;
+ trtp_rtcp_packets_L_t* packets = tsk_null;
+ trtp_rtcp_rblocks_L_t* blocks = tsk_null;
+ tsk_bool_t added = tsk_false;
+ tsk_size_t count = 0;
+
+ switch(p->header->type) {
+ case trtp_rtcp_packet_type_rr: {
+ const trtp_rtcp_report_rr_t* rr = (const trtp_rtcp_report_rr_t*)p;
+ _trtp_rtcp_session_add_source_2(session, ((const trtp_rtcp_report_rr_t*)p)->ssrc, 0, 0, &added);
+ if(added) {
+ ++count;
+ }
+
+ packets = rr->packets;
+ blocks = rr->blocks;
+ break;
+ }
+ case trtp_rtcp_packet_type_sr: {
+ const trtp_rtcp_report_sr_t* sr = (const trtp_rtcp_report_sr_t*)p;
+ _trtp_rtcp_session_add_source_2(session, ((const trtp_rtcp_report_sr_t*)p)->ssrc, 0, 0, &added);
+ if(added) {
+ ++count;
+ }
+ packets = sr->packets;
+ blocks = sr->blocks;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ if(!sender) {
+ if(packets) {
+ const tsk_list_item_t *item;
+ tsk_list_foreach(item, packets) {
+ AddMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*)item->data, sender);
+ }
+ }
+ if(blocks) {
+ const tsk_list_item_t *item;
+ tsk_list_foreach(item, blocks) {
+ _trtp_rtcp_session_add_source_2(session, TRTP_RTCP_RBLOCK(item->data)->ssrc, 0, 0, &added);
+ if(added) {
+ ++count;
+ }
}
- }
-
- if(!sender){
- if(packets){
- const tsk_list_item_t *item;
- tsk_list_foreach(item, packets){
- AddMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*)item->data, sender);
- }
- }
- if(blocks){
- const tsk_list_item_t *item;
- tsk_list_foreach(item, blocks){
- _trtp_rtcp_session_add_source_2(session, TRTP_RTCP_RBLOCK(item->data)->ssrc, 0, 0, &added);
- if(added) ++count;
- }
- }
- }
-
- return count;
+ }
+ }
+
+ return count;
}
static tsk_size_t AddMember_(trtp_rtcp_session_t* session, const packet_ p, tsk_bool_t sender)
{
- tsk_size_t count = 0;
- if(IsRtpPacket(p)){
- const trtp_rtp_packet_t* packet_rtp = (const trtp_rtp_packet_t*)p;
- tsk_size_t i;
- tsk_bool_t added = tsk_false;
- _trtp_rtcp_session_add_source_2(session, packet_rtp->header->ssrc, packet_rtp->header->seq_num, packet_rtp->header->timestamp, &added);
- if(added) ++count;
- for(i = 0; i < packet_rtp->header->csrc_count && i < sizeof(packet_rtp->header->csrc)/sizeof(packet_rtp->header->csrc[0]); ++i){
- _trtp_rtcp_session_add_source_2(session, packet_rtp->header->csrc[i], 0, 0, &added);
- if(added) ++count;
- }
- }
- else{
- count += AddMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*) p, sender);
- }
- return count;
+ tsk_size_t count = 0;
+ if(IsRtpPacket(p)) {
+ const trtp_rtp_packet_t* packet_rtp = (const trtp_rtp_packet_t*)p;
+ tsk_size_t i;
+ tsk_bool_t added = tsk_false;
+ _trtp_rtcp_session_add_source_2(session, packet_rtp->header->ssrc, packet_rtp->header->seq_num, packet_rtp->header->timestamp, &added);
+ if(added) {
+ ++count;
+ }
+ for(i = 0; i < packet_rtp->header->csrc_count && i < sizeof(packet_rtp->header->csrc)/sizeof(packet_rtp->header->csrc[0]); ++i) {
+ _trtp_rtcp_session_add_source_2(session, packet_rtp->header->csrc[i], 0, 0, &added);
+ if(added) {
+ ++count;
+ }
+ }
+ }
+ else {
+ count += AddMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*) p, sender);
+ }
+ return count;
}
#define AddMember(session, p) AddMember_((session), (p), tsk_false)
@@ -1116,73 +1155,80 @@ static tsk_size_t AddMember_(trtp_rtcp_session_t* session, const packet_ p, tsk_
static tsk_size_t RemoveMemberUsingRTCPPacket(trtp_rtcp_session_t* session, const trtp_rtcp_packet_t* p)
{
- trtp_rtcp_packets_L_t* packets = tsk_null;
- trtp_rtcp_rblocks_L_t* blocks = tsk_null;
- tsk_bool_t removed = tsk_false;
- tsk_size_t count = 0;
-
- switch(p->header->type){
- case trtp_rtcp_packet_type_rr:
- {
- const trtp_rtcp_report_rr_t* rr = (const trtp_rtcp_report_rr_t*)p;
- _trtp_rtcp_session_remove_source(session, ((const trtp_rtcp_report_rr_t*)p)->ssrc, &removed);
- if(removed) ++count;
-
- packets = rr->packets;
- blocks = rr->blocks;
- break;
- }
- case trtp_rtcp_packet_type_sr:
- {
- const trtp_rtcp_report_sr_t* sr = (const trtp_rtcp_report_sr_t*)p;
- _trtp_rtcp_session_remove_source(session, ((const trtp_rtcp_report_sr_t*)p)->ssrc, &removed);
- if(removed) ++count;
- packets = sr->packets;
- blocks = sr->blocks;
- break;
- }
- default:
- {
- break;
+ trtp_rtcp_packets_L_t* packets = tsk_null;
+ trtp_rtcp_rblocks_L_t* blocks = tsk_null;
+ tsk_bool_t removed = tsk_false;
+ tsk_size_t count = 0;
+
+ switch(p->header->type) {
+ case trtp_rtcp_packet_type_rr: {
+ const trtp_rtcp_report_rr_t* rr = (const trtp_rtcp_report_rr_t*)p;
+ _trtp_rtcp_session_remove_source(session, ((const trtp_rtcp_report_rr_t*)p)->ssrc, &removed);
+ if(removed) {
+ ++count;
+ }
+
+ packets = rr->packets;
+ blocks = rr->blocks;
+ break;
+ }
+ case trtp_rtcp_packet_type_sr: {
+ const trtp_rtcp_report_sr_t* sr = (const trtp_rtcp_report_sr_t*)p;
+ _trtp_rtcp_session_remove_source(session, ((const trtp_rtcp_report_sr_t*)p)->ssrc, &removed);
+ if(removed) {
+ ++count;
+ }
+ packets = sr->packets;
+ blocks = sr->blocks;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ if(packets) {
+ const tsk_list_item_t *item;
+ tsk_list_foreach(item, packets) {
+ RemoveMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*)item->data);
+ }
+ }
+ if(blocks) {
+ const tsk_list_item_t *item;
+ tsk_list_foreach(item, blocks) {
+ _trtp_rtcp_session_remove_source(session, TRTP_RTCP_RBLOCK(item->data)->ssrc, &removed);
+ if(removed) {
+ ++count;
}
- }
-
- if(packets){
- const tsk_list_item_t *item;
- tsk_list_foreach(item, packets){
- RemoveMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*)item->data);
- }
- }
- if(blocks){
- const tsk_list_item_t *item;
- tsk_list_foreach(item, blocks){
- _trtp_rtcp_session_remove_source(session, TRTP_RTCP_RBLOCK(item->data)->ssrc, &removed);
- if(removed) ++count;
- }
- }
-
-
- return count;
+ }
+ }
+
+
+ return count;
}
static tsk_size_t RemoveMember(trtp_rtcp_session_t* session, const packet_ p)
{
- tsk_size_t count = 0;
- if(IsRtpPacket(p)){
- const trtp_rtp_packet_t* packet_rtp = (const trtp_rtp_packet_t*)p;
- tsk_size_t i;
- tsk_bool_t removed = tsk_false;
- _trtp_rtcp_session_remove_source(session, packet_rtp->header->ssrc, &removed);
- if(removed) ++count;
- for(i = 0; i < packet_rtp->header->csrc_count && i < sizeof(packet_rtp->header->csrc)/sizeof(packet_rtp->header->csrc[0]); ++i){
- _trtp_rtcp_session_remove_source(session, packet_rtp->header->csrc[i], &removed);
- if(removed) ++count;
- }
- }
- else{
- count += RemoveMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*) p);
- }
- return count;
+ tsk_size_t count = 0;
+ if(IsRtpPacket(p)) {
+ const trtp_rtp_packet_t* packet_rtp = (const trtp_rtp_packet_t*)p;
+ tsk_size_t i;
+ tsk_bool_t removed = tsk_false;
+ _trtp_rtcp_session_remove_source(session, packet_rtp->header->ssrc, &removed);
+ if(removed) {
+ ++count;
+ }
+ for(i = 0; i < packet_rtp->header->csrc_count && i < sizeof(packet_rtp->header->csrc)/sizeof(packet_rtp->header->csrc[0]); ++i) {
+ _trtp_rtcp_session_remove_source(session, packet_rtp->header->csrc[i], &removed);
+ if(removed) {
+ ++count;
+ }
+ }
+ }
+ else {
+ count += RemoveMemberUsingRTCPPacket(session, (const trtp_rtcp_packet_t*) p);
+ }
+ return count;
}
#define RemoveSender(session, p) RemoveMember((session), (p))
@@ -1190,395 +1236,414 @@ static tsk_size_t RemoveMember(trtp_rtcp_session_t* session, const packet_ p)
// Sends BYE in synchronous mode
static void SendBYEPacket(trtp_rtcp_session_t* session, event_ e)
{
- trtp_rtcp_report_bye_t* bye;
- tsk_size_t __num_bytes_pad = 0;
+ trtp_rtcp_report_bye_t* bye;
+ tsk_size_t __num_bytes_pad = 0;
- if(!session->remote_addr || session->local_fd <= 0){
- TSK_DEBUG_ERROR("Invalid network settings");
- return;
- }
+ if(!session->remote_addr || session->local_fd <= 0) {
+ TSK_DEBUG_ERROR("Invalid network settings");
+ return;
+ }
- tsk_safeobj_lock(session);
+ tsk_safeobj_lock(session);
#if HAVE_SRTP
- if(session->srtp.session) __num_bytes_pad = (SRTP_MAX_TRAILER_LEN + 0x4);
+ if(session->srtp.session) {
+ __num_bytes_pad = (SRTP_MAX_TRAILER_LEN + 0x4);
+ }
#endif
- if(session->source_local && (bye = trtp_rtcp_report_bye_create_2(session->source_local->ssrc))){
- tsk_buffer_t* buffer;
- // serialize and send the packet
- if((buffer = trtp_rtcp_packet_serialize((const trtp_rtcp_packet_t*)bye, __num_bytes_pad))){
- void* data = buffer->data;
- int size = (int)buffer->size;
+ if(session->source_local && (bye = trtp_rtcp_report_bye_create_2(session->source_local->ssrc))) {
+ tsk_buffer_t* buffer;
+ // serialize and send the packet
+ if((buffer = trtp_rtcp_packet_serialize((const trtp_rtcp_packet_t*)bye, __num_bytes_pad))) {
+ void* data = buffer->data;
+ int size = (int)buffer->size;
#if HAVE_SRTP
- if(session->srtp.session){
- if(srtp_protect_rtcp(((srtp_t)*session->srtp.session), data, &size) != err_status_ok){
- TSK_DEBUG_ERROR("srtp_protect_rtcp() failed");
- }
- }
+ if(session->srtp.session) {
+ if(srtp_protect_rtcp(((srtp_t)*session->srtp.session), data, &size) != err_status_ok) {
+ TSK_DEBUG_ERROR("srtp_protect_rtcp() failed");
+ }
+ }
#endif
- _trtp_rtcp_session_send_raw(session, data, size);
- TSK_OBJECT_SAFE_FREE(buffer);
- }
- TSK_OBJECT_SAFE_FREE(bye);
- }
+ _trtp_rtcp_session_send_raw(session, data, size);
+ TSK_OBJECT_SAFE_FREE(buffer);
+ }
+ TSK_OBJECT_SAFE_FREE(bye);
+ }
- tsk_safeobj_unlock(session);
+ tsk_safeobj_unlock(session);
}
// returns sent packet size
static tsk_size_t SendRTCPReport(trtp_rtcp_session_t* session, event_ e)
{
- tsk_size_t ret = 0;
-
- tsk_safeobj_lock(session);
-
- if(session->initial){
- // Send Receiver report (manadatory to be the first on)
- trtp_rtcp_report_rr_t* rr = trtp_rtcp_report_rr_create_2(session->source_local->ssrc);
- if(rr){
- // serialize and send the packet
- ret = _trtp_rtcp_session_send_pkt(session, (trtp_rtcp_packet_t*)rr);
- TSK_OBJECT_SAFE_FREE(rr);
- }
- }
- else{
- trtp_rtcp_report_sr_t* sr = trtp_rtcp_report_sr_create_null();
- uint32_t media_ssrc_list[16] = {0};
- uint32_t media_ssrc_list_count = 0;
- if(sr){
- uint64_t ntp_now = tsk_time_ntp();
- uint64_t time_now = tsk_time_now();
- trtp_rtcp_rblock_t* rblock;
- trtp_rtcp_source_t* source;
- tsk_list_item_t *item;
- tsk_bool_t packet_lost = tsk_false;
-
- // sender info
- sr->ssrc = session->source_local->ssrc;
- sr->sender_info.ntp_msw = (ntp_now >> 32);
- sr->sender_info.ntp_lsw = (ntp_now & 0xFFFFFFFF);
- sr->sender_info.sender_pcount = session->packets_count;
- sr->sender_info.sender_ocount = session->octets_count;
- { /* rtp_timestamp */
- struct timeval tv;
- uint64_t rtp_timestamp = (time_now - session->time_start) * (session->source_local->rate / 1000);
- tv.tv_sec = (long)(rtp_timestamp / 1000);
- tv.tv_usec = (long)(rtp_timestamp - ((rtp_timestamp / 1000) * 1000)) * 1000;
+ tsk_size_t ret = 0;
+
+ tsk_safeobj_lock(session);
+
+ if(session->initial) {
+ // Send Receiver report (manadatory to be the first on)
+ trtp_rtcp_report_rr_t* rr = trtp_rtcp_report_rr_create_2(session->source_local->ssrc);
+ if(rr) {
+ // serialize and send the packet
+ ret = _trtp_rtcp_session_send_pkt(session, (trtp_rtcp_packet_t*)rr);
+ TSK_OBJECT_SAFE_FREE(rr);
+ }
+ }
+ else {
+ trtp_rtcp_report_sr_t* sr = trtp_rtcp_report_sr_create_null();
+ uint32_t media_ssrc_list[16] = {0};
+ uint32_t media_ssrc_list_count = 0;
+ if(sr) {
+ uint64_t ntp_now = tsk_time_ntp();
+ uint64_t time_now = tsk_time_now();
+ trtp_rtcp_rblock_t* rblock;
+ trtp_rtcp_source_t* source;
+ tsk_list_item_t *item;
+ tsk_bool_t packet_lost = tsk_false;
+
+ // sender info
+ sr->ssrc = session->source_local->ssrc;
+ sr->sender_info.ntp_msw = (ntp_now >> 32);
+ sr->sender_info.ntp_lsw = (ntp_now & 0xFFFFFFFF);
+ sr->sender_info.sender_pcount = session->packets_count;
+ sr->sender_info.sender_ocount = session->octets_count;
+ { /* rtp_timestamp */
+ struct timeval tv;
+ uint64_t rtp_timestamp = (time_now - session->time_start) * (session->source_local->rate / 1000);
+ tv.tv_sec = (long)(rtp_timestamp / 1000);
+ tv.tv_usec = (long)(rtp_timestamp - ((rtp_timestamp / 1000) * 1000)) * 1000;
#if 1
- sr->sender_info.rtp_timestamp = (uint32_t)tsk_time_get_ms(&tv);
+ sr->sender_info.rtp_timestamp = (uint32_t)tsk_time_get_ms(&tv);
#else
- sr->sender_info.rtp_timestamp = (uint32_t)tsk_time_get_ntp_ms(&tv);
+ sr->sender_info.rtp_timestamp = (uint32_t)tsk_time_get_ntp_ms(&tv);
#endif
- }
-
- // report blocks
- tsk_list_foreach(item, session->sources){
- if(!(source = (trtp_rtcp_source_t*)item->data) || !_trtp_rtcp_source_is_probed(source)){
- continue;
- }
- if((rblock = trtp_rtcp_rblock_create_null())){
- int32_t expected, expected_interval, received_interval, lost_interval;
-
- rblock->ssrc = source->ssrc;
- // RFC 3550 - A.3 Determining Number of Packets Expected and Lost
- expected = (source->cycles + source->max_seq) - source->base_seq + 1;
- expected_interval = expected - source->expected_prior;
- source->expected_prior = expected;
- received_interval = source->received - source->received_prior;
- source->received_prior = source->received;
- lost_interval = expected_interval - received_interval;
- if (expected_interval == 0 || lost_interval <= 0) rblock->fraction = 0;
- else rblock->fraction = (lost_interval << 8) / expected_interval;
- rblock->cumulative_no_lost = ((expected - source->received));
- if(!packet_lost && rblock->fraction) packet_lost = tsk_true;
-
- rblock->last_seq = ((source->cycles & 0xFFFF) << 16) | source->max_seq;
- rblock->jitter = (uint32_t)source->jitter;
- rblock->lsr = ((source->ntp_msw & 0xFFFF) << 16) | ((source->ntp_lsw & 0xFFFF0000) >> 16);
- if(source->dlsr){
- rblock->dlsr = (uint32_t)(((time_now - source->dlsr) * 65536) / 1000); // in units of 1/65536 seconds
- }
-
- trtp_rtcp_report_sr_add_block(sr, rblock);
- TSK_OBJECT_SAFE_FREE(rblock);
- }
-
- if((media_ssrc_list_count + 1) < sizeof(media_ssrc_list)/sizeof(media_ssrc_list[0])){
- media_ssrc_list[media_ssrc_list_count++] = source->ssrc;
- }
- }
-
- if(media_ssrc_list_count > 0){
- // draft-alvestrand-rmcat-remb-02
- if(session->app_bw_max_download > 0 && session->app_bw_max_download != INT_MAX){ // INT_MAX or <=0 means undefined
- // app_bw_max_download unit is kbps while create_afb_remb() expect bps
- trtp_rtcp_report_psfb_t* psfb_afb_remb = trtp_rtcp_report_psfb_create_afb_remb(session->source_local->ssrc/*sender SSRC*/, media_ssrc_list, media_ssrc_list_count, (session->app_bw_max_download * 1024));
- if(psfb_afb_remb){
- TSK_DEBUG_INFO("Packing RTCP-AFB-REMB (bw_dwn=%d kbps) for outgoing RTCP-SR", session->app_bw_max_download);
- trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)sr, (trtp_rtcp_packet_t*)psfb_afb_remb, tsk_false);
- TSK_OBJECT_SAFE_FREE(psfb_afb_remb);
- }
- }
- }
-
- // serialize and send the packet
- ret = _trtp_rtcp_session_send_pkt(session, (trtp_rtcp_packet_t*)sr);
- TSK_OBJECT_SAFE_FREE(sr);
- }
- }
-
- tsk_safeobj_unlock(session);
- return ret;
+ }
+
+ // report blocks
+ tsk_list_foreach(item, session->sources) {
+ if(!(source = (trtp_rtcp_source_t*)item->data) || !_trtp_rtcp_source_is_probed(source)) {
+ continue;
+ }
+ if((rblock = trtp_rtcp_rblock_create_null())) {
+ int32_t expected, expected_interval, received_interval, lost_interval;
+
+ rblock->ssrc = source->ssrc;
+ // RFC 3550 - A.3 Determining Number of Packets Expected and Lost
+ expected = (source->cycles + source->max_seq) - source->base_seq + 1;
+ expected_interval = expected - source->expected_prior;
+ source->expected_prior = expected;
+ received_interval = source->received - source->received_prior;
+ source->received_prior = source->received;
+ lost_interval = expected_interval - received_interval;
+ if (expected_interval == 0 || lost_interval <= 0) {
+ rblock->fraction = 0;
+ }
+ else {
+ rblock->fraction = (lost_interval << 8) / expected_interval;
+ }
+ rblock->cumulative_no_lost = ((expected - source->received));
+ if(!packet_lost && rblock->fraction) {
+ packet_lost = tsk_true;
+ }
+
+ rblock->last_seq = ((source->cycles & 0xFFFF) << 16) | source->max_seq;
+ rblock->jitter = (uint32_t)source->jitter;
+ rblock->lsr = ((source->ntp_msw & 0xFFFF) << 16) | ((source->ntp_lsw & 0xFFFF0000) >> 16);
+ if(source->dlsr) {
+ rblock->dlsr = (uint32_t)(((time_now - source->dlsr) * 65536) / 1000); // in units of 1/65536 seconds
+ }
+
+ trtp_rtcp_report_sr_add_block(sr, rblock);
+ TSK_OBJECT_SAFE_FREE(rblock);
+ }
+
+ if((media_ssrc_list_count + 1) < sizeof(media_ssrc_list)/sizeof(media_ssrc_list[0])) {
+ media_ssrc_list[media_ssrc_list_count++] = source->ssrc;
+ }
+ }
+
+ if(media_ssrc_list_count > 0) {
+ // draft-alvestrand-rmcat-remb-02
+ if(session->app_bw_max_download > 0 && session->app_bw_max_download != INT_MAX) { // INT_MAX or <=0 means undefined
+ // app_bw_max_download unit is kbps while create_afb_remb() expect bps
+ trtp_rtcp_report_psfb_t* psfb_afb_remb = trtp_rtcp_report_psfb_create_afb_remb(session->source_local->ssrc/*sender SSRC*/, media_ssrc_list, media_ssrc_list_count, (session->app_bw_max_download * 1024));
+ if(psfb_afb_remb) {
+ TSK_DEBUG_INFO("Packing RTCP-AFB-REMB (bw_dwn=%d kbps) for outgoing RTCP-SR", session->app_bw_max_download);
+ trtp_rtcp_packet_add_packet((trtp_rtcp_packet_t*)sr, (trtp_rtcp_packet_t*)psfb_afb_remb, tsk_false);
+ TSK_OBJECT_SAFE_FREE(psfb_afb_remb);
+ }
+ }
+ }
+
+ // serialize and send the packet
+ ret = _trtp_rtcp_session_send_pkt(session, (trtp_rtcp_packet_t*)sr);
+ TSK_OBJECT_SAFE_FREE(sr);
+ }
+ }
+
+ tsk_safeobj_unlock(session);
+ return ret;
}
static void Schedule(trtp_rtcp_session_t* session, double tn, event_ e)
{
- tsk_safeobj_lock(session); // must
- switch(e){
- case EVENT_BYE:
- if(!TSK_TIMER_ID_IS_VALID(session->timer.id_bye)){
- session->timer.id_bye = tsk_timer_manager_schedule(session->timer.handle_global, (uint64_t)tn, _trtp_rtcp_session_timer_callback, session);
- }
- break;
- case EVENT_REPORT:
- if(!TSK_TIMER_ID_IS_VALID(session->timer.id_report)){
- session->timer.id_report = tsk_timer_manager_schedule(session->timer.handle_global, (uint64_t)tn, _trtp_rtcp_session_timer_callback, session);
- }
- break;
- default: TSK_DEBUG_ERROR("Unexpected code called"); break;
- }
- tsk_safeobj_unlock(session);
+ tsk_safeobj_lock(session); // must
+ switch(e) {
+ case EVENT_BYE:
+ if(!TSK_TIMER_ID_IS_VALID(session->timer.id_bye)) {
+ session->timer.id_bye = tsk_timer_manager_schedule(session->timer.handle_global, (uint64_t)tn, _trtp_rtcp_session_timer_callback, session);
+ }
+ break;
+ case EVENT_REPORT:
+ if(!TSK_TIMER_ID_IS_VALID(session->timer.id_report)) {
+ session->timer.id_report = tsk_timer_manager_schedule(session->timer.handle_global, (uint64_t)tn, _trtp_rtcp_session_timer_callback, session);
+ }
+ break;
+ default:
+ TSK_DEBUG_ERROR("Unexpected code called");
+ break;
+ }
+ tsk_safeobj_unlock(session);
}
#define Reschedule(session, tn, e) Schedule((session), (tn), (e))
static double rtcp_interval(int32_t members,
- int32_t senders,
- double rtcp_bw,
- int32_t we_sent,
- double avg_rtcp_size,
- tsk_bool_t initial)
+ int32_t senders,
+ double rtcp_bw,
+ int32_t we_sent,
+ double avg_rtcp_size,
+ tsk_bool_t initial)
{
- /*
- * Minimum average time between RTCP packets from this site (in
- * seconds). This time prevents the reports from `clumping' when
- * sessions are small and the law of large numbers isn't helping
- * to smooth out the traffic. It also keeps the report interval
- * from becoming ridiculously small during transient outages like
- * a network partition.
- */
- #define RTCP_MIN_TIME 5.
- /*
- * Fraction of the RTCP bandwidth to be shared among active
- * senders. (This fraction was chosen so that in a typical
- * session with one or two active senders, the computed report
- * time would be roughly equal to the minimum report time so that
- * we don't unnecessarily slow down receiver reports.) The
- * receiver fraction must be 1 - the sender fraction.
- */
- #define RTCP_SENDER_BW_FRACTION 0.25
- #define RTCP_RCVR_BW_FRACTION (1 - RTCP_SENDER_BW_FRACTION)
- /*
- * To compensate for "timer reconsideration" converging to a
- * value below the intended average.
- */
- #define COMPENSATION (2.71828 - 1.5)
-
- double t; /* interval */
- double rtcp_min_time = RTCP_MIN_TIME;
- int n; /* no. of members for computation */
-
- /*
- * Very first call at application start-up uses half the min
- * delay for quicker notification while still allowing some time
- * before reporting for randomization and to learn about other
- * sources so the report interval will converge to the correct
- * interval more quickly.
- */
- if (initial) {
- rtcp_min_time /= 2;
- }
- /*
- * Dedicate a fraction of the RTCP bandwidth to senders unless
- * the number of senders is large enough that their share is
- * more than that fraction.
- */
- n = members;
- if (senders <= members * RTCP_SENDER_BW_FRACTION) {
- if (we_sent) {
- rtcp_bw *= RTCP_SENDER_BW_FRACTION;
- n = senders;
- } else {
- rtcp_bw *= RTCP_RCVR_BW_FRACTION;
- n -= senders;
- }
- }
-
- /*
- * The effective number of sites times the average packet size is
- * the total number of octets sent when each site sends a report.
- * Dividing this by the effective bandwidth gives the time
- * interval over which those packets must be sent in order to
- * meet the bandwidth target, with a minimum enforced. In that
- * time interval we send one report so this time is also our
- * average time between reports.
- */
- t = avg_rtcp_size * n / rtcp_bw;
- if (t < rtcp_min_time) t = rtcp_min_time;
-
- /*
- * To avoid traffic bursts from unintended synchronization with
- * other sites, we then pick our actual next report interval as a
- * random number uniformly distributed between 0.5*t and 1.5*t.
- */
- t = t * (drand48() + 0.5);
- t = t / COMPENSATION;
-
- return (t * 1000);
+ /*
+ * Minimum average time between RTCP packets from this site (in
+ * seconds). This time prevents the reports from `clumping' when
+ * sessions are small and the law of large numbers isn't helping
+ * to smooth out the traffic. It also keeps the report interval
+ * from becoming ridiculously small during transient outages like
+ * a network partition.
+ */
+#define RTCP_MIN_TIME 5.
+ /*
+ * Fraction of the RTCP bandwidth to be shared among active
+ * senders. (This fraction was chosen so that in a typical
+ * session with one or two active senders, the computed report
+ * time would be roughly equal to the minimum report time so that
+ * we don't unnecessarily slow down receiver reports.) The
+ * receiver fraction must be 1 - the sender fraction.
+ */
+#define RTCP_SENDER_BW_FRACTION 0.25
+#define RTCP_RCVR_BW_FRACTION (1 - RTCP_SENDER_BW_FRACTION)
+ /*
+ * To compensate for "timer reconsideration" converging to a
+ * value below the intended average.
+ */
+#define COMPENSATION (2.71828 - 1.5)
+
+ double t; /* interval */
+ double rtcp_min_time = RTCP_MIN_TIME;
+ int n; /* no. of members for computation */
+
+ /*
+ * Very first call at application start-up uses half the min
+ * delay for quicker notification while still allowing some time
+ * before reporting for randomization and to learn about other
+ * sources so the report interval will converge to the correct
+ * interval more quickly.
+ */
+ if (initial) {
+ rtcp_min_time /= 2;
+ }
+ /*
+ * Dedicate a fraction of the RTCP bandwidth to senders unless
+ * the number of senders is large enough that their share is
+ * more than that fraction.
+ */
+ n = members;
+ if (senders <= members * RTCP_SENDER_BW_FRACTION) {
+ if (we_sent) {
+ rtcp_bw *= RTCP_SENDER_BW_FRACTION;
+ n = senders;
+ }
+ else {
+ rtcp_bw *= RTCP_RCVR_BW_FRACTION;
+ n -= senders;
+ }
+ }
+
+ /*
+ * The effective number of sites times the average packet size is
+ * the total number of octets sent when each site sends a report.
+ * Dividing this by the effective bandwidth gives the time
+ * interval over which those packets must be sent in order to
+ * meet the bandwidth target, with a minimum enforced. In that
+ * time interval we send one report so this time is also our
+ * average time between reports.
+ */
+ t = avg_rtcp_size * n / rtcp_bw;
+ if (t < rtcp_min_time) {
+ t = rtcp_min_time;
+ }
+
+ /*
+ * To avoid traffic bursts from unintended synchronization with
+ * other sites, we then pick our actual next report interval as a
+ * random number uniformly distributed between 0.5*t and 1.5*t.
+ */
+ t = t * (drand48() + 0.5);
+ t = t / COMPENSATION;
+
+ return (t * 1000);
}
static void OnExpire(trtp_rtcp_session_t* session, event_ e)
{
- /* This function is responsible for deciding whether to send an
- * RTCP report or BYE packet now, or to reschedule transmission.
- * It is also responsible for updating the pmembers, initial, tp,
- * and avg_rtcp_size state variables. This function should be
- * called upon expiration of the event timer used by Schedule().
- */
-
- double t; /* Interval */
- double tn; /* Next transmit time */
- double tc;
-
- /* In the case of a BYE, we use "timer reconsideration" to
- * reschedule the transmission of the BYE if necessary */
-
- if (TypeOfEvent(e) == EVENT_BYE) {
- t = rtcp_interval(session->members,
- session->senders,
- session->rtcp_bw,
- session->we_sent,
- session->avg_rtcp_size,
- session->initial);
- tn = session->tp + t;
- if (tn <= session->tc()) {
- SendBYEPacket(session, e);
+ /* This function is responsible for deciding whether to send an
+ * RTCP report or BYE packet now, or to reschedule transmission.
+ * It is also responsible for updating the pmembers, initial, tp,
+ * and avg_rtcp_size state variables. This function should be
+ * called upon expiration of the event timer used by Schedule().
+ */
+
+ double t; /* Interval */
+ double tn; /* Next transmit time */
+ double tc;
+
+ /* In the case of a BYE, we use "timer reconsideration" to
+ * reschedule the transmission of the BYE if necessary */
+
+ if (TypeOfEvent(e) == EVENT_BYE) {
+ t = rtcp_interval(session->members,
+ session->senders,
+ session->rtcp_bw,
+ session->we_sent,
+ session->avg_rtcp_size,
+ session->initial);
+ tn = session->tp + t;
+ if (tn <= session->tc()) {
+ SendBYEPacket(session, e);
#if 0
- exit(1);
+ exit(1);
#endif
- } else {
+ }
+ else {
#if 0
- Schedule(session, tn, e);
+ Schedule(session, tn, e);
#else
- Schedule(session, 0, e);
+ Schedule(session, 0, e);
#endif
- }
-
- } else if (TypeOfEvent(e) == EVENT_REPORT) {
- t = rtcp_interval(session->members,
- session->senders,
- session->rtcp_bw,
- session->we_sent,
- session->avg_rtcp_size,
- session->initial);
- tn = session->tp + t;
- if (tn <= (tc = session->tc())) {
- tsk_size_t SentPacketSize = SendRTCPReport(session, e);
- session->avg_rtcp_size = (1./16.)*SentPacketSize + (15./16.)*(session->avg_rtcp_size);
- session->tp = tc;
-
- /* We must redraw the interval. Don't reuse the
- one computed above, since its not actually
- distributed the same, as we are conditioned
- on it being small enough to cause a packet to
- be sent */
-
- t = rtcp_interval(session->members,
- session->senders,
- session->rtcp_bw,
- session->we_sent,
- session->avg_rtcp_size,
- session->initial);
+ }
+
+ }
+ else if (TypeOfEvent(e) == EVENT_REPORT) {
+ t = rtcp_interval(session->members,
+ session->senders,
+ session->rtcp_bw,
+ session->we_sent,
+ session->avg_rtcp_size,
+ session->initial);
+ tn = session->tp + t;
+ if (tn <= (tc = session->tc())) {
+ tsk_size_t SentPacketSize = SendRTCPReport(session, e);
+ session->avg_rtcp_size = (1./16.)*SentPacketSize + (15./16.)*(session->avg_rtcp_size);
+ session->tp = tc;
+
+ /* We must redraw the interval. Don't reuse the
+ one computed above, since its not actually
+ distributed the same, as we are conditioned
+ on it being small enough to cause a packet to
+ be sent */
+
+ t = rtcp_interval(session->members,
+ session->senders,
+ session->rtcp_bw,
+ session->we_sent,
+ session->avg_rtcp_size,
+ session->initial);
#if 0
- Schedule(session, t+tc, e);
+ Schedule(session, t+tc, e);
#else
- Schedule(session, t, e);
+ Schedule(session, t, e);
#endif
- session->initial = tsk_false;
- } else {
+ session->initial = tsk_false;
+ }
+ else {
#if 0
- Schedule(session, tn, e);
+ Schedule(session, tn, e);
#else
- Schedule(session, 0, e);
+ Schedule(session, 0, e);
#endif
- }
- session->pmembers = session->members;
- }
+ }
+ session->pmembers = session->members;
+ }
}
static void OnReceive(trtp_rtcp_session_t* session, const packet_ p, event_ e, tsk_size_t ReceivedPacketSize)
{
- /* What we do depends on whether we have left the group, and are
- * waiting to send a BYE (TypeOfEvent(e) == EVENT_BYE) or an RTCP
- * report. p represents the packet that was just received. */
-
- if (PacketType(p) == PACKET_RTCP_REPORT) {
- if (NewMember(session, p) && (TypeOfEvent(e) == EVENT_REPORT)) {
- session->members += (int32_t)AddMember(session, p);
- }
- session->avg_rtcp_size = (1./16.)*ReceivedPacketSize + (15./16.)*(session->avg_rtcp_size);
- } else if (PacketType(p) == PACKET_RTP) {
+ /* What we do depends on whether we have left the group, and are
+ * waiting to send a BYE (TypeOfEvent(e) == EVENT_BYE) or an RTCP
+ * report. p represents the packet that was just received. */
+
+ if (PacketType(p) == PACKET_RTCP_REPORT) {
+ if (NewMember(session, p) && (TypeOfEvent(e) == EVENT_REPORT)) {
+ session->members += (int32_t)AddMember(session, p);
+ }
+ session->avg_rtcp_size = (1./16.)*ReceivedPacketSize + (15./16.)*(session->avg_rtcp_size);
+ }
+ else if (PacketType(p) == PACKET_RTP) {
#if 0
- if (NewMember(session, p) && (TypeOfEvent(e) == EVENT_REPORT)) {
- session->members += AddMember(session, p);
- }
- if (NewSender(session, p) && (TypeOfEvent(e) == EVENT_REPORT)) {
- tsk_size_t count = AddSender(session, p);
- session->senders += count;
- session->members += count;
- }
+ if (NewMember(session, p) && (TypeOfEvent(e) == EVENT_REPORT)) {
+ session->members += AddMember(session, p);
+ }
+ if (NewSender(session, p) && (TypeOfEvent(e) == EVENT_REPORT)) {
+ tsk_size_t count = AddSender(session, p);
+ session->senders += count;
+ session->members += count;
+ }
#else
- if (NewSender(session, p)) {
- tsk_size_t count = AddSender(session, p);
- session->senders += (int32_t)count;
- session->members += (int32_t)count;
- }
+ if (NewSender(session, p)) {
+ tsk_size_t count = AddSender(session, p);
+ session->senders += (int32_t)count;
+ session->members += (int32_t)count;
+ }
#endif
- } else if (PacketType(p) == PACKET_BYE) {
- session->avg_rtcp_size = (1./16.)*ReceivedPacketSize + (15./16.)*(session->avg_rtcp_size);
-
- if (TypeOfEvent(e) == EVENT_REPORT) {
- double tc = session->tc();
- tsk_size_t count = RemoveMember(session, p);
- session->senders -= (int32_t)count;
- session->members -= (int32_t)count;
+ }
+ else if (PacketType(p) == PACKET_BYE) {
+ session->avg_rtcp_size = (1./16.)*ReceivedPacketSize + (15./16.)*(session->avg_rtcp_size);
+
+ if (TypeOfEvent(e) == EVENT_REPORT) {
+ double tc = session->tc();
+ tsk_size_t count = RemoveMember(session, p);
+ session->senders -= (int32_t)count;
+ session->members -= (int32_t)count;
#if 0
- if (NewSender(session, p) == tsk_false) {
- RemoveSender(p);
- session->senders -= 1;
- }
- if (NewMember(session, p) == tsk_false) {
- RemoveMember(p);
- session->members -= 1;
- }
+ if (NewSender(session, p) == tsk_false) {
+ RemoveSender(p);
+ session->senders -= 1;
+ }
+ if (NewMember(session, p) == tsk_false) {
+ RemoveMember(p);
+ session->members -= 1;
+ }
#endif
- if (session->members < session->pmembers && session->pmembers) {
- session->tn = (time_tp)(tc +
- (((double) session->members)/(session->pmembers))*(session->tn - tc));
- session->tp = (time_tp)(tc -
- (((double) session->members)/(session->pmembers))*(tc - session->tp));
+ if (session->members < session->pmembers && session->pmembers) {
+ session->tn = (time_tp)(tc +
+ (((double) session->members)/(session->pmembers))*(session->tn - tc));
+ session->tp = (time_tp)(tc -
+ (((double) session->members)/(session->pmembers))*(tc - session->tp));
- /* Reschedule the next report for time tn */
+ /* Reschedule the next report for time tn */
- Reschedule(session, session->tn, e);
- session->pmembers = session->members;
- }
+ Reschedule(session, session->tn, e);
+ session->pmembers = session->members;
+ }
- } else if (TypeOfEvent(e) == EVENT_BYE) {
- session->members += 1;
- }
- }
+ }
+ else if (TypeOfEvent(e) == EVENT_BYE) {
+ session->members += 1;
+ }
+ }
}
OpenPOWER on IntegriCloud