63#define MOD_NAME "[fec/rs] "
68#define restrict __restrict
82rs::rs(
unsigned int k,
unsigned int n)
90 assert(
state != NULL);
92 LOG(
LOG_LEVEL_ERROR) <<
"zfec support is not compiled in, error correction is disabled\n";
96rs::rs(
const char *c_cfg,
bool is_audio)
98 if (strcmp(c_cfg,
"help") == 0) {
102 char *cfg = strdup(c_cfg);
103 char *
item, *save_ptr;
104 item = strtok_r(cfg,
":", &save_ptr);
107 item = strtok_r(NULL,
":", &save_ptr);
108 assert(
item != NULL);
122 assert(
state != NULL);
123 MSG(INFO,
"Using Reed-Solomon with k=%u n=%u\n",
m_k,
m_n);
132 if (
state !=
nullptr) {
133 fec_free((fec_t *)
state);
138shared_ptr<video_frame>
rs::encode(shared_ptr<video_frame> in)
141 assert(
state !=
nullptr);
145 const size_t hdr_len =
sizeof(hdr);
149 for (
unsigned i = 0; i < in->tile_count; ++i) {
150 size_t len = in->tiles[i].data_len;
151 char *data = in->tiles[i].data;
154 int buffer_len = ss *
m_n;
156 out_data = out->
tiles[i].
data = (
char *) malloc(buffer_len);
157 uint32_t len32 =
len + hdr_len;
158 memcpy(out_data, &len32,
sizeof(len32));
159 memcpy(out_data +
sizeof(len32), hdr, hdr_len);
160 memcpy(out_data +
sizeof(len32) + hdr_len, data,
len);
161 memset(out_data +
sizeof(len32) + hdr_len +
len, 0, ss *
m_k - (
sizeof(len32) + hdr_len +
len));
165 for (
int k = 0; k <
m_k; ++k) {
166 src[k] = *out + ss * k;
169 for (
int m = 0; m <
m_n -
m_k; ++m) {
170 fec_encode(
state, src, *out + ss * (
m_k + m), m, ss);
174 for (
unsigned int k = 0; k <
m_k; ++k) {
175 src[k] = out_data + ss * k;
178 unsigned int dst_idx[
MAX_N];
179 for (
unsigned int m = 0; m <
m_n-
m_k; ++m) {
180 dst[m] = out_data + ss * (
m_k + m);
181 dst_idx[m] =
m_k + m;
184 fec_encode((
const fec_t *)
state, (gf **) src,
185 (gf **) dst, dst_idx,
m_n-
m_k, ss);
215 size_t hdr_len =
sizeof(hdr);
217 uint32_t len32 =
len + hdr_len;
219 out.
append(i, (
char *) &len32,
sizeof len32);
220 out.
append(i, (
char *) &hdr,
sizeof hdr);
224 int buffer_len = ss *
m_n;
225 out.
resize(i, buffer_len);
226 memset(out.
get_data(i) +
sizeof(len32) + hdr_len +
len, 0, ss *
m_k - (
sizeof(len32) + hdr_len +
len));
231 for (
unsigned int k = 0; k <
m_k; ++k) {
236 unsigned int dst_idx[
MAX_N];
237 for (
unsigned int m = 0; m <
m_n-
m_k; ++m) {
239 dst_idx[m] =
m_k + m;
242 fec_encode((
const fec_t *)
state, (gf **) src,
243 (gf **) dst, dst_idx,
m_n-
m_k, ss);
257 return ((
sizeof(uint32_t) + hdr_len +
len) +
m_k - 1) /
m_k;
265 if (
auto it = c_m.find(0); it != c_m.end() && it->second >= 4) {
267 memcpy(&out_sz, buf,
sizeof(out_sz));
274 std::map<int, int>
const & c_m)
276 std::map<int, int> m = c_m;
277 unsigned int ss = in_len /
m_n;
280 for (
auto it = m.begin(); it != m.end(); ++it) {
281 int start = it->first;
282 int size = it->second;
284 auto neighbour = m.end();
285 while ((neighbour = m.find(
start + size)) != m.end()) {
286 it->second += neighbour->second;
292 if (
state ==
nullptr) {
294 *out = (
char *) in +
sizeof(uint32_t);
295 auto fst_sgmt = m.find(0);
296 return fst_sgmt != m.end() && (unsigned) fst_sgmt->second >= ss *
m_k;
302 unsigned int index[
MAX_N];
309 for (
auto it = m.begin(); it != m.end(); ++it) {
310 int start = it->first;
313 int first_symbol_start = (
start + ss - 1) / ss * ss;
316 for (
int j = first_symbol_start; j < last_symbol_end; j += ss) {
318 pkt[i] = (
void *) (in + j);
333 int ret = fec_decode(
state, pkt, index, ss);
339 memcpy(&out_sz, pkt[0],
sizeof(out_sz));
340 fprintf(stderr,
"%d %d\n\n", out_sz, index[0]);
342 *out = (
char *) in + 4;
346 std::bitset<MAX_K> empty_slots;
347 std::bitset<MAX_K> repaired_slots;
349 for (
auto it = m.begin(); it != m.end(); ++it) {
350 int start = it->first;
351 int size = it->second;
353 unsigned int first_symbol_start = (
start + ss - 1) / ss * ss;
354 unsigned int last_symbol_end = (
start + size) / ss * ss;
355 for (
unsigned int j = first_symbol_start; j < last_symbol_end; j += ss) {
359 empty_slots.set(j/ss);
362 for (
unsigned int k = 0; k <
m_k; ++k) {
363 if (!empty_slots.test(k)) {
368 repaired_slots.set(k);
385 *out = (
char *) in +
sizeof(uint32_t);
389 char **output = (
char **) malloc(
m_k *
sizeof(
char *));
390 for (
unsigned int i = 0; i <
m_k; ++i) {
391 output[i] = (
char *) malloc(ss);
394 fec_decode((
const fec_t *)
state, (
const gf *
const *) pkt,
395 (gf *
const *) output, index, ss);
398 for (
unsigned int j = 0; j <
m_k; ++j) {
399 if (repaired_slots.test(j)) {
400 memcpy((
void *) (in + j * ss), output[i], ss);
405 for (
unsigned int i = 0; i <
m_k; ++i) {
411 memcpy(&out_sz, in,
sizeof(out_sz));
414 *out = (
char *) in +
sizeof(uint32_t);
426 TBOLD(
"%d")
", max %d)\n"
427 "\t" TBOLD(
"<n>")
" - length of block + parity "
428 "(default " TBOLD(
"%d")
", max %d),\n"
429 "\t\t\tmust be > <k>\n\n",
433 "The n/k ratio determines the redundancy that the FEC provides. "
434 "But please note that the " TUNDERLINE(
"strength")
435 " of the FEC applies " TBOLD (
"per frame")
" basis, so 20%"
436 " redundancy will cover 20% loss in a signle frame only.\n";
struct video_frame * frame
int void(** deleter)(void *))
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_desc video_desc_from_frame(const struct video_frame *frame)
Returns struct video_desc from video frame.
struct video_frame * vf_alloc_desc(struct video_desc desc)
Allocates video frame accordig given desc.
void resize(int channel, size_t len)
char * get_data(int channel)
void set_fec_params(int channel, fec_desc const &)
void init(int nr_channels, audio_codec_t codec, int bps, int sample_rate)
Initializes audio_frame2 for use. If already initialized, data are dropped.
audio_codec_t get_codec() const
int get_channel_count() const
size_t get_data_len(int channel) const
int get_sample_rate() const
void append(audio_frame2 const &frame)
int color_printf(const char *format,...)
static __device__ const float offset
#define LOG_LEVEL_ERROR
general errors
uint32_t audio_payload_hdr_t[5]
uint32_t video_payload_hdr_t[6]
rs(unsigned int k, unsigned int n)
uint32_t get_buf_len(const char *buf, std::map< int, int > const &c_m)
bool decode(char *in, int in_len, char **out, int *len, const std::map< int, int > &) override
int get_ss(int hdr_len, int len)
std::shared_ptr< video_frame > encode(std::shared_ptr< video_frame > frame) override
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
Struct video_frame represents a video frame and contains video description.
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
struct fec_desc fec_params
void format_video_header(struct video_frame *frame, int tile_idx, int buffer_idx, uint32_t *video_hdr)
void format_audio_header(const audio_frame2 *frame, int channel, int buffer_idx, uint32_t *audio_hdr)
char * wrap_paragraph(char *text)
This is an umbrella header for video functions.