Reason for revert: dependent project adjusted Original issue's description: > Revert of Simplify and extend RtpHeaderExtensionMap (patchset #12 id:260001 of https://codereview.webrtc.org/2452293004/ ) > > Reason for revert: > breaks downstream project > > Original issue's description: > > Simplify and extend RtpHeaderExtensionMap > > Add register functions for various codepaths. > > Add initialize-list constructor to create usable const RtpHeaderExtensionMap > > Optimize implementation for GetId/GetType. > > > > BUG=webrtc:1994 > > > > Committed: https://crrev.com/d1d26fbeb37a69471a34004c6ac2d3fafde5d404 > > Cr-Commit-Position: refs/heads/master@{#14986} > > TBR=sprang@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:1994 > > Committed: https://crrev.com/bc38b4d450a80bf45efbe5b0a452e0374cdae1e6 > Cr-Commit-Position: refs/heads/master@{#14988} TBR=sprang@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:1994 Review-Url: https://codereview.webrtc.org/2492443002 Cr-Commit-Position: refs/heads/master@{#15000}
200 lines
7.3 KiB
C++
200 lines
7.3 KiB
C++
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
|
|
|
|
#include "webrtc/base/checks.h"
|
|
#include "webrtc/base/logging.h"
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
|
|
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
|
|
|
namespace webrtc {
|
|
// Absolute send time in RTP streams.
|
|
//
|
|
// The absolute send time is signaled to the receiver in-band using the
|
|
// general mechanism for RTP header extensions [RFC5285]. The payload
|
|
// of this extension (the transmitted value) is a 24-bit unsigned integer
|
|
// containing the sender's current time in seconds as a fixed point number
|
|
// with 18 bits fractional part.
|
|
//
|
|
// The form of the absolute send time extension block:
|
|
//
|
|
// 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=2 | absolute send time |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
constexpr RTPExtensionType AbsoluteSendTime::kId;
|
|
constexpr uint8_t AbsoluteSendTime::kValueSizeBytes;
|
|
constexpr const char* AbsoluteSendTime::kUri;
|
|
|
|
bool AbsoluteSendTime::Parse(const uint8_t* data, uint32_t* time_24bits) {
|
|
*time_24bits = ByteReader<uint32_t, 3>::ReadBigEndian(data);
|
|
return true;
|
|
}
|
|
|
|
bool AbsoluteSendTime::Write(uint8_t* data, int64_t time_ms) {
|
|
ByteWriter<uint32_t, 3>::WriteBigEndian(data, MsTo24Bits(time_ms));
|
|
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/
|
|
//
|
|
// The form of the audio level extension block:
|
|
//
|
|
// 0 1
|
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// | ID | len=0 |V| level |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
//
|
|
constexpr RTPExtensionType AudioLevel::kId;
|
|
constexpr uint8_t AudioLevel::kValueSizeBytes;
|
|
constexpr const char* AudioLevel::kUri;
|
|
|
|
bool AudioLevel::Parse(const uint8_t* data,
|
|
bool* voice_activity,
|
|
uint8_t* audio_level) {
|
|
*voice_activity = (data[0] & 0x80) != 0;
|
|
*audio_level = data[0] & 0x7F;
|
|
return true;
|
|
}
|
|
|
|
bool AudioLevel::Write(uint8_t* data,
|
|
bool voice_activity,
|
|
uint8_t audio_level) {
|
|
RTC_CHECK_LE(audio_level, 0x7f);
|
|
data[0] = (voice_activity ? 0x80 : 0x00) | audio_level;
|
|
return true;
|
|
}
|
|
|
|
// From RFC 5450: Transmission Time Offsets in RTP Streams.
|
|
//
|
|
// The transmission time is signaled to the receiver in-band using the
|
|
// general mechanism for RTP header extensions [RFC5285]. The payload
|
|
// of this extension (the transmitted value) is a 24-bit signed integer.
|
|
// When added to the RTP timestamp of the packet, it represents the
|
|
// "effective" RTP transmission time of the packet, on the RTP
|
|
// timescale.
|
|
//
|
|
// The form of the transmission offset extension block:
|
|
//
|
|
// 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=2 | transmission offset |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
constexpr RTPExtensionType TransmissionOffset::kId;
|
|
constexpr uint8_t TransmissionOffset::kValueSizeBytes;
|
|
constexpr const char* TransmissionOffset::kUri;
|
|
|
|
bool TransmissionOffset::Parse(const uint8_t* data, int32_t* rtp_time) {
|
|
*rtp_time = ByteReader<int32_t, 3>::ReadBigEndian(data);
|
|
return true;
|
|
}
|
|
|
|
bool TransmissionOffset::Write(uint8_t* data, int32_t rtp_time) {
|
|
RTC_DCHECK_LE(rtp_time, 0x00ffffff);
|
|
ByteWriter<int32_t, 3>::WriteBigEndian(data, rtp_time);
|
|
return true;
|
|
}
|
|
|
|
// 0 1 2
|
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// | ID | L=1 |transport wide sequence number |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
constexpr RTPExtensionType TransportSequenceNumber::kId;
|
|
constexpr uint8_t TransportSequenceNumber::kValueSizeBytes;
|
|
constexpr const char* TransportSequenceNumber::kUri;
|
|
|
|
bool TransportSequenceNumber::Parse(const uint8_t* data, uint16_t* value) {
|
|
*value = ByteReader<uint16_t>::ReadBigEndian(data);
|
|
return true;
|
|
}
|
|
|
|
bool TransportSequenceNumber::Write(uint8_t* data, uint16_t value) {
|
|
ByteWriter<uint16_t>::WriteBigEndian(data, value);
|
|
return true;
|
|
}
|
|
|
|
// Coordination of Video Orientation in RTP streams.
|
|
//
|
|
// Coordination of Video Orientation consists in signaling of the current
|
|
// orientation of the image captured on the sender side to the receiver for
|
|
// appropriate rendering and displaying.
|
|
//
|
|
// 0 1
|
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// | ID | len=0 |0 0 0 0 C F R R|
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
constexpr RTPExtensionType VideoOrientation::kId;
|
|
constexpr uint8_t VideoOrientation::kValueSizeBytes;
|
|
constexpr const char* VideoOrientation::kUri;
|
|
|
|
bool VideoOrientation::Parse(const uint8_t* data, VideoRotation* rotation) {
|
|
*rotation = ConvertCVOByteToVideoRotation(data[0]);
|
|
return true;
|
|
}
|
|
|
|
bool VideoOrientation::Write(uint8_t* data, VideoRotation rotation) {
|
|
data[0] = ConvertVideoRotationToCVOByte(rotation);
|
|
return true;
|
|
}
|
|
|
|
bool VideoOrientation::Parse(const uint8_t* data, uint8_t* value) {
|
|
*value = data[0];
|
|
return true;
|
|
}
|
|
|
|
bool VideoOrientation::Write(uint8_t* data, uint8_t value) {
|
|
data[0] = value;
|
|
return true;
|
|
}
|
|
|
|
// 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=2 | MIN delay | MAX delay |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
constexpr RTPExtensionType PlayoutDelayLimits::kId;
|
|
constexpr uint8_t PlayoutDelayLimits::kValueSizeBytes;
|
|
constexpr const char* PlayoutDelayLimits::kUri;
|
|
|
|
bool PlayoutDelayLimits::Parse(const uint8_t* data,
|
|
PlayoutDelay* playout_delay) {
|
|
RTC_DCHECK(playout_delay);
|
|
uint32_t raw = ByteReader<uint32_t, 3>::ReadBigEndian(data);
|
|
uint16_t min_raw = (raw >> 12);
|
|
uint16_t max_raw = (raw & 0xfff);
|
|
if (min_raw > max_raw)
|
|
return false;
|
|
playout_delay->min_ms = min_raw * kGranularityMs;
|
|
playout_delay->max_ms = max_raw * kGranularityMs;
|
|
return true;
|
|
}
|
|
|
|
bool PlayoutDelayLimits::Write(uint8_t* data,
|
|
const PlayoutDelay& playout_delay) {
|
|
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);
|
|
return true;
|
|
}
|
|
|
|
} // namespace webrtc
|