Add MID sending to FlexfecSender
Bug: webrtc:4050
Change-Id: I1eefd99cca1c02751d3f5a2d3b57625ccb45323f
Reviewed-on: https://webrtc-review.googlesource.com/64321
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22811}
diff --git a/modules/rtp_rtcp/include/flexfec_sender.h b/modules/rtp_rtcp/include/flexfec_sender.h
index 5b939d5..ac07b8d 100644
--- a/modules/rtp_rtcp/include/flexfec_sender.h
+++ b/modules/rtp_rtcp/include/flexfec_sender.h
@@ -12,6 +12,7 @@
#define MODULES_RTP_RTCP_INCLUDE_FLEXFEC_SENDER_H_
#include <memory>
+#include <string>
#include <vector>
#include "api/array_view.h"
@@ -38,6 +39,7 @@
FlexfecSender(int payload_type,
uint32_t ssrc,
uint32_t protected_media_ssrc,
+ const std::string& mid,
const std::vector<RtpExtension>& rtp_header_extensions,
rtc::ArrayView<const RtpExtensionSize> extension_sizes,
const RtpState* rtp_state,
@@ -79,6 +81,8 @@
const uint32_t timestamp_offset_;
const uint32_t ssrc_;
const uint32_t protected_media_ssrc_;
+ // MID value to send in the MID header extension.
+ const std::string mid_;
// Sequence number of next packet to generate.
uint16_t seq_num_;
diff --git a/modules/rtp_rtcp/source/flexfec_sender.cc b/modules/rtp_rtcp/source/flexfec_sender.cc
index 28945ed..9704096 100644
--- a/modules/rtp_rtcp/source/flexfec_sender.cc
+++ b/modules/rtp_rtcp/source/flexfec_sender.cc
@@ -38,7 +38,7 @@
// How often to log the generated FEC packets to the text log.
constexpr int64_t kPacketLogIntervalMs = 10000;
-RtpHeaderExtensionMap RegisterBweExtensions(
+RtpHeaderExtensionMap RegisterSupportedExtensions(
const std::vector<RtpExtension>& rtp_header_extensions) {
RtpHeaderExtensionMap map;
for (const auto& extension : rtp_header_extensions) {
@@ -48,10 +48,12 @@
map.Register<AbsoluteSendTime>(extension.id);
} else if (extension.uri == TransmissionOffset::kUri) {
map.Register<TransmissionOffset>(extension.id);
+ } else if (extension.uri == RtpMid::kUri) {
+ map.Register<RtpMid>(extension.id);
} else {
RTC_LOG(LS_INFO)
<< "FlexfecSender only supports RTP header extensions for "
- << "BWE, so the extension " << extension.ToString()
+ << "BWE and MID, so the extension " << extension.ToString()
<< " will not be used.";
}
}
@@ -64,6 +66,7 @@
int payload_type,
uint32_t ssrc,
uint32_t protected_media_ssrc,
+ const std::string& mid,
const std::vector<RtpExtension>& rtp_header_extensions,
rtc::ArrayView<const RtpExtensionSize> extension_sizes,
const RtpState* rtp_state,
@@ -79,11 +82,13 @@
: random_.Rand<uint32_t>()),
ssrc_(ssrc),
protected_media_ssrc_(protected_media_ssrc),
+ mid_(mid),
seq_num_(rtp_state ? rtp_state->sequence_number
: random_.Rand(1, kMaxInitRtpSeqNumber)),
ulpfec_generator_(
ForwardErrorCorrection::CreateFlexfec(ssrc, protected_media_ssrc)),
- rtp_header_extension_map_(RegisterBweExtensions(rtp_header_extensions)),
+ rtp_header_extension_map_(
+ RegisterSupportedExtensions(rtp_header_extensions)),
header_extensions_size_(
rtp_header_extension_map_.GetTotalLengthInBytes(extension_sizes)) {
// This object should not have been instantiated if FlexFEC is disabled.
@@ -134,6 +139,11 @@
fec_packet_to_send->ReserveExtension<AbsoluteSendTime>();
fec_packet_to_send->ReserveExtension<TransmissionOffset>();
fec_packet_to_send->ReserveExtension<TransportSequenceNumber>();
+ // Possibly include the MID header extension.
+ if (!mid_.empty()) {
+ // This is a no-op if the MID header extension is not registered.
+ fec_packet_to_send->SetExtension<RtpMid>(mid_);
+ }
// RTP payload.
uint8_t* payload = fec_packet_to_send->AllocatePayload(fec_packet->length);
diff --git a/modules/rtp_rtcp/source/flexfec_sender_unittest.cc b/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
index aa729ed..4c2a48d 100644
--- a/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/flexfec_sender_unittest.cc
@@ -32,6 +32,7 @@
constexpr int kFlexfecPayloadType = 123;
constexpr uint32_t kMediaSsrc = 1234;
constexpr uint32_t kFlexfecSsrc = 5678;
+const char kNoMid[] = "";
const std::vector<RtpExtension> kNoRtpHeaderExtensions;
const std::vector<RtpExtensionSize> kNoRtpHeaderExtensionSizes;
// Assume a single protected media SSRC.
@@ -76,7 +77,7 @@
TEST(FlexfecSenderTest, Ssrc) {
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
@@ -85,7 +86,7 @@
TEST(FlexfecSenderTest, NoFecAvailableBeforeMediaAdded) {
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
@@ -96,7 +97,7 @@
TEST(FlexfecSenderTest, ProtectOneFrameWithOneFecPacket) {
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
auto fec_packet = GenerateSingleFlexfecPacket(&sender);
@@ -119,7 +120,7 @@
constexpr size_t kNumFrames = 2;
constexpr size_t kNumPacketsPerFrame = 2;
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
sender.SetFecParameters(params);
@@ -159,7 +160,7 @@
constexpr size_t kNumFrames = 2;
constexpr size_t kNumPacketsPerFrame = 2;
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
sender.SetFecParameters(params);
@@ -195,7 +196,7 @@
TEST(FlexfecSenderTest, NoRtpHeaderExtensionsForBweByDefault) {
const std::vector<RtpExtension> kRtpHeaderExtensions{};
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
auto fec_packet = GenerateSingleFlexfecPacket(&sender);
@@ -209,7 +210,7 @@
const std::vector<RtpExtension> kRtpHeaderExtensions{
{RtpExtension::kAbsSendTimeUri, 1}};
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
auto fec_packet = GenerateSingleFlexfecPacket(&sender);
@@ -223,7 +224,7 @@
const std::vector<RtpExtension> kRtpHeaderExtensions{
{RtpExtension::kTimestampOffsetUri, 1}};
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
auto fec_packet = GenerateSingleFlexfecPacket(&sender);
@@ -237,7 +238,7 @@
const std::vector<RtpExtension> kRtpHeaderExtensions{
{RtpExtension::kTransportSequenceNumberUri, 1}};
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
auto fec_packet = GenerateSingleFlexfecPacket(&sender);
@@ -253,7 +254,7 @@
{RtpExtension::kTimestampOffsetUri, 2},
{RtpExtension::kTransportSequenceNumberUri, 3}};
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
auto fec_packet = GenerateSingleFlexfecPacket(&sender);
@@ -265,7 +266,7 @@
TEST(FlexfecSenderTest, MaxPacketOverhead) {
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
@@ -285,7 +286,7 @@
kExtensionHeaderLength + AbsoluteSendTime::kValueSizeBytes +
kExtensionHeaderLength + TransmissionOffset::kValueSizeBytes +
kExtensionHeaderLength + TransportSequenceNumber::kValueSizeBytes);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kRtpHeaderExtensions, RTPSender::FecExtensionSizes(),
nullptr /* rtp_state */, &clock);
@@ -293,12 +294,28 @@
sender.MaxPacketOverhead());
}
+TEST(FlexfecSenderTest, MidIncludedInPacketsWhenSet) {
+ const std::vector<RtpExtension> kRtpHeaderExtensions{
+ {RtpExtension::kMidUri, 1}};
+ const char kMid[] = "mid";
+ SimulatedClock clock(kInitialSimulatedClockTime);
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kMid,
+ kRtpHeaderExtensions, RTPSender::FecExtensionSizes(),
+ nullptr /* rtp_state */, &clock);
+
+ auto fec_packet = GenerateSingleFlexfecPacket(&sender);
+
+ std::string mid;
+ ASSERT_TRUE(fec_packet->GetExtension<RtpMid>(&mid));
+ EXPECT_EQ(kMid, mid);
+}
+
TEST(FlexfecSenderTest, SetsAndGetsRtpState) {
RtpState initial_rtp_state;
initial_rtp_state.sequence_number = 100;
initial_rtp_state.start_timestamp = 200;
SimulatedClock clock(kInitialSimulatedClockTime);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
&initial_rtp_state, &clock);
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.h b/modules/rtp_rtcp/source/rtp_header_extensions.h
index 6ef5040..8526f13 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.h
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.h
@@ -150,6 +150,10 @@
// Subclasses must defined kId and kUri static constexpr members.
class BaseRtpStringExtension {
public:
+ // String RTP header extensions are limited to 16 bytes because it is the
+ // maximum length that can be encoded with one-byte header extensions.
+ static constexpr uint8_t kMaxValueSizeBytes = 16;
+
static bool Parse(rtc::ArrayView<const uint8_t> data,
StringRtpHeaderExtension* str);
static size_t ValueSize(const StringRtpHeaderExtension& str) {
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index 8db6791..11e96b5 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -60,6 +60,7 @@
CreateExtensionSize<TransmissionOffset>(),
CreateExtensionSize<TransportSequenceNumber>(),
CreateExtensionSize<PlayoutDelayLimits>(),
+ {RtpMid::kId, RtpMid::kMaxValueSizeBytes},
};
// Size info for header extensions that might be used in video packets.
@@ -71,6 +72,7 @@
CreateExtensionSize<VideoOrientation>(),
CreateExtensionSize<VideoContentTypeExtension>(),
CreateExtensionSize<VideoTimingExtension>(),
+ {RtpMid::kId, RtpMid::kMaxValueSizeBytes},
};
const char* FrameTypeToString(FrameType frame_type) {
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index d769ec3..282e44a 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -980,10 +980,11 @@
constexpr int kFlexfecPayloadType = 118;
constexpr uint32_t kMediaSsrc = 1234;
constexpr uint32_t kFlexfecSsrc = 5678;
+ const char kNoMid[] = "";
const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
- kNoRtpExtensions, kNoRtpExtensionSizes,
+ kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
nullptr /* rtp_state */, &fake_clock_);
// Reset |rtp_sender_| to use FlexFEC.
@@ -1038,11 +1039,12 @@
constexpr int kFlexfecPayloadType = 118;
constexpr uint32_t kMediaSsrc = 1234;
constexpr uint32_t kFlexfecSsrc = 5678;
+ const char kNoMid[] = "";
const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
- kNoRtpExtensions, kNoRtpExtensionSizes,
+ kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
nullptr /* rtp_state */, &fake_clock_);
// Reset |rtp_sender_| to use FlexFEC.
@@ -1138,10 +1140,11 @@
constexpr int kFlexfecPayloadType = 118;
constexpr uint32_t kMediaSsrc = 1234;
constexpr uint32_t kFlexfecSsrc = 5678;
+ const char kNoMid[] = "";
const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
- kNoRtpExtensions, kNoRtpExtensionSizes,
+ kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
nullptr /* rtp_state */, &fake_clock_);
// Reset |rtp_sender_| to use FlexFEC.
@@ -1201,10 +1204,11 @@
constexpr int kFlexfecPayloadType = 118;
constexpr uint32_t kMediaSsrc = 1234;
constexpr uint32_t kFlexfecSsrc = 5678;
+ const char kNoMid[] = "";
const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
- kNoRtpExtensions, kNoRtpExtensionSizes,
+ kNoMid, kNoRtpExtensions, kNoRtpExtensionSizes,
nullptr /* rtp_state */, &fake_clock_);
// Reset |rtp_sender_| to use FlexFEC.
diff --git a/test/fuzzers/flexfec_sender_fuzzer.cc b/test/fuzzers/flexfec_sender_fuzzer.cc
index 64bc3ed..ab08850 100644
--- a/test/fuzzers/flexfec_sender_fuzzer.cc
+++ b/test/fuzzers/flexfec_sender_fuzzer.cc
@@ -23,6 +23,7 @@
constexpr int kFlexfecPayloadType = 123;
constexpr uint32_t kMediaSsrc = 1234;
constexpr uint32_t kFlexfecSsrc = 5678;
+const char kNoMid[] = "";
const std::vector<RtpExtension> kNoRtpHeaderExtensions;
const std::vector<RtpExtensionSize> kNoRtpHeaderExtensionSizes;
@@ -35,7 +36,7 @@
}
SimulatedClock clock(1 + data[i++]);
- FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
+ FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
FecProtectionParams params = {
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index a7a41e0..4152efd 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -150,8 +150,9 @@
RTC_DCHECK_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
return rtc::MakeUnique<FlexfecSender>(
config.rtp.flexfec.payload_type, config.rtp.flexfec.ssrc,
- config.rtp.flexfec.protected_media_ssrcs[0], config.rtp.extensions,
- RTPSender::FecExtensionSizes(), rtp_state, Clock::GetRealTimeClock());
+ config.rtp.flexfec.protected_media_ssrcs[0], config.rtp.mid,
+ config.rtp.extensions, RTPSender::FecExtensionSizes(), rtp_state,
+ Clock::GetRealTimeClock());
}
bool TransportSeqNumExtensionConfigured(const VideoSendStream::Config& config) {