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:
stefan@webrtc.org 2014-06-11 13:41:36 +00:00
parent 5d223a7d2d
commit fbb567dacd
8 changed files with 86 additions and 22 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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.