Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
L
libjitsi
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ZRTP
libjitsi
Commits
846ae416
You need to sign in or sign up before continuing.
Commit
846ae416
authored
10 years ago
by
Boris Grozev
Browse files
Options
Downloads
Patches
Plain Diff
Adds a RED (RFC2198) transform engine.
parent
0c97661a
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/org/jitsi/impl/neomedia/transform/REDTransformEngine.java
+276
-0
276 additions, 0 deletions
...org/jitsi/impl/neomedia/transform/REDTransformEngine.java
with
276 additions
and
0 deletions
src/org/jitsi/impl/neomedia/transform/REDTransformEngine.java
0 → 100644
+
276
−
0
View file @
846ae416
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package
org.jitsi.impl.neomedia.transform
;
import
org.jitsi.impl.neomedia.*
;
import
org.jitsi.util.*
;
import
java.util.HashSet
;
import
java.util.Set
;
/**
* Implements a {@link org.jitsi.impl.neomedia.transform.PacketTransformer} and
* {@link org.jitsi.impl.neomedia.transform.TransformEngine} for RED (RFC2198).
*
* @author Boris Grozev
*/
public
class
REDTransformEngine
implements
TransformEngine
,
PacketTransformer
{
/**
* The <tt>Logger</tt> used by the <tt>REDTransformEngine</tt> class and
* its instances to print debug information.
*/
private
static
final
Logger
logger
=
Logger
.
getLogger
(
REDTransformEngine
.
class
);
/**
* The RED payload type for incoming packets. Only RTP packets with this
* payload type will be reverse-transformed by this <tt>PacketTransformer</tt>.
*
* The special value "-1" is used to effectively disable reverse-transforming
* packets by this <tt>PacketTransformer</tt>.
*/
private
byte
incomingPT
;
/**
* The payload type to set when constructing RED packets (e.g. for outgoing)
* packets.
*
* The special value "-1" is used to effectively disable transforming
* packets by this <tt>PacketTransformer</tt>.
*/
private
byte
outgoingPT
;
/**
* Initializes a new <tt>REDTransformEngine</tt> instance.
*
* @param incomingPT the RED payload type number for incoming packets.
* @param outgoingPT the RED payload type number for outgoing packets.
*/
public
REDTransformEngine
(
byte
incomingPT
,
byte
outgoingPT
)
{
setIncomingPT
(
incomingPT
);
setOutgoingPT
(
outgoingPT
);
}
/**
* Initializes a new <tt>REDTransformEngine</tt> instance.
*/
public
REDTransformEngine
()
{
this
((
byte
)-
1
,
(
byte
)-
1
);
}
/**
* Sets the RED payload type for incoming red packets.
* @param incomingPT the payload type to set.
*/
public
void
setIncomingPT
(
byte
incomingPT
)
{
this
.
incomingPT
=
incomingPT
;
if
(
logger
.
isInfoEnabled
())
logger
.
info
(
"Set incoming payload type "
+
incomingPT
);
}
/**
* Sets the RED payload type for outgoing red packets.
* @param outgoingPT the payload type to set.
*/
public
void
setOutgoingPT
(
byte
outgoingPT
)
{
this
.
outgoingPT
=
outgoingPT
;
if
(
logger
.
isInfoEnabled
())
logger
.
info
(
"Set outgoing payload type "
+
outgoingPT
);
}
/**
* {@inheritDoc}
*/
@Override
public
void
close
()
{
}
/**
* {@inheritDoc}
*
* Reverse-transform a RED (RFC2198) packet.
*/
@Override
public
RawPacket
[]
reverseTransform
(
RawPacket
[]
pkts
)
{
if
(
incomingPT
==
-
1
)
return
pkts
;
// XXX: in the general case we should transform each packet in pkts and
// then merge all the results somehow. However, for performance(*) and
// simplicity, we assume that there is at most a single packet in pkts,
// and the rest is null. This is a valid assumption with the currently
// available PacketTransformers in libjitsi.
//
// (*) in the majority of packets there will be a single packet as a
// result, and thus we get to reuse both pkts[0] and pkts itself.
if
(
pkts
!=
null
&&
pkts
.
length
>
0
)
{
if
(
pkts
[
0
]
!=
null
&&
pkts
[
0
].
getPayloadType
()
==
incomingPT
)
return
reverseTransformSingle
(
pkts
[
0
],
pkts
);
}
return
pkts
;
}
/**
* {@inheritDoc}
*
* Encapsulates the packets in <tt>pkts</tt> with RED (RFC2198).
*
* Effectively inserts the following 1-byte RED header right after the
* RTP header (where "Block PT" is the payload type of the original packet)
* and changes the payload type of the packet to <tt>outgoingPT</tt>
*
* 0 1 2 3 4 5 6 7
* +-+-+-+-+-+-+-+-+
* |0| Block PT |
* +-+-+-+-+-+-+-+-+
*/
@Override
public
RawPacket
[]
transform
(
RawPacket
[]
pkts
)
{
if
(
outgoingPT
==
-
1
)
return
pkts
;
for
(
RawPacket
pkt
:
pkts
)
{
// we don't touch packets with PT=0, because they might be ZRTP
// packets. Do we need any other filters -- PT, SSRC?
if
(
pkt
!=
null
&&
pkt
.
getPayloadType
()
!=
0
)
{
byte
[]
buf
=
pkt
.
getBuffer
();
int
len
=
pkt
.
getLength
();
int
off
=
pkt
.
getOffset
();
int
hdrLen
=
pkt
.
getHeaderLength
();
byte
[]
newBuf
=
buf
;
//try to reuse
if
(
newBuf
.
length
<
len
+
1
)
{
newBuf
=
new
byte
[
len
+
1
];
}
System
.
arraycopy
(
buf
,
off
,
newBuf
,
0
,
hdrLen
);
System
.
arraycopy
(
buf
,
off
+
hdrLen
,
newBuf
,
hdrLen
+
1
,
len
-
hdrLen
);
newBuf
[
hdrLen
]
=
pkt
.
getPayloadType
();
pkt
.
setBuffer
(
newBuf
);
pkt
.
setOffset
(
0
);
pkt
.
setLength
(
len
+
1
);
pkt
.
setPayloadType
(
outgoingPT
);
}
}
return
pkts
;
}
/**
* Transforms the RFC2198 packet <tt>pkt</tt> into an array of RTP packets.
*/
private
RawPacket
[]
reverseTransformSingle
(
RawPacket
pkt
,
RawPacket
[]
pkts
)
{
byte
[]
buf
=
pkt
.
getBuffer
();
int
off
=
pkt
.
getOffset
();
int
hdrLen
=
pkt
.
getHeaderLength
();
int
idx
=
off
+
hdrLen
;
//beginning of RTP payload
int
pktCount
=
1
;
//number of packets inside RED
// 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
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//|F| block PT | timestamp offset | block length |
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
while
(
(
buf
[
idx
]
&
0x80
)
!=
0
)
{
pktCount
++;
idx
+=
4
;
}
idx
=
off
+
hdrLen
;
//back to beginning of RTP payload
if
(
pkts
.
length
<
pktCount
)
pkts
=
new
RawPacket
[
pktCount
];
if
(
pktCount
!=
1
&&
logger
.
isInfoEnabled
())
logger
.
info
(
"Received a RED packet with more than one packet inside"
);
int
payloadOffset
=
idx
+
(
pktCount
-
1
)*
4
+
1
/* RED headers */
;
//write non-primary packets, keep pkts[0] for the primary
for
(
int
i
=
1
;
i
<
pktCount
;
i
++)
{
int
blockLen
=
(
buf
[
idx
+
2
]
&
0x03
)
<<
8
|
(
buf
[
idx
+
3
]);
// XXX: we might need to optimize
byte
[]
newBuf
=
new
byte
[
hdrLen
+
blockLen
];
System
.
arraycopy
(
buf
,
payloadOffset
,
newBuf
,
0
,
hdrLen
+
blockLen
);
// XXX: we might need to optimize
if
(
pkts
[
i
]
==
null
)
pkts
[
i
]
=
new
RawPacket
();
pkts
[
i
].
setBuffer
(
newBuf
);
pkts
[
i
].
setOffset
(
0
);
pkts
[
i
].
setLength
(
hdrLen
+
blockLen
);
pkts
[
i
].
setPayloadType
((
byte
)
(
buf
[
idx
]
&
0xf7
));
//TODO: update timestamp
idx
+=
4
;
// next RED header
payloadOffset
+=
blockLen
;
}
//idx is now at the "primary encoding block header":
// 0 1 2 3 4 5 6 7
//+-+-+-+-+-+-+-+-+
//|0| Block PT |
//+-+-+-+-+-+-+-+-+
//write primary packet: reuse pkt
pkt
.
setPayloadType
((
byte
)
(
buf
[
idx
]
&
0x7f
));
// reuse the buffer, move the header "right"
System
.
arraycopy
(
buf
,
off
,
buf
,
off
+
payloadOffset
-
hdrLen
,
hdrLen
);
pkt
.
setOffset
(
off
+
payloadOffset
-
hdrLen
);
pkt
.
setLength
(
pkt
.
getLength
()
-
(
payloadOffset
-
hdrLen
));
pkts
[
0
]
=
pkt
;
return
pkts
;
}
/**
* {@inheritDoc}
*
* Return the single <tt>PacketTransformer</tt> for this
* <tt>TransformEngine</tt>
*/
@Override
public
PacketTransformer
getRTPTransformer
()
{
return
this
;
}
/**
* {@inheritDoc}
*
* We don't touch RTCP
*/
@Override
public
PacketTransformer
getRTCPTransformer
()
{
return
null
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment