Skip to content

Commit

Permalink
Merge pull request jitsi#22 from jitsi/rtp-extensions
Browse files Browse the repository at this point in the history
Implements rtp extensions natively (does not use libjitsi).
  • Loading branch information
bgrozev committed Mar 20, 2019
2 parents df25513 + 490e0f3 commit 51aeba9
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 39 deletions.
4 changes: 2 additions & 2 deletions src/main/kotlin/org/jitsi/nlj/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
package org.jitsi.nlj

import org.jitsi.nlj.format.PayloadType
import org.jitsi.nlj.rtp.RtpExtension
import org.jitsi.nlj.rtp.SsrcAssociationType
import org.jitsi.service.neomedia.MediaType
import org.jitsi.service.neomedia.RTPExtension
import org.jitsi_modified.impl.neomedia.rtp.MediaStreamTrackDesc

interface Event
Expand All @@ -31,7 +31,7 @@ class RtpPayloadTypeAddedEvent(val payloadType: PayloadType) : Event {
}
class RtpPayloadTypeClearEvent : Event

class RtpExtensionAddedEvent(val extensionId: Byte, val rtpExtension: RTPExtension) : Event
class RtpExtensionAddedEvent(val rtpExtension: RtpExtension) : Event
class RtpExtensionClearEvent : Event

class ReceiveSsrcAddedEvent(val ssrc: Long) : Event
Expand Down
12 changes: 6 additions & 6 deletions src/main/kotlin/org/jitsi/nlj/Transceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.bouncycastle.crypto.tls.TlsContext
import org.jitsi.impl.neomedia.rtp.remotebitrateestimator.RemoteBitrateObserver
import org.jitsi.nlj.format.PayloadType
import org.jitsi.nlj.rtcp.RtcpEventNotifier
import org.jitsi.nlj.rtp.RtpExtension
import org.jitsi.nlj.rtp.SsrcAssociationType
import org.jitsi.nlj.srtp.SrtpUtil
import org.jitsi.nlj.srtp.TlsRole
Expand All @@ -32,7 +33,6 @@ import org.jitsi.nlj.util.cinfo
import org.jitsi.nlj.util.getLogger
import org.jitsi.rtp.rtcp.RtcpPacket
import org.jitsi.service.neomedia.MediaType
import org.jitsi.service.neomedia.RTPExtension
import org.jitsi.util.DiagnosticContext
import org.jitsi.util.Logger
import org.jitsi_modified.impl.neomedia.rtp.MediaStreamTrackDesc
Expand Down Expand Up @@ -69,7 +69,7 @@ class Transceiver(
logLevelDelegate: Logger? = null
) : Stoppable, NodeStatsProducer, RemoteBitrateObserver {
private val logger = getLogger(this.javaClass, logLevelDelegate)
private val rtpExtensions = mutableMapOf<Byte, RTPExtension>()
private val rtpExtensions = mutableMapOf<Byte, RtpExtension>()
private val payloadTypes = mutableMapOf<Byte, PayloadType>()
private val receiveSsrcs = ConcurrentHashMap.newKeySet<Long>()
val packetIOActivity = PacketIOActivity()
Expand Down Expand Up @@ -236,10 +236,10 @@ class Transceiver(
payloadTypes.clear()
}

fun addRtpExtension(extensionId: Byte, rtpExtension: RTPExtension) {
logger.cdebug { "Adding RTP extension: $extensionId -> $rtpExtension" }
rtpExtensions[extensionId] = rtpExtension
val rtpExtensionAddedEvent = RtpExtensionAddedEvent(extensionId, rtpExtension)
fun addRtpExtension(rtpExtension: RtpExtension) {
logger.cdebug { "Adding RTP extension: $rtpExtension" }
rtpExtensions[rtpExtension.id] = rtpExtension
val rtpExtensionAddedEvent = RtpExtensionAddedEvent(rtpExtension)
rtpReceiver.handleEvent(rtpExtensionAddedEvent)
rtpSender.handleEvent(rtpExtensionAddedEvent)
}
Expand Down
104 changes: 104 additions & 0 deletions src/main/kotlin/org/jitsi/nlj/rtp/RtpExtensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright @ 2019-Present 8x8, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.nlj.rtp

/**
* Represents a signalled RTP header extension.
*
* @author Boris Grozev
*/
data class RtpExtension(
/**
* The ID that was signalled.
*/
val id: Byte,
/**
* The type.
*/
val type: RtpExtensionType)

/**
* Represents an RTP header extension type.
*
* @author Boris Grozev
*/
enum class RtpExtensionType (val uri: String) {
/**
* The URN identifying the RTP extension that allows mixers to send to
* conference participants the audio levels of all contributing sources.
* Defined in RFC6465.
*/
CSRC_AUDIO_LEVEL("urn:ietf:params:rtp-hdrext:csrc-audio-level"),

/**
* The URN identifying the RTP extension that allows clients to send to
* conference mixers the audio level of their packet payload. Defined in
* RFC6464.
*/
SSRC_AUDIO_LEVEL("urn:ietf:params:rtp-hdrext:ssrc-audio-level"),

/**
* The URN identifying the abs-send-time RTP extension.
* Defined at
* {@link "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"}
*/
ABS_SEND_TIME("http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"),

/**
* The URN which identifies the framemarking RTP extension defined at
* {@link "https://tools.ietf.org/html/draft-ietf-avtext-framemarking-03"}
*/
FRAME_MARKING("http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07"),

/**
* The URN which identifies the Original Header Block RTP extension defined
* in {@link "https://tools.ietf.org/html/draft-ietf-perc-double-02"}.
*/
ORIGINAL_HEADER_BLOCK("urn:ietf:params:rtp-hdrext:ohb"),

/**
* The URN which identifies the Transport-Wide Congestion Control RTP
* extension.
*/
TRANSPORT_CC("http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"),

/**
* The URN which identifies the rtp-stream-id extensions
* in {@link "https://tools.ietf.org/html/draft-ietf-mmusic-rid-10"}.
*/
RTP_STREAM_ID("urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"),

/**
* The URN which identifies the transmission time-offset extensions
* in {@link "https://tools.ietf.org/html/rfc5450"}.
*/
TOF("urn:ietf:params:rtp-hdrext:toffset"),

/**
* The URN which identifies the RTP Header Extension for Video Content Type.
*/
VIDEO_CONTENT_TYPE("http://www.webrtc.org/experiments/rtp-hdrext/video-content-type");

companion object {
fun createFrom(value: String): RtpExtensionType? {
return try {
RtpExtensionType.valueOf(value.toUpperCase())
} catch (e: IllegalArgumentException) {
return null
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ import org.jitsi.nlj.Event
import org.jitsi.nlj.PacketInfo
import org.jitsi.nlj.RtpExtensionAddedEvent
import org.jitsi.nlj.RtpExtensionClearEvent
import org.jitsi.nlj.rtp.RtpExtensionType.SSRC_AUDIO_LEVEL
import org.jitsi.nlj.transform.node.ObserverNode
import org.jitsi.nlj.util.cdebug
import org.jitsi.nlj.util.cinfo
import org.jitsi.rtp.extensions.unsigned.toPositiveLong
import org.jitsi.rtp.rtp.RtpPacket
import org.jitsi.service.neomedia.RTPExtension
import unsigned.toUInt

/**
Expand Down Expand Up @@ -54,8 +53,8 @@ class AudioLevelReader : ObserverNode("Audio level reader") {
override fun handleEvent(event: Event) {
when (event) {
is RtpExtensionAddedEvent -> {
if (RTPExtension.SSRC_AUDIO_LEVEL_URN.equals(event.rtpExtension.uri.toString())) {
audioLevelExtId = event.extensionId.toUInt()
if (event.rtpExtension.type == SSRC_AUDIO_LEVEL) {
audioLevelExtId = event.rtpExtension.id.toUInt()
logger.cdebug { "Setting extension ID to $audioLevelExtId" }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import org.jitsi.nlj.ReceiveSsrcAddedEvent
import org.jitsi.nlj.ReceiveSsrcRemovedEvent
import org.jitsi.nlj.RtpExtensionAddedEvent
import org.jitsi.nlj.RtpExtensionClearEvent
import org.jitsi.nlj.rtp.RtpExtensionType.TRANSPORT_CC
import org.jitsi.nlj.stats.NodeStatsBlock
import org.jitsi.nlj.transform.node.ObserverNode
import org.jitsi.nlj.util.cinfo
import org.jitsi.rtp.rtcp.RtcpPacket
import org.jitsi.rtp.rtcp.rtcpfb.transport_layer_fb.tcc.RtcpFbTccPacketBuilder
import org.jitsi.rtp.rtp.RtpPacket
import org.jitsi.service.neomedia.RTPExtension
import org.jitsi.util.RTPUtils
import unsigned.toUInt

Expand Down Expand Up @@ -75,8 +75,8 @@ class TccGeneratorNode(
override fun handleEvent(event: Event) {
when (event) {
is RtpExtensionAddedEvent -> {
if (RTPExtension.TRANSPORT_CC_URN.equals(event.rtpExtension.uri.toString())) {
tccExtensionId = event.extensionId.toUInt()
if (event.rtpExtension.type == TRANSPORT_CC) {
tccExtensionId = event.rtpExtension.id.toUInt()
logger.cinfo { "TCC generator setting extension ID to $tccExtensionId" }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import org.jitsi.nlj.Event
import org.jitsi.nlj.PacketInfo
import org.jitsi.nlj.RtpExtensionAddedEvent
import org.jitsi.nlj.RtpExtensionClearEvent
import org.jitsi.nlj.rtp.RtpExtensionType.ABS_SEND_TIME
import org.jitsi.nlj.transform.node.TransformerNode
import org.jitsi.nlj.util.cdebug
import org.jitsi.rtp.rtp.header_extensions.AbsSendTimeHeaderExtension
import org.jitsi.rtp.rtp.header_extensions.HeaderExtensionType
import org.jitsi.rtp.NewRawPacket
import org.jitsi.service.neomedia.RTPExtension
import unsigned.toUInt
import java.nio.ByteBuffer

Expand All @@ -44,8 +44,8 @@ class AbsSendTime : TransformerNode("Absolute send time") {
override fun handleEvent(event: Event) {
when (event) {
is RtpExtensionAddedEvent -> {
if (RTPExtension.ABS_SEND_TIME_URN.equals(event.rtpExtension.uri.toString())) {
extensionId = event.extensionId.toUInt()
if (event.rtpExtension.type == ABS_SEND_TIME) {
extensionId = event.rtpExtension.id.toUInt()
logger.cdebug { "Setting extension ID to $extensionId" }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ import org.jitsi.nlj.Event
import org.jitsi.nlj.PacketInfo
import org.jitsi.nlj.RtpExtensionAddedEvent
import org.jitsi.nlj.RtpExtensionClearEvent
import org.jitsi.nlj.rtp.RtpExtensionType.TRANSPORT_CC
import org.jitsi.nlj.transform.node.TransformerNode
import org.jitsi.nlj.util.cinfo
import org.jitsi.nlj.util.toLegacyRawPacket
import org.jitsi.rtp.rtp.header_extensions.HeaderExtensionType
import org.jitsi.rtp.rtp.header_extensions.TccHeaderExtension
import org.jitsi.rtp.NewRawPacket
import org.jitsi.service.neomedia.RTPExtension
import org.jitsi_modified.impl.neomedia.rtp.TransportCCEngine
import unsigned.toUInt
import java.nio.ByteBuffer
Expand Down Expand Up @@ -55,8 +55,8 @@ class TccSeqNumTagger(
override fun handleEvent(event: Event) {
when (event) {
is RtpExtensionAddedEvent -> {
if (RTPExtension.TRANSPORT_CC_URN.equals(event.rtpExtension.uri.toString())) {
tccExtensionId = event.extensionId.toUInt()
if (event.rtpExtension.type == TRANSPORT_CC) {
tccExtensionId = event.rtpExtension.id.toUInt()
logger.cinfo { "TCC seq num tagger setting extension ID to $tccExtensionId" }
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/kotlin/org/jitsi/nlj/module_tests/ReceiverFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import org.jitsi.nlj.RtpReceiverImpl
import org.jitsi.nlj.SsrcAssociationEvent
import org.jitsi.nlj.format.PayloadType
import org.jitsi.nlj.rtcp.RtcpEventNotifier
import org.jitsi.nlj.rtp.RtpExtension
import org.jitsi.rtp.rtcp.RtcpPacket
import org.jitsi.test_utils.RtpExtensionInfo
import org.jitsi.test_utils.SourceAssociation
import org.jitsi.test_utils.SrtpData
import java.util.Random
Expand All @@ -38,7 +38,7 @@ class ReceiverFactory {
backgroundExecutor: ScheduledExecutorService,
srtpData: SrtpData,
payloadTypes: List<PayloadType>,
headerExtensions: List<RtpExtensionInfo>,
headerExtensions: List<RtpExtension>,
ssrcAssociations: List<SourceAssociation>,
rtcpSender: (RtcpPacket) -> Unit = {}
): RtpReceiver {
Expand All @@ -57,7 +57,7 @@ class ReceiverFactory {
receiver.handleEvent(RtpPayloadTypeAddedEvent(it))
}
headerExtensions.forEach {
receiver.handleEvent(RtpExtensionAddedEvent(it.id.toByte(), it.extension))
receiver.handleEvent(RtpExtensionAddedEvent(it))
}
ssrcAssociations.forEach {
receiver.handleEvent(SsrcAssociationEvent(it.primarySsrc, it.secondarySsrc, it.associationType))
Expand Down
6 changes: 3 additions & 3 deletions src/test/kotlin/org/jitsi/nlj/module_tests/SenderFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import org.jitsi.nlj.SetLocalSsrcEvent
import org.jitsi.nlj.SsrcAssociationEvent
import org.jitsi.nlj.format.PayloadType
import org.jitsi.nlj.rtcp.RtcpEventNotifier
import org.jitsi.nlj.rtp.RtpExtension
import org.jitsi.service.neomedia.MediaType
import org.jitsi.test_utils.RtpExtensionInfo
import org.jitsi.test_utils.SourceAssociation
import org.jitsi.test_utils.SrtpData
import java.util.Random
Expand All @@ -39,7 +39,7 @@ class SenderFactory {
backgroundExecutor: ScheduledExecutorService,
srtpData: SrtpData,
payloadTypes: List<PayloadType>,
headerExtensions: List<RtpExtensionInfo>,
headerExtensions: List<RtpExtension>,
ssrcAssociations: List<SourceAssociation>
): RtpSender {
val sender = RtpSenderImpl(
Expand All @@ -56,7 +56,7 @@ class SenderFactory {
sender.handleEvent(RtpPayloadTypeAddedEvent(it))
}
headerExtensions.forEach {
sender.handleEvent(RtpExtensionAddedEvent(it.id.toByte(), it.extension))
sender.handleEvent(RtpExtensionAddedEvent(it))
}
ssrcAssociations.forEach {
sender.handleEvent(SsrcAssociationEvent(it.primarySsrc, it.secondarySsrc, it.associationType))
Expand Down
19 changes: 7 additions & 12 deletions src/test/kotlin/org/jitsi/test_utils/Pcap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import org.jitsi.nlj.format.OpusPayloadType
import org.jitsi.nlj.format.PayloadType
import org.jitsi.nlj.format.RtxPayloadType
import org.jitsi.nlj.format.Vp8PayloadType
import org.jitsi.nlj.rtp.RtpExtension
import org.jitsi.nlj.rtp.RtpExtensionType.*
import org.jitsi.nlj.rtp.SsrcAssociationType
import org.jitsi.nlj.srtp.SrtpProfileInformation
import org.jitsi.nlj.srtp.TlsRole
import org.jitsi.rtp.util.byteBufferOf
import org.jitsi.service.neomedia.RTPExtension
import java.net.URI

data class SrtpData(
var srtpProfileInformation: SrtpProfileInformation,
Expand All @@ -39,24 +39,19 @@ data class SourceAssociation(
var associationType: SsrcAssociationType
)

data class RtpExtensionInfo(
var id: Int,
var extension: RTPExtension
)

data class PcapInformation(
var filePath: String,
var srtpData: SrtpData,
var payloadTypes: List<PayloadType>,
var headerExtensions: List<RtpExtensionInfo>,
var headerExtensions: List<RtpExtension>,
var ssrcAssociations: List<SourceAssociation>
)

val DEFAULT_HEADER_EXTENSIONS = listOf(
RtpExtensionInfo(1, RTPExtension(URI(RTPExtension.SSRC_AUDIO_LEVEL_URN))),
RtpExtensionInfo(3, RTPExtension(URI(RTPExtension.ABS_SEND_TIME_URN))),
RtpExtensionInfo(4, RTPExtension(URI(RTPExtension.RTP_STREAM_ID_URN))),
RtpExtensionInfo(5, RTPExtension(URI(RTPExtension.TRANSPORT_CC_URN)))
RtpExtension(1, SSRC_AUDIO_LEVEL),
RtpExtension(3, ABS_SEND_TIME),
RtpExtension(4, RTP_STREAM_ID),
RtpExtension(5, TRANSPORT_CC)
)

object Pcaps {
Expand Down

0 comments on commit 51aeba9

Please sign in to comment.