Skip to content

API: Encoding data

RicardoFonseca edited this page Jun 5, 2014 · 4 revisions

This page describes in detail how to create and use encoders for source data and source blocks.


Main Classes

Class net.fec.openrq.encoder.SourceBlockEncoder (abbreviated here to SourceBlockEncoder for simplicity) provides the interface for encoding individual source blocks.

Class net.fec.openrq.encoder.DataEncoder (abbreviated here to DataEncoder for simplicity) provides the interface for accessing SourceBlockEncoder instances.

Class net.fec.openrq.OpenRQ (abbreviated here to OpenRQ for simplicity) provides static factory methods for creating DataEncoder instances.

Creating data encoders

You can create an instance of DataEncoder from a:

Accessing source block encoders

You can access SourceBlockEncoder instances from a DataEncoder object dataEnc by:

Coding examples

Creating an instance of DataEncoder using an array of bytes
import net.fec.openrq.ArrayDataEncoder;
import net.fec.openrq.OpenRQ;
import net.fec.openrq.parameters.FECParameters;


public class MyEncoders {

    /**
     * Returns an encoder for data inside an array of bytes.
     * 
     * @param data
     *            An array of bytes
     * @param fecParams
     *            FEC parameters associated to the encoded data
     * @return an instance of <code>ArrayDataEncoder</code>
     */
    public static ArrayDataEncoder getEncoder(byte[] data, FECParameters fecParams) {

        return OpenRQ.newEncoder(data, fecParams);
    }

    /**
     * Returns an encoder for data inside an array of bytes.
     * 
     * @param data
     *            An array of bytes
     * @param off
     *            The starting index of the data
     * @param fecParams
     *            FEC parameters associated to the encoded data
     * @return an instance of <code>ArrayDataEncoder</code>
     */
    public static ArrayDataEncoder getEncoder(byte[] data, int off, FECParameters fecParams) {

        return OpenRQ.newEncoder(data, off, fecParams);
    }
}

In this example we provide two methods for creating instances of ArrayDataEncoder, which is a subclass of DataEncoder that encodes data from an array of bytes. Calling the first method is equivalent to calling the second method with a zero offset.

Note that an array of bytes cannot have more than Integer.MAX_VALUE (2 147 483 647) bytes, so the data length in the FEC parameters must not exceed this value.


Accessing source blocks
import net.fec.openrq.encoder.DataEncoder;
import net.fec.openrq.encoder.SourceBlockEncoder;


public class MyEncoders {

    /**
     * Encodes all source blocks from a data encoder, sequentially.
     * 
     * @param dataEnc
     *            A data encoder
     */
    public static void encodeData(DataEncoder dataEnc) {

        for (SourceBlockEncoder sbEnc : dataEnc.sourceBlockIterable()) {
            encodeSourceBlock(sbEnc);
        }
    }

    /**
     * Encodes a specific source block from a data encoder.
     * 
     * @param dataEnc
     *            A data encoder
     * @param sbn
     *            A "source block number": the identifier of the source block to be encoded
     */
    public static void encodeBlock(DataEncoder dataEnc, int sbn) {

        SourceBlockEncoder sbEnc = dataEnc.sourceBlock(sbn);
        encodeSourceBlock(sbEnc);
    }

    private static void encodeSourceBlock(SourceBlockEncoder sbEnc) {

        // encode the source block
    }
}

In this example we provide two methods for accessing the source blocks for encoding. The first method traverses all source blocks sequentially, while the second accesses a specific block. Since all source blocks are independent of each other, the encoding may be done in parallel, e.g by accessing each source block in a separate thread.


Encoding source blocks
import net.fec.openrq.EncodingPacket;
import net.fec.openrq.encoder.SourceBlockEncoder;


public class MyEncoders {

    private static void encodeSourceBlock(SourceBlockEncoder sbEnc) {

        // send all source symbols
        for (EncodingPacket pac : sbEnc.sourcePacketsIterable()) {
            sendPacket(pac);
        }

        // number of repair symbols
        int nr = numberOfRepairSymbols();

        // send nr repair symbols
        for (EncodingPacket pac : sbEnc.repairPacketsIterable(nr)) {
            sendPacket(pac);
        }
    }

    private static int numberOfRepairSymbols() {

        // return a number of repair symbols to encode
        // (e.g. the number may depend on a channel loss rate)
    }

    private static void sendPacket(EncodingPacket pac) {

        // send the packet to the receiver
    }
}