Add APIs to enable padding with redundant payloads.
Also makes a small change to the tests to remove flakiness. We can't do BWE only based on rtp timestamps if we preemptively resend packets instead of sending padding packets. BUG=1812,2992 R=mflodman@webrtc.org, pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/15719004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6400 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
5d223a7d2d
commit
fbb567dacd
@ -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<PaddingStrategy>(new PaddingStrategy(rtx));
|
||||
scoped_ptr<Call> 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);
|
||||
}
|
||||
|
||||
|
@ -381,8 +381,10 @@ bool VideoSendStream::ReconfigureVideoEncoder(
|
||||
static_cast<unsigned char>(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<unsigned char>(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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<PaddingStrategy>().redundant_payloads)
|
||||
rtx_settings |= kRtxRedundantPayloads;
|
||||
rtp_rtcp_->SetRtxSendPayloadType(payload_type);
|
||||
for (std::list<RtpRtcp*>::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<RtpRtcp*>::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) {
|
||||
|
@ -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<RtcpBandwidthObserver> 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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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<uint32_t> 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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user