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:
@ -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/
|
||||
|
||||
Reference in New Issue
Block a user