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}
This commit is contained in:
Steve Anton 2018-04-09 13:33:52 -07:00 committed by Commit Bot
parent a3177057c7
commit f0482ea9dd
8 changed files with 66 additions and 23 deletions

View file

@ -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 @@ class FlexfecSender {
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 @@ class FlexfecSender {
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_;

View file

@ -38,7 +38,7 @@ const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
// 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 @@ RtpHeaderExtensionMap RegisterBweExtensions(
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 @@ FlexfecSender::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,11 +82,13 @@ FlexfecSender::FlexfecSender(
: 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 @@ std::vector<std::unique_ptr<RtpPacketToSend>> FlexfecSender::GetFecPackets() {
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);

View file

@ -32,6 +32,7 @@ using test::fec::AugmentedPacketGenerator;
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 @@ std::unique_ptr<RtpPacketToSend> GenerateSingleFlexfecPacket(
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, Ssrc) {
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, NoFecAvailableBeforeMediaAdded) {
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 @@ TEST(FlexfecSenderTest, ProtectTwoFramesWithOneFecPacket) {
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 @@ TEST(FlexfecSenderTest, ProtectTwoFramesWithTwoFecPackets) {
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, ProtectTwoFramesWithTwoFecPackets) {
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 @@ TEST(FlexfecSenderTest, RegisterAbsoluteSendTimeRtpHeaderExtension) {
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 @@ TEST(FlexfecSenderTest, RegisterTransmissionOffsetRtpHeaderExtension) {
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 @@ TEST(FlexfecSenderTest, RegisterTransportSequenceNumberRtpHeaderExtension) {
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 @@ TEST(FlexfecSenderTest, RegisterAllRtpHeaderExtensionsForBwe) {
{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, RegisterAllRtpHeaderExtensionsForBwe) {
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 @@ TEST(FlexfecSenderTest, MaxPacketOverheadWithExtensions) {
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 @@ TEST(FlexfecSenderTest, MaxPacketOverheadWithExtensions) {
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);

View file

@ -150,6 +150,10 @@ class VideoTimingExtension {
// 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) {

View file

@ -60,6 +60,7 @@ constexpr RtpExtensionSize kFecOrPaddingExtensionSizes[] = {
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 @@ constexpr RtpExtensionSize kVideoExtensionSizes[] = {
CreateExtensionSize<VideoOrientation>(),
CreateExtensionSize<VideoContentTypeExtension>(),
CreateExtensionSize<VideoTimingExtension>(),
{RtpMid::kId, RtpMid::kMaxValueSizeBytes},
};
const char* FrameTypeToString(FrameType frame_type) {

View file

@ -980,10 +980,11 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
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 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
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 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
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 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
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.

View file

@ -23,6 +23,7 @@ namespace {
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 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
}
SimulatedClock clock(1 + data[i++]);
FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc,
FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
nullptr /* rtp_state */, &clock);
FecProtectionParams params = {

View file

@ -150,8 +150,9 @@ std::unique_ptr<FlexfecSender> MaybeCreateFlexfecSender(
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) {