UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
rs Struct Reference

#include <rs.h>

Inheritance diagram for rs:
Inheritance graph
Collaboration diagram for rs:
Collaboration graph

Public Member Functions

 rs (const char *cfg, bool is_audio)
 
 rs (unsigned int k, unsigned int n)
 
virtual ~rs ()
 
bool decode (char *in, int in_len, char **out, int *len, const std::map< int, int > &) override
 
virtual audio_frame2 encode (audio_frame2 const &) override
 
std::shared_ptr< video_frame > encode (std::shared_ptr< video_frame > frame) override
 
- Public Member Functions inherited from fec
virtual ~fec ()
 

Private Member Functions

uint32_t get_buf_len (const char *buf, std::map< int, int > const &c_m)
 
int get_ss (int hdr_len, int len)
 

Private Attributes

unsigned int m_k
 
unsigned int m_n
 
void * state = nullptr
 

Additional Inherited Members

- Static Public Member Functions inherited from fec
static fec * create_from_config (const char *str, bool is_audio) noexcept
 
static fec * create_from_desc (struct fec_desc) noexcept
 
static enum fec_type fec_type_from_pt (int pt) throw ()
 
static int pt_from_fec_type (enum tx_media_type media_type, enum fec_type fec_type, bool encrypted) throw ()
 

Detailed Description

Definition at line 49 of file rs.h.

Constructor & Destructor Documentation

◆ rs() [1/2]

rs::rs ( unsigned int k,
unsigned int n )

Constructs RS state. Since this constructor is currently used only for the decoder, it allows creation of dummy state even if zfec was not compiled in.

Definition at line 82 of file rs.cpp.

83 : m_k(k), m_n(n)
84{
85 assert (k <= MAX_K);
86 assert (n <= MAX_N);
87 assert (m_k <= m_n);
88#ifdef HAVE_ZFEC
89 state = fec_new(m_k, m_n);
90 assert(state != NULL);
91#else
92 LOG(LOG_LEVEL_ERROR) << "zfec support is not compiled in, error correction is disabled\n";
93#endif
94}
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG(level)
Definition debug.h:313
#define MAX_K
Definition ldgm.cpp:145
#define MAX_N
Definition rs.cpp:61
unsigned int m_k
Definition rs.h:62
void * state
Definition rs.h:61
unsigned int m_n
Definition rs.h:62

References LOG, LOG_LEVEL_ERROR, m_k, m_n, MAX_K, MAX_N, and state.

◆ rs() [2/2]

rs::rs ( const char * cfg,
bool is_audio )

Definition at line 96 of file rs.cpp.

97{
98 if (strcmp(c_cfg, "help") == 0) {
99 usage();
100 throw 0;
101 }
102 char *cfg = strdup(c_cfg);
103 char *item, *save_ptr;
104 item = strtok_r(cfg, ":", &save_ptr);
105 if (item != NULL) {
106 m_k = atoi(item);
107 item = strtok_r(NULL, ":", &save_ptr);
108 assert(item != NULL);
109 m_n = atoi(item);
110 } else {
111 m_k = is_audio ? DEFAULT_K_AUDIO : DEFAULT_K_VIDEO;
112 m_n = DEFAULT_N;
113 }
114 free(cfg);
115 if (m_k > MAX_K || m_n > MAX_N || m_k >= m_n) {
116 usage();
117 throw 1;
118 }
119
120#ifdef HAVE_ZFEC
121 state = fec_new(m_k, m_n);
122 assert(state != NULL);
123 MSG(INFO, "Using Reed-Solomon with k=%u n=%u\n", m_k, m_n);
124#else
125 throw ug_runtime_error("zfec support is not compiled in");
126#endif
127}
#define MSG(l, fmt,...)
Definition debug.h:96
void usage()
Definition main.cpp:28
@ DEFAULT_K_VIDEO
Definition rs.cpp:56
@ DEFAULT_N
Definition rs.cpp:57
@ DEFAULT_K_AUDIO
Definition rs.cpp:55
Definition hd-rum.c:27

References DEFAULT_K_AUDIO, DEFAULT_K_VIDEO, DEFAULT_N, m_k, m_n, MAX_K, MAX_N, MSG, state, and usage().

Here is the call graph for this function:

◆ ~rs()

rs::~rs ( )
virtual

Definition at line 129 of file rs.cpp.

130{
131#ifdef HAVE_ZFEC
132 if (state != nullptr) {
133 fec_free((fec_t *) state);
134 }
135#endif
136}

References state.

Member Function Documentation

◆ decode()

bool rs::decode ( char * in,
int in_len,
char ** out,
int * out_len,
const std::map< int, int > &  )
overridevirtual
Return values
trueif whole frame was reconstructed
falseif decoder was unable to reconstruct the frame However, if it was reconstructed at least partially (or the code is a systematic one) and length can be read, set len to a non-zero value.

Implements fec.

Definition at line 273 of file rs.cpp.

275{
276 std::map<int, int> m = c_m; // make private copy
277 unsigned int ss = in_len / m_n;
278
279 // compact neighbouring segments
280 for (auto it = m.begin(); it != m.end(); ++it) {
281 int start = it->first;
282 int size = it->second;
283
284 auto neighbour = m.end();
285 while ((neighbour = m.find(start + size)) != m.end()) {
286 it->second += neighbour->second;
287 size = it->second;
288 m.erase(neighbour);
289 }
290 }
291
292 if (state == nullptr) { // zfec was not compiled in - dummy mode
293 *len = get_buf_len(in, c_m);
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;
297 }
298
299#ifdef HAVE_ZFEC
300 assert(m_n <= MAX_N);
301 void *pkt[MAX_N];
302 unsigned int index[MAX_N];
303 unsigned int i = 0;
304#if 0
305
307
308
309 for (auto it = m.begin(); it != m.end(); ++it) {
310 int start = it->first;
311 int offset = it->second;
312
313 int first_symbol_start = (start + ss - 1) / ss * ss;
314 int last_symbol_end = (start + offset) / ss * ss;
315 //fprintf(stderr, "%d %d %d\n", first_symbol_start, last_symbol_end, start);
316 for (int j = first_symbol_start; j < last_symbol_end; j += ss) {
317 //fprintf(stderr, "%d\n", j);
318 pkt[i] = (void *) (in + j);
319 index[i] = j / ss;
320 i++;
321 if (i == m_k) break;
322 }
323 if (i == m_k) break;
324 }
325
326 if (i != m_k) {
327 *len = 0;
328 return;
329 }
330
331 assert (i == m_k);
332
333 int ret = fec_decode(state, pkt, index, ss);
334 if (ret != 0) {
335 *len = 0;
336 return;
337 }
338 uint32_t out_sz;
339 memcpy(&out_sz, pkt[0], sizeof(out_sz));
340 fprintf(stderr, "%d %d\n\n", out_sz, index[0]);
341 *len = out_sz;
342 *out = (char *) in + 4;
343#else
344 //const unsigned int bitset_size = m_k;
345
346 std::bitset<MAX_K> empty_slots;
347 std::bitset<MAX_K> repaired_slots;
348
349 for (auto it = m.begin(); it != m.end(); ++it) {
350 int start = it->first;
351 int size = it->second;
352
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) {
356 if (j/ss < m_k) {
357 pkt[j/ss] = in + j;
358 index[j/ss] = j/ss;
359 empty_slots.set(j/ss);
360 //fprintf(stderr, "%d\n", j/ss);
361 } else {
362 for (unsigned int k = 0; k < m_k; ++k) {
363 if (!empty_slots.test(k)) {
364 pkt[k] = in + j;
365 index[k] = j/ss;
366 //fprintf(stderr, "%d\n", j/ss);
367 empty_slots.set(k);
368 repaired_slots.set(k);
369 break;
370 }
371 //fprintf(stderr, "what???\n", j/ss);
372 }
373 }
374 i++;
375 //fprintf(stderr, " %d\n", i);
376 if (i == m_k) break;
377 }
378 if (i == m_k) break;
379 }
380
381 //fprintf(stderr, " %d\n", i);
382
383 if (i != m_k) {
384 *len = get_buf_len(in, c_m);
385 *out = (char *) in + sizeof(uint32_t);
386 return false;
387 }
388
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);
392 }
393
394 fec_decode((const fec_t *) state, (const gf *const *) pkt,
395 (gf *const *) output, index, ss);
396
397 i = 0;
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);
401 i++;
402 }
403 }
404
405 for (unsigned int i = 0; i < m_k; ++i) {
406 free(output[i]);
407 }
408 free(output);
409
410 uint32_t out_sz;
411 memcpy(&out_sz, in, sizeof(out_sz));
412 //fprintf(stderr, " %d\n", out_sz);
413 *len = out_sz;
414 *out = (char *) in + sizeof(uint32_t);
415#endif
416#endif // defined HAVE_ZFEC
417
418 return true;
419}
int void size_t * len
static __device__ const float offset
Definition cuda_dxt.cu:139
static void start()
Definition sdp.c:202
uint32_t get_buf_len(const char *buf, std::map< int, int > const &c_m)
Definition rs.cpp:263

References get_buf_len(), len, m_k, m_n, MAX_N, offset, start(), and state.

Here is the call graph for this function:

◆ encode() [1/2]

audio_frame2 rs::encode ( audio_frame2 const & in)
overridevirtual

Reimplemented from fec.

Definition at line 205 of file rs.cpp.

206{
207#ifdef HAVE_ZFEC
208 audio_frame2 out;
209 out.init(in.get_channel_count(), in.get_codec(), in.get_bps(), in.get_sample_rate());
210 out.reserve(3 * in.get_data_len() / in.get_channel_count()); // just an estimate
211
212 for (int i = 0; i < in.get_channel_count(); ++i) {
214 format_audio_header(&in, i, 0, (uint32_t *) &hdr);
215 size_t hdr_len = sizeof(hdr);
216 size_t len = in.get_data_len(i);
217 uint32_t len32 = len + hdr_len;
218 //const char *data = in->get_data(i);
219 out.append(i, (char *) &len32, sizeof len32);
220 out.append(i, (char *) &hdr, sizeof hdr);
221 out.append(i, in.get_data(i), in.get_data_len(i));
222
223 int ss = get_ss(hdr_len, len);
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));
227
228 out.set_fec_params(i, fec_desc(FEC_RS, m_k, m_n - m_k, 0, 0, ss));
229
230 void *src[MAX_K];
231 for (unsigned int k = 0; k < m_k; ++k) {
232 src[k] = out.get_data(i) + ss * k;
233 }
234
235 void *dst[MAX_N];
236 unsigned int dst_idx[MAX_N];
237 for (unsigned int m = 0; m < m_n-m_k; ++m) {
238 dst[m] = out.get_data(i) + ss * (m_k + m);
239 dst_idx[m] = m_k + m;
240 }
241
242 fec_encode((const fec_t *)state, (gf **) src,
243 (gf **) dst, dst_idx, m_n-m_k, ss);
244 }
245
246 return out;
247#else
248 (void) in;
249 return {};
250#endif // defined HAVE_ZFEC
251}
void resize(int channel, size_t len)
Definition types.cpp:183
char * get_data(int channel)
Definition types.cpp:218
void set_fec_params(int channel, fec_desc const &)
Definition types.cpp:293
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.
Definition types.cpp:115
void reserve(size_t len)
Definition types.cpp:161
void append(audio_frame2 const &frame)
Definition types.cpp:125
uint32_t audio_payload_hdr_t[5]
Definition rtp_types.h:129
int get_ss(int hdr_len, int len)
Definition rs.cpp:256
void format_audio_header(const audio_frame2 *frame, int channel, int buffer_idx, uint32_t *audio_hdr)
Definition transmit.cpp:460
@ FEC_RS
Definition types.h:204

References audio_frame2::append(), FEC_RS, format_audio_header(), audio_frame2::get_bps(), audio_frame2::get_channel_count(), audio_frame2::get_codec(), audio_frame2::get_data(), audio_frame2::get_data_len(), audio_frame2::get_sample_rate(), get_ss(), audio_frame2::init(), len, m_k, m_n, MAX_K, MAX_N, audio_frame2::reserve(), audio_frame2::resize(), audio_frame2::set_fec_params(), and state.

Here is the call graph for this function:

◆ encode() [2/2]

shared_ptr< video_frame > rs::encode ( std::shared_ptr< video_frame > frame)
overridevirtual

Implements fec.

Definition at line 138 of file rs.cpp.

139{
140#ifdef HAVE_ZFEC
141 assert(state != nullptr);
142
144 format_video_header(in.get(), 0, 0, hdr);
145 const size_t hdr_len = sizeof(hdr);
146
147 struct video_frame *out = vf_alloc_desc(video_desc_from_frame(in.get()));
148
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;
152 //int encode(char *hdr, int hdr_len, char *in, int len, char **out) {
153 int ss = get_ss(hdr_len, len);
154 int buffer_len = ss * m_n;
155 char *out_data;
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));
162
163#if 0
164 void *src[MAX_K];
165 for (int k = 0; k < m_k; ++k) {
166 src[k] = *out + ss * k;
167 }
168
169 for (int m = 0; m < m_n - m_k; ++m) {
170 fec_encode(state, src, *out + ss * (m_k + m), m, ss);
171 }
172#else
173 void *src[MAX_K];
174 for (unsigned int k = 0; k < m_k; ++k) {
175 src[k] = out_data + ss * k;
176 }
177 void *dst[MAX_N];
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;
182 }
183
184 fec_encode((const fec_t *)state, (gf **) src,
185 (gf **) dst, dst_idx, m_n-m_k, ss);
186#endif
187
188 out->tiles[i].data_len = buffer_len;
189 out->fec_params = fec_desc(FEC_RS, m_k, m_n - m_k, 0, 0, ss);
190 }
191
192 static auto deleter = [](video_frame *frame) {
193 for (unsigned i = 0; i < frame->tile_count; ++i) {
194 free(frame->tiles[i].data);
195 }
196 vf_free(frame);
197 };
198 return {out, deleter};
199#else
200 (void) in;
201 return {};
202#endif // defined HAVE_ZFEC
203}
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.
uint32_t video_payload_hdr_t[6]
Definition rtp_types.h:107
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
unsigned int data_len
length of the data
Definition types.h:288
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345
unsigned int tile_count
Definition types.h:344
struct fec_desc fec_params
Definition types.h:328
void format_video_header(struct video_frame *frame, int tile_idx, int buffer_idx, uint32_t *video_hdr)
Definition transmit.cpp:445

References tile::data, tile::data_len, deleter, video_frame::fec_params, FEC_RS, format_video_header(), frame, get_ss(), len, m_k, m_n, MAX_K, MAX_N, state, video_frame::tile_count, video_frame::tiles, vf_alloc_desc(), vf_free(), and video_desc_from_frame().

Here is the call graph for this function:

◆ get_buf_len()

uint32_t rs::get_buf_len ( const char * buf,
std::map< int, int > const & c_m )
private
Returns
stored buffer data length or 0 if first packet (header) is missing

Definition at line 263 of file rs.cpp.

264{
265 if (auto it = c_m.find(0); it != c_m.end() && it->second >= 4) {
266 uint32_t out_sz;
267 memcpy(&out_sz, buf, sizeof(out_sz));
268 return out_sz;
269 }
270 return 0U;
271}

Referenced by decode().

◆ get_ss()

int rs::get_ss ( int hdr_len,
int len )
private

Returns symbol size (?) for given headers len and with configured m_k

Definition at line 256 of file rs.cpp.

256 {
257 return ((sizeof(uint32_t) + hdr_len + len) + m_k - 1) / m_k;
258}

References len, and m_k.

Referenced by encode(), and encode().

Member Data Documentation

◆ m_k

unsigned int rs::m_k
private

Definition at line 62 of file rs.h.

Referenced by rs(), rs(), decode(), encode(), encode(), and get_ss().

◆ m_n

unsigned int rs::m_n
private

Definition at line 62 of file rs.h.

Referenced by rs(), rs(), decode(), encode(), and encode().

◆ state

void* rs::state = nullptr
private

Definition at line 61 of file rs.h.

Referenced by rs(), rs(), ~rs(), decode(), encode(), and encode().


The documentation for this struct was generated from the following files: