roc-toolkit
roc-toolkit copied to clipboard
Switch to another reed-solomon FEC code implementation
Last revised: Oct 2023
Problem
Currently we have two FEC schemes: Reed-Solomon (the default and most used one) and LDPC-Staircase. The network part is implemented by our code, and the codec part is implemented in OpenFEC library.
OpenFEC is a great library, but there are several issues with it:
-
It's not actively maintained. We currently use our fork which fixes numerous bugs and portability issues. There is little chance that those patches will be ever upstreamed. At the same time, OpenFEC internals are far from simple, and currently we have no one who would fully understand them, so maintaining a fork is not a good option.
-
Its license is quite restrictive (a LGPL-like license). This means that Roc built with OpenFEC support likely won't be used in some commercial software, despite that the Roc itself is distributed under a more permissive license.
-
There are some minor technical issues, not resolved in our fork yet. For example, despite we configure OpenFEC to use our custom allocator, there are cases when it bypasses it and use malloc() instead. It's quite hard to fix this.
Solution
Switch to another implementation of Reed-Solomon scheme and keep OpenFEC only for LDPC-Staircase.
Requirements:
-
It should be either a well-maintained external library (preferably), or maybe a small and rather clean implementation which we can include into our repo.
-
The implementation should be portable. It should work on a variety of platforms and compilers, including old ones. Preferably it should be C (not C++).
-
The implementation should work on symbol level, i.e. it should not force any network packet format, only decode and encode payload. On the other hand, it should be compatible with FECFRAME reed-solomon code.
-
Preferably, the implementation should allow to use our own allocator.
-
The license should not be very strict: some permissive license like MIT/BSD/Apache or MPL would be OK.
Implementation
If it will be an external library, a new target (say, target_somelib) and dependency should be added to SConstruct and build-3rdparty.py. Instructions for adding a new dependency can be found in #573
Then we should add target_somelib directory to roc_fec and add fec::RsEncoder and fec::RsDecoder classes (implementation of fec::IBlockEncoder and fec::IBlockDecoder interfaces), similar to fec::OpenfecEncoder and fec::OpenfecDecoder (OpenFEC codecs).
We should also register RsEncoder and RsDecoder in fec::CodecMap. If the new library is enabled during build, CodecMap should use it instead of OpenFEC for Reed-Solomon. Otherwise it should fallback to OpenFEC (if it's enabled).
Most likely, no other changes are needed.
Testing
We should ensure that the new implementation will be fully compatible with the OpenFEC one, on the binary/packet level. This is important because OpenFEC is known to conform the FECFRAME spec; i.e. the sender built with the new implementation can work with the receiver using OpenFEC, and vice versa.
Info
Our docs: https://roc-streaming.org/toolkit/docs/internals/fec.html
RFCs: