Skip to content

API: FEC Parameters

Ricardo Fonseca edited this page Nov 18, 2017 · 20 revisions

This page describes in detail the FEC parameters, how to create and transmit them, and shows some coding examples.


Main Classes

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.

Creating FEC Parameters

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.

Transmitting FEC Parameters

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:

Coding examples

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.