Pass buffer with size when writing rtp header extension

Bug: chromium:826911
Change-Id: I617fecfee74745004067d892d6e31c94304f99ea
Reviewed-on: https://webrtc-review.googlesource.com/83945
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23641}
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.cc b/modules/rtp_rtcp/source/rtp_header_extensions.cc
index 958ad02..2dba4d7 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.cc
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.cc
@@ -43,9 +43,11 @@
   return true;
 }
 
-bool AbsoluteSendTime::Write(uint8_t* data, uint32_t time_24bits) {
+bool AbsoluteSendTime::Write(rtc::ArrayView<uint8_t> data,
+                             uint32_t time_24bits) {
+  RTC_DCHECK_EQ(data.size(), 3);
   RTC_DCHECK_LE(time_24bits, 0x00FFFFFF);
-  ByteWriter<uint32_t, 3>::WriteBigEndian(data, time_24bits);
+  ByteWriter<uint32_t, 3>::WriteBigEndian(data.data(), time_24bits);
   return true;
 }
 
@@ -75,9 +77,10 @@
   return true;
 }
 
-bool AudioLevel::Write(uint8_t* data,
+bool AudioLevel::Write(rtc::ArrayView<uint8_t> data,
                        bool voice_activity,
                        uint8_t audio_level) {
+  RTC_DCHECK_EQ(data.size(), 1);
   RTC_CHECK_LE(audio_level, 0x7f);
   data[0] = (voice_activity ? 0x80 : 0x00) | audio_level;
   return true;
@@ -111,9 +114,10 @@
   return true;
 }
 
-bool TransmissionOffset::Write(uint8_t* data, int32_t rtp_time) {
+bool TransmissionOffset::Write(rtc::ArrayView<uint8_t> data, int32_t rtp_time) {
+  RTC_DCHECK_EQ(data.size(), 3);
   RTC_DCHECK_LE(rtp_time, 0x00ffffff);
-  ByteWriter<int32_t, 3>::WriteBigEndian(data, rtp_time);
+  ByteWriter<int32_t, 3>::WriteBigEndian(data.data(), rtp_time);
   return true;
 }
 
@@ -134,8 +138,10 @@
   return true;
 }
 
-bool TransportSequenceNumber::Write(uint8_t* data, uint16_t value) {
-  ByteWriter<uint16_t>::WriteBigEndian(data, value);
+bool TransportSequenceNumber::Write(rtc::ArrayView<uint8_t> data,
+                                    uint16_t value) {
+  RTC_DCHECK_EQ(data.size(), 2);
+  ByteWriter<uint16_t>::WriteBigEndian(data.data(), value);
   return true;
 }
 
@@ -162,7 +168,9 @@
   return true;
 }
 
-bool VideoOrientation::Write(uint8_t* data, VideoRotation rotation) {
+bool VideoOrientation::Write(rtc::ArrayView<uint8_t> data,
+                             VideoRotation rotation) {
+  RTC_DCHECK_EQ(data.size(), 1);
   data[0] = ConvertVideoRotationToCVOByte(rotation);
   return true;
 }
@@ -175,7 +183,8 @@
   return true;
 }
 
-bool VideoOrientation::Write(uint8_t* data, uint8_t value) {
+bool VideoOrientation::Write(rtc::ArrayView<uint8_t> data, uint8_t value) {
+  RTC_DCHECK_EQ(data.size(), 1);
   data[0] = value;
   return true;
 }
@@ -204,15 +213,17 @@
   return true;
 }
 
-bool PlayoutDelayLimits::Write(uint8_t* data,
+bool PlayoutDelayLimits::Write(rtc::ArrayView<uint8_t> data,
                                const PlayoutDelay& playout_delay) {
+  RTC_DCHECK_EQ(data.size(), 3);
   RTC_DCHECK_LE(0, playout_delay.min_ms);
   RTC_DCHECK_LE(playout_delay.min_ms, playout_delay.max_ms);
   RTC_DCHECK_LE(playout_delay.max_ms, kMaxMs);
   // Convert MS to value to be sent on extension header.
   uint32_t min_delay = playout_delay.min_ms / kGranularityMs;
   uint32_t max_delay = playout_delay.max_ms / kGranularityMs;
-  ByteWriter<uint32_t, 3>::WriteBigEndian(data, (min_delay << 12) | max_delay);
+  ByteWriter<uint32_t, 3>::WriteBigEndian(data.data(),
+                                          (min_delay << 12) | max_delay);
   return true;
 }
 
@@ -239,8 +250,9 @@
   return false;
 }
 
-bool VideoContentTypeExtension::Write(uint8_t* data,
+bool VideoContentTypeExtension::Write(rtc::ArrayView<uint8_t> data,
                                       VideoContentType content_type) {
+  RTC_DCHECK_EQ(data.size(), 1);
   data[0] = static_cast<uint8_t>(content_type);
   return true;
 }
@@ -303,35 +315,38 @@
   return true;
 }
 
-bool VideoTimingExtension::Write(uint8_t* data, const VideoSendTiming& timing) {
-  ByteWriter<uint8_t>::WriteBigEndian(data + VideoSendTiming::kFlagsOffset,
-                                      timing.flags);
+bool VideoTimingExtension::Write(rtc::ArrayView<uint8_t> data,
+                                 const VideoSendTiming& timing) {
+  RTC_DCHECK_EQ(data.size(), 1 + 2 * 6);
+  ByteWriter<uint8_t>::WriteBigEndian(
+      data.data() + VideoSendTiming::kFlagsOffset, timing.flags);
   ByteWriter<uint16_t>::WriteBigEndian(
-      data + VideoSendTiming::kEncodeStartDeltaOffset,
+      data.data() + VideoSendTiming::kEncodeStartDeltaOffset,
       timing.encode_start_delta_ms);
   ByteWriter<uint16_t>::WriteBigEndian(
-      data + VideoSendTiming::kEncodeFinishDeltaOffset,
+      data.data() + VideoSendTiming::kEncodeFinishDeltaOffset,
       timing.encode_finish_delta_ms);
   ByteWriter<uint16_t>::WriteBigEndian(
-      data + VideoSendTiming::kPacketizationFinishDeltaOffset,
+      data.data() + VideoSendTiming::kPacketizationFinishDeltaOffset,
       timing.packetization_finish_delta_ms);
   ByteWriter<uint16_t>::WriteBigEndian(
-      data + VideoSendTiming::kPacerExitDeltaOffset,
+      data.data() + VideoSendTiming::kPacerExitDeltaOffset,
       timing.pacer_exit_delta_ms);
   ByteWriter<uint16_t>::WriteBigEndian(
-      data + VideoSendTiming::kNetworkTimestampDeltaOffset,
+      data.data() + VideoSendTiming::kNetworkTimestampDeltaOffset,
       timing.network_timestamp_delta_ms);
   ByteWriter<uint16_t>::WriteBigEndian(
-      data + VideoSendTiming::kNetwork2TimestampDeltaOffset,
+      data.data() + VideoSendTiming::kNetwork2TimestampDeltaOffset,
       timing.network2_timestamp_delta_ms);
   return true;
 }
 
-bool VideoTimingExtension::Write(uint8_t* data,
+bool VideoTimingExtension::Write(rtc::ArrayView<uint8_t> data,
                                  uint16_t time_delta_ms,
                                  uint8_t offset) {
+  RTC_DCHECK_GE(data.size(), offset + 2);
   RTC_DCHECK_LE(offset, kValueSizeBytes - sizeof(uint16_t));
-  ByteWriter<uint16_t>::WriteBigEndian(data + offset, time_delta_ms);
+  ByteWriter<uint16_t>::WriteBigEndian(data.data() + offset, time_delta_ms);
   return true;
 }
 
@@ -344,11 +359,12 @@
   return true;
 }
 
-bool BaseRtpStringExtension::Write(uint8_t* data,
+bool BaseRtpStringExtension::Write(rtc::ArrayView<uint8_t> data,
                                    const StringRtpHeaderExtension& str) {
+  RTC_DCHECK_EQ(data.size(), str.size());
   RTC_DCHECK_GE(str.size(), 1);
   RTC_DCHECK_LE(str.size(), StringRtpHeaderExtension::kMaxSize);
-  memcpy(data, str.data(), str.size());
+  memcpy(data.data(), str.data(), str.size());
   return true;
 }
 
@@ -364,10 +380,12 @@
   return true;
 }
 
-bool BaseRtpStringExtension::Write(uint8_t* data, const std::string& str) {
+bool BaseRtpStringExtension::Write(rtc::ArrayView<uint8_t> data,
+                                   const std::string& str) {
+  RTC_DCHECK_EQ(data.size(), str.size());
   RTC_DCHECK_GE(str.size(), 1);
   RTC_DCHECK_LE(str.size(), StringRtpHeaderExtension::kMaxSize);
-  memcpy(data, str.data(), str.size());
+  memcpy(data.data(), str.data(), str.size());
   return true;
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.h b/modules/rtp_rtcp/source/rtp_header_extensions.h
index 8526f13..4e1afc1 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.h
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.h
@@ -30,7 +30,7 @@
 
   static bool Parse(rtc::ArrayView<const uint8_t> data, uint32_t* time_24bits);
   static size_t ValueSize(uint32_t time_24bits) { return kValueSizeBytes; }
-  static bool Write(uint8_t* data, uint32_t time_24bits);
+  static bool Write(rtc::ArrayView<uint8_t> data, uint32_t time_24bits);
 
   static constexpr uint32_t MsTo24Bits(int64_t time_ms) {
     return static_cast<uint32_t>(((time_ms << 18) + 500) / 1000) & 0x00FFFFFF;
@@ -50,7 +50,9 @@
   static size_t ValueSize(bool voice_activity, uint8_t audio_level) {
     return kValueSizeBytes;
   }
-  static bool Write(uint8_t* data, bool voice_activity, uint8_t audio_level);
+  static bool Write(rtc::ArrayView<uint8_t> data,
+                    bool voice_activity,
+                    uint8_t audio_level);
 };
 
 class TransmissionOffset {
@@ -61,7 +63,7 @@
 
   static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time);
   static size_t ValueSize(int32_t rtp_time) { return kValueSizeBytes; }
-  static bool Write(uint8_t* data, int32_t rtp_time);
+  static bool Write(rtc::ArrayView<uint8_t> data, int32_t rtp_time);
 };
 
 class TransportSequenceNumber {
@@ -73,7 +75,7 @@
       "draft-holmer-rmcat-transport-wide-cc-extensions-01";
   static bool Parse(rtc::ArrayView<const uint8_t> data, uint16_t* value);
   static size_t ValueSize(uint16_t value) { return kValueSizeBytes; }
-  static bool Write(uint8_t* data, uint16_t value);
+  static bool Write(rtc::ArrayView<uint8_t> data, uint16_t value);
 };
 
 class VideoOrientation {
@@ -84,10 +86,10 @@
 
   static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
   static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
-  static bool Write(uint8_t* data, VideoRotation value);
+  static bool Write(rtc::ArrayView<uint8_t> data, VideoRotation value);
   static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
   static size_t ValueSize(uint8_t value) { return kValueSizeBytes; }
-  static bool Write(uint8_t* data, uint8_t value);
+  static bool Write(rtc::ArrayView<uint8_t> data, uint8_t value);
 };
 
 class PlayoutDelayLimits {
@@ -109,7 +111,8 @@
   static size_t ValueSize(const PlayoutDelay&) {
     return kValueSizeBytes;
   }
-  static bool Write(uint8_t* data, const PlayoutDelay& playout_delay);
+  static bool Write(rtc::ArrayView<uint8_t> data,
+                    const PlayoutDelay& playout_delay);
 };
 
 class VideoContentTypeExtension {
@@ -124,7 +127,8 @@
   static size_t ValueSize(VideoContentType) {
     return kValueSizeBytes;
   }
-  static bool Write(uint8_t* data, VideoContentType content_type);
+  static bool Write(rtc::ArrayView<uint8_t> data,
+                    VideoContentType content_type);
 };
 
 class VideoTimingExtension {
@@ -137,13 +141,16 @@
   static bool Parse(rtc::ArrayView<const uint8_t> data,
                     VideoSendTiming* timing);
   static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
-  static bool Write(uint8_t* data, const VideoSendTiming& timing);
+  static bool Write(rtc::ArrayView<uint8_t> data,
+                    const VideoSendTiming& timing);
 
   static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) {
     return kValueSizeBytes;
   }
   // Writes only single time delta to position idx.
-  static bool Write(uint8_t* data, uint16_t time_delta_ms, uint8_t idx);
+  static bool Write(rtc::ArrayView<uint8_t> data,
+                    uint16_t time_delta_ms,
+                    uint8_t idx);
 };
 
 // Base extension class for RTP header extensions which are strings.
@@ -159,11 +166,12 @@
   static size_t ValueSize(const StringRtpHeaderExtension& str) {
     return str.size();
   }
-  static bool Write(uint8_t* data, const StringRtpHeaderExtension& str);
+  static bool Write(rtc::ArrayView<uint8_t> data,
+                    const StringRtpHeaderExtension& str);
 
   static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* str);
   static size_t ValueSize(const std::string& str) { return str.size(); }
-  static bool Write(uint8_t* data, const std::string& str);
+  static bool Write(rtc::ArrayView<uint8_t> data, const std::string& str);
 };
 
 class RtpStreamId : public BaseRtpStringExtension {
diff --git a/modules/rtp_rtcp/source/rtp_packet.h b/modules/rtp_rtcp/source/rtp_packet.h
index acb5880..2f0ef75 100644
--- a/modules/rtp_rtcp/source/rtp_packet.h
+++ b/modules/rtp_rtcp/source/rtp_packet.h
@@ -181,7 +181,7 @@
   auto buffer = AllocateExtension(Extension::kId, value_size);
   if (buffer.empty())
     return false;
-  return Extension::Write(buffer.data(), values...);
+  return Extension::Write(buffer, values...);
 }
 
 template <typename Extension>
diff --git a/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
index 3a801fb..60d23d8 100644
--- a/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
@@ -206,12 +206,12 @@
   auto raw = packet.AllocateRawExtension(kTransmissionOffsetExtensionId,
                                          TransmissionOffset::kValueSizeBytes);
   EXPECT_EQ(raw.size(), TransmissionOffset::kValueSizeBytes);
-  TransmissionOffset::Write(raw.data(), kTimeOffset);
+  TransmissionOffset::Write(raw, kTimeOffset);
 
   raw = packet.AllocateRawExtension(kAudioLevelExtensionId,
                                     AudioLevel::kValueSizeBytes);
   EXPECT_EQ(raw.size(), AudioLevel::kValueSizeBytes);
-  AudioLevel::Write(raw.data(), kVoiceActive, kAudioLevel);
+  AudioLevel::Write(raw, kVoiceActive, kAudioLevel);
 
   EXPECT_THAT(kPacketWithTOAndAL,
               ElementsAreArray(packet.data(), packet.size()));