Propagate ECN to RtpPacketReceived

Bug: webrtc:15368
Change-Id: Ie2d982a9172759a65f7f7225eeddd64cfa82490d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/341560
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41903}
This commit is contained in:
Per K 2024-03-12 13:00:50 +01:00 committed by WebRTC LUCI CQ
parent a0672c5f32
commit 776c1a1a86
10 changed files with 64 additions and 13 deletions

View file

@ -133,6 +133,7 @@ rtc_library("rtp_rtcp_format") {
"../../rtc_base:macromagic",
"../../rtc_base:safe_conversions",
"../../rtc_base:stringutils",
"../../rtc_base/network:ecn_marking",
"../../system_wrappers",
"../video_coding:codec_globals_headers",
]

View file

@ -20,6 +20,7 @@
#include "api/scoped_refptr.h"
#include "api/units/timestamp.h"
#include "modules/rtp_rtcp/source/rtp_packet.h"
#include "rtc_base/network/ecn_marking.h"
namespace webrtc {
// Class to hold rtp packet with metadata for receiver side.
@ -48,6 +49,11 @@ class RtpPacketReceived : public RtpPacket {
webrtc::Timestamp arrival_time() const { return arrival_time_; }
void set_arrival_time(webrtc::Timestamp time) { arrival_time_ = time; }
// Explicit Congestion Notification (ECN), RFC-3168, Section 5.
// Used by L4S: https://www.rfc-editor.org/rfc/rfc9331.html
rtc::EcnMarking ecn() const { return ecn_; }
void set_ecn(rtc::EcnMarking ecn) { ecn_ = ecn; }
// Flag if packet was recovered via RTX or FEC.
bool recovered() const { return recovered_; }
void set_recovered(bool value) { recovered_ = value; }
@ -68,6 +74,7 @@ class RtpPacketReceived : public RtpPacket {
private:
webrtc::Timestamp arrival_time_ = Timestamp::MinusInfinity();
rtc::EcnMarking ecn_ = rtc::EcnMarking::kNotEct;
int payload_type_frequency_ = 0;
bool recovered_ = false;
rtc::scoped_refptr<rtc::RefCountedBase> additional_data_;

View file

@ -1100,6 +1100,7 @@ if (rtc_include_tests) {
"../rtc_base:socket_server",
"../rtc_base:ssl",
"../rtc_base:threading",
"../rtc_base:timeutils",
"../rtc_base/network:received_packet",
"../rtc_base/third_party/sigslot",
"../test:test_support",

View file

@ -16,6 +16,7 @@
#include "p2p/base/packet_transport_internal.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/time_utils.h"
namespace rtc {
@ -64,7 +65,7 @@ class FakePacketTransport : public PacketTransportInternal {
return -1;
}
CopyOnWriteBuffer packet(data, len);
SendPacketInternal(packet);
SendPacketInternal(packet, options);
SentPacket sent_packet(options.packet_id, TimeMillis());
SignalSentPacket(this, sent_packet);
@ -120,11 +121,13 @@ class FakePacketTransport : public PacketTransportInternal {
SignalReceivingState(this);
}
void SendPacketInternal(const CopyOnWriteBuffer& packet) {
void SendPacketInternal(const CopyOnWriteBuffer& packet,
const rtc::PacketOptions& options) {
last_sent_packet_ = packet;
if (dest_) {
dest_->NotifyPacketReceived(rtc::ReceivedPacket::CreateFromLegacy(
packet.data(), packet.size(), rtc::TimeMicros()));
dest_->NotifyPacketReceived(rtc::ReceivedPacket(
packet, SocketAddress(), webrtc::Timestamp::Micros(rtc::TimeMicros()),
options.ecn_1 ? EcnMarking::kEct1 : EcnMarking::kNotEct));
}
}

View file

@ -191,8 +191,11 @@ flat_set<uint32_t> RtpTransport::GetSsrcsForSink(RtpPacketSinkInterface* sink) {
}
void RtpTransport::DemuxPacket(rtc::CopyOnWriteBuffer packet,
webrtc::Timestamp arrival_time) {
RtpPacketReceived parsed_packet(&header_extension_map_, arrival_time);
webrtc::Timestamp arrival_time,
rtc::EcnMarking ecn) {
RtpPacketReceived parsed_packet(&header_extension_map_);
parsed_packet.set_arrival_time(arrival_time);
parsed_packet.set_ecn(ecn);
if (!parsed_packet.Parse(std::move(packet))) {
RTC_LOG(LS_ERROR)
@ -247,8 +250,10 @@ void RtpTransport::OnSentPacket(rtc::PacketTransportInternal* packet_transport,
void RtpTransport::OnRtpPacketReceived(
const rtc::ReceivedPacket& received_packet) {
rtc::CopyOnWriteBuffer payload(received_packet.payload());
DemuxPacket(payload, received_packet.arrival_time().value_or(
Timestamp::MinusInfinity()));
DemuxPacket(
payload,
received_packet.arrival_time().value_or(Timestamp::MinusInfinity()),
received_packet.ecn());
}
void RtpTransport::OnRtcpPacketReceived(

View file

@ -92,7 +92,9 @@ class RtpTransport : public RtpTransportInternal {
protected:
// These methods will be used in the subclasses.
void DemuxPacket(rtc::CopyOnWriteBuffer packet, Timestamp arrival_time);
void DemuxPacket(rtc::CopyOnWriteBuffer packet,
Timestamp arrival_time,
rtc::EcnMarking ecn);
bool SendPacket(bool rtcp,
rtc::CopyOnWriteBuffer* packet,

View file

@ -301,6 +301,29 @@ TEST(RtpTransportTest, SignalHandledRtpPayloadType) {
transport.UnregisterRtpDemuxerSink(&observer);
}
TEST(RtpTransportTest, ReceivedPacketEcnMarkingPropagatedToDemuxedPacket) {
RtpTransport transport(kMuxDisabled);
// Setup FakePacketTransport to send packets to itself.
rtc::FakePacketTransport fake_rtp("fake_rtp");
fake_rtp.SetDestination(&fake_rtp, true);
transport.SetRtpPacketTransport(&fake_rtp);
TransportObserver observer(&transport);
RtpDemuxerCriteria demuxer_criteria;
// Add a payload type of kRtpData.
demuxer_criteria.payload_types().insert(0x11);
transport.RegisterRtpDemuxerSink(demuxer_criteria, &observer);
rtc::PacketOptions options;
options.ecn_1 = true;
const int flags = 0;
rtc::Buffer rtp_data(kRtpData, kRtpLen);
fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
ASSERT_EQ(observer.rtp_count(), 1);
EXPECT_EQ(observer.last_recv_rtp_packet().ecn(), rtc::EcnMarking::kEct1);
transport.UnregisterRtpDemuxerSink(&observer);
}
// Test that SignalPacketReceived does not fire when a RTP packet with an
// unhandled payload type is received.
TEST(RtpTransportTest, DontSignalUnhandledRtpPayloadType) {

View file

@ -145,7 +145,8 @@ void SrtpTransport::OnRtpPacketReceived(const rtc::ReceivedPacket& packet) {
}
payload.SetSize(len);
DemuxPacket(std::move(payload),
packet.arrival_time().value_or(Timestamp::MinusInfinity()));
packet.arrival_time().value_or(Timestamp::MinusInfinity()),
packet.ecn());
}
void SrtpTransport::OnRtcpPacketReceived(const rtc::ReceivedPacket& packet) {

View file

@ -46,7 +46,7 @@ class TransportObserver : public RtpPacketSinkInterface {
// RtpPacketInterface override.
void OnRtpPacket(const RtpPacketReceived& packet) override {
rtp_count_++;
last_recv_rtp_packet_ = packet.Buffer();
last_recv_rtp_packet_ = packet;
}
void OnUndemuxableRtpPacket(const RtpPacketReceived& packet) {
@ -64,7 +64,7 @@ class TransportObserver : public RtpPacketSinkInterface {
int rtcp_count() const { return rtcp_count_; }
int sent_packet_count() const { return sent_packet_count_; }
rtc::CopyOnWriteBuffer last_recv_rtp_packet() {
const RtpPacketReceived& last_recv_rtp_packet() {
return last_recv_rtp_packet_;
}
@ -98,7 +98,7 @@ class TransportObserver : public RtpPacketSinkInterface {
int rtcp_count_ = 0;
int sent_packet_count_ = 0;
int ready_to_send_signal_count_ = 0;
rtc::CopyOnWriteBuffer last_recv_rtp_packet_;
RtpPacketReceived last_recv_rtp_packet_;
rtc::CopyOnWriteBuffer last_recv_rtcp_packet_;
absl::AnyInvocable<void(bool)> action_on_ready_to_send_;
absl::AnyInvocable<void()> action_on_sent_packet_;

View file

@ -50,6 +50,14 @@ struct RTC_EXPORT PacketOptions {
~PacketOptions();
DiffServCodePoint dscp = DSCP_NO_CHANGE;
// Packet will be sent with ECN(1), RFC-3168, Section 5.
// Intended to be used with L4S
// https://www.rfc-editor.org/rfc/rfc9331.html
// TODO(https://bugs.webrtc.org/15368): Actually implement support for sending
// packets with different marking.
bool ecn_1 = false;
// When used with RTP packets (for example, webrtc::PacketOptions), the value
// should be 16 bits. A value of -1 represents "not set".
int64_t packet_id = -1;