Adding reduced size RTCP configuration down to the video stream level.
Still waiting to turn on negotiation (in mediasession.cc) until we verify it's working as expected. BUG=webrtc:4868 Review URL: https://codereview.webrtc.org/1418123003 Cr-Commit-Position: refs/heads/master@{#10958}
This commit is contained in:
parent
ee4082137b
commit
1387149ad1
@ -122,6 +122,7 @@ static const char kLineTypeAttributes = 'a';
|
||||
static const char kAttributeGroup[] = "group";
|
||||
static const char kAttributeMid[] = "mid";
|
||||
static const char kAttributeRtcpMux[] = "rtcp-mux";
|
||||
static const char kAttributeRtcpReducedSize[] = "rtcp-rsize";
|
||||
static const char kAttributeSsrc[] = "ssrc";
|
||||
static const char kSsrcAttributeCname[] = "cname";
|
||||
static const char kAttributeExtmap[] = "extmap";
|
||||
@ -1400,6 +1401,13 @@ void BuildRtpContentAttributes(
|
||||
AddLine(os.str(), message);
|
||||
}
|
||||
|
||||
// RFC 5506
|
||||
// a=rtcp-rsize
|
||||
if (media_desc->rtcp_reduced_size()) {
|
||||
InitAttrLine(kAttributeRtcpReducedSize, &os);
|
||||
AddLine(os.str(), message);
|
||||
}
|
||||
|
||||
// RFC 4568
|
||||
// a=crypto:<tag> <crypto-suite> <key-params> [<session-params>]
|
||||
for (std::vector<CryptoParams>::const_iterator it =
|
||||
@ -2553,6 +2561,8 @@ bool ParseContent(const std::string& message,
|
||||
//
|
||||
if (HasAttribute(line, kAttributeRtcpMux)) {
|
||||
media_desc->set_rtcp_mux(true);
|
||||
} else if (HasAttribute(line, kAttributeRtcpReducedSize)) {
|
||||
media_desc->set_rtcp_reduced_size(true);
|
||||
} else if (HasAttribute(line, kAttributeSsrcGroup)) {
|
||||
if (!ParseSsrcGroupAttribute(line, &ssrc_groups, error)) {
|
||||
return false;
|
||||
|
||||
@ -153,6 +153,7 @@ static const char kSdpFullString[] =
|
||||
"a=mid:audio_content_name\r\n"
|
||||
"a=sendrecv\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=rtcp-rsize\r\n"
|
||||
"a=crypto:1 AES_CM_128_HMAC_SHA1_32 "
|
||||
"inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 "
|
||||
"dummy_session_params\r\n"
|
||||
@ -220,6 +221,7 @@ static const char kSdpString[] =
|
||||
"a=mid:audio_content_name\r\n"
|
||||
"a=sendrecv\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=rtcp-rsize\r\n"
|
||||
"a=crypto:1 AES_CM_128_HMAC_SHA1_32 "
|
||||
"inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 "
|
||||
"dummy_session_params\r\n"
|
||||
@ -704,6 +706,7 @@ class WebRtcSdpTest : public testing::Test {
|
||||
AudioContentDescription* CreateAudioContentDescription() {
|
||||
AudioContentDescription* audio = new AudioContentDescription();
|
||||
audio->set_rtcp_mux(true);
|
||||
audio->set_rtcp_reduced_size(true);
|
||||
StreamParams audio_stream1;
|
||||
audio_stream1.id = kAudioTrackId1;
|
||||
audio_stream1.cname = kStream1Cname;
|
||||
@ -735,6 +738,9 @@ class WebRtcSdpTest : public testing::Test {
|
||||
// rtcp_mux
|
||||
EXPECT_EQ(cd1->rtcp_mux(), cd2->rtcp_mux());
|
||||
|
||||
// rtcp_reduced_size
|
||||
EXPECT_EQ(cd1->rtcp_reduced_size(), cd2->rtcp_reduced_size());
|
||||
|
||||
// cryptos
|
||||
EXPECT_EQ(cd1->cryptos().size(), cd2->cryptos().size());
|
||||
if (cd1->cryptos().size() != cd2->cryptos().size()) {
|
||||
|
||||
@ -927,6 +927,10 @@ struct DataMediaInfo {
|
||||
std::vector<DataReceiverInfo> receivers;
|
||||
};
|
||||
|
||||
struct RtcpParameters {
|
||||
bool reduced_size = false;
|
||||
};
|
||||
|
||||
template <class Codec>
|
||||
struct RtpParameters {
|
||||
virtual std::string ToString() const {
|
||||
@ -941,6 +945,7 @@ struct RtpParameters {
|
||||
std::vector<Codec> codecs;
|
||||
std::vector<RtpHeaderExtension> extensions;
|
||||
// TODO(pthatcher): Add streams.
|
||||
RtcpParameters rtcp;
|
||||
};
|
||||
|
||||
template <class Codec, class Options>
|
||||
|
||||
@ -792,10 +792,20 @@ bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) {
|
||||
LOG(LS_INFO) << "SetSendParameters: " << params.ToString();
|
||||
// TODO(pbos): Refactor this to only recreate the send streams once
|
||||
// instead of 4 times.
|
||||
return (SetSendCodecs(params.codecs) &&
|
||||
SetSendRtpHeaderExtensions(params.extensions) &&
|
||||
SetMaxSendBandwidth(params.max_bandwidth_bps) &&
|
||||
SetOptions(params.options));
|
||||
if (!SetSendCodecs(params.codecs) ||
|
||||
!SetSendRtpHeaderExtensions(params.extensions) ||
|
||||
!SetMaxSendBandwidth(params.max_bandwidth_bps) ||
|
||||
!SetOptions(params.options)) {
|
||||
return false;
|
||||
}
|
||||
if (send_params_.rtcp.reduced_size != params.rtcp.reduced_size) {
|
||||
rtc::CritScope stream_lock(&stream_crit_);
|
||||
for (auto& kv : send_streams_) {
|
||||
kv.second->SetSendParameters(params);
|
||||
}
|
||||
}
|
||||
send_params_ = params;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) {
|
||||
@ -803,8 +813,18 @@ bool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) {
|
||||
LOG(LS_INFO) << "SetRecvParameters: " << params.ToString();
|
||||
// TODO(pbos): Refactor this to only recreate the recv streams once
|
||||
// instead of twice.
|
||||
return (SetRecvCodecs(params.codecs) &&
|
||||
SetRecvRtpHeaderExtensions(params.extensions));
|
||||
if (!SetRecvCodecs(params.codecs) ||
|
||||
!SetRecvRtpHeaderExtensions(params.extensions)) {
|
||||
return false;
|
||||
}
|
||||
if (recv_params_.rtcp.reduced_size != params.rtcp.reduced_size) {
|
||||
rtc::CritScope stream_lock(&stream_crit_);
|
||||
for (auto& kv : receive_streams_) {
|
||||
kv.second->SetRecvParameters(params);
|
||||
}
|
||||
}
|
||||
recv_params_ = params;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string WebRtcVideoChannel2::CodecSettingsVectorToString(
|
||||
@ -1025,15 +1045,10 @@ bool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) {
|
||||
webrtc::VideoSendStream::Config config(this);
|
||||
config.overuse_callback = this;
|
||||
|
||||
WebRtcVideoSendStream* stream =
|
||||
new WebRtcVideoSendStream(call_,
|
||||
sp,
|
||||
config,
|
||||
external_encoder_factory_,
|
||||
options_,
|
||||
bitrate_config_.max_bitrate_bps,
|
||||
send_codec_,
|
||||
send_rtp_extensions_);
|
||||
WebRtcVideoSendStream* stream = new WebRtcVideoSendStream(
|
||||
call_, sp, config, external_encoder_factory_, options_,
|
||||
bitrate_config_.max_bitrate_bps, send_codec_, send_rtp_extensions_,
|
||||
send_params_);
|
||||
|
||||
uint32_t ssrc = sp.first_ssrc();
|
||||
RTC_DCHECK(ssrc != 0);
|
||||
@ -1175,6 +1190,9 @@ void WebRtcVideoChannel2::ConfigureReceiverRtp(
|
||||
config->rtp.local_ssrc = rtcp_receiver_report_ssrc_;
|
||||
|
||||
config->rtp.extensions = recv_rtp_extensions_;
|
||||
config->rtp.rtcp_mode = recv_params_.rtcp.reduced_size
|
||||
? webrtc::RtcpMode::kReducedSize
|
||||
: webrtc::RtcpMode::kCompound;
|
||||
|
||||
// TODO(pbos): This protection is against setting the same local ssrc as
|
||||
// remote which is not permitted by the lower-level API. RTCP requires a
|
||||
@ -1661,7 +1679,10 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream(
|
||||
const VideoOptions& options,
|
||||
int max_bitrate_bps,
|
||||
const rtc::Optional<VideoCodecSettings>& codec_settings,
|
||||
const std::vector<webrtc::RtpExtension>& rtp_extensions)
|
||||
const std::vector<webrtc::RtpExtension>& rtp_extensions,
|
||||
// TODO(deadbeef): Don't duplicate information between send_params,
|
||||
// rtp_extensions, options, etc.
|
||||
const VideoSendParameters& send_params)
|
||||
: ssrcs_(sp.ssrcs),
|
||||
ssrc_groups_(sp.ssrc_groups),
|
||||
call_(call),
|
||||
@ -1682,6 +1703,9 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream(
|
||||
¶meters_.config.rtp.rtx.ssrcs);
|
||||
parameters_.config.rtp.c_name = sp.cname;
|
||||
parameters_.config.rtp.extensions = rtp_extensions;
|
||||
parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size
|
||||
? webrtc::RtcpMode::kReducedSize
|
||||
: webrtc::RtcpMode::kCompound;
|
||||
|
||||
if (codec_settings) {
|
||||
SetCodec(*codec_settings);
|
||||
@ -1998,6 +2022,18 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions(
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters(
|
||||
const VideoSendParameters& send_params) {
|
||||
rtc::CritScope cs(&lock_);
|
||||
parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size
|
||||
? webrtc::RtcpMode::kReducedSize
|
||||
: webrtc::RtcpMode::kCompound;
|
||||
if (stream_ != nullptr) {
|
||||
LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters";
|
||||
RecreateWebRtcStream();
|
||||
}
|
||||
}
|
||||
|
||||
webrtc::VideoEncoderConfig
|
||||
WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig(
|
||||
const Dimensions& dimensions,
|
||||
@ -2435,6 +2471,15 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions(
|
||||
RecreateWebRtcStream();
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvParameters(
|
||||
const VideoRecvParameters& recv_params) {
|
||||
config_.rtp.rtcp_mode = recv_params.rtcp.reduced_size
|
||||
? webrtc::RtcpMode::kReducedSize
|
||||
: webrtc::RtcpMode::kCompound;
|
||||
LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters";
|
||||
RecreateWebRtcStream();
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() {
|
||||
if (stream_ != NULL) {
|
||||
call_->DestroyVideoReceiveStream(stream_);
|
||||
|
||||
@ -249,13 +249,17 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
|
||||
const VideoOptions& options,
|
||||
int max_bitrate_bps,
|
||||
const rtc::Optional<VideoCodecSettings>& codec_settings,
|
||||
const std::vector<webrtc::RtpExtension>& rtp_extensions);
|
||||
const std::vector<webrtc::RtpExtension>& rtp_extensions,
|
||||
const VideoSendParameters& send_params);
|
||||
~WebRtcVideoSendStream();
|
||||
|
||||
void SetOptions(const VideoOptions& options);
|
||||
void SetCodec(const VideoCodecSettings& codec);
|
||||
void SetRtpExtensions(
|
||||
const std::vector<webrtc::RtpExtension>& rtp_extensions);
|
||||
// TODO(deadbeef): Move logic from SetCodec/SetRtpExtensions/etc.
|
||||
// into this method. Currently this method only sets the RTCP mode.
|
||||
void SetSendParameters(const VideoSendParameters& send_params);
|
||||
|
||||
void InputFrame(VideoCapturer* capturer, const VideoFrame* frame);
|
||||
bool SetCapturer(VideoCapturer* capturer);
|
||||
@ -405,6 +409,9 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
|
||||
bool transport_cc_enabled);
|
||||
void SetRecvCodecs(const std::vector<VideoCodecSettings>& recv_codecs);
|
||||
void SetRtpExtensions(const std::vector<webrtc::RtpExtension>& extensions);
|
||||
// TODO(deadbeef): Move logic from SetRecvCodecs/SetRtpExtensions/etc.
|
||||
// into this method. Currently this method only sets the RTCP mode.
|
||||
void SetRecvParameters(const VideoRecvParameters& recv_params);
|
||||
|
||||
void RenderFrame(const webrtc::VideoFrame& frame,
|
||||
int time_to_render_ms) override;
|
||||
@ -525,6 +532,10 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
|
||||
std::vector<webrtc::RtpExtension> recv_rtp_extensions_;
|
||||
webrtc::Call::Config::BitrateConfig bitrate_config_;
|
||||
VideoOptions options_;
|
||||
// TODO(deadbeef): Don't duplicate information between
|
||||
// send_params/recv_params, rtp_extensions, options, etc.
|
||||
VideoSendParameters send_params_;
|
||||
VideoRecvParameters recv_params_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -2418,6 +2418,42 @@ TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) {
|
||||
channel_->SetInterface(NULL);
|
||||
}
|
||||
|
||||
// This test verifies that the RTCP reduced size mode is properly applied to
|
||||
// send video streams.
|
||||
TEST_F(WebRtcVideoChannel2Test, TestSetSendRtcpReducedSize) {
|
||||
// Create stream, expecting that default mode is "compound".
|
||||
FakeVideoSendStream* stream1 = AddSendStream();
|
||||
EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
|
||||
|
||||
// Now enable reduced size mode.
|
||||
send_parameters_.rtcp.reduced_size = true;
|
||||
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
|
||||
stream1 = fake_call_->GetVideoSendStreams()[0];
|
||||
EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
|
||||
|
||||
// Create a new stream and ensure it picks up the reduced size mode.
|
||||
FakeVideoSendStream* stream2 = AddSendStream();
|
||||
EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
|
||||
}
|
||||
|
||||
// This test verifies that the RTCP reduced size mode is properly applied to
|
||||
// receive video streams.
|
||||
TEST_F(WebRtcVideoChannel2Test, TestSetRecvRtcpReducedSize) {
|
||||
// Create stream, expecting that default mode is "compound".
|
||||
FakeVideoReceiveStream* stream1 = AddRecvStream();
|
||||
EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
|
||||
|
||||
// Now enable reduced size mode.
|
||||
recv_parameters_.rtcp.reduced_size = true;
|
||||
EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
|
||||
stream1 = fake_call_->GetVideoReceiveStreams()[0];
|
||||
EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
|
||||
|
||||
// Create a new stream and ensure it picks up the reduced size mode.
|
||||
FakeVideoReceiveStream* stream2 = AddRecvStream();
|
||||
EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
|
||||
EXPECT_EQ(webrtc::kNetworkUp, fake_call_->GetNetworkState());
|
||||
|
||||
|
||||
@ -152,6 +152,7 @@ void RtpParametersFromMediaDescription(
|
||||
if (desc->rtp_header_extensions_set()) {
|
||||
params->extensions = desc->rtp_header_extensions();
|
||||
}
|
||||
params->rtcp.reduced_size = desc->rtcp_reduced_size();
|
||||
}
|
||||
|
||||
template <class Codec, class Options>
|
||||
|
||||
@ -760,6 +760,11 @@ static bool CreateMediaContentOffer(
|
||||
offer->set_crypto_required(CT_SDES);
|
||||
}
|
||||
offer->set_rtcp_mux(options.rtcp_mux_enabled);
|
||||
// TODO(deadbeef): Once we're sure this works correctly, enable it in
|
||||
// CreateOffer.
|
||||
// if (offer->type() == cricket::MEDIA_TYPE_VIDEO) {
|
||||
// offer->set_rtcp_reduced_size(true);
|
||||
// }
|
||||
offer->set_multistream(options.is_muc);
|
||||
offer->set_rtp_header_extensions(rtp_extensions);
|
||||
|
||||
@ -1038,6 +1043,11 @@ static bool CreateMediaContentAnswer(
|
||||
answer->set_rtp_header_extensions(negotiated_rtp_extensions);
|
||||
|
||||
answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux());
|
||||
// TODO(deadbeef): Once we're sure this works correctly, enable it in
|
||||
// CreateAnswer.
|
||||
// if (answer->type() == cricket::MEDIA_TYPE_VIDEO) {
|
||||
// answer->set_rtcp_reduced_size(offer->rtcp_reduced_size());
|
||||
// }
|
||||
|
||||
if (sdes_policy != SEC_DISABLED) {
|
||||
CryptoParams crypto;
|
||||
|
||||
@ -167,17 +167,7 @@ struct MediaSessionOptions {
|
||||
// "content" (as used in XEP-0166) descriptions for voice and video.
|
||||
class MediaContentDescription : public ContentDescription {
|
||||
public:
|
||||
MediaContentDescription()
|
||||
: rtcp_mux_(false),
|
||||
bandwidth_(kAutoBandwidth),
|
||||
crypto_required_(CT_NONE),
|
||||
rtp_header_extensions_set_(false),
|
||||
multistream_(false),
|
||||
conference_mode_(false),
|
||||
partial_(false),
|
||||
buffered_mode_latency_(kBufferedModeDisabled),
|
||||
direction_(MD_SENDRECV) {
|
||||
}
|
||||
MediaContentDescription() {}
|
||||
|
||||
virtual MediaType type() const = 0;
|
||||
virtual bool has_codecs() const = 0;
|
||||
@ -195,6 +185,11 @@ class MediaContentDescription : public ContentDescription {
|
||||
bool rtcp_mux() const { return rtcp_mux_; }
|
||||
void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
|
||||
|
||||
bool rtcp_reduced_size() const { return rtcp_reduced_size_; }
|
||||
void set_rtcp_reduced_size(bool reduced_size) {
|
||||
rtcp_reduced_size_ = reduced_size;
|
||||
}
|
||||
|
||||
int bandwidth() const { return bandwidth_; }
|
||||
void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
|
||||
|
||||
@ -291,19 +286,20 @@ class MediaContentDescription : public ContentDescription {
|
||||
int buffered_mode_latency() const { return buffered_mode_latency_; }
|
||||
|
||||
protected:
|
||||
bool rtcp_mux_;
|
||||
int bandwidth_;
|
||||
bool rtcp_mux_ = false;
|
||||
bool rtcp_reduced_size_ = false;
|
||||
int bandwidth_ = kAutoBandwidth;
|
||||
std::string protocol_;
|
||||
std::vector<CryptoParams> cryptos_;
|
||||
CryptoType crypto_required_;
|
||||
CryptoType crypto_required_ = CT_NONE;
|
||||
std::vector<RtpHeaderExtension> rtp_header_extensions_;
|
||||
bool rtp_header_extensions_set_;
|
||||
bool multistream_;
|
||||
bool rtp_header_extensions_set_ = false;
|
||||
bool multistream_ = false;
|
||||
StreamParamsVec streams_;
|
||||
bool conference_mode_;
|
||||
bool partial_;
|
||||
int buffered_mode_latency_;
|
||||
MediaContentDirection direction_;
|
||||
bool conference_mode_ = false;
|
||||
bool partial_ = false;
|
||||
int buffered_mode_latency_ = kBufferedModeDisabled;
|
||||
MediaContentDirection direction_ = MD_SENDRECV;
|
||||
};
|
||||
|
||||
template <class C>
|
||||
|
||||
@ -516,7 +516,7 @@ void VideoSendStream::SignalNetworkState(NetworkState state) {
|
||||
// When it goes down, disable RTCP afterwards. This ensures that any packets
|
||||
// sent due to the network state changed will not be dropped.
|
||||
if (state == kNetworkUp)
|
||||
vie_channel_->SetRTCPMode(RtcpMode::kCompound);
|
||||
vie_channel_->SetRTCPMode(config_.rtp.rtcp_mode);
|
||||
vie_encoder_->SetNetworkTransmissionState(state == kNetworkUp);
|
||||
if (state == kNetworkDown)
|
||||
vie_channel_->SetRTCPMode(RtcpMode::kOff);
|
||||
|
||||
@ -100,6 +100,9 @@ class VideoSendStream : public SendStream {
|
||||
|
||||
std::vector<uint32_t> ssrcs;
|
||||
|
||||
// See RtcpMode for description.
|
||||
RtcpMode rtcp_mode = RtcpMode::kCompound;
|
||||
|
||||
// Max RTP packet size delivered to send transport from VideoEngine.
|
||||
size_t max_packet_size = kDefaultMaxPacketSize;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user