chiaki/lib/src/fec.c
2020-12-27 16:46:09 +01:00

75 lines
1.6 KiB
C

// SPDX-License-Identifier: LicenseRef-AGPL-3.0-only-OpenSSL
#include <chiaki/fec.h>
#include <jerasure.h>
#include <cauchy.h>
#include <string.h>
#include <stdlib.h>
int *create_matrix(unsigned int k, unsigned int m)
{
return cauchy_original_coding_matrix(k, m, CHIAKI_FEC_WORDSIZE);
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_fec_decode(uint8_t *frame_buf, size_t unit_size, size_t stride, unsigned int k, unsigned int m, const unsigned int *erasures, size_t erasures_count)
{
if(stride < unit_size)
return CHIAKI_ERR_INVALID_DATA;
int *matrix = create_matrix(k, m);
if(!matrix)
return CHIAKI_ERR_MEMORY;
ChiakiErrorCode err = CHIAKI_ERR_SUCCESS;
int *jerasures = calloc(erasures_count + 1, sizeof(int));
if(!jerasures)
{
err = CHIAKI_ERR_MEMORY;
goto error_matrix;
}
memcpy(jerasures, erasures, erasures_count * sizeof(int));
jerasures[erasures_count] = -1;
uint8_t **data_ptrs = calloc(k, sizeof(uint8_t *));
if(!data_ptrs)
{
err = CHIAKI_ERR_MEMORY;
goto error_jerasures;
}
uint8_t **coding_ptrs = calloc(m, sizeof(uint8_t *));
if(!coding_ptrs)
{
err = CHIAKI_ERR_MEMORY;
goto error_data_ptrs;
}
for(size_t i=0; i<k+m; i++)
{
uint8_t *buf_ptr = frame_buf + stride * i;
if(i < k)
data_ptrs[i] = buf_ptr;
else
coding_ptrs[i - k] = buf_ptr;
}
int res = jerasure_matrix_decode(k, m, CHIAKI_FEC_WORDSIZE, matrix, 0, jerasures,
(char **)data_ptrs, (char **)coding_ptrs, unit_size);
if(res < 0)
err = CHIAKI_ERR_FEC_FAILED;
else
err = CHIAKI_ERR_SUCCESS;
free(coding_ptrs);
error_data_ptrs:
free(data_ptrs);
error_jerasures:
free(jerasures);
error_matrix:
free(matrix);
return err;
}