зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1390318 - add MID support to webrtc.org. r=drno
MozReview-Commit-ID: EHgEuhw855n --HG-- extra : rebase_source : 8d575753a628b18472c3acd13ca88f5aa63c16b1
This commit is contained in:
Родитель
69512fc01f
Коммит
cb5753f469
|
@ -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_;
|
||||
|
|
Загрузка…
Ссылка в новой задаче