diff --git a/webrtc/video/rampup_tests.cc b/webrtc/video/rampup_tests.cc index 989deeaf5d..d8eb6c786f 100644 --- a/webrtc/video/rampup_tests.cc +++ b/webrtc/video/rampup_tests.cc @@ -38,7 +38,7 @@ namespace webrtc { namespace { -static const int kAbsoluteSendTimeExtensionId = 7; +static const int kTransmissionTimeOffsetExtensionId = 6; static const int kMaxPacketSize = 1500; class StreamObserver : public newapi::Transport, public RemoteBitrateObserver { @@ -75,8 +75,8 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver { rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); rtp_rtcp_->SetREMBStatus(true); rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); - rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, - kAbsoluteSendTimeExtensionId); + rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset, + kTransmissionTimeOffsetExtensionId); AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory; const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; remote_bitrate_estimator_.reset( @@ -218,8 +218,8 @@ class LowRateStreamObserver : public test::DirectTransport, rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); rtp_rtcp_->SetREMBStatus(true); rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); - rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, - kAbsoluteSendTimeExtensionId); + rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset, + kTransmissionTimeOffsetExtensionId); AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory; const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 10000; remote_bitrate_estimator_.reset( @@ -421,9 +421,6 @@ class RampUpTest : public ::testing::Test { Clock::GetRealTimeClock()); Call::Config call_config(&stream_observer); - webrtc::Config webrtc_config; - call_config.webrtc_config = &webrtc_config; - webrtc_config.Set(new PaddingStrategy(rtx)); scoped_ptr call(Call::Create(call_config)); VideoSendStream::Config send_config = call->GetDefaultSendConfig(); @@ -447,9 +444,11 @@ class RampUpTest : public ::testing::Test { if (rtx) { send_config.rtp.rtx.payload_type = 96; send_config.rtp.rtx.ssrcs = rtx_ssrcs; + send_config.rtp.rtx.pad_with_redundant_payloads = true; } send_config.rtp.extensions.push_back( - RtpExtension(RtpExtension::kAbsSendTime, kAbsoluteSendTimeExtensionId)); + RtpExtension(RtpExtension::kTOffset, + kTransmissionTimeOffsetExtensionId)); if (num_streams == 1) { // For single stream rampup until 1mbps @@ -514,7 +513,8 @@ class RampUpTest : public ::testing::Test { send_config.rtp.ssrcs.insert( send_config.rtp.ssrcs.begin(), ssrcs.begin(), ssrcs.end()); send_config.rtp.extensions.push_back( - RtpExtension(RtpExtension::kAbsSendTime, kAbsoluteSendTimeExtensionId)); + RtpExtension(RtpExtension::kTOffset, + kTransmissionTimeOffsetExtensionId)); send_config.suspend_below_min_bitrate = true; send_config.pacing = true; @@ -581,8 +581,7 @@ TEST_F(RampUpTest, SimulcastWithPacing) { RunRampUpTest(true, false, 3); } -// TODO(pbos): Re-enable, webrtc:2992. -TEST_F(RampUpTest, DISABLED_SimulcastWithPacingAndRtx) { +TEST_F(RampUpTest, SimulcastWithPacingAndRtx) { RunRampUpTest(true, true, 3); } diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 8a43387553..fa13c997de 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -381,8 +381,10 @@ bool VideoSendStream::ReconfigureVideoEncoder( static_cast(i)); } - if (config_.rtp.rtx.ssrcs.empty()) + if (config_.rtp.rtx.ssrcs.empty()) { + assert(!config_.rtp.rtx.pad_with_redundant_payloads); return true; + } // Set up RTX. assert(config_.rtp.rtx.ssrcs.size() == config_.rtp.ssrcs.size()); @@ -393,6 +395,10 @@ bool VideoSendStream::ReconfigureVideoEncoder( static_cast(i)); } + if (config_.rtp.rtx.pad_with_redundant_payloads) { + rtp_rtcp_->SetPadWithRedundantPayloads(channel_, true); + } + assert(config_.rtp.rtx.payload_type >= 0); rtp_rtcp_->SetRtxSendPayloadType(channel_, config_.rtp.rtx.payload_type); diff --git a/webrtc/video_engine/include/vie_rtp_rtcp.h b/webrtc/video_engine/include/vie_rtp_rtcp.h index 46d80989c9..972ca58486 100644 --- a/webrtc/video_engine/include/vie_rtp_rtcp.h +++ b/webrtc/video_engine/include/vie_rtp_rtcp.h @@ -134,6 +134,15 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP { virtual int SetRtxSendPayloadType(const int video_channel, const uint8_t payload_type) = 0; + // This enables sending redundant payloads when padding up the bitrate instead + // of sending dummy padding packets. This feature is off by default and will + // only have an effect if RTX is also enabled. + // TODO(holmer): Remove default implementation once this has been implemented + // in libjingle. + virtual int SetPadWithRedundantPayloads(int video_channel, bool enable) { + return 0; + } + virtual int SetRtxReceivePayloadType(const int video_channel, const uint8_t payload_type) = 0; diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index b830d86aa4..62bb095996 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -89,6 +89,7 @@ ViEChannel::ViEChannel(int32_t channel_id, intra_frame_observer_(intra_frame_observer), rtt_stats_(rtt_stats), paced_sender_(paced_sender), + pad_with_redundant_payloads_(false), bandwidth_observer_(bandwidth_observer), send_timestamp_extension_id_(kInvalidRtpExtensionId), absolute_send_time_extension_id_(kInvalidRtpExtensionId), @@ -102,8 +103,7 @@ ViEChannel::ViEChannel(int32_t channel_id, sender_(sender), nack_history_size_sender_(kSendSidePacketHistorySize), max_nack_reordering_threshold_(kMaxPacketAgeToNack), - pre_render_callback_(NULL), - config_(config) { + pre_render_callback_(NULL) { RtpRtcp::Configuration configuration; configuration.id = ViEModuleId(engine_id, channel_id); configuration.audio = false; @@ -860,19 +860,46 @@ int32_t ViEChannel::GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]) { return 0; } +void ViEChannel::SetPadWithRedundantPayloads(bool enable) { + { + CriticalSectionScoped cs(callback_cs_.get()); + pad_with_redundant_payloads_ = enable; + } + int mode; + uint32_t ssrc; + int payload_type; + rtp_rtcp_->RTXSendStatus(&mode, &ssrc, &payload_type); + if (mode != kRtxOff) { + // Since RTX was already enabled we have to reset it with payload-based + // padding on. + SetRtxSendStatus(true); + } +} + int ViEChannel::SetRtxSendPayloadType(int payload_type) { - int rtx_settings = kRtxRetransmitted; - if (config_.Get().redundant_payloads) - rtx_settings |= kRtxRedundantPayloads; rtp_rtcp_->SetRtxSendPayloadType(payload_type); + for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); + it != simulcast_rtp_rtcp_.end(); it++) { + (*it)->SetRtxSendPayloadType(payload_type); + } + SetRtxSendStatus(true); + return 0; +} + +void ViEChannel::SetRtxSendStatus(bool enable) { + int rtx_settings = kRtxOff; + if (enable) { + CriticalSectionScoped cs(callback_cs_.get()); + rtx_settings = kRtxRetransmitted; + if (pad_with_redundant_payloads_) + rtx_settings |= kRtxRedundantPayloads; + } rtp_rtcp_->SetRTXSendStatus(rtx_settings); CriticalSectionScoped cs(rtp_rtcp_cs_.get()); for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->SetRtxSendPayloadType(payload_type); (*it)->SetRTXSendStatus(rtx_settings); } - return 0; } void ViEChannel::SetRtxReceivePayloadType(int payload_type) { diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index 4837d7d62a..23b7e5e592 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -145,6 +145,8 @@ class ViEChannel int32_t GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]); int SetRtxSendPayloadType(int payload_type); + // Only has an effect once RTX is enabled. + void SetPadWithRedundantPayloads(bool enable); void SetRtxReceivePayloadType(int payload_type); // Sets the starting sequence number, must be called before StartSend. @@ -370,6 +372,7 @@ class ViEChannel const unsigned char payload_typeFEC); // Compute NACK list parameters for the buffering mode. int GetRequiredNackListSize(int target_delay_ms); + void SetRtxSendStatus(bool enable); int32_t channel_id_; int32_t engine_id_; @@ -403,6 +406,7 @@ class ViEChannel RtcpIntraFrameObserver* intra_frame_observer_; RtcpRttStats* rtt_stats_; PacedSender* paced_sender_; + bool pad_with_redundant_payloads_; scoped_ptr bandwidth_observer_; int send_timestamp_extension_id_; @@ -426,7 +430,6 @@ class ViEChannel int nack_history_size_sender_; int max_nack_reordering_threshold_; I420FrameCallback* pre_render_callback_; - const Config& config_; }; } // namespace webrtc diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.cc b/webrtc/video_engine/vie_rtp_rtcp_impl.cc index 3ee5d5214b..53610b4a32 100644 --- a/webrtc/video_engine/vie_rtp_rtcp_impl.cc +++ b/webrtc/video_engine/vie_rtp_rtcp_impl.cc @@ -207,6 +207,21 @@ int ViERTP_RTCPImpl::SetRtxSendPayloadType(const int video_channel, return 0; } +int ViERTP_RTCPImpl::SetPadWithRedundantPayloads(int video_channel, + bool enable) { + LOG_F(LS_INFO) << "channel: " << video_channel + << " pad with redundant payloads: " << (enable ? "enable" : + "disable"); + ViEChannelManagerScoped cs(*(shared_data_->channel_manager())); + ViEChannel* vie_channel = cs.Channel(video_channel); + if (!vie_channel) { + shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); + return -1; + } + vie_channel->SetPadWithRedundantPayloads(enable); + return 0; +} + int ViERTP_RTCPImpl::SetRtxReceivePayloadType(const int video_channel, const uint8_t payload_type) { LOG_F(LS_INFO) << "channel: " << video_channel diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.h b/webrtc/video_engine/vie_rtp_rtcp_impl.h index 1702d63e2a..5eec0efe14 100644 --- a/webrtc/video_engine/vie_rtp_rtcp_impl.h +++ b/webrtc/video_engine/vie_rtp_rtcp_impl.h @@ -41,6 +41,7 @@ class ViERTP_RTCPImpl unsigned int CSRCs[kRtpCsrcSize]) const; virtual int SetRtxSendPayloadType(const int video_channel, const uint8_t payload_type); + virtual int SetPadWithRedundantPayloads(int video_channel, bool enable); virtual int SetRtxReceivePayloadType(const int video_channel, const uint8_t payload_type); virtual int SetStartSequenceNumber(const int video_channel, diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h index b33f389347..f8af797d39 100644 --- a/webrtc/video_send_stream.h +++ b/webrtc/video_send_stream.h @@ -106,13 +106,17 @@ class VideoSendStream { // Settings for RTP retransmission payload format, see RFC 4588 for // details. struct Rtx { - Rtx() : payload_type(-1) {} + Rtx() : payload_type(-1), pad_with_redundant_payloads(false) {} std::string ToString() const; // SSRCs to use for the RTX streams. std::vector ssrcs; // Payload type to use for the RTX stream. int payload_type; + // Use redundant payloads to pad the bitrate. Instead of padding with + // randomized packets, we will preemptively retransmit media packets on + // the RTX stream. + bool pad_with_redundant_payloads; } rtx; // RTCP CNAME, see RFC 3550.