--- a/media/webrtc/trunk/webrtc/common_types.cc
+++ b/media/webrtc/trunk/webrtc/common_types.cc
@@ -71,16 +71,18 @@ RTPHeaderExtension::operator=(const RTPH
audioLevel = rhs.audioLevel;
hasVideoRotation = rhs.hasVideoRotation;
videoRotation = rhs.videoRotation;
rtpStreamId = rhs.rtpStreamId;
repairedRtpStreamId = rhs.repairedRtpStreamId;
+ mId = rhs.mId;
+
return *this;
}
RTPHeader::RTPHeader()
: markerBit(false),
payloadType(0),
sequenceNumber(0),
timestamp(0),
--- a/media/webrtc/trunk/webrtc/common_types.h
+++ b/media/webrtc/trunk/webrtc/common_types.h
@@ -885,16 +885,18 @@ struct RTPHeaderExtension {
PlayoutDelay playout_delay = {-1, -1};
// For identification of a stream when ssrc is not signaled. See
// https://tools.ietf.org/html/draft-ietf-avtext-rid-09
// TODO(danilchap): Update url from draft to release version.
StreamId rtpStreamId;
StreamId repairedRtpStreamId;
+
+ StreamId mId;
};
struct RTPHeader {
RTPHeader();
bool markerBit;
uint8_t payloadType;
uint16_t sequenceNumber;
--- a/media/webrtc/trunk/webrtc/config.cc
+++ b/media/webrtc/trunk/webrtc/config.cc
@@ -75,16 +75,20 @@ const int RtpExtension::kPlayoutDelayDef
const char* RtpExtension::kRtpStreamIdUri =
"urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
const int RtpExtension::kRtpStreamIdDefaultId = 7;
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 ||
uri == webrtc::RtpExtension::kRtpStreamIdUri ||
uri == webrtc::RtpExtension::kRepairedRtpStreamIdUri;
}
bool RtpExtension::IsSupportedForVideo(const std::string& uri) {
--- a/media/webrtc/trunk/webrtc/config.h
+++ b/media/webrtc/trunk/webrtc/config.h
@@ -99,16 +99,19 @@ struct RtpExtension {
static const int kPlayoutDelayDefaultId;
static const char* kRtpStreamIdUri;
static const int kRtpStreamIdDefaultId;
static const char* kRepairedRtpStreamIdUri;
static const int kRepairedRtpStreamIdDefaultId;
+ static const char* kMIdUri;
+ static const int kMIdDefaultId;
+
std::string uri;
int id;
};
struct VideoStream {
VideoStream();
~VideoStream();
std::string ToString() const;
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h
@@ -72,16 +72,17 @@ enum RTPExtensionType {
kRtpExtensionTransmissionTimeOffset,
kRtpExtensionAudioLevel,
kRtpExtensionAbsoluteSendTime,
kRtpExtensionVideoRotation,
kRtpExtensionTransportSequenceNumber,
kRtpExtensionPlayoutDelay,
kRtpExtensionRtpStreamId,
kRtpExtensionRepairedRtpStreamId,
+ kRtpExtensionMId,
kRtpExtensionNumberOfExtensions // Must be the last entity in the enum.
};
enum RTCPAppSubTypes { kAppSubtypeBwe = 0x00 };
// TODO(sprang): Make this an enum class once rtcp_receiver has been cleaned up.
enum RTCPPacketType : uint32_t {
kRtcpReport = 0x0001,
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc
@@ -35,16 +35,17 @@ constexpr ExtensionInfo kExtensions[] =
CreateExtensionInfo<TransmissionOffset>(),
CreateExtensionInfo<AudioLevel>(),
CreateExtensionInfo<AbsoluteSendTime>(),
CreateExtensionInfo<VideoOrientation>(),
CreateExtensionInfo<TransportSequenceNumber>(),
CreateExtensionInfo<PlayoutDelayLimits>(),
CreateExtensionInfo<RtpStreamId>(),
CreateExtensionInfo<RepairedRtpStreamId>(),
+ CreateExtensionInfo<MId>(),
};
// Because of kRtpExtensionNone, NumberOfExtension is 1 bigger than the actual
// number of known extensions.
static_assert(arraysize(kExtensions) ==
static_cast<int>(kRtpExtensionNumberOfExtensions) - 1,
"kExtensions expect to list all known extensions");
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
@@ -283,9 +283,37 @@ bool RepairedRtpStreamId::Parse(rtc::Arr
size_t RepairedRtpStreamId::ValueSize(const std::string& rsid) {
return RtpStreamId::ValueSize(rsid);
}
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
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h
@@ -132,10 +132,25 @@ class RepairedRtpStreamId {
static size_t ValueSize(const StreamId& rsid);
static bool Write(uint8_t* data, const StreamId& rsid);
static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* rsid);
static size_t ValueSize(const std::string& rsid);
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_
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_packet.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_packet.cc
@@ -169,16 +169,17 @@ void Packet::GetHeader(RTPHeader* header
&header->extension.transportSequenceNumber);
header->extension.hasAudioLevel = GetExtension<AudioLevel>(
&header->extension.voiceActivity, &header->extension.audioLevel);
header->extension.hasVideoRotation =
GetExtension<VideoOrientation>(&header->extension.videoRotation);
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 {
return payload_offset_;
}
size_t Packet::payload_size() const {
return payload_size_;
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
@@ -60,16 +60,26 @@ constexpr uint8_t kPacketWithRsid[] = {
0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78,
0xbe, 0xde, 0x00, 0x03,
0xa7, 's', 't', 'r',
'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;
constexpr uint8_t kPacket[] = {
0xb2, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78,
0x34, 0x56, 0x78, 0x90,
@@ -137,16 +147,28 @@ TEST(RtpPacketTest, CreateWithDynamicSiz
packet.SetPayloadType(kPayloadType);
packet.SetSequenceNumber(kSeqNum);
packet.SetTimestamp(kTimestamp);
packet.SetSsrc(kSsrc);
packet.SetExtension<RtpStreamId>(kStreamId);
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);
RtpPacketToSend packet(&extensions);
EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
}
TEST(RtpPacketTest, TryToCreateWithLongRsid) {
@@ -417,36 +439,56 @@ TEST(RtpPacketTest, ParseDynamicSizeExte
0x00}; // Extension padding.
const uint8_t kPacket2[] = {
0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
0x65, 0x43, 0x12, 0x78, // Timestamp.
0x12, 0x34, 0x56, 0x79, // Ssrc.
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)));
std::string rsid;
EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
EXPECT_EQ(rsid, "rtx");
std::string repaired_rsid;
EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
EXPECT_EQ(repaired_rsid, "HD");
// Parse another packet with RtpStreamId extension of different size.
ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
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) {
RtpPacketReceived::ExtensionManager extensions;
RtpPacketReceived packet(&extensions);
// Use ExtensionManager to set kInvalidId to 0 to demonstrate natural way for
// using zero value as a parameter to Packet::*RawExtension functions.
const int kInvalidId = extensions.GetId(TransmissionOffset::kId);
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -40,16 +40,18 @@ RTPExtensionType StringToRtpExtensionTyp
if (extension == RtpExtension::kTransportSequenceNumberUri)
return kRtpExtensionTransportSequenceNumber;
if (extension == RtpExtension::kPlayoutDelayUri)
return kRtpExtensionPlayoutDelay;
if (extension == RtpExtension::kRtpStreamIdUri)
return kRtpExtensionRtpStreamId;
if (extension == RtpExtension::kRepairedRtpStreamIdUri)
return kRtpExtensionRepairedRtpStreamId;
+ if (extension == RtpExtension::kMIdUri)
+ return kRtpExtensionMId;
RTC_NOTREACHED() << "Looking up unsupported RTP extension.";
return kRtpExtensionNone;
}
RtpRtcp::Configuration::Configuration()
: receive_statistics(NullObjectReceiveStatistics()) {}
RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -215,16 +215,25 @@ int32_t RTPSender::SetRID(const char* ri
rtc::CritScope lock(&send_critsect_);
const size_t len = (rid && rid[0]) ? strlen(rid) : 0;
if (len) {
rtpStreamId.Set(rid, len);
}
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_);
return rtp_header_extension_map_.RegisterByType(id, type) ? 0 : -1;
}
bool RTPSender::IsRtpHeaderExtensionRegistered(RTPExtensionType type) const {
rtc::CritScope lock(&send_critsect_);
@@ -446,17 +455,17 @@ bool RTPSender::SendOutgoingData(FrameTy
if (rtp_header) {
playout_delay_oracle_.UpdateRequest(ssrc, rtp_header->playout_delay,
sequence_number);
}
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_);
// Note: This is currently only counting for video.
if (frame_type == kVideoFrameKey) {
++frame_counts_.key_frames;
} else if (frame_type == kVideoFrameDelta) {
++frame_counts_.delta_frames;
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender.h
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender.h
@@ -115,16 +115,17 @@ class RTPSender {
int64_t capture_time_ms,
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* rtp_header,
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);
bool IsRtpHeaderExtensionRegistered(RTPExtensionType type) const;
int32_t DeregisterRtpHeaderExtension(RTPExtensionType type);
bool TimeToSendPacket(uint32_t ssrc,
uint16_t sequence_number,
@@ -282,16 +283,18 @@ class RTPSender {
int8_t payload_type_ GUARDED_BY(send_critsect_);
std::map<int8_t, RtpUtility::Payload*> payload_type_map_;
RtpHeaderExtensionMap rtp_header_extension_map_ GUARDED_BY(send_critsect_);
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.
PlayoutDelayOracle playout_delay_oracle_;
RtpPacketHistory packet_history_;
// TODO(brandtr): Remove |flexfec_packet_history_| when the FlexfecSender
// is hooked up to the PacedSender.
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -286,17 +286,18 @@ bool RTPSenderVideo::SendVideo(RtpVideoC
FrameType frame_type,
int8_t payload_type,
uint32_t rtp_timestamp,
int64_t capture_time_ms,
const uint8_t* payload_data,
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;
// Create header that will be reused in all packets.
std::unique_ptr<RtpPacketToSend> rtp_header = rtp_sender_->AllocatePacket();
rtp_header->SetPayloadType(payload_type);
rtp_header->SetTimestamp(rtp_timestamp);
rtp_header->set_capture_time_ms(capture_time_ms);
@@ -323,16 +324,19 @@ bool RTPSenderVideo::SendVideo(RtpVideoC
if (frame_type == kVideoFrameKey || current_rotation != last_rotation_ ||
current_rotation != kVideoRotation_0)
rtp_header->SetExtension<VideoOrientation>(current_rotation);
last_rotation_ = current_rotation;
}
if (rtpStreamId && !rtpStreamId->empty()) {
rtp_header->SetExtension<RtpStreamId>(*rtpStreamId);
}
+ if (mId && !mId->empty()) {
+ rtp_header->SetExtension<MId>(*mId);
+ }
// FEC settings.
const FecProtectionParams& fec_params =
frame_type == kVideoFrameKey ? key_fec_params_ : delta_fec_params_;
if (flexfec_enabled())
flexfec_sender_->SetFecParameters(fec_params);
if (ulpfec_enabled())
ulpfec_generator_.SetFecParameters(fec_params);
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -56,17 +56,18 @@ class RTPSenderVideo {
FrameType frame_type,
int8_t payload_type,
uint32_t capture_timestamp,
int64_t capture_time_ms,
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* video_header,
- const StreamId* rtpStreamId);
+ const StreamId* rtpStreamId,
+ const StreamId* mId);
void SetVideoCodecType(RtpVideoCodecTypes type);
// ULPFEC.
void SetUlpfecConfig(int red_payload_type, int ulpfec_payload_type);
void GetUlpfecConfig(int* red_payload_type, int* ulpfec_payload_type) const;
// FlexFEC/ULPFEC.
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
@@ -460,16 +460,20 @@ void RtpHeaderParser::ParseOneByteExtens
header->extension.rtpStreamId.Set(rtc::MakeArrayView(ptr, len + 1));
break;
}
case kRtpExtensionRepairedRtpStreamId: {
header->extension.repairedRtpStreamId.Set(
rtc::MakeArrayView(ptr, len + 1));
break;
}
+ case kRtpExtensionMId: {
+ header->extension.mId.Set(rtc::MakeArrayView(ptr, len + 1));
+ break;
+ }
default:
case kRtpExtensionNone:
case kRtpExtensionNumberOfExtensions: {
RTC_NOTREACHED() << "Invalid extension type: " << type;
return;
}
}
}
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility_unittest.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility_unittest.cc
@@ -143,46 +143,48 @@ TEST(RtpHeaderParser, ParseWithOverSized
EXPECT_TRUE(parser.Parse(&header, &extensions));
// Parse should ignore extension.
EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
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.
0x81, 0xce, 0xab, // TransportSequenceNumber.
0xa0, 0x03, // VideoRotation.
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);
RtpHeaderExtensionMap extensions;
extensions.Register<TransmissionOffset>(2);
extensions.Register<AudioLevel>(4);
extensions.Register<AbsoluteSendTime>(6);
extensions.Register<TransportSequenceNumber>(8);
extensions.Register<VideoOrientation>(0xa);
extensions.Register<PlayoutDelayLimits>(0xb);
extensions.Register<RtpStreamId>(0xc);
extensions.Register<RepairedRtpStreamId>(0xd);
+ extensions.Register<MId>(0xe);
RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket));
RTPHeader header;
EXPECT_TRUE(parser.Parse(&header, &extensions));
EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
EXPECT_EQ(0x156ce, header.extension.transmissionTimeOffset);
@@ -200,16 +202,17 @@ TEST(RtpHeaderParser, ParseAll8Extension
EXPECT_EQ(kVideoRotation_270, header.extension.videoRotation);
EXPECT_EQ(0x124 * PlayoutDelayLimits::kGranularityMs,
header.extension.playout_delay.min_ms);
EXPECT_EQ(0x876 * PlayoutDelayLimits::kGranularityMs,
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) {
// clang-format off
const uint8_t kPacket[] = {
0x90, kPayloadType, 0x00, kSeqNum,
0x65, 0x43, 0x12, 0x78, // kTimestamp.
0x12, 0x34, 0x56, 0x78, // kSsrc.
--- a/media/webrtc/trunk/webrtc/test/fuzzers/rtp_packet_fuzzer.cc
+++ b/media/webrtc/trunk/webrtc/test/fuzzers/rtp_packet_fuzzer.cc
@@ -91,12 +91,17 @@ void FuzzOneInput(const uint8_t* data, s
packet.GetExtension<RtpStreamId>(&rsid);
break;
}
case kRtpExtensionRepairedRtpStreamId: {
std::string rsid;
packet.GetExtension<RepairedRtpStreamId>(&rsid);
break;
}
+ case kRtpExtensionMId: {
+ std::string mid;
+ packet.GetExtension<MId>(&mid);
+ break;
+ }
}
}
}
} // namespace webrtc
--- a/media/webrtc/trunk/webrtc/video/rtp_stream_receiver.cc
+++ b/media/webrtc/trunk/webrtc/video/rtp_stream_receiver.cc
@@ -273,16 +273,32 @@ bool RtpStreamReceiver::SetReceiveRIDSta
return false;
}
}
receiving_rid_enabled_ = false;
return rtp_header_parser_->DeregisterRtpHeaderExtension(
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,
const WebRtcRTPHeader* rtp_header) {
RTC_DCHECK(video_receiver_);
WebRtcRTPHeader rtp_header_with_ntp = *rtp_header;
rtp_header_with_ntp.ntp_time_ms =
ntp_estimator_.Estimate(rtp_header->header.timestamp);
@@ -389,16 +405,18 @@ bool RtpStreamReceiver::DeliverRtp(const
if (header.extension.hasTransmissionTimeOffset)
ss << ", toffset: " << header.extension.transmissionTimeOffset;
if (header.extension.hasAbsoluteSendTime)
ss << ", abs send time: " << header.extension.absoluteSendTime;
if (!header.extension.rtpStreamId.empty())
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;
}
}
remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_length,
header);
header.payload_type_frequency = kVideoPayloadTypeFrequency;
--- a/media/webrtc/trunk/webrtc/video/rtp_stream_receiver.h
+++ b/media/webrtc/trunk/webrtc/video/rtp_stream_receiver.h
@@ -86,16 +86,17 @@ class RtpStreamReceiver : public RtpData
const std::map<std::string, std::string>& codec_params);
bool AddReceiveCodec(const VideoCodec& video_codec);
uint32_t GetRemoteSsrc() const;
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(); }
void StartReceive();
void StopReceive();
bool DeliverRtp(const uint8_t* rtp_packet,
@@ -182,16 +183,17 @@ class RtpStreamReceiver : public RtpData
const std::unique_ptr<ReceiveStatistics> rtp_receive_statistics_;
std::unique_ptr<UlpfecReceiver> ulpfec_receiver_;
rtc::CriticalSection receive_cs_;
bool receiving_ GUARDED_BY(receive_cs_);
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_;
// Members for the new jitter buffer experiment.
bool jitter_buffer_experiment_;
video_coding::OnCompleteFrameCallback* complete_frame_callback_;
KeyFrameRequestSender* keyframe_request_sender_;