Add writing and parsing of the abs-capture-time RTP header extension.

This change adds the writing and parsing of the `abs-capture-time` RTP header extension defined at:

  http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time

We are still missing the code to:

- Negotiate the header extension.
- Collect capture time for audio and video and have the info sent with the header extension.
- Receive the header extension and use its info.

Bug: webrtc:10739
Change-Id: I75af492e994367f45a5bdc110af199900327b126
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144221
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Chen Xing <chxg@google.com>
Cr-Commit-Position: refs/heads/master@{#28468}
This commit is contained in:
Chen Xing
2019-07-01 10:56:51 +02:00
committed by Commit Bot
parent 53d45baa50
commit cd8a6e2f38
14 changed files with 250 additions and 3 deletions

View File

@ -56,6 +56,89 @@ bool AbsoluteSendTime::Write(rtc::ArrayView<uint8_t> data,
return true;
}
// Absolute Capture Time
//
// The Absolute Capture Time extension is used to stamp RTP packets with a NTP
// timestamp showing when the first audio or video frame in a packet was
// originally captured. The intent of this extension is to provide a way to
// accomplish audio-to-video synchronization when RTCP-terminating intermediate
// systems (e.g. mixers) are involved.
//
// Data layout of the shortened version of abs-capture-time:
//
// 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
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ID | len=7 | absolute capture timestamp (bit 0-23) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | absolute capture timestamp (bit 24-55) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... (56-63) |
// +-+-+-+-+-+-+-+-+
//
// Data layout of the extended version of abs-capture-time:
//
// 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
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ID | len=15| absolute capture timestamp (bit 0-23) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | absolute capture timestamp (bit 24-55) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... (56-63) | estimated capture clock offset (bit 0-23) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | estimated capture clock offset (bit 24-55) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... (56-63) |
// +-+-+-+-+-+-+-+-+
constexpr RTPExtensionType AbsoluteCaptureTimeExtension::kId;
constexpr uint8_t AbsoluteCaptureTimeExtension::kValueSizeBytes;
constexpr uint8_t AbsoluteCaptureTimeExtension::
kValueSizeBytesWithoutEstimatedCaptureClockOffset;
constexpr const char AbsoluteCaptureTimeExtension::kUri[];
bool AbsoluteCaptureTimeExtension::Parse(rtc::ArrayView<const uint8_t> data,
AbsoluteCaptureTime* extension) {
if (data.size() != kValueSizeBytes &&
data.size() != kValueSizeBytesWithoutEstimatedCaptureClockOffset) {
return false;
}
extension->absolute_capture_timestamp =
ByteReader<uint64_t>::ReadBigEndian(data.data());
if (data.size() != kValueSizeBytesWithoutEstimatedCaptureClockOffset) {
extension->estimated_capture_clock_offset =
ByteReader<int64_t>::ReadBigEndian(data.data() + 8);
}
return true;
}
size_t AbsoluteCaptureTimeExtension::ValueSize(
const AbsoluteCaptureTime& extension) {
if (extension.estimated_capture_clock_offset != absl::nullopt) {
return kValueSizeBytes;
} else {
return kValueSizeBytesWithoutEstimatedCaptureClockOffset;
}
}
bool AbsoluteCaptureTimeExtension::Write(rtc::ArrayView<uint8_t> data,
const AbsoluteCaptureTime& extension) {
RTC_DCHECK_EQ(data.size(), ValueSize(extension));
ByteWriter<uint64_t>::WriteBigEndian(data.data(),
extension.absolute_capture_timestamp);
if (data.size() != kValueSizeBytesWithoutEstimatedCaptureClockOffset) {
ByteWriter<int64_t>::WriteBigEndian(
data.data() + 8, extension.estimated_capture_clock_offset.value());
}
return true;
}
// An RTP Header Extension for Client-to-Mixer Audio Level Indication
//
// https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/