Prepare WebRtcVideoReceiveStream for configuration changes.
This is a step in the direction of being able to make configuration
changes without having to tear down and reconstruct the object
during renegotiation.
Bug: none
Change-Id: If594fd41f3a561060f64212c479a25d19adf8598
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/223740
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34402}
diff --git a/call/video_receive_stream.cc b/call/video_receive_stream.cc
index 0b95d66..d0518b6 100644
--- a/call/video_receive_stream.cc
+++ b/call/video_receive_stream.cc
@@ -14,10 +14,18 @@
namespace webrtc {
+VideoReceiveStream::Decoder::Decoder(SdpVideoFormat video_format,
+ int payload_type)
+ : video_format(std::move(video_format)), payload_type(payload_type) {}
VideoReceiveStream::Decoder::Decoder() : video_format("Unset") {}
VideoReceiveStream::Decoder::Decoder(const Decoder&) = default;
VideoReceiveStream::Decoder::~Decoder() = default;
+bool VideoReceiveStream::Decoder::operator==(const Decoder& other) const {
+ return payload_type == other.payload_type &&
+ video_format == other.video_format;
+}
+
std::string VideoReceiveStream::Decoder::ToString() const {
char buf[1024];
rtc::SimpleStringBuilder ss(buf);
diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h
index 61edc88..86e5052 100644
--- a/call/video_receive_stream.h
+++ b/call/video_receive_stream.h
@@ -59,9 +59,13 @@
// TODO(mflodman) Move all these settings to VideoDecoder and move the
// declaration to common_types.h.
struct Decoder {
+ Decoder(SdpVideoFormat video_format, int payload_type);
Decoder();
Decoder(const Decoder&);
~Decoder();
+
+ bool operator==(const Decoder& other) const;
+
std::string ToString() const;
SdpVideoFormat video_format;
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index 897aa77..38a210e 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -2875,43 +2875,84 @@
return rtp_parameters;
}
-void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
+bool WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
const std::vector<VideoCodecSettings>& recv_codecs) {
RTC_DCHECK(!recv_codecs.empty());
- config_.decoders.clear();
- config_.rtp.rtx_associated_payload_types.clear();
- config_.rtp.raw_payload_types.clear();
+ std::map<int, int> rtx_associated_payload_types;
+ std::set<int> raw_payload_types;
+ std::vector<webrtc::VideoReceiveStream::Decoder> decoders;
for (const auto& recv_codec : recv_codecs) {
- webrtc::VideoReceiveStream::Decoder decoder;
- decoder.payload_type = recv_codec.codec.id;
- decoder.video_format =
- webrtc::SdpVideoFormat(recv_codec.codec.name, recv_codec.codec.params);
- config_.decoders.push_back(decoder);
- config_.rtp.rtx_associated_payload_types[recv_codec.rtx_payload_type] =
- recv_codec.codec.id;
+ decoders.emplace_back(
+ webrtc::SdpVideoFormat(recv_codec.codec.name, recv_codec.codec.params),
+ recv_codec.codec.id);
+ rtx_associated_payload_types.insert(
+ {recv_codec.rtx_payload_type, recv_codec.codec.id});
if (recv_codec.codec.packetization == kPacketizationParamRaw) {
- config_.rtp.raw_payload_types.insert(recv_codec.codec.id);
+ raw_payload_types.insert(recv_codec.codec.id);
}
}
- const auto& codec = recv_codecs.front();
- config_.rtp.ulpfec_payload_type = codec.ulpfec.ulpfec_payload_type;
- config_.rtp.red_payload_type = codec.ulpfec.red_payload_type;
+ bool recreate_needed = (stream_ == nullptr);
- config_.rtp.lntf.enabled = HasLntf(codec.codec);
- config_.rtp.nack.rtp_history_ms = HasNack(codec.codec) ? kNackHistoryMs : 0;
+ const auto& codec = recv_codecs.front();
+ if (config_.rtp.ulpfec_payload_type != codec.ulpfec.ulpfec_payload_type) {
+ config_.rtp.ulpfec_payload_type = codec.ulpfec.ulpfec_payload_type;
+ recreate_needed = true;
+ }
+
+ if (config_.rtp.red_payload_type != codec.ulpfec.red_payload_type) {
+ config_.rtp.red_payload_type = codec.ulpfec.red_payload_type;
+ recreate_needed = true;
+ }
+
+ const bool has_lntf = HasLntf(codec.codec);
+ if (config_.rtp.lntf.enabled != has_lntf) {
+ config_.rtp.lntf.enabled = has_lntf;
+ recreate_needed = true;
+ }
+
+ const int rtp_history_ms = HasNack(codec.codec) ? kNackHistoryMs : 0;
+ if (rtp_history_ms != config_.rtp.nack.rtp_history_ms) {
+ config_.rtp.nack.rtp_history_ms = rtp_history_ms;
+ recreate_needed = true;
+ }
+
// The rtx-time parameter can be used to override the hardcoded default for
// the NACK buffer length.
if (codec.rtx_time != -1 && config_.rtp.nack.rtp_history_ms != 0) {
config_.rtp.nack.rtp_history_ms = codec.rtx_time;
+ recreate_needed = true;
}
- config_.rtp.rtcp_xr.receiver_reference_time_report = HasRrtr(codec.codec);
+
+ const bool has_rtr = HasRrtr(codec.codec);
+ if (has_rtr != config_.rtp.rtcp_xr.receiver_reference_time_report) {
+ config_.rtp.rtcp_xr.receiver_reference_time_report = has_rtr;
+ recreate_needed = true;
+ }
+
if (codec.ulpfec.red_rtx_payload_type != -1) {
- config_.rtp
- .rtx_associated_payload_types[codec.ulpfec.red_rtx_payload_type] =
+ rtx_associated_payload_types[codec.ulpfec.red_rtx_payload_type] =
codec.ulpfec.red_payload_type;
}
+
+ if (config_.rtp.rtx_associated_payload_types !=
+ rtx_associated_payload_types) {
+ rtx_associated_payload_types.swap(config_.rtp.rtx_associated_payload_types);
+ recreate_needed = true;
+ }
+
+ if (raw_payload_types != config_.rtp.raw_payload_types) {
+ raw_payload_types.swap(config_.rtp.raw_payload_types);
+ recreate_needed = true;
+ }
+
+ if (decoders != config_.decoders) {
+ decoders.swap(config_.decoders);
+ recreate_needed = true;
+ }
+
+ return recreate_needed;
}
void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetLocalSsrc(
@@ -2973,8 +3014,7 @@
const ChangedRecvParameters& params) {
bool video_needs_recreation = false;
if (params.codec_settings) {
- ConfigureCodecs(*params.codec_settings);
- video_needs_recreation = true;
+ video_needs_recreation = ConfigureCodecs(*params.codec_settings);
}
if (params.rtp_header_extensions) {
diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h
index e79ebbf..a67a010 100644
--- a/media/engine/webrtc_video_engine.h
+++ b/media/engine/webrtc_video_engine.h
@@ -483,7 +483,10 @@
private:
void RecreateWebRtcVideoStream();
- void ConfigureCodecs(const std::vector<VideoCodecSettings>& recv_codecs);
+ // Applies a new receive codecs configration to `config_`. Returns true
+ // if the internal stream needs to be reconstructed, or false if no changes
+ // were applied.
+ bool ConfigureCodecs(const std::vector<VideoCodecSettings>& recv_codecs);
std::string GetCodecNameFromPayloadType(int payload_type);