Skip to content

Commit

Permalink
Add support for playout-delay extension (#1412)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidNegro authored Jun 25, 2024
1 parent e88517d commit a16f047
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 2 deletions.
11 changes: 10 additions & 1 deletion node/src/RtpParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ export type RtpHeaderExtensionUri =
| 'urn:ietf:params:rtp-hdrext:toffset'
| 'http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01'
| 'http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time'
| 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time';
| 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time'
| 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay';

/**
* Defines a RTP header extension within the RTP parameters. The list of RTP
Expand Down Expand Up @@ -758,6 +759,10 @@ export function rtpHeaderExtensionUriFromFbs(
case FbsRtpHeaderExtensionUri.AbsCaptureTime: {
return 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time';
}

case FbsRtpHeaderExtensionUri.PlayoutDelay: {
return 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay';
}
}
}

Expand Down Expand Up @@ -809,6 +814,10 @@ export function rtpHeaderExtensionUriToFbs(
return FbsRtpHeaderExtensionUri.AbsCaptureTime;
}

case 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay': {
return FbsRtpHeaderExtensionUri.PlayoutDelay;
}

default: {
throw new TypeError(`invalid RtpHeaderExtensionUri: ${uri}`);
}
Expand Down
14 changes: 14 additions & 0 deletions node/src/supportedRtpCapabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,20 @@ const supportedRtpCapabilities: RtpCapabilities = {
preferredEncrypt: false,
direction: 'sendrecv',
},
{
kind: 'audio',
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
preferredId: 14,
preferredEncrypt: false,
direction: 'sendrecv',
},
{
kind: 'video',
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
preferredId: 14,
preferredEncrypt: false,
direction: 'sendrecv',
},
],
};

Expand Down
30 changes: 30 additions & 0 deletions node/src/test/test-PipeTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ test('router.pipeToRouter() succeeds with audio', async () => {
encrypt: false,
parameters: {},
},
{
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
id: 14,
encrypt: false,
parameters: {},
},
]);
expect(pipeConsumer.type).toBe('pipe');
expect(pipeConsumer.paused).toBe(false);
Expand Down Expand Up @@ -313,6 +319,12 @@ test('router.pipeToRouter() succeeds with audio', async () => {
encrypt: false,
parameters: {},
},
{
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
id: 14,
encrypt: false,
parameters: {},
},
]);
expect(pipeProducer.paused).toBe(false);
}, 2000);
Expand Down Expand Up @@ -387,6 +399,12 @@ test('router.pipeToRouter() succeeds with video', async () => {
encrypt: false,
parameters: {},
},
{
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
id: 14,
encrypt: false,
parameters: {},
},
]);

expect(pipeConsumer.type).toBe('pipe');
Expand Down Expand Up @@ -448,6 +466,12 @@ test('router.pipeToRouter() succeeds with video', async () => {
encrypt: false,
parameters: {},
},
{
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
id: 14,
encrypt: false,
parameters: {},
},
]);
expect(pipeProducer.paused).toBe(true);
}, 2000);
Expand Down Expand Up @@ -561,6 +585,12 @@ test('router.createPipeTransport() with enableRtx succeeds', async () => {
encrypt: false,
parameters: {},
},
{
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
id: 14,
encrypt: false,
parameters: {},
},
]);

expect(pipeConsumer.type).toBe('pipe');
Expand Down
14 changes: 14 additions & 0 deletions rust/src/rtp_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,10 @@ pub enum RtpHeaderExtensionUri {
/// <http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time>
#[serde(rename = "http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time")]
AbsCaptureTime,
/// <http://www.webrtc.org/experiments/rtp-hdrext/playout-delay>
#[serde(rename = "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay")]
PlayoutDelay,

#[doc(hidden)]
#[serde(other, rename = "unsupported")]
Unsupported,
Expand Down Expand Up @@ -620,6 +624,9 @@ impl RtpHeaderExtensionUri {
RtpHeaderExtensionUri::AbsCaptureTime => {
rtp_parameters::RtpHeaderExtensionUri::AbsCaptureTime
}
RtpHeaderExtensionUri::PlayoutDelay => {
rtp_parameters::RtpHeaderExtensionUri::PlayoutDelay
}
RtpHeaderExtensionUri::Unsupported => panic!("Invalid RTP extension header URI"),
}
}
Expand Down Expand Up @@ -653,6 +660,9 @@ impl RtpHeaderExtensionUri {
rtp_parameters::RtpHeaderExtensionUri::AbsCaptureTime => {
RtpHeaderExtensionUri::AbsCaptureTime
}
rtp_parameters::RtpHeaderExtensionUri::PlayoutDelay => {
RtpHeaderExtensionUri::PlayoutDelay
}
}
}
}
Expand All @@ -679,6 +689,7 @@ impl FromStr for RtpHeaderExtensionUri {
"http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time" => {
Ok(Self::AbsCaptureTime)
}
"http://www.webrtc.org/experiments/rtp-hdrext/playout-delay" => Ok(Self::PlayoutDelay),
_ => Err(RtpHeaderExtensionUriParseError::Unsupported),
}
}
Expand Down Expand Up @@ -710,6 +721,9 @@ impl RtpHeaderExtensionUri {
RtpHeaderExtensionUri::AbsCaptureTime => {
"http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time"
}
RtpHeaderExtensionUri::PlayoutDelay => {
"http://www.webrtc.org/experiments/rtp-hdrext/playout-delay"
}
RtpHeaderExtensionUri::Unsupported => "unsupported",
}
}
Expand Down
14 changes: 14 additions & 0 deletions rust/src/supported_rtp_capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,20 @@ pub fn get_supported_rtp_capabilities() -> RtpCapabilities {
preferred_encrypt: false,
direction: RtpHeaderExtensionDirection::SendRecv,
},
RtpHeaderExtension {
kind: MediaKind::Audio,
uri: RtpHeaderExtensionUri::PlayoutDelay,
preferred_id: 14,
preferred_encrypt: false,
direction: RtpHeaderExtensionDirection::SendRecv,
},
RtpHeaderExtension {
kind: MediaKind::Video,
uri: RtpHeaderExtensionUri::PlayoutDelay,
preferred_id: 14,
preferred_encrypt: false,
direction: RtpHeaderExtensionDirection::SendRecv,
},
],
}
}
27 changes: 26 additions & 1 deletion rust/tests/integration/pipe_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,11 @@ fn pipe_to_router_succeeds_with_audio() {
uri: RtpHeaderExtensionUri::AbsCaptureTime,
id: 13,
encrypt: false,
},
RtpHeaderExtensionParameters {
uri: RtpHeaderExtensionUri::PlayoutDelay,
id: 14,
encrypt: false,
}
],
);
Expand Down Expand Up @@ -395,7 +400,12 @@ fn pipe_to_router_succeeds_with_audio() {
uri: RtpHeaderExtensionUri::AbsCaptureTime,
id: 13,
encrypt: false,
}
},
RtpHeaderExtensionParameters {
uri: RtpHeaderExtensionUri::PlayoutDelay,
id: 14,
encrypt: false,
},
],
);
assert!(!pipe_producer.paused());
Expand Down Expand Up @@ -499,6 +509,11 @@ fn pipe_to_router_succeeds_with_video() {
id: 13,
encrypt: false,
},
RtpHeaderExtensionParameters {
uri: RtpHeaderExtensionUri::PlayoutDelay,
id: 14,
encrypt: false,
},
],
);
assert_eq!(pipe_consumer.r#type(), ConsumerType::Pipe);
Expand Down Expand Up @@ -556,6 +571,11 @@ fn pipe_to_router_succeeds_with_video() {
id: 13,
encrypt: false,
},
RtpHeaderExtensionParameters {
uri: RtpHeaderExtensionUri::PlayoutDelay,
id: 14,
encrypt: false,
},
],
);
assert!(pipe_producer.paused());
Expand Down Expand Up @@ -753,6 +773,11 @@ fn create_with_enable_rtx_succeeds() {
id: 13,
encrypt: false,
},
RtpHeaderExtensionParameters {
uri: RtpHeaderExtensionUri::PlayoutDelay,
id: 14,
encrypt: false,
},
],
);
assert_eq!(pipe_consumer.r#type(), ConsumerType::Pipe);
Expand Down
1 change: 1 addition & 0 deletions worker/fbs/rtpParameters.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum RtpHeaderExtensionUri: uint8 {
TransportWideCcDraft01,
AbsSendTime,
AbsCaptureTime,
PlayoutDelay,
}

table RtpHeaderExtensionParameters {
Expand Down
1 change: 1 addition & 0 deletions worker/include/RTC/RtpDictionaries.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ namespace RTC
VIDEO_ORIENTATION = 11,
TOFFSET = 12,
ABS_CAPTURE_TIME = 13,
PLAYOUT_DELAY = 14,
};

public:
Expand Down
1 change: 1 addition & 0 deletions worker/include/RTC/RtpHeaderExtensionIds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace RTC
uint8_t videoOrientation{ 0u };
uint8_t toffset{ 0u };
uint8_t absCaptureTime{ 0u };
uint8_t playoutDelay{ 0u };
};
} // namespace RTC

Expand Down
22 changes: 22 additions & 0 deletions worker/include/RTC/RtpPacket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ namespace RTC
this->videoOrientationExtensionId = id;
}

void SetPlayoutDelayExtensionId(uint8_t id)
{
this->playoutDelayExtensionId = id;
}

bool ReadMid(std::string& mid) const
{
uint8_t extenLen;
Expand Down Expand Up @@ -489,6 +494,22 @@ namespace RTC
return true;
}

bool ReadPlayoutDelay(uint16_t& minDelay, uint16_t& maxDelay) const
{
uint8_t extenLen;
uint8_t* extenValue = GetExtension(this->playoutDelayExtensionId, extenLen);

if (extenLen != 3)
{
return false;
}

uint32_t v = Utils::Byte::Get3Bytes(extenValue, 0);
minDelay = v >> 12u;
maxDelay = v & 0xFFFu;
return true;
}

bool HasExtension(uint8_t id) const
{
if (id == 0u)
Expand Down Expand Up @@ -672,6 +693,7 @@ namespace RTC
uint8_t frameMarkingExtensionId{ 0u };
uint8_t ssrcAudioLevelExtensionId{ 0u };
uint8_t videoOrientationExtensionId{ 0u };
uint8_t playoutDelayExtensionId{ 0u };
uint8_t* payload{ nullptr };
size_t payloadLength{ 0u };
uint8_t payloadPadding{ 0u };
Expand Down
5 changes: 5 additions & 0 deletions worker/src/RTC/Consumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ namespace RTC
this->rtpHeaderExtensionIds.videoOrientation = exten.id;
}

if (this->rtpHeaderExtensionIds.playoutDelay == 0u && exten.type == RTC::RtpHeaderExtensionUri::Type::PLAYOUT_DELAY)
{
this->rtpHeaderExtensionIds.playoutDelay = exten.id;
}

if (this->rtpHeaderExtensionIds.absSendTime == 0u && exten.type == RTC::RtpHeaderExtensionUri::Type::ABS_SEND_TIME)
{
this->rtpHeaderExtensionIds.absSendTime = exten.id;
Expand Down
20 changes: 20 additions & 0 deletions worker/src/RTC/Producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ namespace RTC
{
this->rtpHeaderExtensionIds.absCaptureTime = exten.id;
}

if (this->rtpHeaderExtensionIds.playoutDelay == 0u && exten.type == RTC::RtpHeaderExtensionUri::Type::PLAYOUT_DELAY)
{
this->rtpHeaderExtensionIds.playoutDelay = exten.id;
}
}

// Set the RTCP report generation interval.
Expand Down Expand Up @@ -1264,6 +1269,19 @@ namespace RTC
bufferPtr += extenLen;
}

// Proxy http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
extenValue = packet->GetExtension(this->rtpHeaderExtensionIds.playoutDelay, extenLen);

if (extenValue)
{
std::memcpy(bufferPtr, extenValue, extenLen);

extensions.emplace_back(
static_cast<uint8_t>(RTC::RtpHeaderExtensionUri::Type::PLAYOUT_DELAY), extenLen, bufferPtr);

bufferPtr += extenLen;
}

if (this->kind == RTC::Media::Kind::AUDIO)
{
// Proxy urn:ietf:params:rtp-hdrext:ssrc-audio-level.
Expand Down Expand Up @@ -1396,6 +1414,8 @@ namespace RTC
static_cast<uint8_t>(RTC::RtpHeaderExtensionUri::Type::SSRC_AUDIO_LEVEL));
packet->SetVideoOrientationExtensionId(
static_cast<uint8_t>(RTC::RtpHeaderExtensionUri::Type::VIDEO_ORIENTATION));
packet->SetPlayoutDelayExtensionId(
static_cast<uint8_t>(RTC::RtpHeaderExtensionUri::Type::PLAYOUT_DELAY));
}

return true;
Expand Down
10 changes: 10 additions & 0 deletions worker/src/RTC/RtpDictionaries/RtpHeaderExtensionUri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ namespace RTC
return RtpHeaderExtensionUri::Type::VIDEO_ORIENTATION;
}

case FBS::RtpParameters::RtpHeaderExtensionUri::PlayoutDelay:
{
return RtpHeaderExtensionUri::Type::PLAYOUT_DELAY;
}

case FBS::RtpParameters::RtpHeaderExtensionUri::TimeOffset:
{
return RtpHeaderExtensionUri::Type::TOFFSET;
Expand Down Expand Up @@ -120,6 +125,11 @@ namespace RTC
return FBS::RtpParameters::RtpHeaderExtensionUri::VideoOrientation;
}

case RtpHeaderExtensionUri::Type::PLAYOUT_DELAY:
{
return FBS::RtpParameters::RtpHeaderExtensionUri::PlayoutDelay;
}

case RtpHeaderExtensionUri::Type::TOFFSET:
{
return FBS::RtpParameters::RtpHeaderExtensionUri::TimeOffset;
Expand Down
Loading

0 comments on commit a16f047

Please sign in to comment.