Skip to content

Instantly share code, notes, and snippets.

@gavv
Created June 10, 2019 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gavv/9f10eb6500f7d2bc570acead11218cbc to your computer and use it in GitHub Desktop.
Save gavv/9f10eb6500f7d2bc570acead11218cbc to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <of_openfec_api.h>
#define CHECK(expr) if (!(expr)) { fprintf(stderr, "CHECK failed: %s\n", #expr); exit(1); }
// these parameters allows us to repair *all* source packets
#define N_SOURCE 10
#define N_REPAIR 20
static char **encode_block(size_t payload_size) {
of_session_t *of_inst = NULL;
struct of_ldpc_parameters params = {};
CHECK(OF_STATUS_OK == of_create_codec_instance(&of_inst,
OF_CODEC_LDPC_STAIRCASE_STABLE,
OF_ENCODER, 0));
params.nb_source_symbols = N_SOURCE;
params.nb_repair_symbols = N_REPAIR;
params.encoding_symbol_length = payload_size;
params.prng_seed = 1297501556;
params.N1 = 7;
CHECK(OF_STATUS_OK ==
of_set_fec_parameters(of_inst, (of_parameters_t *)&params));
char **encoded_block = calloc(N_SOURCE + N_REPAIR, sizeof(void *));
unsigned i;
// allocate source and repair packets
for (i = 0; i < N_SOURCE + N_REPAIR; i++) {
encoded_block[i] = calloc(payload_size, 1);
}
// fill source packets
for (i = 0; i < N_SOURCE; i++) {
memset(encoded_block[i], 0xcc, payload_size);
}
// build repair packets
for (i = N_SOURCE; i < N_SOURCE + N_REPAIR; i++) {
CHECK(OF_STATUS_OK ==
of_build_repair_symbol(of_inst, (void **)encoded_block, i));
}
of_release_codec_instance(of_inst);
return encoded_block;
}
static void full_repair(char **encoded_block, size_t payload_size) {
of_session_t *of_inst = NULL;
struct of_ldpc_parameters params = {};
CHECK(OF_STATUS_OK == of_create_codec_instance(&of_inst,
OF_CODEC_LDPC_STAIRCASE_STABLE,
OF_DECODER, 0));
params.nb_source_symbols = N_SOURCE;
params.nb_repair_symbols = N_REPAIR;
params.encoding_symbol_length = payload_size;
params.prng_seed = 1297501556;
params.N1 = 7;
CHECK(OF_STATUS_OK ==
of_set_fec_parameters(of_inst, (of_parameters_t *)&params));
// pass repair packets to the decoder
unsigned i;
for (i = N_SOURCE; i < N_SOURCE + N_REPAIR; i++) {
CHECK(OF_STATUS_OK == of_decode_with_new_symbol(of_inst, encoded_block[i], i));
}
CHECK(OF_STATUS_OK == of_finish_decoding(of_inst));
// try to repair all source packets
char **decoded_block = calloc(N_SOURCE + N_REPAIR, sizeof(void *));
of_get_source_symbols_tab(of_inst, (void **)decoded_block);
for (i = 0; i < N_SOURCE; i++) {
CHECK(decoded_block[i] != NULL);
CHECK(memcmp(encoded_block[i], decoded_block[i], payload_size) == 0);
}
of_release_codec_instance(of_inst);
// free decoded packets
for (i = 0; i < N_SOURCE; i++) {
free(decoded_block[i]);
}
free(decoded_block);
}
static void release(char **encoded_block) {
unsigned i;
for (i = 0; i < N_SOURCE + N_REPAIR; i++) {
free(encoded_block[i]);
}
free(encoded_block);
}
int main(int argc, char **argv) {
CHECK(argc == 2);
size_t payload_size = atoi(argv[1]);
char **encoded_block = encode_block(payload_size);
CHECK(encoded_block);
printf("encoding done\n");
full_repair(encoded_block, payload_size);
printf("decoding done\n");
release(encoded_block);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment