diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 9716f8a872..5c62c5aad5 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -52,7 +52,11 @@ RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) { } ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration) - : _rtpSender(configuration.id, configuration.audio, configuration.clock), + : _rtpSender(configuration.id, + configuration.audio, + configuration.clock, + configuration.outgoing_transport, + configuration.audio_messages), _rtpReceiver(configuration.id, configuration.audio, configuration.clock, this), _rtcpSender(configuration.id, configuration.audio, configuration.clock, @@ -97,10 +101,8 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration) _rtcpReceiver.RegisterRtcpObservers(configuration.intra_frame_callback, configuration.bandwidth_callback, configuration.rtcp_feedback); - _rtpSender.RegisterAudioCallback(configuration.audio_messages); _rtpReceiver.RegisterIncomingAudioCallback(configuration.audio_messages); - _rtpSender.RegisterSendTransport(configuration.outgoing_transport); _rtcpSender.RegisterSendTransport(configuration.outgoing_transport); // make sure that RTCP objects are aware of our SSRC @@ -628,7 +630,8 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetStartTimestamp( "SetStartTimestamp(%d)", timestamp); _rtcpSender.SetStartTimestamp(timestamp); - return _rtpSender.SetStartTimestamp(timestamp, true); + _rtpSender.SetStartTimestamp(timestamp, true); + return 0; // TODO(pwestin): change to void. } WebRtc_UWord16 ModuleRtpRtcpImpl::SequenceNumber() const { @@ -646,7 +649,8 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetSequenceNumber( "SetSequenceNumber(%d)", seqNum); - return _rtpSender.SetSequenceNumber(seqNum); + _rtpSender.SetSequenceNumber(seqNum); + return 0; // TODO(pwestin): change to void. } WebRtc_UWord32 ModuleRtpRtcpImpl::SSRC() const { @@ -659,17 +663,16 @@ WebRtc_UWord32 ModuleRtpRtcpImpl::SSRC() const { WebRtc_Word32 ModuleRtpRtcpImpl::SetSSRC(const WebRtc_UWord32 ssrc) { WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetSSRC(%d)", ssrc); - if (_rtpSender.SetSSRC(ssrc) == 0) { - _rtcpReceiver.SetSSRC(ssrc); - _rtcpSender.SetSSRC(ssrc); - return 0; - } - return -1; + _rtpSender.SetSSRC(ssrc); + _rtcpReceiver.SetSSRC(ssrc); + _rtcpSender.SetSSRC(ssrc); + return 0; // TODO(pwestin): change to void. } WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCStatus(const bool include) { _rtcpSender.SetCSRCStatus(include); - return _rtpSender.SetCSRCStatus(include); + _rtpSender.SetCSRCStatus(include); + return 0; // TODO(pwestin): change to void. } WebRtc_Word32 ModuleRtpRtcpImpl::CSRCs( @@ -702,16 +705,15 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCs( } it++; } - return 0; - } else { for (int i = 0; i < arrLength; i++) { WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "\tidx:%d CSRC:%u", i, arrOfCSRC[i]); } _rtcpSender.SetCSRCs(arrOfCSRC, arrLength); - return _rtpSender.SetCSRCs(arrOfCSRC, arrLength); + _rtpSender.SetCSRCs(arrOfCSRC, arrLength); } + return 0; // TODO(pwestin): change to void. } WebRtc_UWord32 ModuleRtpRtcpImpl::PacketCountSent() const { @@ -1129,7 +1131,8 @@ WebRtc_Word32 ModuleRtpRtcpImpl::ResetSendDataCountersRTP() { WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ResetSendDataCountersRTP()"); - return _rtpSender.ResetDataCounters(); + _rtpSender.ResetDataCounters(); + return 0; // TODO(pwestin): change to void. } // Force a send of an RTCP packet @@ -1495,7 +1498,8 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetStorePacketsStatus( WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetStorePacketsStatus(disable)"); } - return _rtpSender.SetStorePacketsStatus(enable, numberToStore); + _rtpSender.SetStorePacketsStatus(enable, numberToStore); + return 0; // TODO(pwestin): change to void. } /* diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index 259f0bebe0..76073ab101 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -22,89 +22,80 @@ namespace webrtc { RTPSender::RTPSender(const WebRtc_Word32 id, const bool audio, - RtpRtcpClock* clock) : - Bitrate(clock), - _id(id), - _audioConfigured(audio), - _audio(NULL), - _video(NULL), - _sendCritsect(CriticalSectionWrapper::CreateCriticalSection()), - _transportCritsect(CriticalSectionWrapper::CreateCriticalSection()), + RtpRtcpClock* clock, + Transport* transport, + RtpAudioFeedback* audio_feedback) + : Bitrate(clock), + _id(id), + _audioConfigured(audio), + _audio(NULL), + _video(NULL), + _sendCritsect(CriticalSectionWrapper::CreateCriticalSection()), + _transport(transport), + _sendingMedia(true), // Default to sending media - _transport(NULL), + _maxPayloadLength(IP_PACKET_SIZE-28), // default is IP-v4/UDP + _targetSendBitrate(0), + _packetOverHead(28), - _sendingMedia(true), // Default to sending media + _payloadType(-1), + _payloadTypeMap(), - _maxPayloadLength(IP_PACKET_SIZE-28), // default is IP/UDP - _targetSendBitrate(0), - _packetOverHead(28), + _rtpHeaderExtensionMap(), + _transmissionTimeOffset(0), - _payloadType(-1), - _payloadTypeMap(), + _nackByteCountTimes(), + _nackByteCount(), + _nackBitrate(clock), - _rtpHeaderExtensionMap(), - _transmissionTimeOffset(0), + _packetHistory(new RTPPacketHistory(clock)), + _sendBucket(clock), + _timeLastSendToNetworkUpdate(clock->GetTimeInMS()), + _transmissionSmoothing(false), - // NACK - _nackByteCountTimes(), - _nackByteCount(), - _nackBitrate(clock), + _packetsSent(0), + _payloadBytesSent(0), - _packetHistory(new RTPPacketHistory(clock)), - _sendBucket(clock), - _timeLastSendToNetworkUpdate(clock->GetTimeInMS()), - _transmissionSmoothing(false), + _startTimeStampForced(false), + _startTimeStamp(0), + _ssrcDB(*SSRCDatabase::GetSSRCDatabase()), + _remoteSSRC(0), + _sequenceNumberForced(false), + _sequenceNumber(0), + _sequenceNumberRTX(0), + _ssrcForced(false), + _ssrc(0), + _timeStamp(0), + _CSRCs(0), + _CSRC(), + _includeCSRCs(true), + _RTX(false), + _ssrcRTX(0) { + memset(_nackByteCountTimes, 0, sizeof(_nackByteCountTimes)); + memset(_nackByteCount, 0, sizeof(_nackByteCount)); + memset(_CSRC, 0, sizeof(_CSRC)); - // statistics - _packetsSent(0), - _payloadBytesSent(0), + // We need to seed the random generator. + srand( (WebRtc_UWord32)_clock.GetTimeInMS() ); + _ssrc = _ssrcDB.CreateSSRC(); // Can't be 0. - // RTP variables - _startTimeStampForced(false), - _startTimeStamp(0), - _ssrcDB(*SSRCDatabase::GetSSRCDatabase()), - _remoteSSRC(0), - _sequenceNumberForced(false), - _sequenceNumber(0), - _sequenceNumberRTX(0), - _ssrcForced(false), - _ssrc(0), - _timeStamp(0), - _CSRCs(0), - _CSRC(), - _includeCSRCs(true), - _RTX(false), - _ssrcRTX(0) -{ - memset(_nackByteCountTimes, 0, sizeof(_nackByteCountTimes)); - memset(_nackByteCount, 0, sizeof(_nackByteCount)); - - memset(_CSRC, 0, sizeof(_CSRC)); - - // we need to seed the random generator, otherwise we get 26500 each time, hardly a random value :) - srand( (WebRtc_UWord32)_clock.GetTimeInMS() ); - - _ssrc = _ssrcDB.CreateSSRC(); // can't be 0 - - if(audio) - { - _audio = new RTPSenderAudio(id, &_clock, this); - } else - { - _video = new RTPSenderVideo(id, &_clock, this); - } - WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); + if (audio) { + _audio = new RTPSenderAudio(id, &_clock, this); + _audio->RegisterAudioCallback(audio_feedback); + } else { + _video = new RTPSenderVideo(id, &_clock, this); + } + WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); } RTPSender::~RTPSender() { - if(_remoteSSRC != 0) { + if (_remoteSSRC != 0) { _ssrcDB.ReturnSSRC(_remoteSSRC); } _ssrcDB.ReturnSSRC(_ssrc); SSRCDatabase::ReturnSSRCDatabase(); delete _sendCritsect; - delete _transportCritsect; while (!_payloadTypeMap.empty()) { std::map::iterator it = _payloadTypeMap.begin(); @@ -117,132 +108,61 @@ RTPSender::~RTPSender() { WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__); } -/* -WebRtc_Word32 -RTPSender::Init(const WebRtc_UWord32 remoteSSRC) -{ - CriticalSectionScoped cs(_sendCritsect); - - // reset to default generation - _ssrcForced = false; - _startTimeStampForced = false; - - // register a remote SSRC if we have it to avoid collisions - if(remoteSSRC != 0) - { - if(_ssrc == remoteSSRC) - { - // collision detected - _ssrc = _ssrcDB.CreateSSRC(); // can't be 0 - } - _remoteSSRC = remoteSSRC; - _ssrcDB.RegisterSSRC(remoteSSRC); - } - _sequenceNumber = rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); - _sequenceNumberRTX = rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); - _packetsSent = 0; - _payloadBytesSent = 0; - _packetOverHead = 28; - - _rtpHeaderExtensionMap.Erase(); - - while (!_payloadTypeMap.empty()) { - std::map::iterator it = - _payloadTypeMap.begin(); - delete it->second; - _payloadTypeMap.erase(it); - } - - memset(_CSRC, 0, sizeof(_CSRC)); - - memset(_nackByteCount, 0, sizeof(_nackByteCount)); - memset(_nackByteCountTimes, 0, sizeof(_nackByteCountTimes)); - _nackBitrate.Init(); - - SetStorePacketsStatus(false, 0); - _sendBucket.Reset(); - - Bitrate::Init(); - - if(_audioConfigured) - { - _audio->Init(); - } else - { - _video->Init(); - } - return(0); -} -*/ void RTPSender::SetTargetSendBitrate(const WebRtc_UWord32 bits) { _targetSendBitrate = static_cast(bits / 1000); } -WebRtc_UWord16 -RTPSender::ActualSendBitrateKbit() const -{ - return (WebRtc_UWord16) (Bitrate::BitrateNow()/1000); +WebRtc_UWord16 RTPSender::ActualSendBitrateKbit() const { + return (WebRtc_UWord16) (Bitrate::BitrateNow() / 1000); } -WebRtc_UWord32 -RTPSender::VideoBitrateSent() const { - if (_video) +WebRtc_UWord32 RTPSender::VideoBitrateSent() const { + if (_video) { return _video->VideoBitrateSent(); - else - return 0; + } + return 0; } -WebRtc_UWord32 -RTPSender::FecOverheadRate() const { - if (_video) +WebRtc_UWord32 RTPSender::FecOverheadRate() const { + if (_video) { return _video->FecOverheadRate(); - else - return 0; + } + return 0; } -WebRtc_UWord32 -RTPSender::NackOverheadRate() const { +WebRtc_UWord32 RTPSender::NackOverheadRate() const { return _nackBitrate.BitrateLast(); } -WebRtc_Word32 -RTPSender::SetTransmissionTimeOffset( - const WebRtc_Word32 transmissionTimeOffset) -{ - if (transmissionTimeOffset > (0x800000 - 1) || - transmissionTimeOffset < -(0x800000 - 1)) // Word24 - { - return -1; - } - CriticalSectionScoped cs(_sendCritsect); - _transmissionTimeOffset = transmissionTimeOffset; - return 0; +WebRtc_Word32 RTPSender::SetTransmissionTimeOffset( + const WebRtc_Word32 transmissionTimeOffset) { + if (transmissionTimeOffset > (0x800000 - 1) || + transmissionTimeOffset < -(0x800000 - 1)) { // Word24 + return -1; + } + CriticalSectionScoped cs(_sendCritsect); + _transmissionTimeOffset = transmissionTimeOffset; + return 0; } -WebRtc_Word32 -RTPSender::RegisterRtpHeaderExtension(const RTPExtensionType type, - const WebRtc_UWord8 id) -{ - CriticalSectionScoped cs(_sendCritsect); - return _rtpHeaderExtensionMap.Register(type, id); +WebRtc_Word32 RTPSender::RegisterRtpHeaderExtension(const RTPExtensionType type, + const WebRtc_UWord8 id) { + CriticalSectionScoped cs(_sendCritsect); + return _rtpHeaderExtensionMap.Register(type, id); } -WebRtc_Word32 -RTPSender::DeregisterRtpHeaderExtension(const RTPExtensionType type) -{ - CriticalSectionScoped cs(_sendCritsect); - return _rtpHeaderExtensionMap.Deregister(type); +WebRtc_Word32 RTPSender::DeregisterRtpHeaderExtension( + const RTPExtensionType type) { + CriticalSectionScoped cs(_sendCritsect); + return _rtpHeaderExtensionMap.Deregister(type); } -WebRtc_UWord16 -RTPSender::RtpHeaderExtensionTotalLength() const -{ - CriticalSectionScoped cs(_sendCritsect); - return _rtpHeaderExtensionMap.GetTotalLengthInBytes(); +WebRtc_UWord16 RTPSender::RtpHeaderExtensionTotalLength() const { + CriticalSectionScoped cs(_sendCritsect); + return _rtpHeaderExtensionMap.GetTotalLengthInBytes(); } -//can be called multiple times WebRtc_Word32 RTPSender::RegisterPayload( const char payloadName[RTP_PAYLOAD_NAME_SIZE], const WebRtc_Word8 payloadNumber, @@ -271,7 +191,7 @@ WebRtc_Word32 RTPSender::RegisterPayload( // Ensure that we update the rate if new or old is zero return 0; } - if(!_audioConfigured && !payload->audio) { + if (!_audioConfigured && !payload->audio) { return 0; } } @@ -286,7 +206,7 @@ WebRtc_Word32 RTPSender::RegisterPayload( retVal = _video->RegisterVideoPayload(payloadName, payloadNumber, rate, payload); } - if(payload) { + if (payload) { _payloadTypeMap[payloadNumber] = payload; } return retVal; @@ -298,46 +218,43 @@ WebRtc_Word32 RTPSender::DeRegisterSendPayload(const WebRtc_Word8 payloadType) { std::map::iterator it = _payloadTypeMap.find(payloadType); - if (_payloadTypeMap.end() == it) return -1; - + if (_payloadTypeMap.end() == it) { + return -1; + } ModuleRTPUtility::Payload* payload = it->second; delete payload; _payloadTypeMap.erase(it); return 0; } -WebRtc_Word8 RTPSender::SendPayloadType() const -{ - return _payloadType; +WebRtc_Word8 RTPSender::SendPayloadType() const { + return _payloadType; } - -int RTPSender::SendPayloadFrequency() const -{ - return _audio->AudioFrequency(); +int RTPSender::SendPayloadFrequency() const { + return _audio->AudioFrequency(); } +WebRtc_Word32 RTPSender::SetMaxPayloadLength( + const WebRtc_UWord16 maxPayloadLength, + const WebRtc_UWord16 packetOverHead) { + // sanity check + if (maxPayloadLength < 100 || maxPayloadLength > IP_PACKET_SIZE) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "%s invalid argument", __FUNCTION__); + return -1; + } + CriticalSectionScoped cs(_sendCritsect); + _maxPayloadLength = maxPayloadLength; + _packetOverHead = packetOverHead; -WebRtc_Word32 -RTPSender::SetMaxPayloadLength(const WebRtc_UWord16 maxPayloadLength, const WebRtc_UWord16 packetOverHead) -{ - // sanity check - if(maxPayloadLength < 100 || maxPayloadLength > IP_PACKET_SIZE) - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); - return -1; - } - - CriticalSectionScoped cs(_sendCritsect); - _maxPayloadLength = maxPayloadLength; - _packetOverHead = packetOverHead; - - WEBRTC_TRACE(kTraceInfo, kTraceRtpRtcp, _id, "SetMaxPayloadLength to %d.", maxPayloadLength); - return 0; + WEBRTC_TRACE(kTraceInfo, kTraceRtpRtcp, _id, + "SetMaxPayloadLength to %d.", maxPayloadLength); + return 0; } WebRtc_UWord16 RTPSender::MaxDataPayloadLength() const { - if(_audioConfigured) { + if (_audioConfigured) { return _maxPayloadLength - RTPHeaderLength(); } else { return _maxPayloadLength - RTPHeaderLength() - @@ -346,16 +263,12 @@ WebRtc_UWord16 RTPSender::MaxDataPayloadLength() const { } } -WebRtc_UWord16 -RTPSender::MaxPayloadLength() const -{ - return _maxPayloadLength; +WebRtc_UWord16 RTPSender::MaxPayloadLength() const { + return _maxPayloadLength; } -WebRtc_UWord16 -RTPSender::PacketOverHead() const -{ - return _packetOverHead; +WebRtc_UWord16 RTPSender::PacketOverHead() const { + return _packetOverHead; } void RTPSender::SetTransmissionSmoothingStatus(const bool enable) { @@ -382,8 +295,7 @@ void RTPSender::SetRTXStatus(const bool enable, } } -void RTPSender::RTXStatus(bool* enable, - WebRtc_UWord32* SSRC) const { +void RTPSender::RTXStatus(bool* enable, WebRtc_UWord32* SSRC) const { CriticalSectionScoped cs(_sendCritsect); *enable = _RTX; *SSRC = _ssrcRTX; @@ -402,7 +314,7 @@ WebRtc_Word32 RTPSender::CheckPayloadType(const WebRtc_Word8 payloadType, WebRtc_Word8 redPlType = -1; if (_audio->RED(redPlType) == 0) { // We have configured RED. - if(redPlType == payloadType) { + if (redPlType == payloadType) { // And it's a match... return 0; } @@ -427,67 +339,62 @@ WebRtc_Word32 RTPSender::CheckPayloadType(const WebRtc_Word8 payloadType, if (!payload->audio && !_audioConfigured) { _video->SetVideoCodecType(payload->typeSpecific.Video.videoCodecType); videoType = payload->typeSpecific.Video.videoCodecType; - _video->SetMaxConfiguredBitrateVideo( - payload->typeSpecific.Video.maxRate); + _video->SetMaxConfiguredBitrateVideo(payload->typeSpecific.Video.maxRate); } return 0; } -WebRtc_Word32 -RTPSender::SendOutgoingData(const FrameType frame_type, - const WebRtc_Word8 payload_type, - const WebRtc_UWord32 capture_timestamp, - int64_t capture_time_ms, - const WebRtc_UWord8* payload_data, - const WebRtc_UWord32 payload_size, - const RTPFragmentationHeader* fragmentation, - VideoCodecInformation* codec_info, - const RTPVideoTypeHeader* rtp_type_hdr) -{ - { - // Drop this packet if we're not sending media packets. - CriticalSectionScoped cs(_sendCritsect); - if (!_sendingMedia) - { - return 0; - } +WebRtc_Word32 RTPSender::SendOutgoingData( + const FrameType frame_type, + const WebRtc_Word8 payload_type, + const WebRtc_UWord32 capture_timestamp, + int64_t capture_time_ms, + const WebRtc_UWord8* payload_data, + const WebRtc_UWord32 payload_size, + const RTPFragmentationHeader* fragmentation, + VideoCodecInformation* codec_info, + const RTPVideoTypeHeader* rtp_type_hdr) { + { + // Drop this packet if we're not sending media packets. + CriticalSectionScoped cs(_sendCritsect); + if (!_sendingMedia) { + return 0; } - RtpVideoCodecTypes video_type = kRtpNoVideo; - if (CheckPayloadType(payload_type, video_type) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, - "%s invalid argument failed to find payloadType:%d", - __FUNCTION__, payload_type); - return -1; - } - - if (_audioConfigured) - { - assert(frame_type == kAudioFrameSpeech || - frame_type == kAudioFrameCN || - frame_type == kFrameEmpty); - - return _audio->SendAudio(frame_type, payload_type, capture_timestamp, - payload_data, payload_size,fragmentation); - } else { - assert(frame_type != kAudioFrameSpeech && - frame_type != kAudioFrameCN); - - if (frame_type == kFrameEmpty) { - return SendPaddingAccordingToBitrate(payload_type, capture_timestamp, - capture_time_ms); - } - return _video->SendVideo(video_type, - frame_type, - payload_type, - capture_timestamp, - capture_time_ms, - payload_data, - payload_size, - fragmentation, - codec_info, - rtp_type_hdr); + } + RtpVideoCodecTypes video_type = kRtpNoVideo; + if (CheckPayloadType(payload_type, video_type) != 0) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "%s invalid argument failed to find payloadType:%d", + __FUNCTION__, payload_type); + return -1; + } + + if (_audioConfigured) { + assert(frame_type == kAudioFrameSpeech || + frame_type == kAudioFrameCN || + frame_type == kFrameEmpty); + + return _audio->SendAudio(frame_type, payload_type, capture_timestamp, + payload_data, payload_size,fragmentation); + } else { + assert(frame_type != kAudioFrameSpeech && + frame_type != kAudioFrameCN); + + if (frame_type == kFrameEmpty) { + return SendPaddingAccordingToBitrate(payload_type, capture_timestamp, + capture_time_ms); } + return _video->SendVideo(video_type, + frame_type, + payload_type, + capture_timestamp, + capture_time_ms, + payload_data, + payload_size, + fragmentation, + codec_info, + rtp_type_hdr); + } } WebRtc_Word32 RTPSender::SendPaddingAccordingToBitrate( @@ -498,23 +405,22 @@ WebRtc_Word32 RTPSender::SendPaddingAccordingToBitrate( // estimate since then, to get the most up to date bitrate. uint32_t current_bitrate = BitrateNow(); int bitrate_diff = _targetSendBitrate * 1000 - current_bitrate; - if (bitrate_diff > 0) { - int bytes = 0; - if (current_bitrate == 0) { - // Start up phase. Send one 33.3 ms batch to start with. - bytes = (bitrate_diff / 8) / 30; - } else { - bytes = (bitrate_diff / 8); - // Cap at 200 ms of target send data. - int bytes_cap = _targetSendBitrate * 25; // 1000 / 8 / 5 - if (bytes > bytes_cap) { - bytes = bytes_cap; - } - } - // Send padding data. - return SendPadData(payload_type, capture_timestamp, capture_time_ms, bytes); + if (bitrate_diff <= 0) { + return 0; } - return 0; + int bytes = 0; + if (current_bitrate == 0) { + // Start up phase. Send one 33.3 ms batch to start with. + bytes = (bitrate_diff / 8) / 30; + } else { + bytes = (bitrate_diff / 8); + // Cap at 200 ms of target send data. + int bytes_cap = _targetSendBitrate * 25; // 1000 / 8 / 5 + if (bytes > bytes_cap) { + bytes = bytes_cap; + } + } + return SendPadData(payload_type, capture_timestamp, capture_time_ms, bytes); } WebRtc_Word32 RTPSender::SendPadData(WebRtc_Word8 payload_type, @@ -538,23 +444,19 @@ WebRtc_Word32 RTPSender::SendPadData(WebRtc_Word8 payload_type, // Sanity don't send empty packets. break; } - - WebRtc_Word32 header_length; - { - // Correct seq num, timestamp and payload type. - header_length = BuildRTPheader(data_buffer, - payload_type, - false, // No markerbit. - capture_timestamp, - true, // Timestamp provided. - true); // Increment sequence number. - } + // 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. WebRtc_Word32* data = reinterpret_cast(&(data_buffer[header_length])); // Fill data buffer with random data. - for(int j = 0; j < (padding_bytes_in_packet >> 2); j++) { + for (int j = 0; j < (padding_bytes_in_packet >> 2); j++) { data[j] = rand(); } // Set number of padding bytes in the last byte of the packet. @@ -577,11 +479,10 @@ WebRtc_Word32 RTPSender::SendPadData(WebRtc_Word8 payload_type, return 0; } -WebRtc_Word32 RTPSender::SetStorePacketsStatus( +void RTPSender::SetStorePacketsStatus( const bool enable, const WebRtc_UWord16 numberToStore) { _packetHistory->SetStorePacketsStatus(enable, numberToStore); - return 0; } bool RTPSender::StorePackets() const { @@ -603,13 +504,11 @@ WebRtc_Word32 RTPSender::ReSendPacket(WebRtc_UWord16 packet_id, // Packet not found. return 0; } - if (length == 0 || type == kDontRetransmit) { // No bytes copied (packet recently resent, skip resending) or // packet should not be retransmitted. return 0; } - WebRtc_UWord8 data_buffer_rtx[IP_PACKET_SIZE]; if (_RTX) { buffer_to_send_ptr = data_buffer_rtx; @@ -646,34 +545,26 @@ WebRtc_Word32 RTPSender::ReSendPacket(WebRtc_UWord16 packet_id, length - rtp_header.header.headerLength); length += 2; } - WebRtc_Word32 bytes_sent = ReSendToNetwork(buffer_to_send_ptr, length); if (bytes_sent <= 0) { WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "Transport failed to resend packet_id %u", packet_id); return -1; } - // Store the time when the packet was last resent. _packetHistory->UpdateResendTime(packet_id); - return bytes_sent; } WebRtc_Word32 RTPSender::ReSendToNetwork(const WebRtc_UWord8* packet, const WebRtc_UWord32 size) { WebRtc_Word32 bytes_sent = -1; - { - CriticalSectionScoped lock(_transportCritsect); - if (_transport) { - bytes_sent = _transport->SendPacket(_id, packet, size); - } + if (_transport) { + bytes_sent = _transport->SendPacket(_id, packet, size); } - if (bytes_sent <= 0) { return -1; } - // Update send statistics CriticalSectionScoped cs(_sendCritsect); Bitrate::Update(bytes_sent); @@ -693,12 +584,11 @@ int RTPSender::SetSelectiveRetransmissions(uint8_t settings) { return _video->SetSelectiveRetransmissions(settings); } -void -RTPSender::OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength, - const WebRtc_UWord16* nackSequenceNumbers, - const WebRtc_UWord16 avgRTT) { - const WebRtc_Word64 now = _clock.GetTimeInMS(); - WebRtc_UWord32 bytesReSent = 0; +void RTPSender::OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength, + const WebRtc_UWord16* nackSequenceNumbers, + const WebRtc_UWord16 avgRTT) { + const WebRtc_Word64 now = _clock.GetTimeInMS(); + WebRtc_UWord32 bytesReSent = 0; // Enough bandwidth to send NACK? if (!ProcessNACKBitRate(now)) { @@ -745,9 +635,6 @@ RTPSender::OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength, } } -/** -* @return true if the nack bitrate is lower than the requested max bitrate -*/ bool RTPSender::ProcessNACKBitRate(const WebRtc_UWord32 now) { WebRtc_UWord32 num = 0; WebRtc_Word32 byteCount = 0; @@ -771,7 +658,7 @@ bool RTPSender::ProcessNACKBitRate(const WebRtc_UWord32 now) { // More than NACK_BYTECOUNT_SIZE nack messages has been received // during the last msgInterval timeInterval = now - _nackByteCountTimes[num-1]; - if(timeInterval < 0) { + if (timeInterval < 0) { timeInterval = avgInterval; } } @@ -783,16 +670,16 @@ void RTPSender::UpdateNACKBitRate(const WebRtc_UWord32 bytes, CriticalSectionScoped cs(_sendCritsect); // save bitrate statistics - if(bytes > 0) { - if(now == 0) { + if (bytes > 0) { + if (now == 0) { // add padding length _nackByteCount[0] += bytes; } else { - if(_nackByteCountTimes[0] == 0) { + if (_nackByteCountTimes[0] == 0) { // first no shift } else { // shift - for(int i = (NACK_BYTECOUNT_SIZE-2); i >= 0 ; i--) { + for (int i = (NACK_BYTECOUNT_SIZE-2); i >= 0 ; i--) { _nackByteCount[i+1] = _nackByteCount[i]; _nackByteCountTimes[i+1] = _nackByteCountTimes[i]; } @@ -803,7 +690,6 @@ void RTPSender::UpdateNACKBitRate(const WebRtc_UWord32 bytes, } } -// Function triggered by timer. void RTPSender::ProcessSendToNetwork() { WebRtc_Word64 delta_time_ms; { @@ -819,7 +705,6 @@ void RTPSender::ProcessSendToNetwork() { _sendBucket.UpdateBytesPerInterval(delta_time_ms, _targetSendBitrate); while (!_sendBucket.Empty()) { - WebRtc_Word32 seq_num = _sendBucket.GetNextPacket(); if (seq_num < 0) { break; @@ -853,11 +738,8 @@ void RTPSender::ProcessSendToNetwork() { // Send packet WebRtc_Word32 bytes_sent = -1; - { - CriticalSectionScoped cs(_transportCritsect); - if (_transport) { - bytes_sent = _transport->SendPacket(_id, data_buffer, length); - } + if (_transport) { + bytes_sent = _transport->SendPacket(_id, data_buffer, length); } // Update send statistics @@ -872,19 +754,16 @@ void RTPSender::ProcessSendToNetwork() { } } -WebRtc_Word32 -RTPSender::SendToNetwork(WebRtc_UWord8* buffer, - const WebRtc_UWord16 payload_length, - const WebRtc_UWord16 rtp_header_length, - int64_t capture_time_ms, - const StorageType storage) -{ +WebRtc_Word32 RTPSender::SendToNetwork(WebRtc_UWord8* buffer, + WebRtc_UWord16 payload_length, + WebRtc_UWord16 rtp_header_length, + int64_t capture_time_ms, + StorageType storage) { // Used for NACK or to spead out the transmission of packets. if (_packetHistory->PutRTPPacket(buffer, rtp_header_length + payload_length, _maxPayloadLength, capture_time_ms, storage) != 0) { return -1; } - if (_transmissionSmoothing) { const WebRtc_UWord16 sequenceNumber = (buffer[2] << 8) + buffer[3]; const WebRtc_UWord32 timestamp = (buffer[4] << 24) + (buffer[5] << 16) + @@ -894,7 +773,6 @@ RTPSender::SendToNetwork(WebRtc_UWord8* buffer, // Packet will be sent at a later time. return 0; } - // |capture_time_ms| <= 0 is considered invalid. // TODO(holmer): This should be changed all over Video Engine so that negative // time is consider invalid, while 0 is considered a valid time. @@ -911,21 +789,15 @@ RTPSender::SendToNetwork(WebRtc_UWord8* buffer, rtp_header.header.headerLength); } } - // Send packet WebRtc_Word32 bytes_sent = -1; - { - CriticalSectionScoped cs(_transportCritsect); - if (_transport) { - bytes_sent = _transport->SendPacket(_id, buffer, + if (_transport) { + bytes_sent = _transport->SendPacket(_id, buffer, payload_length + rtp_header_length); - } } - if (bytes_sent <= 0) { return -1; } - // Update send statistics CriticalSectionScoped cs(_sendCritsect); Bitrate::Update(bytes_sent); @@ -936,143 +808,106 @@ RTPSender::SendToNetwork(WebRtc_UWord8* buffer, return 0; } -void -RTPSender::ProcessBitrate() -{ - CriticalSectionScoped cs(_sendCritsect); - - Bitrate::Process(); - _nackBitrate.Process(); - - if (_audioConfigured) - return; - _video->ProcessBitrate(); +void RTPSender::ProcessBitrate() { + CriticalSectionScoped cs(_sendCritsect); + Bitrate::Process(); + _nackBitrate.Process(); + if (_audioConfigured) { + return; + } + _video->ProcessBitrate(); } -WebRtc_UWord16 -RTPSender::RTPHeaderLength() const -{ - WebRtc_UWord16 rtpHeaderLength = 12; - - if(_includeCSRCs) - { - rtpHeaderLength += sizeof(WebRtc_UWord32)*_CSRCs; - } - rtpHeaderLength += RtpHeaderExtensionTotalLength(); - - return rtpHeaderLength; +WebRtc_UWord16 RTPSender::RTPHeaderLength() const { + WebRtc_UWord16 rtpHeaderLength = 12; + if (_includeCSRCs) { + rtpHeaderLength += sizeof(WebRtc_UWord32)*_CSRCs; + } + rtpHeaderLength += RtpHeaderExtensionTotalLength(); + return rtpHeaderLength; } -WebRtc_UWord16 -RTPSender::IncrementSequenceNumber() -{ - CriticalSectionScoped cs(_sendCritsect); - return _sequenceNumber++; +WebRtc_UWord16 RTPSender::IncrementSequenceNumber() { + CriticalSectionScoped cs(_sendCritsect); + return _sequenceNumber++; } -WebRtc_Word32 -RTPSender::ResetDataCounters() -{ - _packetsSent = 0; - _payloadBytesSent = 0; - - return 0; +void RTPSender::ResetDataCounters() { + _packetsSent = 0; + _payloadBytesSent = 0; } -// number of sent RTP packets -// dont use critsect to avoid potental deadlock -WebRtc_UWord32 -RTPSender::Packets() const -{ - return _packetsSent; +WebRtc_UWord32 RTPSender::Packets() const { + // Don't use critsect to avoid potental deadlock + return _packetsSent; } // number of sent RTP bytes // dont use critsect to avoid potental deadlock -WebRtc_UWord32 -RTPSender::Bytes() const -{ - return _payloadBytesSent; +WebRtc_UWord32 RTPSender::Bytes() const { + return _payloadBytesSent; } -WebRtc_Word32 -RTPSender::BuildRTPheader(WebRtc_UWord8* dataBuffer, - const WebRtc_Word8 payloadType, - const bool markerBit, - const WebRtc_UWord32 captureTimeStamp, - const bool timeStampProvided, - const bool incSequenceNumber) -{ - assert(payloadType>=0); +WebRtc_Word32 RTPSender::BuildRTPheader(WebRtc_UWord8* dataBuffer, + const WebRtc_Word8 payloadType, + const bool markerBit, + const WebRtc_UWord32 captureTimeStamp, + const bool timeStampProvided, + const bool incSequenceNumber) { + assert(payloadType>=0); + CriticalSectionScoped cs(_sendCritsect); - CriticalSectionScoped cs(_sendCritsect); + dataBuffer[0] = static_cast(0x80); // version 2 + dataBuffer[1] = static_cast(payloadType); + if (markerBit) { + dataBuffer[1] |= kRtpMarkerBitMask; // MarkerBit is set + } + if (timeStampProvided) { + _timeStamp = _startTimeStamp + captureTimeStamp; + } else { + // make a unique time stamp + // we can't inc by the actual time, since then we increase the risk of back + // timing. + _timeStamp++; + } + ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer+2, _sequenceNumber); + ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer+4, _timeStamp); + ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer+8, _ssrc); + WebRtc_Word32 rtpHeaderLength = 12; - dataBuffer[0] = static_cast(0x80); // version 2 - dataBuffer[1] = static_cast(payloadType); - if (markerBit) - { - dataBuffer[1] |= kRtpMarkerBitMask; // MarkerBit is set + // Add the CSRCs if any + if (_includeCSRCs && _CSRCs > 0) { + if (_CSRCs > kRtpCsrcSize) { + // error + assert(false); + return -1; } - - if(timeStampProvided) - { - _timeStamp = _startTimeStamp + captureTimeStamp; - } else - { - // make a unique time stamp - // used for inband signaling - // we can't inc by the actual time, since then we increase the risk of back timing - _timeStamp++; + WebRtc_UWord8* ptr = &dataBuffer[rtpHeaderLength]; + for (WebRtc_UWord32 i = 0; i < _CSRCs; ++i) { + ModuleRTPUtility::AssignUWord32ToBuffer(ptr, _CSRC[i]); + ptr +=4; } + dataBuffer[0] = (dataBuffer[0]&0xf0) | _CSRCs; - ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer+2, _sequenceNumber); - ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer+4, _timeStamp); - ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer+8, _ssrc); + // Update length of header + rtpHeaderLength += sizeof(WebRtc_UWord32)*_CSRCs; + } + _sequenceNumber++; // prepare for next packet - WebRtc_Word32 rtpHeaderLength = 12; - - // Add the CSRCs if any - if (_includeCSRCs && _CSRCs > 0) - { - if(_CSRCs > kRtpCsrcSize) - { - // error - assert(false); - return -1; - } - WebRtc_UWord8* ptr = &dataBuffer[rtpHeaderLength]; - for (WebRtc_UWord32 i = 0; i < _CSRCs; ++i) - { - ModuleRTPUtility::AssignUWord32ToBuffer(ptr, _CSRC[i]); - ptr +=4; - } - dataBuffer[0] = (dataBuffer[0]&0xf0) | _CSRCs; - - // Update length of header - rtpHeaderLength += sizeof(WebRtc_UWord32)*_CSRCs; - } - { - _sequenceNumber++; // prepare for next packet - } - - WebRtc_UWord16 len = BuildRTPHeaderExtension(dataBuffer + rtpHeaderLength); - if (len) - { - dataBuffer[0] |= 0x10; // set eXtension bit - rtpHeaderLength += len; - } - - return rtpHeaderLength; + WebRtc_UWord16 len = BuildRTPHeaderExtension(dataBuffer + rtpHeaderLength); + if (len) { + dataBuffer[0] |= 0x10; // set eXtension bit + rtpHeaderLength += len; + } + return rtpHeaderLength; } -WebRtc_UWord16 -RTPSender::BuildRTPHeaderExtension(WebRtc_UWord8* dataBuffer) const -{ - if (_rtpHeaderExtensionMap.Size() <= 0) { - return 0; - } - - /* RTP header extension, RFC 3550. +WebRtc_UWord16 RTPSender::BuildRTPHeaderExtension( + WebRtc_UWord8* dataBuffer) const { + if (_rtpHeaderExtensionMap.Size() <= 0) { + return 0; + } + /* RTP header extension, RFC 3550. 0 1 2 3 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -1080,82 +915,73 @@ RTPSender::BuildRTPHeaderExtension(WebRtc_UWord8* dataBuffer) const +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | header extension | | .... | - */ + */ + const WebRtc_UWord32 kPosLength = 2; + const WebRtc_UWord32 kHeaderLength = RTP_ONE_BYTE_HEADER_LENGTH_IN_BYTES; - const WebRtc_UWord32 kPosLength = 2; - const WebRtc_UWord32 kHeaderLength = RTP_ONE_BYTE_HEADER_LENGTH_IN_BYTES; + // Add extension ID (0xBEDE). + ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer, + RTP_ONE_BYTE_HEADER_EXTENSION); - // Add extension ID (0xBEDE). - ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer, - RTP_ONE_BYTE_HEADER_EXTENSION); + // Add extensions. + WebRtc_UWord16 total_block_length = 0; - // Add extensions. - WebRtc_UWord16 total_block_length = 0; - - RTPExtensionType type = _rtpHeaderExtensionMap.First(); - while (type != kRtpExtensionNone) - { - WebRtc_UWord8 block_length = 0; - if (type == kRtpExtensionTransmissionTimeOffset) - { - block_length = BuildTransmissionTimeOffsetExtension( - dataBuffer + kHeaderLength + total_block_length); - } - total_block_length += block_length; - type = _rtpHeaderExtensionMap.Next(type); + RTPExtensionType type = _rtpHeaderExtensionMap.First(); + while (type != kRtpExtensionNone) { + WebRtc_UWord8 block_length = 0; + if (type == kRtpExtensionTransmissionTimeOffset) { + block_length = BuildTransmissionTimeOffsetExtension( + dataBuffer + kHeaderLength + total_block_length); } - - if (total_block_length == 0) - { - // No extension added. - return 0; - } - - // Set header length (in number of Word32, header excluded). - assert(total_block_length % 4 == 0); - ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer + kPosLength, - total_block_length / 4); - - // Total added length. - return kHeaderLength + total_block_length; + total_block_length += block_length; + type = _rtpHeaderExtensionMap.Next(type); + } + if (total_block_length == 0) { + // No extension added. + return 0; + } + // Set header length (in number of Word32, header excluded). + assert(total_block_length % 4 == 0); + ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer + kPosLength, + total_block_length / 4); + // Total added length. + return kHeaderLength + total_block_length; } -WebRtc_UWord8 -RTPSender::BuildTransmissionTimeOffsetExtension(WebRtc_UWord8* dataBuffer) const -{ - // From RFC 5450: Transmission Time Offsets in RTP Streams. - // - // The transmission time is signaled to the receiver in-band using the - // general mechanism for RTP header extensions [RFC5285]. The payload - // of this extension (the transmitted value) is a 24-bit signed integer. - // When added to the RTP timestamp of the packet, it represents the - // "effective" RTP transmission time of the packet, on the RTP - // timescale. - // - // The form of the transmission offset extension block: - // - // 0 1 2 3 - // 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 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | ID | len=2 | transmission offset | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +WebRtc_UWord8 RTPSender::BuildTransmissionTimeOffsetExtension( + WebRtc_UWord8* dataBuffer) const { + // From RFC 5450: Transmission Time Offsets in RTP Streams. + // + // The transmission time is signaled to the receiver in-band using the + // general mechanism for RTP header extensions [RFC5285]. The payload + // of this extension (the transmitted value) is a 24-bit signed integer. + // When added to the RTP timestamp of the packet, it represents the + // "effective" RTP transmission time of the packet, on the RTP + // timescale. + // + // The form of the transmission offset extension block: + // + // 0 1 2 3 + // 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 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ID | len=2 | transmission offset | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // Get id defined by user. - WebRtc_UWord8 id; - if (_rtpHeaderExtensionMap.GetId(kRtpExtensionTransmissionTimeOffset, &id) - != 0) { - // Not registered. - return 0; - } - - int pos = 0; - const WebRtc_UWord8 len = 2; - dataBuffer[pos++] = (id << 4) + len; - ModuleRTPUtility::AssignUWord24ToBuffer(dataBuffer + pos, - _transmissionTimeOffset); - pos += 3; - assert(pos == TRANSMISSION_TIME_OFFSET_LENGTH_IN_BYTES); - return TRANSMISSION_TIME_OFFSET_LENGTH_IN_BYTES; + // Get id defined by user. + WebRtc_UWord8 id; + if (_rtpHeaderExtensionMap.GetId(kRtpExtensionTransmissionTimeOffset, &id) + != 0) { + // Not registered. + return 0; + } + int pos = 0; + const WebRtc_UWord8 len = 2; + dataBuffer[pos++] = (id << 4) + len; + ModuleRTPUtility::AssignUWord24ToBuffer(dataBuffer + pos, + _transmissionTimeOffset); + pos += 3; + assert(pos == TRANSMISSION_TIME_OFFSET_LENGTH_IN_BYTES); + return TRANSMISSION_TIME_OFFSET_LENGTH_IN_BYTES; } bool RTPSender::UpdateTransmissionTimeOffset( @@ -1168,10 +994,10 @@ bool RTPSender::UpdateTransmissionTimeOffset( // Get length until start of transmission block. int transmission_block_pos = _rtpHeaderExtensionMap.GetLengthUntilBlockStartInBytes( - kRtpExtensionTransmissionTimeOffset); + kRtpExtensionTransmissionTimeOffset); if (transmission_block_pos < 0) { WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, - "Failed to update transmission time offset, not registered."); + "Failed to update transmission time offset, not registered."); return false; } @@ -1179,410 +1005,284 @@ bool RTPSender::UpdateTransmissionTimeOffset( if (rtp_packet_length < block_pos + 4 || rtp_header.header.headerLength < block_pos + 4) { WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, - "Failed to update transmission time offset, invalid length."); + "Failed to update transmission time offset, invalid length."); return false; } - // Verify that header contains extension. if (!((rtp_packet[12 + rtp_header.header.numCSRCs] == 0xBE) && - (rtp_packet[12 + rtp_header.header.numCSRCs + 1] == 0xDE))) { + (rtp_packet[12 + rtp_header.header.numCSRCs + 1] == 0xDE))) { WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, "Failed to update transmission time offset, hdr extension not found."); return false; } - // Get id. WebRtc_UWord8 id = 0; if (_rtpHeaderExtensionMap.GetId(kRtpExtensionTransmissionTimeOffset, &id) != 0) { WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, - "Failed to update transmission time offset, no id."); + "Failed to update transmission time offset, no id."); return false; } - // Verify first byte in block. const WebRtc_UWord8 first_block_byte = (id << 4) + 2; if (rtp_packet[block_pos] != first_block_byte) { WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, - "Failed to update transmission time offset."); + "Failed to update transmission time offset."); return false; } - // Update transmission offset field. ModuleRTPUtility::AssignUWord24ToBuffer(rtp_packet + block_pos + 1, time_diff_ms * 90); // RTP timestamp. return true; } -WebRtc_Word32 -RTPSender::RegisterSendTransport(Transport* transport) -{ - CriticalSectionScoped cs(_transportCritsect); - _transport = transport; +void RTPSender::SetSendingStatus(const bool enabled) { + if (enabled) { + WebRtc_UWord32 freq; + if (_audioConfigured) { + WebRtc_UWord32 frequency = _audio->AudioFrequency(); + + // sanity + switch(frequency) { + case 8000: + case 12000: + case 16000: + case 24000: + case 32000: + break; + default: + assert(false); + return; + } + freq = frequency; + } else { + freq = 90000; // 90 KHz for all video + } + WebRtc_UWord32 RTPtime = ModuleRTPUtility::GetCurrentRTP(&_clock, freq); + + // will be ignored if it's already configured via API + SetStartTimestamp(RTPtime, false); + } else { + if (!_ssrcForced) { + // generate a new SSRC + _ssrcDB.ReturnSSRC(_ssrc); + _ssrc = _ssrcDB.CreateSSRC(); // can't be 0 + + } + // Don't initialize seq number if SSRC passed externally. + if (!_sequenceNumberForced && !_ssrcForced) { + // generate a new sequence number + _sequenceNumber = rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); + } + } +} + +void RTPSender::SetSendingMediaStatus(const bool enabled) { + CriticalSectionScoped cs(_sendCritsect); + _sendingMedia = enabled; +} + +bool RTPSender::SendingMedia() const { + CriticalSectionScoped cs(_sendCritsect); + return _sendingMedia; +} + +WebRtc_UWord32 RTPSender::Timestamp() const { + CriticalSectionScoped cs(_sendCritsect); + return _timeStamp; +} + +void RTPSender::SetStartTimestamp(WebRtc_UWord32 timestamp, bool force) { + CriticalSectionScoped cs(_sendCritsect); + if (force) { + _startTimeStampForced = force; + _startTimeStamp = timestamp; + } else { + if (!_startTimeStampForced) { + _startTimeStamp = timestamp; + } + } +} + +WebRtc_UWord32 RTPSender::StartTimestamp() const { + CriticalSectionScoped cs(_sendCritsect); + return _startTimeStamp; +} + +WebRtc_UWord32 RTPSender::GenerateNewSSRC() { + // if configured via API, return 0 + CriticalSectionScoped cs(_sendCritsect); + + if (_ssrcForced) { return 0; + } + _ssrc = _ssrcDB.CreateSSRC(); // can't be 0 + return _ssrc; } -void -RTPSender::SetSendingStatus(const bool enabled) -{ - if(enabled) - { - WebRtc_UWord32 freq; - if(_audioConfigured) - { - WebRtc_UWord32 frequency = _audio->AudioFrequency(); +void RTPSender::SetSSRC(WebRtc_UWord32 ssrc) { + // this is configured via the API + CriticalSectionScoped cs(_sendCritsect); - // sanity - switch(frequency) - { - case 8000: - case 12000: - case 16000: - case 24000: - case 32000: - break; - default: - assert(false); - return; - } - freq = frequency; - } else - { - freq = 90000; // 90 KHz for all video - } - WebRtc_UWord32 RTPtime = ModuleRTPUtility::GetCurrentRTP(&_clock, freq); - - SetStartTimestamp(RTPtime); // will be ignored if it's already configured via API - - } else - { - if(!_ssrcForced) - { - // generate a new SSRC - _ssrcDB.ReturnSSRC(_ssrc); - _ssrc = _ssrcDB.CreateSSRC(); // can't be 0 - - } - if(!_sequenceNumberForced && !_ssrcForced) // don't initialize seq number if SSRC passed externally - { - // generate a new sequence number - _sequenceNumber = rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); - } - } + if (_ssrc == ssrc && _ssrcForced) { + return; // since it's same ssrc, don't reset anything + } + _ssrcForced = true; + _ssrcDB.ReturnSSRC(_ssrc); + _ssrcDB.RegisterSSRC(ssrc); + _ssrc = ssrc; + if (!_sequenceNumberForced) { + _sequenceNumber = rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); + } } -void -RTPSender::SetSendingMediaStatus(const bool enabled) -{ - CriticalSectionScoped cs(_sendCritsect); - _sendingMedia = enabled; +WebRtc_UWord32 RTPSender::SSRC() const { + CriticalSectionScoped cs(_sendCritsect); + return _ssrc; } -bool -RTPSender::SendingMedia() const -{ - CriticalSectionScoped cs(_sendCritsect); - return _sendingMedia; +void RTPSender::SetCSRCStatus(const bool include) { + _includeCSRCs = include; } -WebRtc_UWord32 -RTPSender::Timestamp() const -{ - CriticalSectionScoped cs(_sendCritsect); - return _timeStamp; +void RTPSender::SetCSRCs(const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize], + const WebRtc_UWord8 arrLength) { + assert(arrLength <= kRtpCsrcSize); + CriticalSectionScoped cs(_sendCritsect); + + for (int i = 0; i < arrLength;i++) { + _CSRC[i] = arrOfCSRC[i]; + } + _CSRCs = arrLength; } - -WebRtc_Word32 -RTPSender::SetStartTimestamp( const WebRtc_UWord32 timestamp, const bool force) -{ - CriticalSectionScoped cs(_sendCritsect); - if(force) - { - _startTimeStampForced = force; - _startTimeStamp = timestamp; - } else - { - if(!_startTimeStampForced) - { - _startTimeStamp = timestamp; - } - } - return 0; +WebRtc_Word32 RTPSender::CSRCs(WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const { + assert(arrOfCSRC); + CriticalSectionScoped cs(_sendCritsect); + for (int i = 0; i < _CSRCs && i < kRtpCsrcSize;i++) { + arrOfCSRC[i] = _CSRC[i]; + } + return _CSRCs; } -WebRtc_UWord32 -RTPSender::StartTimestamp() const -{ - CriticalSectionScoped cs(_sendCritsect); - return _startTimeStamp; +void RTPSender::SetSequenceNumber(WebRtc_UWord16 seq) { + CriticalSectionScoped cs(_sendCritsect); + _sequenceNumberForced = true; + _sequenceNumber = seq; } -WebRtc_UWord32 -RTPSender::GenerateNewSSRC() -{ - // if configured via API, return 0 - CriticalSectionScoped cs(_sendCritsect); - - if(_ssrcForced) - { - return 0; - } - _ssrc = _ssrcDB.CreateSSRC(); // can't be 0 - return _ssrc; +WebRtc_UWord16 RTPSender::SequenceNumber() const { + CriticalSectionScoped cs(_sendCritsect); + return _sequenceNumber; } -WebRtc_Word32 -RTPSender::SetSSRC(WebRtc_UWord32 ssrc) -{ - // this is configured via the API - CriticalSectionScoped cs(_sendCritsect); - - if (_ssrc == ssrc && _ssrcForced) - { - return 0; // since it's same ssrc, don't reset anything - } - - _ssrcForced = true; - - _ssrcDB.ReturnSSRC(_ssrc); - _ssrcDB.RegisterSSRC(ssrc); - _ssrc = ssrc; - - if(!_sequenceNumberForced) - { - _sequenceNumber = rand() / (RAND_MAX / MAX_INIT_RTP_SEQ_NUMBER); - } - return 0; +/* + * Audio + */ +WebRtc_Word32 RTPSender::SendTelephoneEvent(const WebRtc_UWord8 key, + const WebRtc_UWord16 time_ms, + const WebRtc_UWord8 level) { + if (!_audioConfigured) { + return -1; + } + return _audio->SendTelephoneEvent(key, time_ms, level); } -WebRtc_UWord32 -RTPSender::SSRC() const -{ - CriticalSectionScoped cs(_sendCritsect); - return _ssrc; +bool RTPSender::SendTelephoneEventActive(WebRtc_Word8& telephoneEvent) const { + if (!_audioConfigured) { + return false; + } + return _audio->SendTelephoneEventActive(telephoneEvent); } -WebRtc_Word32 -RTPSender::SetCSRCStatus(const bool include) -{ - _includeCSRCs = include; - return 0; -} - -WebRtc_Word32 -RTPSender::SetCSRCs(const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize], - const WebRtc_UWord8 arrLength) -{ - if(arrLength > kRtpCsrcSize) - { - assert(false); - return -1; - } - - CriticalSectionScoped cs(_sendCritsect); - - for(int i = 0; i < arrLength;i++) - { - _CSRC[i] = arrOfCSRC[i]; - } - _CSRCs = arrLength; - return 0; -} - -WebRtc_Word32 -RTPSender::CSRCs(WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const -{ - CriticalSectionScoped cs(_sendCritsect); - - if(arrOfCSRC == NULL) - { - assert(false); - return -1; - } - for(int i = 0; i < _CSRCs && i < kRtpCsrcSize;i++) - { - arrOfCSRC[i] = _CSRC[i]; - } - return _CSRCs; -} - -WebRtc_Word32 -RTPSender::SetSequenceNumber(WebRtc_UWord16 seq) -{ - CriticalSectionScoped cs(_sendCritsect); - _sequenceNumberForced = true; - _sequenceNumber = seq; - return 0; -} - -WebRtc_UWord16 -RTPSender::SequenceNumber() const -{ - CriticalSectionScoped cs(_sendCritsect); - return _sequenceNumber; -} - - - /* - * Audio - */ -WebRtc_Word32 -RTPSender::RegisterAudioCallback(RtpAudioFeedback* messagesCallback) -{ - if(!_audioConfigured) - { - return -1; - } - return _audio->RegisterAudioCallback(messagesCallback); -} - - // Send a DTMF tone, RFC 2833 (4733) -WebRtc_Word32 -RTPSender::SendTelephoneEvent(const WebRtc_UWord8 key, - const WebRtc_UWord16 time_ms, - const WebRtc_UWord8 level) -{ - if(!_audioConfigured) - { - return -1; - } - return _audio->SendTelephoneEvent(key, time_ms, level); -} - -bool -RTPSender::SendTelephoneEventActive(WebRtc_Word8& telephoneEvent) const -{ - if(!_audioConfigured) - { - return false; - } - return _audio->SendTelephoneEventActive(telephoneEvent); -} - - // set audio packet size, used to determine when it's time to send a DTMF packet in silence (CNG) -WebRtc_Word32 -RTPSender::SetAudioPacketSize(const WebRtc_UWord16 packetSizeSamples) -{ - if(!_audioConfigured) - { - return -1; - } - return _audio->SetAudioPacketSize(packetSizeSamples); +WebRtc_Word32 RTPSender::SetAudioPacketSize( + const WebRtc_UWord16 packetSizeSamples) { + if (!_audioConfigured) { + return -1; + } + return _audio->SetAudioPacketSize(packetSizeSamples); } WebRtc_Word32 RTPSender::SetAudioLevelIndicationStatus(const bool enable, - const WebRtc_UWord8 ID) -{ - if(!_audioConfigured) - { - return -1; - } - return _audio->SetAudioLevelIndicationStatus(enable, ID); + const WebRtc_UWord8 ID) { + if (!_audioConfigured) { + return -1; + } + return _audio->SetAudioLevelIndicationStatus(enable, ID); } -WebRtc_Word32 -RTPSender::AudioLevelIndicationStatus(bool& enable, - WebRtc_UWord8& ID) const -{ - return _audio->AudioLevelIndicationStatus(enable, ID); +WebRtc_Word32 RTPSender::AudioLevelIndicationStatus(bool& enable, + WebRtc_UWord8& ID) const { + return _audio->AudioLevelIndicationStatus(enable, ID); } -WebRtc_Word32 -RTPSender::SetAudioLevel(const WebRtc_UWord8 level_dBov) -{ - return _audio->SetAudioLevel(level_dBov); +WebRtc_Word32 RTPSender::SetAudioLevel(const WebRtc_UWord8 level_dBov) { + return _audio->SetAudioLevel(level_dBov); } - // Set payload type for Redundant Audio Data RFC 2198 -WebRtc_Word32 -RTPSender::SetRED(const WebRtc_Word8 payloadType) -{ - if(!_audioConfigured) - { - return -1; - } - return _audio->SetRED(payloadType); +WebRtc_Word32 RTPSender::SetRED(const WebRtc_Word8 payloadType) { + if (!_audioConfigured) { + return -1; + } + return _audio->SetRED(payloadType); } - // Get payload type for Redundant Audio Data RFC 2198 -WebRtc_Word32 -RTPSender::RED(WebRtc_Word8& payloadType) const -{ - if(!_audioConfigured) - { - return -1; - } - return _audio->RED(payloadType); +WebRtc_Word32 RTPSender::RED(WebRtc_Word8& payloadType) const { + if (!_audioConfigured) { + return -1; + } + return _audio->RED(payloadType); } - /* - * Video - */ -VideoCodecInformation* -RTPSender::CodecInformationVideo() -{ - if(_audioConfigured) - { - return NULL; - } - return _video->CodecInformationVideo(); +/* + * Video + */ +VideoCodecInformation* RTPSender::CodecInformationVideo() { + if (_audioConfigured) { + return NULL; + } + return _video->CodecInformationVideo(); } -RtpVideoCodecTypes -RTPSender::VideoCodecType() const -{ - if(_audioConfigured) - { - return kRtpNoVideo; - } - return _video->VideoCodecType(); +RtpVideoCodecTypes RTPSender::VideoCodecType() const { + if (_audioConfigured) { + return kRtpNoVideo; + } + return _video->VideoCodecType(); } -WebRtc_UWord32 -RTPSender::MaxConfiguredBitrateVideo() const -{ - if(_audioConfigured) - { - return 0; - } - return _video->MaxConfiguredBitrateVideo(); +WebRtc_UWord32 RTPSender::MaxConfiguredBitrateVideo() const { + if (_audioConfigured) { + return 0; + } + return _video->MaxConfiguredBitrateVideo(); } -WebRtc_Word32 -RTPSender::SendRTPIntraRequest() -{ - if(_audioConfigured) - { - return -1; - } - return _video->SendRTPIntraRequest(); +WebRtc_Word32 RTPSender::SendRTPIntraRequest() { + if (_audioConfigured) { + return -1; + } + return _video->SendRTPIntraRequest(); } -// FEC -WebRtc_Word32 -RTPSender::SetGenericFECStatus(const bool enable, - const WebRtc_UWord8 payloadTypeRED, - const WebRtc_UWord8 payloadTypeFEC) -{ - if(_audioConfigured) - { - return -1; - } - return _video->SetGenericFECStatus(enable, payloadTypeRED, payloadTypeFEC); +WebRtc_Word32 RTPSender::SetGenericFECStatus( + const bool enable, + const WebRtc_UWord8 payloadTypeRED, + const WebRtc_UWord8 payloadTypeFEC) { + if (_audioConfigured) { + return -1; + } + return _video->SetGenericFECStatus(enable, payloadTypeRED, payloadTypeFEC); } -WebRtc_Word32 -RTPSender::GenericFECStatus(bool& enable, - WebRtc_UWord8& payloadTypeRED, - WebRtc_UWord8& payloadTypeFEC) const -{ - if(_audioConfigured) - { - return -1; - } - return _video->GenericFECStatus(enable, payloadTypeRED, payloadTypeFEC); +WebRtc_Word32 RTPSender::GenericFECStatus(bool& enable, + WebRtc_UWord8& payloadTypeRED, + WebRtc_UWord8& payloadTypeFEC) const { + if (_audioConfigured) { + return -1; + } + return _video->GenericFECStatus(enable, payloadTypeRED, payloadTypeFEC); } WebRtc_Word32 RTPSender::SetFecParameters( @@ -1593,4 +1293,4 @@ WebRtc_Word32 RTPSender::SetFecParameters( } return _video->SetFecParameters(delta_params, key_params); } -} // namespace webrtc +} // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h index 542ad8cc03..2de8a6afef 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -15,9 +15,9 @@ #include #include -#include "rtp_rtcp_config.h" // misc. defines (e.g. MAX_PACKET_LENGTH) +#include "rtp_rtcp_config.h" // misc. defines (e.g. MAX_PACKET_LENGTH) #include "rtp_rtcp_defines.h" -#include "common_types.h" // Encryption +#include "common_types.h" #include "ssrc_database.h" #include "Bitrate.h" #include "rtp_header_extension.h" @@ -32,323 +32,315 @@ class RTPPacketHistory; class RTPSenderAudio; class RTPSenderVideo; -class RTPSenderInterface -{ -public: - RTPSenderInterface() {} - virtual ~RTPSenderInterface() {} +class RTPSenderInterface { + public: + RTPSenderInterface() {} + virtual ~RTPSenderInterface() {} - virtual WebRtc_UWord32 SSRC() const = 0; - virtual WebRtc_UWord32 Timestamp() const = 0; + virtual WebRtc_UWord32 SSRC() const = 0; + virtual WebRtc_UWord32 Timestamp() const = 0; - virtual WebRtc_Word32 BuildRTPheader(WebRtc_UWord8* dataBuffer, + virtual WebRtc_Word32 BuildRTPheader(WebRtc_UWord8* dataBuffer, const WebRtc_Word8 payloadType, const bool markerBit, const WebRtc_UWord32 captureTimeStamp, const bool timeStampProvided = true, const bool incSequenceNumber = true) = 0; - virtual WebRtc_UWord16 RTPHeaderLength() const = 0; - virtual WebRtc_UWord16 IncrementSequenceNumber() = 0; - virtual WebRtc_UWord16 SequenceNumber() const = 0; - virtual WebRtc_UWord16 MaxPayloadLength() const = 0; - virtual WebRtc_UWord16 MaxDataPayloadLength() const = 0; - virtual WebRtc_UWord16 PacketOverHead() const = 0; - virtual WebRtc_UWord16 ActualSendBitrateKbit() const = 0; + virtual WebRtc_UWord16 RTPHeaderLength() const = 0; + virtual WebRtc_UWord16 IncrementSequenceNumber() = 0; + virtual WebRtc_UWord16 SequenceNumber() const = 0; + virtual WebRtc_UWord16 MaxPayloadLength() const = 0; + virtual WebRtc_UWord16 MaxDataPayloadLength() const = 0; + virtual WebRtc_UWord16 PacketOverHead() const = 0; + virtual WebRtc_UWord16 ActualSendBitrateKbit() const = 0; - virtual WebRtc_Word32 SendToNetwork(WebRtc_UWord8* data_buffer, - const WebRtc_UWord16 payload_length, - const WebRtc_UWord16 rtp_header_length, - int64_t capture_time_ms, - const StorageType storage) = 0; + virtual WebRtc_Word32 SendToNetwork(WebRtc_UWord8* data_buffer, + WebRtc_UWord16 payload_length, + WebRtc_UWord16 rtp_header_length, + int64_t capture_time_ms, + StorageType storage) = 0; }; -class RTPSender : public Bitrate, public RTPSenderInterface -{ -public: - RTPSender(const WebRtc_Word32 id, const bool audio, RtpRtcpClock* clock); - virtual ~RTPSender(); +class RTPSender : public Bitrate, public RTPSenderInterface { + public: + RTPSender(const WebRtc_Word32 id, const bool audio, RtpRtcpClock* clock, + Transport* transport, RtpAudioFeedback* audio_feedback); + virtual ~RTPSender(); - void ProcessBitrate(); - void ProcessSendToNetwork(); + void ProcessBitrate(); + void ProcessSendToNetwork(); - WebRtc_UWord16 ActualSendBitrateKbit() const; + WebRtc_UWord16 ActualSendBitrateKbit() const; - WebRtc_UWord32 VideoBitrateSent() const; - WebRtc_UWord32 FecOverheadRate() const; - WebRtc_UWord32 NackOverheadRate() const; + WebRtc_UWord32 VideoBitrateSent() const; + WebRtc_UWord32 FecOverheadRate() const; + WebRtc_UWord32 NackOverheadRate() const; - void SetTargetSendBitrate(const WebRtc_UWord32 bits); + void SetTargetSendBitrate(const WebRtc_UWord32 bits); - WebRtc_UWord16 MaxDataPayloadLength() const; // with RTP and FEC headers + WebRtc_UWord16 MaxDataPayloadLength() const; // with RTP and FEC headers - // callback - WebRtc_Word32 RegisterSendTransport(Transport* outgoingTransport); + WebRtc_Word32 RegisterPayload( + const char payloadName[RTP_PAYLOAD_NAME_SIZE], + const WebRtc_Word8 payloadType, + const WebRtc_UWord32 frequency, + const WebRtc_UWord8 channels, + const WebRtc_UWord32 rate); - WebRtc_Word32 RegisterPayload( - const char payloadName[RTP_PAYLOAD_NAME_SIZE], - const WebRtc_Word8 payloadType, - const WebRtc_UWord32 frequency, - const WebRtc_UWord8 channels, - const WebRtc_UWord32 rate); + WebRtc_Word32 DeRegisterSendPayload(const WebRtc_Word8 payloadType); - WebRtc_Word32 DeRegisterSendPayload(const WebRtc_Word8 payloadType); + WebRtc_Word8 SendPayloadType() const; - WebRtc_Word8 SendPayloadType() const; + int SendPayloadFrequency() const; - int SendPayloadFrequency() const; + void SetSendingStatus(const bool enabled); - void SetSendingStatus(const bool enabled); + void SetSendingMediaStatus(const bool enabled); + bool SendingMedia() const; - void SetSendingMediaStatus(const bool enabled); - bool SendingMedia() const; + // number of sent RTP packets + WebRtc_UWord32 Packets() const; - // number of sent RTP packets - WebRtc_UWord32 Packets() const; + // number of sent RTP bytes + WebRtc_UWord32 Bytes() const; - // number of sent RTP bytes - WebRtc_UWord32 Bytes() const; + void ResetDataCounters(); - WebRtc_Word32 ResetDataCounters(); + WebRtc_UWord32 StartTimestamp() const; + void SetStartTimestamp(WebRtc_UWord32 timestamp, bool force); - WebRtc_UWord32 StartTimestamp() const; - WebRtc_Word32 SetStartTimestamp(const WebRtc_UWord32 timestamp, - const bool force = false); + WebRtc_UWord32 GenerateNewSSRC(); + void SetSSRC(const WebRtc_UWord32 ssrc); - WebRtc_UWord32 GenerateNewSSRC(); - WebRtc_Word32 SetSSRC( const WebRtc_UWord32 ssrc); + WebRtc_UWord16 SequenceNumber() const; + void SetSequenceNumber(WebRtc_UWord16 seq); - WebRtc_UWord16 SequenceNumber() const; - WebRtc_Word32 SetSequenceNumber( WebRtc_UWord16 seq); + WebRtc_Word32 CSRCs(WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const; - WebRtc_Word32 CSRCs(WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const; + void SetCSRCStatus(const bool include); - WebRtc_Word32 SetCSRCStatus(const bool include); + void SetCSRCs(const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize], + const WebRtc_UWord8 arrLength); - WebRtc_Word32 SetCSRCs(const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize], - const WebRtc_UWord8 arrLength); + WebRtc_Word32 SetMaxPayloadLength(const WebRtc_UWord16 length, + const WebRtc_UWord16 packetOverHead); - WebRtc_Word32 SetMaxPayloadLength(const WebRtc_UWord16 length, - const WebRtc_UWord16 packetOverHead); + WebRtc_Word32 SendOutgoingData(const FrameType frameType, + const WebRtc_Word8 payloadType, + const WebRtc_UWord32 timeStamp, + int64_t capture_time_ms, + const WebRtc_UWord8* payloadData, + const WebRtc_UWord32 payloadSize, + const RTPFragmentationHeader* fragmentation, + VideoCodecInformation* codecInfo = NULL, + const RTPVideoTypeHeader* rtpTypeHdr = NULL); - WebRtc_Word32 SendOutgoingData(const FrameType frameType, - const WebRtc_Word8 payloadType, - const WebRtc_UWord32 timeStamp, - int64_t capture_time_ms, - const WebRtc_UWord8* payloadData, - const WebRtc_UWord32 payloadSize, - const RTPFragmentationHeader* fragmentation, - VideoCodecInformation* codecInfo = NULL, - const RTPVideoTypeHeader* rtpTypeHdr = NULL); + WebRtc_Word32 SendPadData(WebRtc_Word8 payload_type, + WebRtc_UWord32 capture_timestamp, + int64_t capture_time_ms, + WebRtc_Word32 bytes); + /* + * RTP header extension + */ + WebRtc_Word32 SetTransmissionTimeOffset( + const WebRtc_Word32 transmissionTimeOffset); - WebRtc_Word32 SendPadData(WebRtc_Word8 payload_type, - WebRtc_UWord32 capture_timestamp, - int64_t capture_time_ms, - WebRtc_Word32 bytes); - /* - * RTP header extension - */ - WebRtc_Word32 SetTransmissionTimeOffset( - const WebRtc_Word32 transmissionTimeOffset); + WebRtc_Word32 RegisterRtpHeaderExtension(const RTPExtensionType type, + const WebRtc_UWord8 id); - WebRtc_Word32 RegisterRtpHeaderExtension(const RTPExtensionType type, - const WebRtc_UWord8 id); + WebRtc_Word32 DeregisterRtpHeaderExtension(const RTPExtensionType type); - WebRtc_Word32 DeregisterRtpHeaderExtension(const RTPExtensionType type); + WebRtc_UWord16 RtpHeaderExtensionTotalLength() const; - WebRtc_UWord16 RtpHeaderExtensionTotalLength() const; + WebRtc_UWord16 BuildRTPHeaderExtension(WebRtc_UWord8* dataBuffer) const; - WebRtc_UWord16 BuildRTPHeaderExtension(WebRtc_UWord8* dataBuffer) const; + WebRtc_UWord8 BuildTransmissionTimeOffsetExtension( + WebRtc_UWord8* dataBuffer) const; - WebRtc_UWord8 BuildTransmissionTimeOffsetExtension( - WebRtc_UWord8* dataBuffer) const; + bool UpdateTransmissionTimeOffset(WebRtc_UWord8* rtp_packet, + const WebRtc_UWord16 rtp_packet_length, + const WebRtcRTPHeader& rtp_header, + const WebRtc_Word64 time_diff_ms) const; - bool UpdateTransmissionTimeOffset(WebRtc_UWord8* rtp_packet, - const WebRtc_UWord16 rtp_packet_length, - const WebRtcRTPHeader& rtp_header, - const WebRtc_Word64 time_diff_ms) const; + void SetTransmissionSmoothingStatus(const bool enable); - void SetTransmissionSmoothingStatus(const bool enable); + bool TransmissionSmoothingStatus() const; - bool TransmissionSmoothingStatus() const; - - /* + /* * NACK */ - int SelectiveRetransmissions() const; - int SetSelectiveRetransmissions(uint8_t settings); - void OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength, - const WebRtc_UWord16* nackSequenceNumbers, - const WebRtc_UWord16 avgRTT); + int SelectiveRetransmissions() const; + int SetSelectiveRetransmissions(uint8_t settings); + void OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength, + const WebRtc_UWord16* nackSequenceNumbers, + const WebRtc_UWord16 avgRTT); - WebRtc_Word32 SetStorePacketsStatus(const bool enable, - const WebRtc_UWord16 numberToStore); + void SetStorePacketsStatus(const bool enable, + const WebRtc_UWord16 numberToStore); - bool StorePackets() const; + bool StorePackets() const; - WebRtc_Word32 ReSendPacket(WebRtc_UWord16 packet_id, - WebRtc_UWord32 min_resend_time = 0); + WebRtc_Word32 ReSendPacket(WebRtc_UWord16 packet_id, + WebRtc_UWord32 min_resend_time = 0); - WebRtc_Word32 ReSendToNetwork(const WebRtc_UWord8* packet, - const WebRtc_UWord32 size); + WebRtc_Word32 ReSendToNetwork(const WebRtc_UWord8* packet, + const WebRtc_UWord32 size); - bool ProcessNACKBitRate(const WebRtc_UWord32 now); + bool ProcessNACKBitRate(const WebRtc_UWord32 now); - /* + /* * RTX */ - void SetRTXStatus(const bool enable, - const bool setSSRC, - const WebRtc_UWord32 SSRC); + void SetRTXStatus(const bool enable, + const bool setSSRC, + const WebRtc_UWord32 SSRC); - void RTXStatus(bool* enable, WebRtc_UWord32* SSRC) const; + void RTXStatus(bool* enable, WebRtc_UWord32* SSRC) const; - /* + /* * Functions wrapping RTPSenderInterface */ - virtual WebRtc_Word32 BuildRTPheader(WebRtc_UWord8* dataBuffer, - const WebRtc_Word8 payloadType, - const bool markerBit, - const WebRtc_UWord32 captureTimeStamp, - const bool timeStampProvided = true, - const bool incSequenceNumber = true); + virtual WebRtc_Word32 BuildRTPheader(WebRtc_UWord8* dataBuffer, + const WebRtc_Word8 payloadType, + const bool markerBit, + const WebRtc_UWord32 captureTimeStamp, + const bool timeStampProvided = true, + const bool incSequenceNumber = true); - virtual WebRtc_UWord16 RTPHeaderLength() const ; - virtual WebRtc_UWord16 IncrementSequenceNumber(); - virtual WebRtc_UWord16 MaxPayloadLength() const; - virtual WebRtc_UWord16 PacketOverHead() const; + virtual WebRtc_UWord16 RTPHeaderLength() const ; + virtual WebRtc_UWord16 IncrementSequenceNumber(); + virtual WebRtc_UWord16 MaxPayloadLength() const; + virtual WebRtc_UWord16 PacketOverHead() const; - // current timestamp - virtual WebRtc_UWord32 Timestamp() const; - virtual WebRtc_UWord32 SSRC() const; + // current timestamp + virtual WebRtc_UWord32 Timestamp() const; + virtual WebRtc_UWord32 SSRC() const; - virtual WebRtc_Word32 SendToNetwork(WebRtc_UWord8* data_buffer, - const WebRtc_UWord16 payload_length, - const WebRtc_UWord16 rtp_header_length, - int64_t capture_time_ms, - const StorageType storage); - - /* + virtual WebRtc_Word32 SendToNetwork(WebRtc_UWord8* data_buffer, + WebRtc_UWord16 payload_length, + WebRtc_UWord16 rtp_header_length, + int64_t capture_time_ms, + StorageType storage); + /* * Audio */ - WebRtc_Word32 RegisterAudioCallback(RtpAudioFeedback* messagesCallback); + // Send a DTMF tone using RFC 2833 (4733) + WebRtc_Word32 SendTelephoneEvent(const WebRtc_UWord8 key, + const WebRtc_UWord16 time_ms, + const WebRtc_UWord8 level); - // Send a DTMF tone using RFC 2833 (4733) - WebRtc_Word32 SendTelephoneEvent(const WebRtc_UWord8 key, - const WebRtc_UWord16 time_ms, - const WebRtc_UWord8 level); + bool SendTelephoneEventActive(WebRtc_Word8& telephoneEvent) const; - bool SendTelephoneEventActive(WebRtc_Word8& telephoneEvent) const; + // Set audio packet size, used to determine when it's time to send a DTMF + // packet in silence (CNG) + WebRtc_Word32 SetAudioPacketSize(const WebRtc_UWord16 packetSizeSamples); - // set audio packet size, used to determine when it's time to send a DTMF packet in silence (CNG) - WebRtc_Word32 SetAudioPacketSize(const WebRtc_UWord16 packetSizeSamples); + // Set status and ID for header-extension-for-audio-level-indication. + WebRtc_Word32 SetAudioLevelIndicationStatus(const bool enable, + const WebRtc_UWord8 ID); - // Set status and ID for header-extension-for-audio-level-indication. - WebRtc_Word32 SetAudioLevelIndicationStatus(const bool enable, - const WebRtc_UWord8 ID); + // Get status and ID for header-extension-for-audio-level-indication. + WebRtc_Word32 AudioLevelIndicationStatus(bool& enable, + WebRtc_UWord8& ID) const; - // Get status and ID for header-extension-for-audio-level-indication. - WebRtc_Word32 AudioLevelIndicationStatus(bool& enable, - WebRtc_UWord8& ID) const; + // Store the audio level in dBov for + // header-extension-for-audio-level-indication. + WebRtc_Word32 SetAudioLevel(const WebRtc_UWord8 level_dBov); - // Store the audio level in dBov for header-extension-for-audio-level-indication. - WebRtc_Word32 SetAudioLevel(const WebRtc_UWord8 level_dBov); + // Set payload type for Redundant Audio Data RFC 2198 + WebRtc_Word32 SetRED(const WebRtc_Word8 payloadType); - // Set payload type for Redundant Audio Data RFC 2198 - WebRtc_Word32 SetRED(const WebRtc_Word8 payloadType); + // Get payload type for Redundant Audio Data RFC 2198 + WebRtc_Word32 RED(WebRtc_Word8& payloadType) const; - // Get payload type for Redundant Audio Data RFC 2198 - WebRtc_Word32 RED(WebRtc_Word8& payloadType) const; - - /* + /* * Video */ - VideoCodecInformation* CodecInformationVideo(); + VideoCodecInformation* CodecInformationVideo(); - RtpVideoCodecTypes VideoCodecType() const; + RtpVideoCodecTypes VideoCodecType() const; - WebRtc_UWord32 MaxConfiguredBitrateVideo() const; + WebRtc_UWord32 MaxConfiguredBitrateVideo() const; - WebRtc_Word32 SendRTPIntraRequest(); + WebRtc_Word32 SendRTPIntraRequest(); - // FEC - WebRtc_Word32 SetGenericFECStatus(const bool enable, - const WebRtc_UWord8 payloadTypeRED, - const WebRtc_UWord8 payloadTypeFEC); + // FEC + WebRtc_Word32 SetGenericFECStatus(const bool enable, + const WebRtc_UWord8 payloadTypeRED, + const WebRtc_UWord8 payloadTypeFEC); - WebRtc_Word32 GenericFECStatus(bool& enable, - WebRtc_UWord8& payloadTypeRED, - WebRtc_UWord8& payloadTypeFEC) const; + WebRtc_Word32 GenericFECStatus(bool& enable, + WebRtc_UWord8& payloadTypeRED, + WebRtc_UWord8& payloadTypeFEC) const; - WebRtc_Word32 SetFecParameters( - const FecProtectionParams* delta_params, - const FecProtectionParams* key_params); + WebRtc_Word32 SetFecParameters( + const FecProtectionParams* delta_params, + const FecProtectionParams* key_params); -protected: - WebRtc_Word32 CheckPayloadType(const WebRtc_Word8 payloadType, - RtpVideoCodecTypes& videoType); + protected: + WebRtc_Word32 CheckPayloadType(const WebRtc_Word8 payloadType, + RtpVideoCodecTypes& videoType); -private: - void UpdateNACKBitRate(const WebRtc_UWord32 bytes, - const WebRtc_UWord32 now); + private: + void UpdateNACKBitRate(const WebRtc_UWord32 bytes, + const WebRtc_UWord32 now); - WebRtc_Word32 SendPaddingAccordingToBitrate( - WebRtc_Word8 payload_type, - WebRtc_UWord32 capture_timestamp, - int64_t capture_time_ms); + WebRtc_Word32 SendPaddingAccordingToBitrate( + WebRtc_Word8 payload_type, + WebRtc_UWord32 capture_timestamp, + int64_t capture_time_ms); - WebRtc_Word32 _id; - const bool _audioConfigured; - RTPSenderAudio* _audio; - RTPSenderVideo* _video; + WebRtc_Word32 _id; + const bool _audioConfigured; + RTPSenderAudio* _audio; + RTPSenderVideo* _video; - CriticalSectionWrapper* _sendCritsect; + CriticalSectionWrapper* _sendCritsect; - CriticalSectionWrapper* _transportCritsect; - Transport* _transport; + Transport* _transport; + bool _sendingMedia; - bool _sendingMedia; + WebRtc_UWord16 _maxPayloadLength; + WebRtc_UWord16 _targetSendBitrate; + WebRtc_UWord16 _packetOverHead; - WebRtc_UWord16 _maxPayloadLength; - WebRtc_UWord16 _targetSendBitrate; - WebRtc_UWord16 _packetOverHead; + WebRtc_Word8 _payloadType; + std::map _payloadTypeMap; - WebRtc_Word8 _payloadType; - std::map _payloadTypeMap; + RtpHeaderExtensionMap _rtpHeaderExtensionMap; + WebRtc_Word32 _transmissionTimeOffset; - RtpHeaderExtensionMap _rtpHeaderExtensionMap; - WebRtc_Word32 _transmissionTimeOffset; + // NACK + WebRtc_UWord32 _nackByteCountTimes[NACK_BYTECOUNT_SIZE]; + WebRtc_Word32 _nackByteCount[NACK_BYTECOUNT_SIZE]; + Bitrate _nackBitrate; - // NACK - WebRtc_UWord32 _nackByteCountTimes[NACK_BYTECOUNT_SIZE]; - WebRtc_Word32 _nackByteCount[NACK_BYTECOUNT_SIZE]; - Bitrate _nackBitrate; + RTPPacketHistory* _packetHistory; + TransmissionBucket _sendBucket; + WebRtc_Word64 _timeLastSendToNetworkUpdate; + bool _transmissionSmoothing; - RTPPacketHistory* _packetHistory; - TransmissionBucket _sendBucket; - WebRtc_Word64 _timeLastSendToNetworkUpdate; - bool _transmissionSmoothing; + // Statistics + WebRtc_UWord32 _packetsSent; + WebRtc_UWord32 _payloadBytesSent; - // statistics - WebRtc_UWord32 _packetsSent; - WebRtc_UWord32 _payloadBytesSent; - - // RTP variables - bool _startTimeStampForced; - WebRtc_UWord32 _startTimeStamp; - SSRCDatabase& _ssrcDB; - WebRtc_UWord32 _remoteSSRC; - bool _sequenceNumberForced; - WebRtc_UWord16 _sequenceNumber; - WebRtc_UWord16 _sequenceNumberRTX; - bool _ssrcForced; - WebRtc_UWord32 _ssrc; - WebRtc_UWord32 _timeStamp; - WebRtc_UWord8 _CSRCs; - WebRtc_UWord32 _CSRC[kRtpCsrcSize]; - bool _includeCSRCs; - bool _RTX; - WebRtc_UWord32 _ssrcRTX; + // RTP variables + bool _startTimeStampForced; + WebRtc_UWord32 _startTimeStamp; + SSRCDatabase& _ssrcDB; + WebRtc_UWord32 _remoteSSRC; + bool _sequenceNumberForced; + WebRtc_UWord16 _sequenceNumber; + WebRtc_UWord16 _sequenceNumberRTX; + bool _ssrcForced; + WebRtc_UWord32 _ssrc; + WebRtc_UWord32 _timeStamp; + WebRtc_UWord8 _CSRCs; + WebRtc_UWord32 _CSRC[kRtpCsrcSize]; + bool _includeCSRCs; + bool _RTX; + WebRtc_UWord32 _ssrcRTX; }; } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc index f1ef5945e6..846bc7a524 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -78,12 +78,11 @@ class RtpSenderTest : public ::testing::Test { protected: RtpSenderTest() : fake_clock_(), - rtp_sender_(new RTPSender(0, false, &fake_clock_)), - transport_(), + rtp_sender_(new RTPSender(0, false, &fake_clock_, &transport_, NULL)), kMarkerBit(true), kType(kRtpExtensionTransmissionTimeOffset), packet_() { - EXPECT_EQ(0, rtp_sender_->SetSequenceNumber(kSeqNum)); + rtp_sender_->SetSequenceNumber(kSeqNum); } ~RtpSenderTest() { delete rtp_sender_; @@ -199,8 +198,6 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) { } TEST_F(RtpSenderTest, NoTrafficSmoothing) { - EXPECT_EQ(0, rtp_sender_->RegisterSendTransport(&transport_)); - WebRtc_Word32 rtp_length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, @@ -218,9 +215,8 @@ TEST_F(RtpSenderTest, NoTrafficSmoothing) { TEST_F(RtpSenderTest, TrafficSmoothing) { rtp_sender_->SetTransmissionSmoothingStatus(true); - EXPECT_EQ(0, rtp_sender_->SetStorePacketsStatus(true, 10)); + rtp_sender_->SetStorePacketsStatus(true, 10); EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId)); - EXPECT_EQ(0, rtp_sender_->RegisterSendTransport(&transport_)); rtp_sender_->SetTargetSendBitrate(300000); WebRtc_Word32 rtp_length = rtp_sender_->BuildRTPheader(packet_,