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}
This commit is contained in:
Tommi 2021-07-01 12:21:21 +02:00 committed by WebRTC LUCI CQ
parent e54914a79e
commit b42ced4dfb
4 changed files with 78 additions and 23 deletions

View File

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

View File

@ -59,9 +59,13 @@ class VideoReceiveStream : public MediaReceiveStream {
// 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;

View File

@ -2875,43 +2875,84 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetRtpParameters() const {
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);
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;
}
config_.rtp.lntf.enabled = HasLntf(codec.codec);
config_.rtp.nack.rtp_history_ms = HasNack(codec.codec) ? kNackHistoryMs : 0;
// 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 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters(
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) {

View File

@ -483,7 +483,10 @@ class WebRtcVideoChannel : public VideoMediaChannel,
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);