-
Notifications
You must be signed in to change notification settings - Fork 27
API: FEC Parameters
This page describes in detail the FEC parameters, how to create and transmit them, and shows some coding examples.
Class net.fec.openrq.parameters.FECParameters
(abbreviated here to FECParameters
for simplicity) is a container class for the FEC parameters. It is an immutable class and only instances that contain valid parameters can be created.
To create an instance of FECParameters
you can use one of these static factory methods:
In this method you need to explicitly indicate the symbol size and the number of source blocks.
In this method the FEC parameters are derived from the provided deriver parameters, which are values typically present in communication protocols:
- The payload length denotes the minimum length of a packet payload containing one encoding symbol. It is equivalent to the symbol size parameter.
- The maximum size for a block decodable in working memory is associated to limitations on the receiver's working memory for flow control purposes, for example.
Hint: Use the first method if you need to control the number of source blocks your data is partitioned into. Use the second method if you need to upper bound the decoder working memory per source block.
It is possible to convert the parameters to a sequence of bytes in a specific format, and parse FECParameters
instances from well defined sequences of bytes. Methods are provided to write/read the sequence of bytes using a:
-
byte[]
: see conversion, write and read methods. -
ByteBuffer
: see conversion, write and read methods. -
DataOutput
: see write method; use for example instances ofDataOutputStream
. -
DataInput
: see read method; use for example instances ofDataInputStream
. -
WritableByteChannel
: see write method; use for example instances ofSocketChannel
. -
ReadableByteChannel
: see read method; use for example instances ofSocketChannel
.
Creating an instance of FECParameters
using fixed values for the payload length and maximum decoding block size
import static net.fec.openrq.parameters.ParameterChecker.maxAllowedDataLength;
import static net.fec.openrq.parameters.ParameterChecker.minDataLength;
import net.fec.openrq.parameters.FECParameters;
public class MyParameters {
// Fixed value for the payload length
private static final int PAY_LEN = 1500 - 20 - 8; // UDP-Ipv4 payload length
// Fixed value for the maximum decoding block size
private static final int MAX_DEC_MEM = 8 * 1024 * 1024; // 8 MiB
// The maximum allowed data length, given the parameters above
public static final long MAX_DATA_LEN = maxAllowedDataLength(PAY_LEN, MAX_DEC_MEM);
/**
* Returns FEC parameters given a data length.
*
* @param dataLen
* The length of the source data
* @return a new instance of <code>FECParameters</code>
* @throws IllegalArgumentException
* If the provided data length is non-positive or surpasses
* <code>MAX_DATA_LEN</code>
*/
public static FECParameters getParameters(long dataLen) {
if (dataLen < minDataLength())
throw new IllegalArgumentException("data length is too small");
if (dataLen > MAX_DATA_LEN)
throw new IllegalArgumentException("data length is too large");
return FECParameters.deriveParameters(dataLen, PAY_LEN, MAX_DEC_MEM);
}
}
In this example we use a fixed value for the payload length for simplicity and it corresponds to the maximum payload length for a IP/UDP packet that avoids IP fragmentation in most cases (1500 bytes is the MTU for Ethernet v2). We enforce a limit on the working memory that is expended at the receiver for each source block being decoded, by using a fixed value for the the maximum decoding block size.
Since FEC parameters are bounded, there is a maximum length for the source data given a payload length and maximum decoding block size. For a payload length of 1472 bytes and a maximum decoding block size of 8 388 608 bytes, the maximum allowed data length is 2 145 681 408 bytes, or 1.99 GiB.
Creating an instance of FECParameters
using a fixed value for the symbol size and a minimum value for the number of source blocks
import static net.fec.openrq.parameters.ParameterChecker.maxAllowedDataLength;
import static net.fec.openrq.parameters.ParameterChecker.minAllowedNumSourceBlocks;
import static net.fec.openrq.parameters.ParameterChecker.minDataLength;
import net.fec.openrq.parameters.FECParameters;
public class MyParameters {
// Fixed value for the symbol size
private static final int SYMB_SIZE = 1500 - 20 - 8; // UDP-Ipv4 payload length
// The maximum allowed data length, given the parameter above
public static final long MAX_DATA_LEN = maxAllowedDataLength(SYMB_SIZE);
/**
* Returns FEC parameters given a data length.
*
* @param dataLen
* The length of the source data
* @return a new instance of <code>FECParameters</code>
* @throws IllegalArgumentException
* If the provided data length is non-positive or surpasses
* <code>MAX_DATA_LEN</code>
*/
public static FECParameters getParameters(long dataLen) {
if (dataLen < minDataLength())
throw new IllegalArgumentException("data length is too small");
if (dataLen > MAX_DATA_LEN)
throw new IllegalArgumentException("data length is too large");
int numSBs = minAllowedNumSourceBlocks(dataLen, SYMB_SIZE);
return FECParameters.newParameters(dataLen, SYMB_SIZE, numSBs);
}
}
In this example we use a fixed value for the symbol size for simplicity and it corresponds to the maximum payload length for a IP/UDP packet that avoids IP fragmentation in most cases (1500 bytes is the MTU for Ethernet v2). We also make sure that the least possible number of source blocks is used, in order to maximize the number of source symbols in each block, which maximizes the efficiency of the RaptorQ code.
Since FEC parameters are bounded, there is a maximum length for the source data given a symbol size. For a symbol size of 1472 bytes, the maximum allowed data length is 21 658 752 000 bytes, or 19.79 GiB.