Chromium Code Reviews| Index: webrtc/modules/rtp_rtcp/source/rtp_sender.cc |
| diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc |
| index 016a8469cd6b3404d84d3c909351051dbb71c277..a82c8a0ae99c3cd49cbe1ef3e7af0c39421ad26c 100644 |
| --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc |
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc |
| @@ -22,6 +22,7 @@ |
| #include "webrtc/call/rtc_event_log.h" |
| #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" |
| #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| +#include "webrtc/modules/rtp_rtcp/source/playout_delay_oracle.h" |
| #include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h" |
| #include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h" |
| #include "webrtc/modules/rtp_rtcp/source/time_util.h" |
| @@ -137,12 +138,13 @@ RTPSender::RTPSender( |
| transmission_time_offset_(0), |
| absolute_send_time_(0), |
| rotation_(kVideoRotation_0), |
| - cvo_mode_(kCVONone), |
| + video_rotation_active_(false), |
| transport_sequence_number_(0), |
| // NACK. |
| nack_byte_count_times_(), |
| nack_byte_count_(), |
| nack_bitrate_(clock, bitrates_.retransmit_bitrate_observer()), |
| + playout_delay_active_(false), |
| packet_history_(clock), |
| // Statistics |
| rtp_stats_callback_(NULL), |
| @@ -271,11 +273,16 @@ int32_t RTPSender::SetTransportSequenceNumber(uint16_t sequence_number) { |
| int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type, |
| uint8_t id) { |
| rtc::CritScope lock(&send_critsect_); |
| - if (type == kRtpExtensionVideoRotation) { |
| - cvo_mode_ = kCVOInactive; |
| - return rtp_header_extension_map_.RegisterInactive(type, id); |
| + switch (type) { |
| + case kRtpExtensionVideoRotation: |
| + video_rotation_active_ = false; |
| + return rtp_header_extension_map_.RegisterInactive(type, id); |
| + case kRtpExtensionPlayoutDelay: |
| + playout_delay_active_ = false; |
| + return rtp_header_extension_map_.RegisterInactive(type, id); |
| + default: |
|
stefan-webrtc
2016/06/06 14:08:16
No default, instead just list all types here.
Irfan
2016/06/06 15:39:41
Done.
|
| + return rtp_header_extension_map_.Register(type, id); |
| } |
| - return rtp_header_extension_map_.Register(type, id); |
| } |
| bool RTPSender::IsRtpHeaderExtensionRegistered(RTPExtensionType type) { |
| @@ -288,7 +295,7 @@ int32_t RTPSender::DeregisterRtpHeaderExtension(RTPExtensionType type) { |
| return rtp_header_extension_map_.Deregister(type); |
| } |
| -size_t RTPSender::RtpHeaderExtensionTotalLength() const { |
| +size_t RTPSender::RtpHeaderExtensionLength() const { |
| rtc::CritScope lock(&send_critsect_); |
| return rtp_header_extension_map_.GetTotalLengthInBytes(); |
| } |
| @@ -386,9 +393,9 @@ size_t RTPSender::MaxDataPayloadLength() const { |
| rtx = rtx_; |
| } |
| if (audio_configured_) { |
| - return max_payload_length_ - RTPHeaderLength(); |
| + return max_payload_length_ - RtpHeaderLength(); |
| } else { |
| - return max_payload_length_ - RTPHeaderLength() // RTP overhead. |
| + return max_payload_length_ - RtpHeaderLength() // RTP overhead. |
| - video_->FECPacketOverhead() // FEC/ULP/RED overhead. |
| - ((rtx) ? 2 : 0); // RTX overhead. |
| } |
| @@ -472,14 +479,14 @@ int32_t RTPSender::CheckPayloadType(int8_t payload_type, |
| return 0; |
| } |
| -RTPSenderInterface::CVOMode RTPSender::ActivateCVORtpHeaderExtension() { |
| - if (cvo_mode_ == kCVOInactive) { |
| +bool RTPSender::ActivateCVORtpHeaderExtension() { |
| + if (!video_rotation_active_) { |
| rtc::CritScope lock(&send_critsect_); |
| if (rtp_header_extension_map_.SetActive(kRtpExtensionVideoRotation, true)) { |
| - cvo_mode_ = kCVOActivated; |
| + video_rotation_active_ = true; |
| } |
| } |
| - return cvo_mode_; |
| + return video_rotation_active_; |
| } |
| int32_t RTPSender::SendOutgoingData(FrameType frame_type, |
| @@ -491,10 +498,12 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type, |
| const RTPFragmentationHeader* fragmentation, |
| const RTPVideoHeader* rtp_hdr) { |
| uint32_t ssrc; |
| + uint16_t sequence_number; |
| { |
| // Drop this packet if we're not sending media packets. |
| rtc::CritScope lock(&send_critsect_); |
| ssrc = ssrc_; |
| + sequence_number = sequence_number_; |
| if (!sending_media_) { |
| return 0; |
| } |
| @@ -523,10 +532,25 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type, |
| if (frame_type == kEmptyFrame) |
| return 0; |
| - ret_val = |
| - video_->SendVideo(video_type, frame_type, payload_type, |
| - capture_timestamp, capture_time_ms, payload_data, |
| - payload_size, fragmentation, rtp_hdr); |
| + if (rtp_hdr) { |
| + playout_delay_oracle_.UpdateRequest(ssrc, rtp_hdr->playout_delay, |
| + sequence_number); |
| + } |
| + |
| + // Update the active/inactive status of playout delay extension based |
| + // on what the oracle indicates. |
| + { |
| + rtc::CritScope lock(&send_critsect_); |
| + if (playout_delay_active_ != playout_delay_oracle_.send_playout_delay()) { |
| + playout_delay_active_ = playout_delay_oracle_.send_playout_delay(); |
| + rtp_header_extension_map_.SetActive(kRtpExtensionPlayoutDelay, |
| + playout_delay_active_); |
| + } |
| + } |
| + |
| + ret_val = video_->SendVideo( |
| + video_type, frame_type, payload_type, capture_timestamp, |
| + capture_time_ms, payload_data, payload_size, fragmentation, rtp_hdr); |
| } |
| rtc::CritScope cs(&statistics_crit_); |
| @@ -833,6 +857,11 @@ void RTPSender::OnReceivedNACK(const std::list<uint16_t>& nack_sequence_numbers, |
| } |
| } |
| +void RTPSender::OnReceivedRtcpReceiverReport( |
| + const ReportBlockList& report_blocks) { |
| + playout_delay_oracle_.OnReceivedRtcpReceiverReport(report_blocks); |
| +} |
| + |
| bool RTPSender::ProcessNACKBitRate(uint32_t now) { |
| uint32_t num = 0; |
| size_t byte_count = 0; |
| @@ -1152,11 +1181,11 @@ void RTPSender::ProcessBitrate() { |
| video_->ProcessBitrate(); |
| } |
| -size_t RTPSender::RTPHeaderLength() const { |
| +size_t RTPSender::RtpHeaderLength() const { |
| rtc::CritScope lock(&send_critsect_); |
| size_t rtp_header_length = kRtpHeaderLength; |
| rtp_header_length += sizeof(uint32_t) * csrcs_.size(); |
| - rtp_header_length += RtpHeaderExtensionTotalLength(); |
| + rtp_header_length += RtpHeaderExtensionLength(); |
| return rtp_header_length; |
| } |
| @@ -1283,6 +1312,11 @@ uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer, |
| block_length = BuildTransportSequenceNumberExtension( |
| extension_data, transport_sequence_number_); |
| break; |
| + case kRtpExtensionPlayoutDelay: |
| + block_length = BuildPlayoutDelayExtension( |
| + extension_data, playout_delay_oracle_.min_playout_delay_ms(), |
| + playout_delay_oracle_.max_playout_delay_ms()); |
| + break; |
| default: |
| assert(false); |
| } |
| @@ -1458,6 +1492,37 @@ uint8_t RTPSender::BuildTransportSequenceNumberExtension( |
| return kTransportSequenceNumberLength; |
| } |
| +uint8_t RTPSender::BuildPlayoutDelayExtension( |
| + uint8_t* data_buffer, |
| + uint16_t min_playout_delay_ms, |
| + uint16_t max_playout_delay_ms) const { |
| + RTC_DCHECK_LE(min_playout_delay_ms, kPlayoutDelayMaxMs); |
| + RTC_DCHECK_LE(max_playout_delay_ms, kPlayoutDelayMaxMs); |
| + RTC_DCHECK_LE(min_playout_delay_ms, max_playout_delay_ms); |
| + // 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 | MIN delay | MAX delay | |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + uint8_t id; |
| + if (rtp_header_extension_map_.GetId(kRtpExtensionPlayoutDelay, &id) != 0) { |
| + // Not registered. |
| + return 0; |
| + } |
| + size_t pos = 0; |
| + const uint8_t len = 2; |
| + // Convert MS to value to be sent on extension header. |
| + uint16_t min_playout = min_playout_delay_ms / kPlayoutDelayGranularityMs; |
| + uint16_t max_playout = max_playout_delay_ms / kPlayoutDelayGranularityMs; |
| + |
| + data_buffer[pos++] = (id << 4) + len; |
| + data_buffer[pos++] = min_playout >> 4; |
| + data_buffer[pos++] = ((min_playout & 0xf) << 4) | (max_playout >> 8); |
| + data_buffer[pos++] = max_playout & 0xff; |
| + assert(pos == kPlayoutDelayLength); |
| + return kPlayoutDelayLength; |
| +} |
| + |
| bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type, |
| const uint8_t* rtp_packet, |
| size_t rtp_packet_length, |