diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index 666f930957..cb2df9f102 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -22,6 +22,9 @@ namespace webrtc { +// Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP. +const int kMaxPaddingLength = 224; + namespace { const char* FrameTypeToString(const FrameType frame_type) { @@ -57,11 +60,11 @@ RTPSender::RTPSender(const int32_t id, const bool audio, Clock *clock, packets_sent_(0), payload_bytes_sent_(0), start_time_stamp_forced_(false), start_time_stamp_(0), ssrc_db_(*SSRCDatabase::GetSSRCDatabase()), remote_ssrc_(0), sequence_number_forced_(false), ssrc_forced_(false), - time_stamp_(0), csrcs_(0), csrc_(), include_csrcs_(true), + timestamp_(0), num_csrcs_(0), csrcs_(), include_csrcs_(true), rtx_(kRtxOff), payload_type_rtx_(-1) { memset(nack_byte_count_times_, 0, sizeof(nack_byte_count_times_)); memset(nack_byte_count_, 0, sizeof(nack_byte_count_)); - memset(csrc_, 0, sizeof(csrc_)); + memset(csrcs_, 0, sizeof(csrcs_)); // We need to seed the random generator. srand(static_cast(clock_->TimeInMilliseconds())); ssrc_ = ssrc_db_.CreateSSRC(); // Can't be 0. @@ -375,7 +378,7 @@ int32_t RTPSender::SendOutgoingData( if (frame_type == kFrameEmpty) { return SendPaddingAccordingToBitrate(payload_type, capture_timestamp, - capture_time_ms); + capture_time_ms) ? 0 : -1; } return video_->SendVideo(video_type, frame_type, payload_type, capture_timestamp, capture_time_ms, payload_data, @@ -384,7 +387,7 @@ int32_t RTPSender::SendOutgoingData( } } -int32_t RTPSender::SendPaddingAccordingToBitrate( +bool RTPSender::SendPaddingAccordingToBitrate( int8_t payload_type, uint32_t capture_timestamp, int64_t capture_time_ms) { // Current bitrate since last estimate(1 second) averaged with the @@ -392,7 +395,7 @@ int32_t RTPSender::SendPaddingAccordingToBitrate( uint32_t current_bitrate = BitrateNow(); int bitrate_diff = target_send_bitrate_ * 1000 - current_bitrate; if (bitrate_diff <= 0) { - return 0; + return true; } int bytes = 0; if (current_bitrate == 0) { @@ -409,54 +412,59 @@ int32_t RTPSender::SendPaddingAccordingToBitrate( return SendPadData(payload_type, capture_timestamp, capture_time_ms, bytes); } -int32_t RTPSender::SendPadData( - int8_t payload_type, uint32_t capture_timestamp, - int64_t capture_time_ms, int32_t bytes) { - // Drop this packet if we're not sending media packets. - if (!sending_media_) { +int RTPSender::BuildPaddingPacket(uint8_t* packet, int header_length, + int32_t bytes) { + int padding_bytes_in_packet = kMaxPaddingLength; + if (bytes < kMaxPaddingLength) { + // Round to the nearest multiple of 32. + padding_bytes_in_packet = (bytes + 16) & 0xffe0; + } + if (padding_bytes_in_packet < 32) { + // Sanity don't send empty packets. return 0; } - // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP. - int max_length = 224; + packet[0] |= 0x20; // Set padding bit. + int32_t *data = + reinterpret_cast(&(packet[header_length])); + + // Fill data buffer with random data. + for (int j = 0; j < (padding_bytes_in_packet >> 2); ++j) { + data[j] = rand(); // NOLINT + } + // Set number of padding bytes in the last byte of the packet. + packet[header_length + padding_bytes_in_packet - 1] = padding_bytes_in_packet; + return padding_bytes_in_packet; +} + +bool RTPSender::SendPadData(int8_t payload_type, uint32_t capture_timestamp, + int64_t capture_time_ms, int32_t bytes) { + // Drop this packet if we're not sending media packets. + if (!sending_media_) { + return true; + } uint8_t data_buffer[IP_PACKET_SIZE]; - - for (; bytes > 0; bytes -= max_length) { - int padding_bytes_in_packet = max_length; - if (bytes < max_length) { - padding_bytes_in_packet = (bytes + 16) & 0xffe0; // Keep our modulus 32. - } - if (padding_bytes_in_packet < 32) { - // Sanity don't send empty packets. - break; - } + for (; bytes > 0; bytes -= kMaxPaddingLength) { // Correct seq num, timestamp and payload type. - int header_length = BuildRTPheader( - data_buffer, payload_type, false, // No markerbit. - capture_timestamp, true, // Timestamp provided. - true); // Increment sequence number. - data_buffer[0] |= 0x20; // Set padding bit. - int32_t *data = - reinterpret_cast(&(data_buffer[header_length])); - - // Fill data buffer with random data. - for (int j = 0; j < (padding_bytes_in_packet >> 2); ++j) { - data[j] = rand(); // NOLINT - } - // Set number of padding bytes in the last byte of the packet. - data_buffer[header_length + padding_bytes_in_packet - 1] = - padding_bytes_in_packet; + int header_length = BuildRTPheader(data_buffer, + payload_type, + false, // No markerbit. + capture_timestamp, + true, // Timestamp provided. + true); // Increment sequence number. + int padding_bytes_in_packet = BuildPaddingPacket(data_buffer, header_length, + bytes); // Send the packet. - if (0 > SendToNetwork(data_buffer, padding_bytes_in_packet, header_length, - capture_time_ms, kDontRetransmit)) { + if (SendToNetwork(data_buffer, padding_bytes_in_packet, header_length, + capture_time_ms, kDontRetransmit) < 0) { // Error sending the packet. break; } } if (bytes > 31) { // 31 due to our modulus 32. // We did not manage to send all bytes. - return -1; + return false; } - return 0; + return true; } void RTPSender::SetStorePacketsStatus(const bool enable, @@ -781,7 +789,7 @@ void RTPSender::ProcessBitrate() { uint16_t RTPSender::RTPHeaderLength() const { uint16_t rtp_header_length = 12; if (include_csrcs_) { - rtp_header_length += sizeof(uint32_t) * csrcs_; + rtp_header_length += sizeof(uint32_t) * num_csrcs_; } rtp_header_length += RtpHeaderExtensionTotalLength(); return rtp_header_length; @@ -808,60 +816,71 @@ uint32_t RTPSender::Bytes() const { return payload_bytes_sent_; } -int32_t RTPSender::BuildRTPheader( - uint8_t *data_buffer, const int8_t payload_type, - const bool marker_bit, const uint32_t capture_time_stamp, - const bool time_stamp_provided, const bool inc_sequence_number) { - assert(payload_type >= 0); - CriticalSectionScoped cs(send_critsect_); - - data_buffer[0] = static_cast(0x80); // version 2. - data_buffer[1] = static_cast(payload_type); +int RTPSender::CreateRTPHeader( + uint8_t* header, int8_t payload_type, uint32_t ssrc, bool marker_bit, + uint32_t timestamp, uint16_t sequence_number, const uint32_t* csrcs, + uint8_t num_csrcs) const { + header[0] = 0x80; // version 2. + header[1] = static_cast(payload_type); if (marker_bit) { - data_buffer[1] |= kRtpMarkerBitMask; // Marker bit is set. + header[1] |= kRtpMarkerBitMask; // Marker bit is set. } - if (time_stamp_provided) { - time_stamp_ = start_time_stamp_ + capture_time_stamp; - } else { - // Make a unique time stamp. - // We can't inc by the actual time, since then we increase the risk of back - // timing. - time_stamp_++; - } - ModuleRTPUtility::AssignUWord16ToBuffer(data_buffer + 2, sequence_number_); - ModuleRTPUtility::AssignUWord32ToBuffer(data_buffer + 4, time_stamp_); - ModuleRTPUtility::AssignUWord32ToBuffer(data_buffer + 8, ssrc_); + ModuleRTPUtility::AssignUWord16ToBuffer(header + 2, sequence_number); + ModuleRTPUtility::AssignUWord32ToBuffer(header + 4, timestamp); + ModuleRTPUtility::AssignUWord32ToBuffer(header + 8, ssrc); int32_t rtp_header_length = 12; // Add the CSRCs if any. - if (include_csrcs_ && csrcs_ > 0) { - if (csrcs_ > kRtpCsrcSize) { + if (num_csrcs > 0) { + if (num_csrcs > kRtpCsrcSize) { // error assert(false); return -1; } - uint8_t *ptr = &data_buffer[rtp_header_length]; - for (uint32_t i = 0; i < csrcs_; ++i) { - ModuleRTPUtility::AssignUWord32ToBuffer(ptr, csrc_[i]); + uint8_t *ptr = &header[rtp_header_length]; + for (int i = 0; i < num_csrcs; ++i) { + ModuleRTPUtility::AssignUWord32ToBuffer(ptr, csrcs[i]); ptr += 4; } - data_buffer[0] = (data_buffer[0] & 0xf0) | csrcs_; + header[0] = (header[0] & 0xf0) | num_csrcs; // Update length of header. - rtp_header_length += sizeof(uint32_t) * csrcs_; + rtp_header_length += sizeof(uint32_t) * num_csrcs; } - sequence_number_++; // Prepare for next packet. - uint16_t len = BuildRTPHeaderExtension(data_buffer + rtp_header_length); - if (len) { - data_buffer[0] |= 0x10; // Set extension bit. + uint16_t len = BuildRTPHeaderExtension(header + rtp_header_length); + if (len > 0) { + header[0] |= 0x10; // Set extension bit. rtp_header_length += len; } return rtp_header_length; } -uint16_t RTPSender::BuildRTPHeaderExtension( - uint8_t *data_buffer) const { +int32_t RTPSender::BuildRTPheader( + uint8_t *data_buffer, const int8_t payload_type, + const bool marker_bit, const uint32_t capture_timestamp, + const bool time_stamp_provided, const bool inc_sequence_number) { + assert(payload_type >= 0); + CriticalSectionScoped cs(send_critsect_); + + if (time_stamp_provided) { + timestamp_ = start_time_stamp_ + capture_timestamp; + capture_timestamp_ = capture_timestamp; + } else { + // Make a unique time stamp. + // We can't inc by the actual time, since then we increase the risk of back + // timing. + timestamp_++; + } + uint32_t sequence_number = sequence_number_++; + int csrcs_length = 0; + if (include_csrcs_) + csrcs_length = num_csrcs_; + return CreateRTPHeader(data_buffer, payload_type, ssrc_, marker_bit, + timestamp_, sequence_number, csrcs_, csrcs_length); +} + +uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer) const { if (rtp_header_extension_map_.Size() <= 0) { return 0; } @@ -1145,7 +1164,7 @@ bool RTPSender::SendingMedia() const { uint32_t RTPSender::Timestamp() const { CriticalSectionScoped cs(send_critsect_); - return time_stamp_; + return timestamp_; } void RTPSender::SetStartTimestamp(uint32_t timestamp, bool force) { @@ -1208,18 +1227,18 @@ void RTPSender::SetCSRCs(const uint32_t arr_of_csrc[kRtpCsrcSize], CriticalSectionScoped cs(send_critsect_); for (int i = 0; i < arr_length; i++) { - csrc_[i] = arr_of_csrc[i]; + csrcs_[i] = arr_of_csrc[i]; } - csrcs_ = arr_length; + num_csrcs_ = arr_length; } int32_t RTPSender::CSRCs(uint32_t arr_of_csrc[kRtpCsrcSize]) const { assert(arr_of_csrc); CriticalSectionScoped cs(send_critsect_); - for (int i = 0; i < csrcs_ && i < kRtpCsrcSize; i++) { - arr_of_csrc[i] = csrc_[i]; + for (int i = 0; i < num_csrcs_ && i < kRtpCsrcSize; i++) { + arr_of_csrc[i] = csrcs_[i]; } - return csrcs_; + return num_csrcs_; } void RTPSender::SetSequenceNumber(uint16_t seq) { diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h index b3afc2a8d3..7caa6247b3 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -130,9 +130,9 @@ class RTPSender : public Bitrate, public RTPSenderInterface { VideoCodecInformation *codec_info = NULL, const RTPVideoTypeHeader * rtp_type_hdr = NULL); - int32_t SendPadData(int8_t payload_type, - uint32_t capture_timestamp, - int64_t capture_time_ms, int32_t bytes); + int BuildPaddingPacket(uint8_t* packet, int header_length, int32_t bytes); + bool SendPadData(int8_t payload_type, uint32_t capture_timestamp, + int64_t capture_time_ms, int32_t bytes); // RTP header extension int32_t SetTransmissionTimeOffset( const int32_t transmission_time_offset); @@ -146,7 +146,7 @@ class RTPSender : public Bitrate, public RTPSenderInterface { uint16_t RtpHeaderExtensionTotalLength() const; - uint16_t BuildRTPHeaderExtension(uint8_t *data_buffer) const; + uint16_t BuildRTPHeaderExtension(uint8_t* data_buffer) const; uint8_t BuildTransmissionTimeOffsetExtension( uint8_t *data_buffer) const; @@ -260,11 +260,16 @@ class RTPSender : public Bitrate, public RTPSenderInterface { RtpVideoCodecTypes *video_type); private: + int CreateRTPHeader(uint8_t* header, int8_t payload_type, + uint32_t ssrc, bool marker_bit, + uint32_t timestamp, uint16_t sequence_number, + const uint32_t* csrcs, uint8_t csrcs_length) const; + void UpdateNACKBitRate(const uint32_t bytes, const uint32_t now); - int32_t SendPaddingAccordingToBitrate(int8_t payload_type, - uint32_t capture_timestamp, - int64_t capture_time_ms); + bool SendPaddingAccordingToBitrate(int8_t payload_type, + uint32_t capture_timestamp, + int64_t capture_time_ms); void BuildRtxPacket(uint8_t* buffer, uint16_t* length, uint8_t* buffer_rtx); @@ -314,9 +319,10 @@ class RTPSender : public Bitrate, public RTPSenderInterface { uint16_t sequence_number_rtx_; bool ssrc_forced_; uint32_t ssrc_; - uint32_t time_stamp_; - uint8_t csrcs_; - uint32_t csrc_[kRtpCsrcSize]; + uint32_t timestamp_; + int64_t capture_timestamp_; + uint8_t num_csrcs_; + uint32_t csrcs_[kRtpCsrcSize]; bool include_csrcs_; RtxMode rtx_; uint32_t ssrc_rtx_;