Align FEC Units by 16

This commit is contained in:
Florian Märkl 2020-10-22 23:14:54 +02:00
commit 9200c0b893
5 changed files with 31 additions and 20 deletions

View file

@ -31,7 +31,7 @@ extern "C" {
#define CHIAKI_FEC_WORDSIZE 8
CHIAKI_EXPORT ChiakiErrorCode chiaki_fec_decode(uint8_t *frame_buf, size_t unit_size, unsigned int k, unsigned int m, const unsigned int *erasures, size_t erasures_count);
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);
#ifdef __cplusplus
}

View file

@ -37,6 +37,7 @@ typedef struct chiaki_frame_processor_t
uint8_t *frame_buf;
size_t frame_buf_size;
size_t buf_size_per_unit;
size_t buf_stride_per_unit;
unsigned int units_source_expected;
unsigned int units_fec_expected;
unsigned int units_source_received;

View file

@ -28,8 +28,10 @@ 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, unsigned int k, unsigned int m, const unsigned int *erasures, size_t erasures_count)
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;
@ -61,7 +63,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_fec_decode(uint8_t *frame_buf, size_t unit_
for(size_t i=0; i<k+m; i++)
{
uint8_t *buf_ptr = frame_buf + unit_size * i;
uint8_t *buf_ptr = frame_buf + stride * i;
if(i < k)
data_ptrs[i] = buf_ptr;
else
@ -84,4 +86,4 @@ error_jerasures:
error_matrix:
free(matrix);
return err;
}
}

View file

@ -42,6 +42,8 @@ CHIAKI_EXPORT void chiaki_frame_processor_init(ChiakiFrameProcessor *frame_proce
frame_processor->log = log;
frame_processor->frame_buf = NULL;
frame_processor->frame_buf_size = 0;
frame_processor->buf_size_per_unit = 0;
frame_processor->buf_stride_per_unit = 0;
frame_processor->units_source_expected = 0;
frame_processor->units_fec_expected = 0;
frame_processor->unit_slots = NULL;
@ -77,6 +79,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_frame_processor_alloc_frame(ChiakiFrameProc
}
frame_processor->buf_size_per_unit += ntohs(((chiaki_unaligned_uint16_t *)packet->data)[0]);
}
frame_processor->buf_stride_per_unit = ((frame_processor->buf_size_per_unit + 0xf) / 0x10) * 0x10;
if(frame_processor->buf_size_per_unit == 0)
{
@ -116,9 +119,9 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_frame_processor_alloc_frame(ChiakiFrameProc
}
memset(frame_processor->unit_slots, 0, frame_processor->unit_slots_size * sizeof(ChiakiFrameUnit));
if(frame_processor->unit_slots_size > SIZE_MAX / frame_processor->buf_size_per_unit)
if(frame_processor->unit_slots_size > SIZE_MAX / frame_processor->buf_stride_per_unit)
return CHIAKI_ERR_OVERFLOW;
size_t frame_buf_size_required = frame_processor->unit_slots_size * frame_processor->buf_size_per_unit;
size_t frame_buf_size_required = frame_processor->unit_slots_size * frame_processor->buf_stride_per_unit;
if(frame_processor->frame_buf_size < frame_buf_size_required)
{
free(frame_processor->frame_buf);
@ -163,7 +166,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_frame_processor_put_unit(ChiakiFrameProcess
}
unit->data_size = packet->data_size;
memcpy(frame_processor->frame_buf + packet->unit_index * frame_processor->buf_size_per_unit,
memcpy(frame_processor->frame_buf + packet->unit_index * frame_processor->buf_stride_per_unit,
packet->data,
packet->data_size);
@ -206,7 +209,8 @@ static ChiakiErrorCode chiaki_frame_processor_fec(ChiakiFrameProcessor *frame_pr
}
assert(erasure_index == erasures_count);
ChiakiErrorCode err = chiaki_fec_decode(frame_processor->frame_buf, frame_processor->buf_size_per_unit,
ChiakiErrorCode err = chiaki_fec_decode(frame_processor->frame_buf,
frame_processor->buf_size_per_unit, frame_processor->buf_stride_per_unit,
frame_processor->units_source_expected, frame_processor->units_fec_received,
erasures, erasures_count);
@ -224,7 +228,7 @@ static ChiakiErrorCode chiaki_frame_processor_fec(ChiakiFrameProcessor *frame_pr
for(size_t i=0; i<frame_processor->units_source_expected; i++)
{
ChiakiFrameUnit *slot = frame_processor->unit_slots + i;
uint8_t *buf_ptr = frame_processor->frame_buf + frame_processor->buf_size_per_unit * i;
uint8_t *buf_ptr = frame_processor->frame_buf + frame_processor->buf_stride_per_unit * i;
uint16_t padding = ntohs(*((chiaki_unaligned_uint16_t *)buf_ptr));
if(padding >= frame_processor->buf_size_per_unit)
{
@ -272,7 +276,7 @@ CHIAKI_EXPORT ChiakiFrameProcessorFlushResult chiaki_frame_processor_flush(Chiak
continue;
}
size_t part_size = unit->data_size - 2;
uint8_t *buf_ptr = frame_processor->frame_buf + i*frame_processor->buf_size_per_unit;
uint8_t *buf_ptr = frame_processor->frame_buf + i*frame_processor->buf_stride_per_unit;
memmove(frame_processor->frame_buf + cur, buf_ptr + 2, part_size);
cur += part_size;
}

View file

@ -34,17 +34,20 @@ typedef struct fec_test_case_t
static MunitResult test_fec_case(FECTestCase *test_case)
{
size_t b64len = strlen(test_case->frame_buffer_b64);
size_t frame_buffer_size = b64len;
uint8_t *frame_buffer_ref = malloc(frame_buffer_size);
uint8_t *frame_buffer_ref = malloc(b64len);
munit_assert_not_null(frame_buffer_ref);
size_t stride = ((test_case->unit_size + 0xf) / 0x10) * 0x10;
size_t frame_buffer_size = stride * (test_case->k + test_case->m);
uint8_t *frame_buffer = malloc(frame_buffer_size);
munit_assert_not_null(frame_buffer);
ChiakiErrorCode err = chiaki_base64_decode(test_case->frame_buffer_b64, b64len, frame_buffer_ref, &frame_buffer_size);
ChiakiErrorCode err = chiaki_base64_decode(test_case->frame_buffer_b64, b64len, frame_buffer_ref, &b64len);
munit_assert_int(err, ==, CHIAKI_ERR_SUCCESS);
munit_assert_size(frame_buffer_size, ==, test_case->unit_size * (test_case->k + test_case->m));
memcpy(frame_buffer, frame_buffer_ref, frame_buffer_size);
munit_assert_size(b64len, ==, test_case->unit_size * (test_case->k + test_case->m));
for(size_t i=0; i<test_case->k + test_case->m; i++)
memcpy(frame_buffer + i * stride, frame_buffer_ref + i * test_case->unit_size, test_case->unit_size);
size_t erasures_count = 0;
for(const int *e = test_case->erasures; *e >= 0; e++, erasures_count++);
@ -54,13 +57,14 @@ static MunitResult test_fec_case(FECTestCase *test_case)
{
unsigned int e = test_case->erasures[i];
munit_assert_uint(e, <, test_case->k + test_case->m);
memset(frame_buffer + test_case->unit_size * e, 0x42, test_case->unit_size);
memset(frame_buffer + stride * e, 0x42, test_case->unit_size);
}
err = chiaki_fec_decode(frame_buffer, test_case->unit_size, test_case->k, test_case->m, (const unsigned int *)test_case->erasures, erasures_count);
err = chiaki_fec_decode(frame_buffer, test_case->unit_size, stride, test_case->k, test_case->m, (const unsigned int *)test_case->erasures, erasures_count);
munit_assert_int(err, ==, CHIAKI_ERR_SUCCESS);
munit_assert_memory_equal(test_case->k * test_case->unit_size, frame_buffer, frame_buffer_ref);
for(size_t i=0; i<test_case->k; i++)
munit_assert_memory_equal(test_case->unit_size, frame_buffer + i * stride, frame_buffer_ref + i * test_case->unit_size);
free(frame_buffer);
free(frame_buffer_ref);
@ -88,4 +92,4 @@ MunitTest tests_fec[] = {
fec_params
},
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
};