Bug 1390318 - add MID support to webrtc.org. r=drno

MozReview-Commit-ID: EHgEuhw855n

--HG--
extra : rebase_source : 8d575753a628b18472c3acd13ca88f5aa63c16b1
This commit is contained in:
Michael Froman 2017-07-27 16:19:56 -05:00
Родитель 69512fc01f
Коммит cb5753f469
20 изменённых файлов: 156 добавлений и 6 удалений

Просмотреть файл

@ -76,6 +76,8 @@ RTPHeaderExtension::operator=(const RTPHeaderExtension& rhs) {
rtpStreamId = rhs.rtpStreamId;
repairedRtpStreamId = rhs.repairedRtpStreamId;
mId = rhs.mId;
return *this;
}

Просмотреть файл

@ -890,6 +890,8 @@ struct RTPHeaderExtension {
// TODO(danilchap): Update url from draft to release version.
StreamId rtpStreamId;
StreamId repairedRtpStreamId;
StreamId mId;
};
struct RTPHeader {

Просмотреть файл

@ -80,6 +80,10 @@ const char* RtpExtension::kRepairedRtpStreamIdUri =
"urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
const int RtpExtension::kRepairedRtpStreamIdDefaultId = 8;
const char* RtpExtension::kMIdUri =
"urn:ietf:params:rtp-hdrext:sdes:mid";
const int RtpExtension::kMIdDefaultId = 9;
bool RtpExtension::IsSupportedForAudio(const std::string& uri) {
return uri == webrtc::RtpExtension::kAudioLevelUri ||
uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||

Просмотреть файл

@ -104,6 +104,9 @@ struct RtpExtension {
static const char* kRepairedRtpStreamIdUri;
static const int kRepairedRtpStreamIdDefaultId;
static const char* kMIdUri;
static const int kMIdDefaultId;
std::string uri;
int id;
};

Просмотреть файл

@ -77,6 +77,7 @@ enum RTPExtensionType {
kRtpExtensionPlayoutDelay,
kRtpExtensionRtpStreamId,
kRtpExtensionRepairedRtpStreamId,
kRtpExtensionMId,
kRtpExtensionNumberOfExtensions // Must be the last entity in the enum.
};

Просмотреть файл

@ -40,6 +40,7 @@ constexpr ExtensionInfo kExtensions[] = {
CreateExtensionInfo<PlayoutDelayLimits>(),
CreateExtensionInfo<RtpStreamId>(),
CreateExtensionInfo<RepairedRtpStreamId>(),
CreateExtensionInfo<MId>(),
};
// Because of kRtpExtensionNone, NumberOfExtension is 1 bigger than the actual

Просмотреть файл

@ -288,4 +288,32 @@ bool RepairedRtpStreamId::Write(uint8_t* data, const std::string& rsid) {
return RtpStreamId::Write(data, rsid);
}
// MId
constexpr RTPExtensionType MId::kId;
constexpr const char* MId::kUri;
bool MId::Parse(rtc::ArrayView<const uint8_t> data, StreamId* mid) {
return RtpStreamId::Parse(data, mid);
}
size_t MId::ValueSize(const StreamId& mid) {
return RtpStreamId::ValueSize(mid);
}
bool MId::Write(uint8_t* data, const StreamId& mid) {
return RtpStreamId::Write(data, mid);
}
bool MId::Parse(rtc::ArrayView<const uint8_t> data, std::string* mid) {
return RtpStreamId::Parse(data, mid);
}
size_t MId::ValueSize(const std::string& mid) {
return RtpStreamId::ValueSize(mid);
}
bool MId::Write(uint8_t* data, const std::string& mid) {
return RtpStreamId::Write(data, mid);
}
} // namespace webrtc

Просмотреть файл

@ -137,5 +137,20 @@ class RepairedRtpStreamId {
static bool Write(uint8_t* data, const std::string& rsid);
};
class MId {
public:
static constexpr RTPExtensionType kId = kRtpExtensionMId;
static constexpr const char* kUri =
"urn:ietf:params:rtp-hdrext:sdes:mid";
static bool Parse(rtc::ArrayView<const uint8_t> data, StreamId* mid);
static size_t ValueSize(const StreamId& mid);
static bool Write(uint8_t* data, const StreamId& mid);
static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* mid);
static size_t ValueSize(const std::string& mid);
static bool Write(uint8_t* data, const std::string& mid);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_

Просмотреть файл

@ -174,6 +174,7 @@ void Packet::GetHeader(RTPHeader* header) const {
GetExtension<RtpStreamId>(&header->extension.rtpStreamId);
GetExtension<RepairedRtpStreamId>(&header->extension.repairedRtpStreamId);
GetExtension<PlayoutDelayLimits>(&header->extension.playout_delay);
GetExtension<MId>(&header->extension.mId);
}
size_t Packet::headers_size() const {

Просмотреть файл

@ -65,6 +65,16 @@ constexpr uint8_t kPacketWithRsid[] = {
'e', 'a', 'm', 'i',
'd' , 0x00, 0x00, 0x00};
constexpr uint8_t kMIdExtensionId = 0xb;
constexpr char kMId[] = "midval";
constexpr uint8_t kPacketWithMid[] = {
0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78,
0xbe, 0xde, 0x00, 0x02,
0xb5, 'm', 'i', 'd',
'v', 'a', 'l', 0x00};
constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
constexpr uint8_t kPacketPaddingSize = 8;
@ -142,6 +152,18 @@ TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
}
TEST(RtpPacketTest, CreateWithDynamicSizedExtensionMid) {
RtpPacketToSend::ExtensionManager extensions;
extensions.Register<RtpStreamId>(kMIdExtensionId);
RtpPacketToSend packet(&extensions);
packet.SetPayloadType(kPayloadType);
packet.SetSequenceNumber(kSeqNum);
packet.SetTimestamp(kTimestamp);
packet.SetSsrc(kSsrc);
packet.SetExtension<RtpStreamId>(kMId);
EXPECT_THAT(kPacketWithMid, ElementsAreArray(packet.data(), packet.size()));
}
TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
RtpPacketToSend::ExtensionManager extensions;
extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
@ -422,10 +444,20 @@ TEST(RtpPacketTest, ParseDynamicSizeExtension) {
0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
0x00}; // Extension padding.
const uint8_t kPacket3[] = {
0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
0x65, 0x43, 0x12, 0x78, // Timestamp.
0x12, 0x34, 0x56, 0x78, // Ssrc.
0xbe, 0xde, 0x00, 0x04, // Extensions block of size 4x32bit words.
0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
0x35, 'm', 'i', 'd', 'v', 'a', 'l', // Extension with id = 3, size = (5+1).
0x00, 0x00}; // Extension padding.
// clang-format on
RtpPacketReceived::ExtensionManager extensions;
extensions.Register<RtpStreamId>(1);
extensions.Register<RepairedRtpStreamId>(2);
extensions.Register<MId>(3);
RtpPacketReceived packet(&extensions);
ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
@ -442,6 +474,16 @@ TEST(RtpPacketTest, ParseDynamicSizeExtension) {
EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
EXPECT_EQ(rsid, "HD");
EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
// Parse another packet with RtpStreamId, RepairedRtpStreamId, MId
ASSERT_TRUE(packet.Parse(kPacket3, sizeof(kPacket3)));
EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
EXPECT_EQ(rsid, "rtx");
EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
EXPECT_EQ(repaired_rsid, "HD");
std::string mid;
EXPECT_TRUE(packet.GetExtension<MId>(&mid));
EXPECT_EQ(mid, "midval");
}
TEST(RtpPacketTest, RawExtensionFunctionsAcceptZeroIdAndReturnFalse) {

Просмотреть файл

@ -45,6 +45,8 @@ RTPExtensionType StringToRtpExtensionType(const std::string& extension) {
return kRtpExtensionRtpStreamId;
if (extension == RtpExtension::kRepairedRtpStreamIdUri)
return kRtpExtensionRepairedRtpStreamId;
if (extension == RtpExtension::kMIdUri)
return kRtpExtensionMId;
RTC_NOTREACHED() << "Looking up unsupported RTP extension.";
return kRtpExtensionNone;
}

Просмотреть файл

@ -220,6 +220,15 @@ int32_t RTPSender::SetRID(const char* rid) {
return 0;
}
int32_t RTPSender::SetMId(const char* mid) {
rtc::CritScope lock(&send_critsect_);
const size_t len = (mid && mid[0]) ? strlen(mid) : 0;
if (len) {
mId.Set(mid, len);
}
return 0;
}
int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type,
uint8_t id) {
rtc::CritScope lock(&send_critsect_);
@ -451,7 +460,7 @@ bool RTPSender::SendOutgoingData(FrameType frame_type,
result = video_->SendVideo(video_type, frame_type, payload_type,
rtp_timestamp, capture_time_ms, payload_data,
payload_size, fragmentation, rtp_header,
&rtpStreamId);
&rtpStreamId, &mId);
}
rtc::CritScope cs(&statistics_crit_);

Просмотреть файл

@ -120,6 +120,7 @@ class RTPSender {
uint32_t* transport_frame_id_out);
int32_t SetRID(const char* rid);
int32_t SetMId(const char* mid);
// RTP header extension
int32_t RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
@ -287,6 +288,8 @@ class RTPSender {
StreamId rtpStreamId GUARDED_BY(send_critsect_);
StreamId mId GUARDED_BY(send_critsect_);
// Tracks the current request for playout delay limits from application
// and decides whether the current RTP frame should include the playout
// delay extension on header.

Просмотреть файл

@ -291,7 +291,8 @@ bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type,
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* video_header,
const StreamId* rtpStreamId) {
const StreamId* rtpStreamId,
const StreamId* mId) {
if (payload_size == 0)
return false;
@ -328,6 +329,9 @@ bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type,
if (rtpStreamId && !rtpStreamId->empty()) {
rtp_header->SetExtension<RtpStreamId>(*rtpStreamId);
}
if (mId && !mId->empty()) {
rtp_header->SetExtension<MId>(*mId);
}
// FEC settings.
const FecProtectionParams& fec_params =

Просмотреть файл

@ -61,7 +61,8 @@ class RTPSenderVideo {
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* video_header,
const StreamId* rtpStreamId);
const StreamId* rtpStreamId,
const StreamId* mId);
void SetVideoCodecType(RtpVideoCodecTypes type);

Просмотреть файл

@ -465,6 +465,10 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
rtc::MakeArrayView(ptr, len + 1));
break;
}
case kRtpExtensionMId: {
header->extension.mId.Set(rtc::MakeArrayView(ptr, len + 1));
break;
}
default:
case kRtpExtensionNone:
case kRtpExtensionNumberOfExtensions: {

Просмотреть файл

@ -148,14 +148,14 @@ TEST(RtpHeaderParser, ParseWithOverSizedExtension) {
EXPECT_EQ(sizeof(kPacket), header.headerLength);
}
TEST(RtpHeaderParser, ParseAll8Extensions) {
TEST(RtpHeaderParser, ParseAll9Extensions) {
const uint8_t kAudioLevel = 0x5a;
// clang-format off
const uint8_t kPacket[] = {
0x90, kPayloadType, 0x00, kSeqNum,
0x65, 0x43, 0x12, 0x78, // kTimestamp.
0x12, 0x34, 0x56, 0x78, // kSsrc.
0xbe, 0xde, 0x00, 0x08, // Extension of size 8x32bit words.
0xbe, 0xde, 0x00, 0x0a, // Extension of size 10x32bit words.
0x40, 0x80|kAudioLevel, // AudioLevel.
0x22, 0x01, 0x56, 0xce, // TransmissionOffset.
0x62, 0x12, 0x34, 0x56, // AbsoluteSendTime.
@ -164,7 +164,8 @@ TEST(RtpHeaderParser, ParseAll8Extensions) {
0xb2, 0x12, 0x48, 0x76, // PlayoutDelayLimits.
0xc2, 'r', 't', 'x', // RtpStreamId
0xd5, 's', 't', 'r', 'e', 'a', 'm', // RepairedRtpStreamId
0x00, 0x00, // Padding to 32bit boundary.
0xe7, 'm', 'i', 'd', 'v', 'a', 'l', 'u', 'e', // MId
0x00, // Padding to 32bit boundary.
};
// clang-format on
ASSERT_EQ(sizeof(kPacket) % 4, 0u);
@ -178,6 +179,7 @@ TEST(RtpHeaderParser, ParseAll8Extensions) {
extensions.Register<PlayoutDelayLimits>(0xb);
extensions.Register<RtpStreamId>(0xc);
extensions.Register<RepairedRtpStreamId>(0xd);
extensions.Register<MId>(0xe);
RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket));
RTPHeader header;
@ -205,6 +207,7 @@ TEST(RtpHeaderParser, ParseAll8Extensions) {
header.extension.playout_delay.max_ms);
EXPECT_EQ(header.extension.rtpStreamId, StreamId("rtx"));
EXPECT_EQ(header.extension.repairedRtpStreamId, StreamId("stream"));
EXPECT_EQ(header.extension.mId, StreamId("midvalue"));
}
TEST(RtpHeaderParser, ParseMalformedRsidExtensions) {

Просмотреть файл

@ -96,6 +96,11 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
packet.GetExtension<RepairedRtpStreamId>(&rsid);
break;
}
case kRtpExtensionMId: {
std::string mid;
packet.GetExtension<MId>(&mid);
break;
}
}
}
}

Просмотреть файл

@ -278,6 +278,22 @@ bool RtpStreamReceiver::SetReceiveRIDStatus(bool enable, int id) {
kRtpExtensionRtpStreamId);
}
bool RtpStreamReceiver::SetReceiveMIdStatus(bool enable, int id) {
rtc::CritScope lock(&receive_cs_);
if (enable) {
if (rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionMId, id)) {
receiving_mid_enabled_ = true;
return true;
} else {
return false;
}
}
receiving_mid_enabled_ = false;
return rtp_header_parser_->DeregisterRtpHeaderExtension(
kRtpExtensionMId);
}
int32_t RtpStreamReceiver::OnReceivedPayloadData(
const uint8_t* payload_data,
size_t payload_size,
@ -394,6 +410,8 @@ bool RtpStreamReceiver::DeliverRtp(const uint8_t* rtp_packet,
ss << ", rid: " << header.extension.rtpStreamId.data();
if (!header.extension.repairedRtpStreamId.empty())
ss << ", repaired rid: " << header.extension.repairedRtpStreamId.data();
if (!header.extension.mId.empty())
ss << ", mid: " << header.extension.mId.data();
LOG(LS_INFO) << ss.str();
last_packet_log_ms_ = now_ms;
}

Просмотреть файл

@ -91,6 +91,7 @@ class RtpStreamReceiver : public RtpData,
int GetCsrcs(uint32_t* csrcs) const;
void GetRID(char rid[256]) const;
bool SetReceiveRIDStatus(bool enable, int id);
bool SetReceiveMIdStatus(bool enable, int id);
RtpReceiver* GetRtpReceiver() const;
RtpRtcp* rtp_rtcp() const { return rtp_rtcp_.get(); }
@ -187,6 +188,7 @@ class RtpStreamReceiver : public RtpData,
uint8_t restored_packet_[IP_PACKET_SIZE] GUARDED_BY(receive_cs_);
bool restored_packet_in_use_ GUARDED_BY(receive_cs_);
bool receiving_rid_enabled_ GUARDED_BY(receive_cs_);
bool receiving_mid_enabled_ GUARDED_BY(receive_cs_);
int64_t last_packet_log_ms_ GUARDED_BY(receive_cs_);
const std::unique_ptr<RtpRtcp> rtp_rtcp_;