Index: webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc |
index 3bb9bc5553849a9acf1d756fd489b9d94c6f1ad3..f8041701ceabb200f226ce36456d55a51a2b1a9f 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc |
@@ -244,6 +244,65 @@ bool VideoContentTypeExtension::Write(uint8_t* data, |
return true; |
} |
+// Video Timing. |
+// 5 timestamps in milliseconds counted from capture time stored in rtp header: |
+// ecode start/finish, packetization complete, pacer exit and reserved for |
+// modification by the network modification. |
+// 0 1 2 3 |
+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+// | ID | len=9 | encode start ms delta | encode finish | |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+// | ms delta | packetizer finish ms delta | pacer exit | |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+// | ms delta | network timestamp ms delta | | |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ |
sprang_webrtc
2017/05/31 11:12:55
So the empty 8bit block at the end is not a part o
ilnik
2017/05/31 15:17:45
Not part of the extension.
|
+constexpr RTPExtensionType VideoTimingExtension::kId; |
+constexpr uint8_t VideoTimingExtension::kValueSizeBytes; |
+constexpr const char* VideoTimingExtension::kUri; |
+ |
+bool VideoTimingExtension::Parse(rtc::ArrayView<const uint8_t> data, |
+ VideoTiming* timing) { |
+ RTC_DCHECK(timing); |
+ if (data.size() != 10) |
+ return false; |
+ timing->encode_start_ms_delta = |
+ ByteReader<uint16_t, 2>::ReadBigEndian(data.data()); |
sprang_webrtc
2017/05/31 11:12:55
You don't need the second template parameter here.
ilnik
2017/05/31 15:17:45
Done.
|
+ timing->encode_finish_ms_delta = ByteReader<uint16_t, 2>::ReadBigEndian( |
+ data.data() + 2 * VideoTiming::kEncodeFinishIdx); |
+ timing->packetization_finish_ms_delta = |
+ ByteReader<uint16_t, 2>::ReadBigEndian( |
+ data.data() + 2 * VideoTiming::kPacketizationFinishDeltaIdx); |
+ timing->pacer_exit_ms_delta = ByteReader<uint16_t, 2>::ReadBigEndian( |
+ data.data() + 2 * VideoTiming::kPacerExitDeltaIdx); |
+ timing->network_timstamp_ms_delta = ByteReader<uint16_t, 2>::ReadBigEndian( |
+ data.data() + 2 * VideoTiming::kNetworkTimestampDeltaIdx); |
+ timing->is_timing_frame = true; |
+ return true; |
+} |
+ |
+bool VideoTimingExtension::Write(uint8_t* data, const VideoTiming& timing) { |
+ ByteWriter<uint16_t, 2>::WriteBigEndian(data, timing.encode_start_ms_delta); |
+ ByteWriter<uint16_t, 2>::WriteBigEndian( |
+ data + 2 * VideoTiming::kEncodeFinishIdx, timing.encode_finish_ms_delta); |
+ ByteWriter<uint16_t, 2>::WriteBigEndian( |
+ data + 2 * VideoTiming::kPacketizationFinishDeltaIdx, |
+ timing.packetization_finish_ms_delta); |
+ ByteWriter<uint16_t, 2>::WriteBigEndian( |
+ data + 2 * VideoTiming::kPacerExitDeltaIdx, timing.pacer_exit_ms_delta); |
+ ByteWriter<uint16_t, 2>::WriteBigEndian( |
+ data + 2 * VideoTiming::kNetworkTimestampDeltaIdx, 0); // reserved |
+ return true; |
+} |
+ |
+bool VideoTimingExtension::Write(uint8_t* data, |
+ uint16_t time_delta_ms, |
+ uint8_t idx) { |
+ ByteWriter<uint16_t, 2>::WriteBigEndian(data + 2 * idx, time_delta_ms); |
+ return true; |
+} |
+ |
// RtpStreamId. |
constexpr RTPExtensionType RtpStreamId::kId; |
constexpr const char* RtpStreamId::kUri; |