diff --git a/include/rtc/rtc.h b/include/rtc/rtc.h index e37ccec86..1476b6a9a 100644 --- a/include/rtc/rtc.h +++ b/include/rtc/rtc.h @@ -341,6 +341,9 @@ typedef struct { // AV1 only rtcObuPacketization obuPacketization; // OBU paketization for AV1 samples + uint8_t playoutDelayId; + uint16_t playoutDelayMin; + uint16_t playoutDelayMax; } rtcPacketizerInit; // Deprecated, do not use diff --git a/include/rtc/rtppacketizationconfig.hpp b/include/rtc/rtppacketizationconfig.hpp index 0e6dcada2..ace13063e 100644 --- a/include/rtc/rtppacketizationconfig.hpp +++ b/include/rtc/rtppacketizationconfig.hpp @@ -61,6 +61,14 @@ class RTC_CPP_EXPORT RtpPacketizationConfig { uint8_t ridId = 0; optional rid; + // the negotiated ID of the playout delay header extension + // https://webrtc.googlesource.com/src/+/main/docs/native-code/rtp-hdrext/playout-delay/README.md + uint8_t playoutDelayId; + + // Minimum/maxiumum playout delay, in 10ms intervals. A value of 10 would equal a 100ms delay + uint16_t playoutDelayMin; + uint16_t playoutDelayMax; + /// Construct RTP configuration used in packetization process /// @param ssrc SSRC of source /// @param cname CNAME of source diff --git a/src/capi.cpp b/src/capi.cpp index b6942214a..6f8c790d2 100644 --- a/src/capi.cpp +++ b/src/capi.cpp @@ -275,6 +275,9 @@ createRtpPacketizationConfig(const rtcPacketizationHandlerInit *init) { init->payloadType, init->clockRate); config->sequenceNumber = init->sequenceNumber; config->timestamp = init->timestamp; + config->playoutDelayId = init->playoutDelayId; + config->playoutDelayMin = init->playoutDelayMin; + config->playoutDelayMax = init->playoutDelayMax; return config; } diff --git a/src/rtppacketizer.cpp b/src/rtppacketizer.cpp index ba7048ac5..9cb7332ae 100644 --- a/src/rtppacketizer.cpp +++ b/src/rtppacketizer.cpp @@ -31,6 +31,11 @@ message_ptr RtpPacketizer::packetize(shared_ptr payload, bool mark) { if (setVideoRotation) rtpExtHeaderSize += 2; + const bool setPlayoutDelay = (rtpConfig->playoutDelayId > 0 && rtpConfig->playoutDelayId < 15); + + if (setPlayoutDelay) + rtpExtHeaderSize += 4; + if (rtpConfig->mid.has_value()) rtpExtHeaderSize += (1 + rtpConfig->mid->length()); @@ -85,6 +90,21 @@ message_ptr RtpPacketizer::packetize(shared_ptr payload, bool mark) { reinterpret_cast(rtpConfig->rid->c_str()), rtpConfig->rid->length()); } + + if (setPlayoutDelay) { + uint16_t min = rtpConfig->playoutDelayMin & 0xFFF; + uint16_t max = rtpConfig->playoutDelayMax & 0xFFF; + + // 12 bits for min + 12 bits for max + byte data[] = { + byte((min >> 4) & 0xFF), + byte(((min & 0xF) << 4) | ((max >> 8) & 0xF)), + byte(max & 0xFF) + }; + + extHeader->writeOneByteHeader(offset, rtpConfig->playoutDelayId, data, 3); + offset += 4; + } } rtp->preparePacket();