From 94038f3c125f1605cf7fd0cec00005648020f4db Mon Sep 17 00:00:00 2001 From: Sergey Khripchenko Date: Wed, 28 Feb 2018 08:27:30 -0800 Subject: [PATCH] FS-11056: [core] fix RTCP lost calculation RTCP/Receiver Report/lost field is a _signed_ 24bit integer and it could be negative (in case of UDP duplication) + any negatives now threated as huge uint32_t + set this field properly on __BIG_ENDIAN + correctly read this value in received RTCP on all arches --- src/include/switch_rtcp_frame.h | 2 +- src/switch_rtp.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/include/switch_rtcp_frame.h b/src/include/switch_rtcp_frame.h index 9e5af76226..965599b623 100644 --- a/src/include/switch_rtcp_frame.h +++ b/src/include/switch_rtcp_frame.h @@ -45,7 +45,7 @@ SWITCH_BEGIN_EXTERN_C struct switch_rtcp_report_block_frame { uint32_t ssrc; /* The SSRC identifier of the source to which the information in this reception report block pertains. */ uint8_t fraction; /* The fraction of RTP data packets from source SSRC_n lost since the previous SR or RR packet was sent */ - uint32_t lost; /* The total number of RTP data packets from source SSRC_n that have been lost since the beginning of reception */ + int32_t lost; /* The total number of RTP data packets from source SSRC_n that have been lost since the beginning of reception. could be negative. */ uint32_t highest_sequence_number_received; uint32_t jitter; /* An estimate of the statistical variance of the RTP data packet interarrival time, measured in timestamp units and expressed as an unsigned integer. */ uint32_t lsr; /* The middle 32 bits out of 64 in the NTP timestamp */ diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 44c4b041c4..3e637da509 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1820,9 +1820,11 @@ static void rtcp_generate_report_block(switch_rtp_t *rtp_session, struct switch_ } else { rtcp_report_block->fraction = 0; } -#if SWITCH_BYTE_ORDER != __BIG_ENDIAN +#if SWITCH_BYTE_ORDER == __BIG_ENDIAN + rtcp_report_block->lost = stats->cum_lost; +#else /* Reversing byte order for 24bits */ - rtcp_report_block->lost = (((stats->cum_lost&0x0000FF)<<16) | ((stats->cum_lost&0x00FF00)) | ((stats->cum_lost&0xFF0000)>>16)); + rtcp_report_block->lost = htonl(stats->cum_lost) >> 8; #endif #ifdef DEBUG_RTCP @@ -6568,7 +6570,12 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t rtp_session->rtcp_frame.reports[i].ssrc = ntohl(report->ssrc); rtp_session->rtcp_frame.reports[i].fraction = (uint8_t)report->fraction; - rtp_session->rtcp_frame.reports[i].lost = ntohl(report->lost); +#if SWITCH_BYTE_ORDER == __BIG_ENDIAN + rtp_session->rtcp_frame.reports[i].lost = report->lost; // signed 24bit will extended signess to int32_t automatically +#else + rtp_session->rtcp_frame.reports[i].lost = ntohl(report->lost)>>8; // signed 24bit casted to uint32_t need >>8 after ntohl()... + rtp_session->rtcp_frame.reports[i].lost = rtp_session->rtcp_frame.reports[i].lost | ((rtp_session->rtcp_frame.reports[i].lost & 0x00800000) ? 0xff000000 : 0x00000000); // ...and signess compensation +#endif rtp_session->rtcp_frame.reports[i].highest_sequence_number_received = ntohl(report->highest_sequence_number_received); rtp_session->rtcp_frame.reports[i].jitter = ntohl(report->jitter); rtp_session->rtcp_frame.reports[i].lsr = ntohl(report->lsr);