Implement the mixer-to-client per CSRC audio level extension (RFC 6465).
This is loosely based on the similar implementation in gecko. Bug: webrtc:9965 Change-Id: I5203a05e1c34ca6f97bd1b143790f95ff245e340 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219791 Reviewed-by: Tommi <tommi@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Doudou Kisabaka <doudouk@google.com> Cr-Commit-Position: refs/heads/master@{#34102}
This commit is contained in:
parent
096ad02c02
commit
ae0d117d51
@ -357,6 +357,11 @@ struct RTC_EXPORT RtpExtension {
|
|||||||
static constexpr char kVideoFrameTrackingIdUri[] =
|
static constexpr char kVideoFrameTrackingIdUri[] =
|
||||||
"http://www.webrtc.org/experiments/rtp-hdrext/video-frame-tracking-id";
|
"http://www.webrtc.org/experiments/rtp-hdrext/video-frame-tracking-id";
|
||||||
|
|
||||||
|
// Header extension for Mixer-to-Client audio levels per CSRC as defined in
|
||||||
|
// https://tools.ietf.org/html/rfc6465
|
||||||
|
static constexpr char kCsrcAudioLevelsUri[] =
|
||||||
|
"urn:ietf:params:rtp-hdrext:csrc-audio-level";
|
||||||
|
|
||||||
// Inclusive min and max IDs for two-byte header extensions and one-byte
|
// Inclusive min and max IDs for two-byte header extensions and one-byte
|
||||||
// header extensions, per RFC8285 Section 4.2-4.3.
|
// header extensions, per RFC8285 Section 4.2-4.3.
|
||||||
static constexpr int kMinId = 1;
|
static constexpr int kMinId = 1;
|
||||||
|
|||||||
@ -57,6 +57,7 @@ enum RTPExtensionType : int {
|
|||||||
kRtpExtensionNone,
|
kRtpExtensionNone,
|
||||||
kRtpExtensionTransmissionTimeOffset,
|
kRtpExtensionTransmissionTimeOffset,
|
||||||
kRtpExtensionAudioLevel,
|
kRtpExtensionAudioLevel,
|
||||||
|
kRtpExtensionCsrcAudioLevel,
|
||||||
kRtpExtensionInbandComfortNoise,
|
kRtpExtensionInbandComfortNoise,
|
||||||
kRtpExtensionAbsoluteSendTime,
|
kRtpExtensionAbsoluteSendTime,
|
||||||
kRtpExtensionAbsoluteCaptureTime,
|
kRtpExtensionAbsoluteCaptureTime,
|
||||||
|
|||||||
@ -34,6 +34,7 @@ constexpr ExtensionInfo CreateExtensionInfo() {
|
|||||||
constexpr ExtensionInfo kExtensions[] = {
|
constexpr ExtensionInfo kExtensions[] = {
|
||||||
CreateExtensionInfo<TransmissionOffset>(),
|
CreateExtensionInfo<TransmissionOffset>(),
|
||||||
CreateExtensionInfo<AudioLevel>(),
|
CreateExtensionInfo<AudioLevel>(),
|
||||||
|
CreateExtensionInfo<CsrcAudioLevel>(),
|
||||||
CreateExtensionInfo<AbsoluteSendTime>(),
|
CreateExtensionInfo<AbsoluteSendTime>(),
|
||||||
CreateExtensionInfo<AbsoluteCaptureTimeExtension>(),
|
CreateExtensionInfo<AbsoluteCaptureTimeExtension>(),
|
||||||
CreateExtensionInfo<VideoOrientation>(),
|
CreateExtensionInfo<VideoOrientation>(),
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include "modules/rtp_rtcp/include/rtp_cvo.h"
|
#include "modules/rtp_rtcp/include/rtp_cvo.h"
|
||||||
@ -186,6 +187,60 @@ bool AudioLevel::Write(rtc::ArrayView<uint8_t> data,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An RTP Header Extension for Mixer-to-Client Audio Level Indication
|
||||||
|
//
|
||||||
|
// https://tools.ietf.org/html/rfc6465
|
||||||
|
//
|
||||||
|
// The form of the audio level 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 |0| level 1 |0| level 2 |0| level 3 |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// Sample Audio Level Encoding Using the One-Byte Header Format
|
||||||
|
//
|
||||||
|
// 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=3 |0| level 1 |0| level 2 |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |0| level 3 | 0 (pad) | ... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// Sample Audio Level Encoding Using the Two-Byte Header Format
|
||||||
|
constexpr RTPExtensionType CsrcAudioLevel::kId;
|
||||||
|
constexpr uint8_t CsrcAudioLevel::kMaxValueSizeBytes;
|
||||||
|
constexpr const char CsrcAudioLevel::kUri[];
|
||||||
|
|
||||||
|
bool CsrcAudioLevel::Parse(rtc::ArrayView<const uint8_t> data,
|
||||||
|
std::vector<uint8_t>* csrc_audio_levels) {
|
||||||
|
if (data.size() > kRtpCsrcSize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
csrc_audio_levels->resize(data.size());
|
||||||
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
|
(*csrc_audio_levels)[i] = data[i] & 0x7F;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CsrcAudioLevel::ValueSize(
|
||||||
|
rtc::ArrayView<const uint8_t> csrc_audio_levels) {
|
||||||
|
return csrc_audio_levels.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CsrcAudioLevel::Write(rtc::ArrayView<uint8_t> data,
|
||||||
|
rtc::ArrayView<const uint8_t> csrc_audio_levels) {
|
||||||
|
RTC_CHECK_LE(csrc_audio_levels.size(), kRtpCsrcSize);
|
||||||
|
if (csrc_audio_levels.size() != data.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < csrc_audio_levels.size(); i++) {
|
||||||
|
data[i] = csrc_audio_levels[i] & 0x7F;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// From RFC 5450: Transmission Time Offsets in RTP Streams.
|
// From RFC 5450: Transmission Time Offsets in RTP Streams.
|
||||||
//
|
//
|
||||||
// The transmission time is signaled to the receiver in-band using the
|
// The transmission time is signaled to the receiver in-band using the
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "api/rtp_headers.h"
|
#include "api/rtp_headers.h"
|
||||||
@ -77,6 +78,20 @@ class AudioLevel {
|
|||||||
uint8_t audio_level);
|
uint8_t audio_level);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CsrcAudioLevel {
|
||||||
|
public:
|
||||||
|
static constexpr RTPExtensionType kId = kRtpExtensionCsrcAudioLevel;
|
||||||
|
static constexpr uint8_t kMaxValueSizeBytes = 15;
|
||||||
|
static constexpr const char kUri[] =
|
||||||
|
"urn:ietf:params:rtp-hdrext:csrc-audio-level";
|
||||||
|
|
||||||
|
static bool Parse(rtc::ArrayView<const uint8_t> data,
|
||||||
|
std::vector<uint8_t>* csrc_audio_levels);
|
||||||
|
static size_t ValueSize(rtc::ArrayView<const uint8_t> csrc_audio_levels);
|
||||||
|
static bool Write(rtc::ArrayView<uint8_t> data,
|
||||||
|
rtc::ArrayView<const uint8_t> csrc_audio_levels);
|
||||||
|
};
|
||||||
|
|
||||||
class TransmissionOffset {
|
class TransmissionOffset {
|
||||||
public:
|
public:
|
||||||
using value_type = int32_t;
|
using value_type = int32_t;
|
||||||
|
|||||||
@ -186,6 +186,7 @@ void RtpPacket::ZeroMutableExtensions() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RTPExtensionType::kRtpExtensionAudioLevel:
|
case RTPExtensionType::kRtpExtensionAudioLevel:
|
||||||
|
case RTPExtensionType::kRtpExtensionCsrcAudioLevel:
|
||||||
case RTPExtensionType::kRtpExtensionAbsoluteCaptureTime:
|
case RTPExtensionType::kRtpExtensionAbsoluteCaptureTime:
|
||||||
case RTPExtensionType::kRtpExtensionColorSpace:
|
case RTPExtensionType::kRtpExtensionColorSpace:
|
||||||
case RTPExtensionType::kRtpExtensionGenericFrameDescriptor00:
|
case RTPExtensionType::kRtpExtensionGenericFrameDescriptor00:
|
||||||
|
|||||||
@ -104,6 +104,7 @@ bool IsNonVolatile(RTPExtensionType type) {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case kRtpExtensionTransmissionTimeOffset:
|
case kRtpExtensionTransmissionTimeOffset:
|
||||||
case kRtpExtensionAudioLevel:
|
case kRtpExtensionAudioLevel:
|
||||||
|
case kRtpExtensionCsrcAudioLevel:
|
||||||
case kRtpExtensionAbsoluteSendTime:
|
case kRtpExtensionAbsoluteSendTime:
|
||||||
case kRtpExtensionTransportSequenceNumber:
|
case kRtpExtensionTransportSequenceNumber:
|
||||||
case kRtpExtensionTransportSequenceNumber02:
|
case kRtpExtensionTransportSequenceNumber02:
|
||||||
|
|||||||
@ -364,6 +364,10 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
|
|||||||
header->extension.hasTransmissionTimeOffset = true;
|
header->extension.hasTransmissionTimeOffset = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kRtpExtensionCsrcAudioLevel: {
|
||||||
|
RTC_LOG(LS_WARNING) << "Csrc audio level extension not supported";
|
||||||
|
return;
|
||||||
|
}
|
||||||
case kRtpExtensionAudioLevel: {
|
case kRtpExtensionAudioLevel: {
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
RTC_LOG(LS_WARNING) << "Incorrect audio level len: " << len;
|
RTC_LOG(LS_WARNING) << "Incorrect audio level len: " << len;
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
||||||
@ -76,6 +77,11 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
|||||||
uint8_t audio_level;
|
uint8_t audio_level;
|
||||||
packet.GetExtension<AudioLevel>(&voice_activity, &audio_level);
|
packet.GetExtension<AudioLevel>(&voice_activity, &audio_level);
|
||||||
break;
|
break;
|
||||||
|
case kRtpExtensionCsrcAudioLevel: {
|
||||||
|
std::vector<uint8_t> audio_levels;
|
||||||
|
packet.GetExtension<CsrcAudioLevel>(&audio_levels);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case kRtpExtensionAbsoluteSendTime:
|
case kRtpExtensionAbsoluteSendTime:
|
||||||
uint32_t sendtime;
|
uint32_t sendtime;
|
||||||
packet.GetExtension<AbsoluteSendTime>(&sendtime);
|
packet.GetExtension<AbsoluteSendTime>(&sendtime);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user