Updated associated payload types without recreating receive streams.

Bug: webrtc:11993
Change-Id: I49c61653b296b1b3ca6a12fa75ac699ee58f096c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/271543
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37799}
This commit is contained in:
Tommi 2022-08-16 10:23:47 +02:00 committed by WebRTC LUCI CQ
parent 94b3b5e341
commit 13b9f81b23
10 changed files with 59 additions and 12 deletions

View file

@ -153,6 +153,7 @@ rtc_library("rtp_receiver") {
"../rtc_base:stringutils", "../rtc_base:stringutils",
"../rtc_base/containers:flat_map", "../rtc_base/containers:flat_map",
"../rtc_base/containers:flat_set", "../rtc_base/containers:flat_set",
"../rtc_base/system:no_unique_address",
] ]
absl_deps = [ absl_deps = [
"//third_party/abseil-cpp/absl/strings:strings", "//third_party/abseil-cpp/absl/strings:strings",

View file

@ -32,6 +32,7 @@ RtxReceiveStream::RtxReceiveStream(
associated_payload_types_(std::move(associated_payload_types)), associated_payload_types_(std::move(associated_payload_types)),
media_ssrc_(media_ssrc), media_ssrc_(media_ssrc),
rtp_receive_statistics_(rtp_receive_statistics) { rtp_receive_statistics_(rtp_receive_statistics) {
packet_checker_.Detach();
if (associated_payload_types_.empty()) { if (associated_payload_types_.empty()) {
RTC_LOG(LS_WARNING) RTC_LOG(LS_WARNING)
<< "RtxReceiveStream created with empty payload type mapping."; << "RtxReceiveStream created with empty payload type mapping.";
@ -40,7 +41,14 @@ RtxReceiveStream::RtxReceiveStream(
RtxReceiveStream::~RtxReceiveStream() = default; RtxReceiveStream::~RtxReceiveStream() = default;
void RtxReceiveStream::SetAssociatedPayloadTypes(
std::map<int, int> associated_payload_types) {
RTC_DCHECK_RUN_ON(&packet_checker_);
associated_payload_types_ = std::move(associated_payload_types);
}
void RtxReceiveStream::OnRtpPacket(const RtpPacketReceived& rtx_packet) { void RtxReceiveStream::OnRtpPacket(const RtpPacketReceived& rtx_packet) {
RTC_DCHECK_RUN_ON(&packet_checker_);
if (rtp_receive_statistics_) { if (rtp_receive_statistics_) {
rtp_receive_statistics_->OnRtpPacket(rtx_packet); rtp_receive_statistics_->OnRtpPacket(rtx_packet);
} }
@ -52,9 +60,9 @@ void RtxReceiveStream::OnRtpPacket(const RtpPacketReceived& rtx_packet) {
auto it = associated_payload_types_.find(rtx_packet.PayloadType()); auto it = associated_payload_types_.find(rtx_packet.PayloadType());
if (it == associated_payload_types_.end()) { if (it == associated_payload_types_.end()) {
RTC_LOG(LS_VERBOSE) << "Unknown payload type " RTC_DLOG(LS_VERBOSE) << "Unknown payload type "
<< static_cast<int>(rtx_packet.PayloadType()) << static_cast<int>(rtx_packet.PayloadType())
<< " on rtx ssrc " << rtx_packet.Ssrc(); << " on rtx ssrc " << rtx_packet.Ssrc();
return; return;
} }
RtpPacketReceived media_packet; RtpPacketReceived media_packet;

View file

@ -14,7 +14,9 @@
#include <cstdint> #include <cstdint>
#include <map> #include <map>
#include "api/sequence_checker.h"
#include "call/rtp_packet_sink_interface.h" #include "call/rtp_packet_sink_interface.h"
#include "rtc_base/system/no_unique_address.h"
namespace webrtc { namespace webrtc {
@ -33,13 +35,19 @@ class RtxReceiveStream : public RtpPacketSinkInterface {
// RtpStreamReceiverController. // RtpStreamReceiverController.
ReceiveStatistics* rtp_receive_statistics = nullptr); ReceiveStatistics* rtp_receive_statistics = nullptr);
~RtxReceiveStream() override; ~RtxReceiveStream() override;
// Update payload types post construction. Must be called from the same
// calling context as `OnRtpPacket` is called on.
void SetAssociatedPayloadTypes(std::map<int, int> associated_payload_types);
// RtpPacketSinkInterface. // RtpPacketSinkInterface.
void OnRtpPacket(const RtpPacketReceived& packet) override; void OnRtpPacket(const RtpPacketReceived& packet) override;
private: private:
RTC_NO_UNIQUE_ADDRESS SequenceChecker packet_checker_;
RtpPacketSinkInterface* const media_sink_; RtpPacketSinkInterface* const media_sink_;
// Map from rtx payload type -> media payload type. // Map from rtx payload type -> media payload type.
const std::map<int, int> associated_payload_types_; std::map<int, int> associated_payload_types_ RTC_GUARDED_BY(&packet_checker_);
// TODO(nisse): Ultimately, the media receive stream shouldn't care about the // TODO(nisse): Ultimately, the media receive stream shouldn't care about the
// ssrc, and we should delete this. // ssrc, and we should delete this.
const uint32_t media_ssrc_; const uint32_t media_ssrc_;

View file

@ -308,6 +308,9 @@ class VideoReceiveStreamInterface : public MediaReceiveStreamInterface {
virtual void SetRtcpXr(Config::Rtp::RtcpXr rtcp_xr) = 0; virtual void SetRtcpXr(Config::Rtp::RtcpXr rtcp_xr) = 0;
virtual void SetAssociatedPayloadTypes(
std::map<int, int> associated_payload_types) = 0;
protected: protected:
virtual ~VideoReceiveStreamInterface() {} virtual ~VideoReceiveStreamInterface() {}
}; };

View file

@ -326,6 +326,7 @@ rtc_library("rtc_audio_video") {
"../rtc_base/experiments:normalize_simulcast_size_experiment", "../rtc_base/experiments:normalize_simulcast_size_experiment",
"../rtc_base/experiments:rate_control_settings", "../rtc_base/experiments:rate_control_settings",
"../rtc_base/synchronization:mutex", "../rtc_base/synchronization:mutex",
"../rtc_base/system:no_unique_address",
"../rtc_base/system:rtc_export", "../rtc_base/system:rtc_export",
"../rtc_base/third_party/base64", "../rtc_base/third_party/base64",
"../system_wrappers", "../system_wrappers",

View file

@ -308,6 +308,11 @@ class FakeVideoReceiveStream final
config_.rtp.rtcp_xr = rtcp_xr; config_.rtp.rtcp_xr = rtcp_xr;
} }
void SetAssociatedPayloadTypes(std::map<int, int> associated_payload_types) {
config_.rtp.rtx_associated_payload_types =
std::move(associated_payload_types);
}
void Start() override; void Start() override;
void Stop() override; void Stop() override;

View file

@ -3017,14 +3017,14 @@ bool WebRtcVideoChannel::WebRtcVideoReceiveStream::ReconfigureCodecs(
codec.ulpfec.red_payload_type; codec.ulpfec.red_payload_type;
} }
bool recreate_needed = false;
if (config_.rtp.rtx_associated_payload_types != if (config_.rtp.rtx_associated_payload_types !=
rtx_associated_payload_types) { rtx_associated_payload_types) {
stream_->SetAssociatedPayloadTypes(rtx_associated_payload_types);
rtx_associated_payload_types.swap(config_.rtp.rtx_associated_payload_types); rtx_associated_payload_types.swap(config_.rtp.rtx_associated_payload_types);
recreate_needed = true;
} }
bool recreate_needed = false;
if (raw_payload_types != config_.rtp.raw_payload_types) { if (raw_payload_types != config_.rtp.raw_payload_types) {
raw_payload_types.swap(config_.rtp.raw_payload_types); raw_payload_types.swap(config_.rtp.raw_payload_types);
recreate_needed = true; recreate_needed = true;

View file

@ -35,6 +35,7 @@
#include "media/engine/unhandled_packets_buffer.h" #include "media/engine/unhandled_packets_buffer.h"
#include "rtc_base/network_route.h" #include "rtc_base/network_route.h"
#include "rtc_base/synchronization/mutex.h" #include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_annotations.h"
namespace webrtc { namespace webrtc {
@ -424,7 +425,7 @@ class WebRtcVideoChannel : public VideoMediaChannel,
webrtc::DegradationPreference GetDegradationPreference() const webrtc::DegradationPreference GetDegradationPreference() const
RTC_EXCLUSIVE_LOCKS_REQUIRED(&thread_checker_); RTC_EXCLUSIVE_LOCKS_REQUIRED(&thread_checker_);
webrtc::SequenceChecker thread_checker_; RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker thread_checker_;
webrtc::TaskQueueBase* const worker_thread_; webrtc::TaskQueueBase* const worker_thread_;
const std::vector<uint32_t> ssrcs_ RTC_GUARDED_BY(&thread_checker_); const std::vector<uint32_t> ssrcs_ RTC_GUARDED_BY(&thread_checker_);
const std::vector<SsrcGroup> ssrc_groups_ RTC_GUARDED_BY(&thread_checker_); const std::vector<SsrcGroup> ssrc_groups_ RTC_GUARDED_BY(&thread_checker_);
@ -588,8 +589,8 @@ class WebRtcVideoChannel : public VideoMediaChannel,
webrtc::TaskQueueBase* const worker_thread_; webrtc::TaskQueueBase* const worker_thread_;
webrtc::ScopedTaskSafety task_safety_; webrtc::ScopedTaskSafety task_safety_;
webrtc::SequenceChecker network_thread_checker_; RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker network_thread_checker_;
webrtc::SequenceChecker thread_checker_; RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker thread_checker_;
uint32_t rtcp_receiver_report_ssrc_ RTC_GUARDED_BY(thread_checker_); uint32_t rtcp_receiver_report_ssrc_ RTC_GUARDED_BY(thread_checker_);
bool sending_ RTC_GUARDED_BY(thread_checker_); bool sending_ RTC_GUARDED_BY(thread_checker_);

View file

@ -268,8 +268,9 @@ VideoReceiveStream2::VideoReceiveStream2(
if (rtx_ssrc()) { if (rtx_ssrc()) {
rtx_receive_stream_ = std::make_unique<RtxReceiveStream>( rtx_receive_stream_ = std::make_unique<RtxReceiveStream>(
&rtp_video_stream_receiver_, config_.rtp.rtx_associated_payload_types, &rtp_video_stream_receiver_,
remote_ssrc(), rtp_receive_statistics_.get()); std::move(config_.rtp.rtx_associated_payload_types), remote_ssrc(),
rtp_receive_statistics_.get());
} else { } else {
rtp_receive_statistics_->EnableRetransmitDetection(remote_ssrc(), true); rtp_receive_statistics_->EnableRetransmitDetection(remote_ssrc(), true);
} }
@ -564,6 +565,23 @@ void VideoReceiveStream2::SetRtcpXr(Config::Rtp::RtcpXr rtcp_xr) {
rtcp_xr.receiver_reference_time_report); rtcp_xr.receiver_reference_time_report);
} }
void VideoReceiveStream2::SetAssociatedPayloadTypes(
std::map<int, int> associated_payload_types) {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
// For setting the associated payload types after construction, we currently
// assume that the rtx_ssrc cannot change. In such a case we can know that
// if the ssrc is non-0, a `rtx_receive_stream_` instance has previously been
// created and configured (and is referenced by `rtx_receiver_`) and we can
// simply reconfigure it.
// If rtx_ssrc is 0 however, we ignore this call.
if (!rtx_ssrc())
return;
rtx_receive_stream_->SetAssociatedPayloadTypes(
std::move(associated_payload_types));
}
void VideoReceiveStream2::CreateAndRegisterExternalDecoder( void VideoReceiveStream2::CreateAndRegisterExternalDecoder(
const Decoder& decoder) { const Decoder& decoder) {
TRACE_EVENT0("webrtc", TRACE_EVENT0("webrtc",

View file

@ -154,6 +154,8 @@ class VideoReceiveStream2
void SetProtectionPayloadTypes(int red_payload_type, void SetProtectionPayloadTypes(int red_payload_type,
int ulpfec_payload_type) override; int ulpfec_payload_type) override;
void SetRtcpXr(Config::Rtp::RtcpXr rtcp_xr) override; void SetRtcpXr(Config::Rtp::RtcpXr rtcp_xr) override;
void SetAssociatedPayloadTypes(
std::map<int, int> associated_payload_types) override;
webrtc::VideoReceiveStreamInterface::Stats GetStats() const override; webrtc::VideoReceiveStreamInterface::Stats GetStats() const override;