[WebRtcVideoReceiveStream] Split initial config and reconfiguration.
This is a step towards getting rid of reconfiguration via tearing down and reconstructing receive streams when parts of the configuration change at runtime. Bug: webrtc:11993 Change-Id: I337e523f17805b75826ddbd75bd3d0eb6e910bd8 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/269250 Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#37680}
This commit is contained in:
@ -1274,6 +1274,28 @@ std::string WebRtcVideoChannel::CodecSettingsVectorToString(
|
||||
return out.Release();
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel::ExtractCodecInformation(
|
||||
rtc::ArrayView<const VideoCodecSettings> recv_codecs,
|
||||
std::map<int, int>& rtx_associated_payload_types,
|
||||
std::set<int>& raw_payload_types,
|
||||
std::vector<webrtc::VideoReceiveStreamInterface::Decoder>& decoders) {
|
||||
RTC_DCHECK(!recv_codecs.empty());
|
||||
RTC_DCHECK(rtx_associated_payload_types.empty());
|
||||
RTC_DCHECK(raw_payload_types.empty());
|
||||
RTC_DCHECK(decoders.empty());
|
||||
|
||||
for (const VideoCodecSettings& recv_codec : recv_codecs) {
|
||||
decoders.emplace_back(
|
||||
webrtc::SdpVideoFormat(recv_codec.codec.name, recv_codec.codec.params),
|
||||
recv_codec.codec.id);
|
||||
rtx_associated_payload_types.emplace(recv_codec.rtx_payload_type,
|
||||
recv_codec.codec.id);
|
||||
if (recv_codec.codec.packetization == kPacketizationParamRaw) {
|
||||
raw_payload_types.insert(recv_codec.codec.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel::SetReceiverReportSsrc(uint32_t ssrc) {
|
||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
||||
if (ssrc == rtcp_receiver_report_ssrc_)
|
||||
@ -2861,10 +2883,33 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
|
||||
first_frame_timestamp_(-1),
|
||||
estimated_remote_start_ntp_time_ms_(0) {
|
||||
RTC_DCHECK(config_.decoder_factory);
|
||||
RTC_DCHECK(config_.decoders.empty())
|
||||
<< "Decoder info is supplied via `recv_codecs`";
|
||||
|
||||
ExtractCodecInformation(recv_codecs, config_.rtp.rtx_associated_payload_types,
|
||||
config_.rtp.raw_payload_types, config_.decoders);
|
||||
const VideoCodecSettings& codec = recv_codecs.front();
|
||||
config_.rtp.ulpfec_payload_type = codec.ulpfec.ulpfec_payload_type;
|
||||
config_.rtp.red_payload_type = codec.ulpfec.red_payload_type;
|
||||
config_.rtp.lntf.enabled = HasLntf(codec.codec);
|
||||
config_.rtp.nack.rtp_history_ms = HasNack(codec.codec) ? kNackHistoryMs : 0;
|
||||
if (codec.rtx_time != -1 && config_.rtp.nack.rtp_history_ms != 0) {
|
||||
config_.rtp.nack.rtp_history_ms = codec.rtx_time;
|
||||
}
|
||||
|
||||
config_.rtp.rtcp_xr.receiver_reference_time_report = HasRrtr(codec.codec);
|
||||
|
||||
if (codec.ulpfec.red_rtx_payload_type != -1) {
|
||||
config_.rtp
|
||||
.rtx_associated_payload_types[codec.ulpfec.red_rtx_payload_type] =
|
||||
codec.ulpfec.red_payload_type;
|
||||
}
|
||||
|
||||
config_.renderer = this;
|
||||
ConfigureCodecs(recv_codecs);
|
||||
flexfec_config_.payload_type = flexfec_config.payload_type;
|
||||
RecreateReceiveStream();
|
||||
|
||||
CreateReceiveStream();
|
||||
StartReceiveStream();
|
||||
}
|
||||
|
||||
WebRtcVideoChannel::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() {
|
||||
@ -2913,25 +2958,18 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetRtpParameters() const {
|
||||
return rtp_parameters;
|
||||
}
|
||||
|
||||
bool WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
|
||||
bool WebRtcVideoChannel::WebRtcVideoReceiveStream::ReconfigureCodecs(
|
||||
const std::vector<VideoCodecSettings>& recv_codecs) {
|
||||
RTC_DCHECK(stream_);
|
||||
RTC_DCHECK(!recv_codecs.empty());
|
||||
|
||||
std::map<int, int> rtx_associated_payload_types;
|
||||
std::set<int> raw_payload_types;
|
||||
std::vector<webrtc::VideoReceiveStreamInterface::Decoder> decoders;
|
||||
for (const auto& recv_codec : recv_codecs) {
|
||||
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) {
|
||||
raw_payload_types.insert(recv_codec.codec.id);
|
||||
}
|
||||
}
|
||||
ExtractCodecInformation(recv_codecs, rtx_associated_payload_types,
|
||||
raw_payload_types, decoders);
|
||||
|
||||
bool recreate_needed = (stream_ == nullptr);
|
||||
bool recreate_needed = false;
|
||||
|
||||
const auto& codec = recv_codecs.front();
|
||||
if (config_.rtp.ulpfec_payload_type != codec.ulpfec.ulpfec_payload_type) {
|
||||
@ -3037,9 +3075,8 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetFeedbackParameters(
|
||||
config_.rtp.lntf.enabled = lntf_enabled;
|
||||
config_.rtp.nack.rtp_history_ms = nack_history_ms;
|
||||
|
||||
RTC_LOG(LS_INFO) << "RecreateReceiveStream (recv) because of "
|
||||
"SetFeedbackParameters; nack="
|
||||
<< nack_enabled;
|
||||
RTC_LOG_F(LS_INFO) << "(recv) because of SetFeedbackParameters; nack="
|
||||
<< nack_enabled;
|
||||
RecreateReceiveStream();
|
||||
}
|
||||
|
||||
@ -3081,7 +3118,7 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters(
|
||||
RTC_DCHECK(stream_);
|
||||
bool video_needs_recreation = false;
|
||||
if (params.codec_settings) {
|
||||
video_needs_recreation = ConfigureCodecs(*params.codec_settings);
|
||||
video_needs_recreation = ReconfigureCodecs(*params.codec_settings);
|
||||
}
|
||||
|
||||
if (params.rtp_header_extensions) {
|
||||
@ -3109,6 +3146,7 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters(
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateReceiveStream() {
|
||||
RTC_DCHECK(stream_);
|
||||
absl::optional<int> base_minimum_playout_delay_ms;
|
||||
absl::optional<webrtc::VideoReceiveStreamInterface::RecordingState>
|
||||
recording_state;
|
||||
@ -3126,14 +3164,8 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateReceiveStream() {
|
||||
flexfec_stream_ = nullptr;
|
||||
}
|
||||
|
||||
if (flexfec_config_.IsCompleteAndEnabled()) {
|
||||
flexfec_stream_ = call_->CreateFlexfecReceiveStream(flexfec_config_);
|
||||
}
|
||||
CreateReceiveStream();
|
||||
|
||||
webrtc::VideoReceiveStreamInterface::Config config = config_.Copy();
|
||||
config.rtp.protected_by_flexfec = (flexfec_stream_ != nullptr);
|
||||
config.rtp.packet_sink_ = flexfec_stream_;
|
||||
stream_ = call_->CreateVideoReceiveStream(std::move(config));
|
||||
if (base_minimum_playout_delay_ms) {
|
||||
stream_->SetBaseMinimumPlayoutDelayMs(
|
||||
base_minimum_playout_delay_ms.value());
|
||||
@ -3143,8 +3175,24 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateReceiveStream() {
|
||||
/*generate_key_frame=*/false);
|
||||
}
|
||||
|
||||
stream_->Start();
|
||||
StartReceiveStream();
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel::WebRtcVideoReceiveStream::CreateReceiveStream() {
|
||||
RTC_DCHECK(!stream_);
|
||||
RTC_DCHECK(!flexfec_stream_);
|
||||
if (flexfec_config_.IsCompleteAndEnabled()) {
|
||||
flexfec_stream_ = call_->CreateFlexfecReceiveStream(flexfec_config_);
|
||||
}
|
||||
|
||||
webrtc::VideoReceiveStreamInterface::Config config = config_.Copy();
|
||||
config.rtp.protected_by_flexfec = (flexfec_stream_ != nullptr);
|
||||
config.rtp.packet_sink_ = flexfec_stream_;
|
||||
stream_ = call_->CreateVideoReceiveStream(std::move(config));
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel::WebRtcVideoReceiveStream::StartReceiveStream() {
|
||||
stream_->Start();
|
||||
if (IsEnabled(call_->trials(), "WebRTC-Video-BufferPacketsWithUnknownSsrc")) {
|
||||
channel_->BackfillBufferedPackets(stream_params_.ssrcs);
|
||||
}
|
||||
@ -3202,18 +3250,6 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetSink(
|
||||
sink_ = sink;
|
||||
}
|
||||
|
||||
std::string
|
||||
WebRtcVideoChannel::WebRtcVideoReceiveStream::GetCodecNameFromPayloadType(
|
||||
int payload_type) {
|
||||
for (const webrtc::VideoReceiveStreamInterface::Decoder& decoder :
|
||||
config_.decoders) {
|
||||
if (decoder.payload_type == payload_type) {
|
||||
return decoder.video_format.name;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
VideoReceiverInfo
|
||||
WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo(
|
||||
bool log_stats) {
|
||||
@ -3224,6 +3260,11 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo(
|
||||
info.decoder_implementation_name = stats.decoder_implementation_name;
|
||||
if (stats.current_payload_type != -1) {
|
||||
info.codec_payload_type = stats.current_payload_type;
|
||||
auto decoder_it = absl::c_find_if(config_.decoders, [&](const auto& d) {
|
||||
return d.payload_type == stats.current_payload_type;
|
||||
});
|
||||
if (decoder_it != config_.decoders.end())
|
||||
info.codec_name = decoder_it->video_format.name;
|
||||
}
|
||||
info.payload_bytes_rcvd = stats.rtp_stats.packet_counter.payload_bytes;
|
||||
info.header_and_padding_bytes_rcvd =
|
||||
@ -3283,8 +3324,6 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo(
|
||||
|
||||
info.content_type = stats.content_type;
|
||||
|
||||
info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type);
|
||||
|
||||
info.firs_sent = stats.rtcp_packet_type_counts.fir_packets;
|
||||
info.plis_sent = stats.rtcp_packet_type_counts.pli_packets;
|
||||
info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets;
|
||||
|
@ -328,6 +328,15 @@ class WebRtcVideoChannel : public VideoMediaChannel,
|
||||
static std::string CodecSettingsVectorToString(
|
||||
const std::vector<VideoCodecSettings>& codecs);
|
||||
|
||||
// Populates `rtx_associated_payload_types`, `raw_payload_types` and
|
||||
// `decoders` based on codec settings provided by `recv_codecs`.
|
||||
// `recv_codecs` must be non-empty and all other parameters must be empty.
|
||||
static void ExtractCodecInformation(
|
||||
rtc::ArrayView<const VideoCodecSettings> recv_codecs,
|
||||
std::map<int, int>& rtx_associated_payload_types,
|
||||
std::set<int>& raw_payload_types,
|
||||
std::vector<webrtc::VideoReceiveStreamInterface::Decoder>& decoders);
|
||||
|
||||
// Called when the local ssrc changes. Sets `rtcp_receiver_report_ssrc_` and
|
||||
// updates the receive streams.
|
||||
void SetReceiverReportSsrc(uint32_t ssrc) RTC_RUN_ON(&thread_checker_);
|
||||
@ -511,13 +520,13 @@ class WebRtcVideoChannel : public VideoMediaChannel,
|
||||
void SetFlexFecPayload(int payload_type);
|
||||
|
||||
void RecreateReceiveStream();
|
||||
void CreateReceiveStream();
|
||||
void StartReceiveStream();
|
||||
|
||||
// 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);
|
||||
bool ReconfigureCodecs(const std::vector<VideoCodecSettings>& recv_codecs);
|
||||
|
||||
WebRtcVideoChannel* const channel_;
|
||||
webrtc::Call* const call_;
|
||||
|
Reference in New Issue
Block a user