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[] =
|
||||
"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
|
||||
// header extensions, per RFC8285 Section 4.2-4.3.
|
||||
static constexpr int kMinId = 1;
|
||||
|
||||
@ -57,6 +57,7 @@ enum RTPExtensionType : int {
|
||||
kRtpExtensionNone,
|
||||
kRtpExtensionTransmissionTimeOffset,
|
||||
kRtpExtensionAudioLevel,
|
||||
kRtpExtensionCsrcAudioLevel,
|
||||
kRtpExtensionInbandComfortNoise,
|
||||
kRtpExtensionAbsoluteSendTime,
|
||||
kRtpExtensionAbsoluteCaptureTime,
|
||||
|
||||
@ -34,6 +34,7 @@ constexpr ExtensionInfo CreateExtensionInfo() {
|
||||
constexpr ExtensionInfo kExtensions[] = {
|
||||
CreateExtensionInfo<TransmissionOffset>(),
|
||||
CreateExtensionInfo<AudioLevel>(),
|
||||
CreateExtensionInfo<CsrcAudioLevel>(),
|
||||
CreateExtensionInfo<AbsoluteSendTime>(),
|
||||
CreateExtensionInfo<AbsoluteCaptureTimeExtension>(),
|
||||
CreateExtensionInfo<VideoOrientation>(),
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#include "modules/rtp_rtcp/include/rtp_cvo.h"
|
||||
@ -186,6 +187,60 @@ bool AudioLevel::Write(rtc::ArrayView<uint8_t> data,
|
||||
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.
|
||||
//
|
||||
// The transmission time is signaled to the receiver in-band using the
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "api/rtp_headers.h"
|
||||
@ -77,6 +78,20 @@ class AudioLevel {
|
||||
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 {
|
||||
public:
|
||||
using value_type = int32_t;
|
||||
|
||||
@ -186,6 +186,7 @@ void RtpPacket::ZeroMutableExtensions() {
|
||||
break;
|
||||
}
|
||||
case RTPExtensionType::kRtpExtensionAudioLevel:
|
||||
case RTPExtensionType::kRtpExtensionCsrcAudioLevel:
|
||||
case RTPExtensionType::kRtpExtensionAbsoluteCaptureTime:
|
||||
case RTPExtensionType::kRtpExtensionColorSpace:
|
||||
case RTPExtensionType::kRtpExtensionGenericFrameDescriptor00:
|
||||
|
||||
@ -104,6 +104,7 @@ bool IsNonVolatile(RTPExtensionType type) {
|
||||
switch (type) {
|
||||
case kRtpExtensionTransmissionTimeOffset:
|
||||
case kRtpExtensionAudioLevel:
|
||||
case kRtpExtensionCsrcAudioLevel:
|
||||
case kRtpExtensionAbsoluteSendTime:
|
||||
case kRtpExtensionTransportSequenceNumber:
|
||||
case kRtpExtensionTransportSequenceNumber02:
|
||||
|
||||
@ -364,6 +364,10 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
|
||||
header->extension.hasTransmissionTimeOffset = true;
|
||||
break;
|
||||
}
|
||||
case kRtpExtensionCsrcAudioLevel: {
|
||||
RTC_LOG(LS_WARNING) << "Csrc audio level extension not supported";
|
||||
return;
|
||||
}
|
||||
case kRtpExtensionAudioLevel: {
|
||||
if (len != 0) {
|
||||
RTC_LOG(LS_WARNING) << "Incorrect audio level len: " << len;
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.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;
|
||||
packet.GetExtension<AudioLevel>(&voice_activity, &audio_level);
|
||||
break;
|
||||
case kRtpExtensionCsrcAudioLevel: {
|
||||
std::vector<uint8_t> audio_levels;
|
||||
packet.GetExtension<CsrcAudioLevel>(&audio_levels);
|
||||
break;
|
||||
}
|
||||
case kRtpExtensionAbsoluteSendTime:
|
||||
uint32_t sendtime;
|
||||
packet.GetExtension<AbsoluteSendTime>(&sendtime);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user