UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
LDGM_session_cpu Class Reference

#include <ldgm-session-cpu.h>

Inheritance diagram for LDGM_session_cpu:
Inheritance graph
Collaboration diagram for LDGM_session_cpu:
Collaboration graph

Public Member Functions

 LDGM_session_cpu ()
 
 ~LDGM_session_cpu ()
 
void * alloc_buf (int size)
 
char * decode_frame (char *received_data, int buf_size, int *frame_size, std::map< int, int > valid_data)
 
void encode (char *, char *)
 
void encode_naive (char *, char *)
 
void free_out_buf (char *buf)
 
void iterate (Tanner_graph *graph)
 
- Public Member Functions inherited from LDGM_session
 LDGM_session ()
 
virtual ~LDGM_session ()
 
void create_edges (Tanner_graph *g)
 
char * encode_frame (char *frame, int frame_size, int *out_buf_size)
 
char * encode_hdr_frame (char *hdr, int hdr_size, char *frame, int frame_size, int *out_buf_size)
 
unsigned int get_packet_size () const
 
bool needs_decoding (Tanner_graph *tanner_graph)
 
void set_params (unsigned short k, unsigned short m, unsigned short rw)
 
void set_pcMatrix (char *matrix)
 
- Public Member Functions inherited from Coding_session

Private Attributes

double elapsed_sum
 
long no_frames
 

Additional Inherited Members

- Protected Attributes inherited from LDGM_session
double elapsed_sum2
 
char * lost_ptr
 
unsigned short max_row_weight
 
long no_frames2
 
unsigned short packet_size
 
unsigned short param_k
 
unsigned short param_m
 
int * pcm
 
char * pcMatrix
 
char * received_ptr
 
unsigned short row_weight
 
- Static Protected Attributes inherited from LDGM_session
static const int HEADER_SIZE = 4
 

Detailed Description

Definition at line 32 of file ldgm-session-cpu.h.

Constructor & Destructor Documentation

◆ LDGM_session_cpu()

LDGM_session_cpu::LDGM_session_cpu ( )
inline

Definition at line 36 of file ldgm-session-cpu.h.

36 {
37 printf("CPU LDGM in progress .... \n");
38 elapsed_sum=0.0;
39 no_frames=0;
40 } /* constructor */

References elapsed_sum, and no_frames.

◆ ~LDGM_session_cpu()

LDGM_session_cpu::~LDGM_session_cpu ( )
inline

Definition at line 41 of file ldgm-session-cpu.h.

41 {
42 printf("LDGM TIME CPU: %f ms\n",this->elapsed_sum2/(double)this->no_frames2 );
43 } /* constructor */
double elapsed_sum2

References LDGM_session::elapsed_sum2, and LDGM_session::no_frames2.

Member Function Documentation

◆ alloc_buf()

void * LDGM_session_cpu::alloc_buf ( int size)
virtual

Implements LDGM_session.

Definition at line 139 of file ldgm-session-cpu.cpp.

140{
141 void *out_buf = aligned_malloc(buf_size, 16);
142 if (!out_buf)
143 {
144 printf ( "Unable to allocate aligned memory\n" );
145
146 }
147 return out_buf;
148
149}
static void * aligned_malloc(size_t size, size_t alignment)

References aligned_malloc().

Here is the call graph for this function:

◆ decode_frame()

char * LDGM_session_cpu::decode_frame ( char * received_data,
int buf_size,
int * frame_size,
std::map< int, int > valid_data )
virtual

Method decode should recover original source data

Parameters
received_dataReceived data (source and parity)
buf_sizeSize of the received buffer
frame_sizeOutput parameter for storing size of the decoded frame
valid_dataMap storing pairs <offset, number of bytes> of received data
Returns
Recovered source data

Implements LDGM_session.

Definition at line 247 of file ldgm-session-cpu.cpp.

249{
250// printf ( "buf_size: %d\n", buf_size );
251
252 Timer_util interval;
253 interval.start();
254
255
256 Tanner_graph graph;
257
258 int p_size = buf_size/(param_m+param_k);
259 this->packet_size = p_size;
260// printf ( "p_size %d\n", p_size );
261 graph.set_data_size(p_size);
262
263 //Timer_util timer;
264
265 int i;
266 int index = 0;
267
268
269// while ( i < (param_k + param_m)*p_size)
270// {
271// printf ( "%2d|", (unsigned char)received[i++] );
272// }
273
274 //one variable node per each data packet in block K
275 for ( i = 0; i < param_k; ++i )
276 graph.add_node(Node::variable_node, index++, received + i*p_size);
277
278 //one variable node per each parity packet in block M
279 for ( i = 0; i < param_m; ++i)
280 graph.add_node(Node::variable_node, index++, received + (i + param_k)*p_size);
281
282 //one constraint node per each row of generation matrix
283 for ( i = 0; i < param_m; ++i)
284 graph.add_node(Node::constraint_node, index++, NULL);
285
286 create_edges(&graph);
287
288// printf("Graph created in: %.3f s\n", t);
289
290 /* printf ( "graf\n" );
291 * for(map<int, Node>::iterator it = graph.nodes.begin(); it != graph.nodes.end(); ++it) {
292 * Node n = it->second;
293 * for ( int i = 0; i < p_size; ++i)
294 * printf("%2d|", *(unsigned char *)(n.getDataPtr() + i));
295 * printf ( "---\n" );
296 * }
297 */
298
299 /* for(map<int, Node>::iterator it = graph.nodes.begin(); it != graph.nodes.end(); ++it) {
300 * Node n = it->second;
301 * printf ( "neigbours of %d (count %lu): ", it->first, (it->second).neighbours.size() );
302 * for(vector<int>::iterator itr = n.neighbours.begin(); itr != n.neighbours.end(); ++itr)
303 * printf ( "%d ", *itr );
304 * printf ( "\n" );
305 * }
306 */
307
308 //We need to merge intervals in the valid data vector
309 map <int, int> merged_intervals;
310 map<int,int>::iterator map_it;
311
312 if ( valid_data.size() != 0 )
313 {
314 for ( map_it = valid_data.begin(); map_it != valid_data.end(); )
315 {
316 int start = map_it->first;
317 int length = map_it->second;
318 while ( start + length == (++map_it)->first )
319 length += map_it->second;
320 merged_intervals.insert ( pair<int, int> (start, length) );
321 }
322 }
323 /* printf ( "Valid data: \n" );
324 * for ( map_it = valid_data.begin(); map_it != valid_data.end(); ++map_it)
325 * {
326 * printf ( "|%d-%d| ", map_it->first, map_it->second );
327 * }
328 * printf ( "\n" );
329 *
330 * printf ( "Merged intervals: \n" );
331 * for ( map_it = merged_intervals.begin(); map_it != merged_intervals.end(); ++map_it)
332 * {
333 * printf ( "|%d-%d| ", map_it->first, map_it->second );
334 * }
335 * printf ( "\n" );
336 *
337 */
338
339
340
341 map<int, Node>::iterator it;
342 if ( merged_intervals.size() != 0)
343 {
344 it = graph.nodes.find(0);
345 const auto variable_node_end_it = graph.nodes.find(param_k+param_m); // == 1st constraint node
346 assert(variable_node_end_it != graph.nodes.end());
347 while (it != variable_node_end_it) {
348 (*it).second.setDone(false);
349 int node_offset = (*it).second.getDataPtr() - received;
350// printf ( "offset: %d\n", node_offset );
351
352 map_it = merged_intervals.begin();
353 //Find the offset in valid data which is equal, or the first offset which is
354 //lower than node offset
355 bool found = false;
356 while ( (map_it->first <= node_offset) && map_it != merged_intervals.end() )
357 {
358 map_it++;
359 found = true;
360 }
361 if ( found )
362 map_it--;
363
364 //Next, find out if some interval covers this symbol
365 if ( found && (map_it->first + map_it->second) >=
366 (node_offset + p_size) )
367 {
368 (*it).second.setDone(true);
369// printf ( "setting node %d with offset %d and size %d as done\n", it->first,
370// node_offset, p_size);
371 }
372
373 ++it;
374 }
375 }
376
377 //int not_done = 0;
378 for ( it = graph.nodes.begin(); it != graph.nodes.find(param_k); it++)
379 {
380 if ( !it->second.isDone())
381 {
382 memset(it->second.getDataPtr(), 0, p_size);
383// printf ( "resetting node: %d\n", it->first );
384 //not_done++;
385 }
386 }
387// printf ( "not done: %d\n", not_done );
388 /* srand(time(NULL));
389 * for ( int j = 0; j < 100; j++)
390 * {
391 * it = graph.nodes.find(rand()%(param_k+param_m));
392 * (*it).second.setDone(false);
393 * }
394 */
395 int iter = 0;
396
397 while ( needs_decoding(&graph) && iter < 4) {
398// printf ( "iteratin\n" );
399 iterate(&graph);
400 iter++;
401 }
402
403// printf("decoding process: %.3f s\n", t);
404
405 //printf ( "iterations: %d\n", iter );
406
407 int undecoded = 0;
408 it = graph.nodes.find(0);
409 while ( it != graph.nodes.find(param_k) ) {
410 if (!(*it).second.isDone())
411 undecoded++;
412 ++it;
413 }
414// printf ( "Number of not recovered data packets: %d\n", undecoded );
415
416 // printf("rest: %.3f s\n", t);
417
418 if ( undecoded == 0 )
419 {
420 union int_bytes {
421 unsigned int number;
422 unsigned char bytes[4];
423 };
424 union int_bytes fs;
425 memcpy(&(fs.bytes), received, 4);
426 *frame_size = fs.number;
427 }
428 else
429 *frame_size = 0;
430
431
432 interval.end();
433 //printf("time: %e\n",elapsed/1000.0 );
434 this->elapsed_sum2 += interval.elapsed_time_ms();
435 this->no_frames2++;
436
437 if(this->no_frames==150){
438 //printf("TIME: %f ms\n",this->elapsed_sum/(double)this->no_frames );
439 }
440
441 return received + LDGM_session::HEADER_SIZE;
442} /* ----- end ofmethod LDGM_session_cpu::decode ----- */
void iterate(Tanner_graph *graph)
static const int HEADER_SIZE
unsigned short param_m
bool needs_decoding(Tanner_graph *tanner_graph)
unsigned short param_k
unsigned short packet_size
void create_edges(Tanner_graph *g)
@ variable_node
Definition tanner.h:40
@ constraint_node
Definition tanner.h:41
std::map< int, Node > nodes
Definition tanner.h:145
void set_data_size(int size)
Definition tanner.cpp:70
void add_node(Node::Node_type t, int index, char *data)
Definition tanner.cpp:74
This class implements timer utils.
Definition timer-util.h:26
void end()
Definition timer-util.h:36
double elapsed_time_ms() const
Definition timer-util.h:52
void start()
Definition timer-util.h:32
codec_t first
Definition sdl2.c:423
static void start()
Definition sdp.c:202

References Tanner_graph::add_node(), Node::constraint_node, LDGM_session::create_edges(), LDGM_session::elapsed_sum2, Timer_util::elapsed_time_ms(), Timer_util::end(), first, LDGM_session::HEADER_SIZE, iterate(), LDGM_session::needs_decoding(), no_frames, LDGM_session::no_frames2, Tanner_graph::nodes, LDGM_session::packet_size, LDGM_session::param_k, LDGM_session::param_m, Tanner_graph::set_data_size(), start(), Timer_util::start(), and Node::variable_node.

Referenced by demo().

Here is the call graph for this function:

◆ encode()

void LDGM_session_cpu::encode ( char * data_ptr,
char * parity_ptr )
virtual

Implements LDGM_session.

Definition at line 152 of file ldgm-session-cpu.cpp.

153{
154// start encoding
155 // printf ( "packet_size: %d\n", this->packet_size );
156
157 char *parity_packet;
158
159 parity_packet = (char *) aligned_malloc(packet_size, 16);
160 if (!parity_packet)
161 {
162 printf ( "Error while using posix_memalign\n" );
163 return;
164 }
165 memset(parity_packet, 0, packet_size);
166
167 for ( int m = 0; m < param_m; ++m) {
168// printf ( "m: %d\n", m );
169
170// printf ( "max w: %d\n", max_row_weight );
171 //Find out which packets to XOR
172 for ( int k = 0; k < max_row_weight+2; ++k) {
173 int idx = pcm[m*(max_row_weight+2) + k];
174// printf ( "adept: %d\n", idx );
175 if (idx > -1 && idx < param_k) {
176// printf ( "xoring idx: %d\n", idx );
177 char *ptr = data_ptr + idx*packet_size;
178 parity_packet = xor_using_sse(ptr, parity_packet, packet_size);
179 }
180 }
181
182 //Add the new parity packet to overall parity
183 memcpy ( parity_ptr + m*packet_size, parity_packet, packet_size );
184 }
185
186 aligned_free(parity_packet);
187
188 return ;
189} /* ----- end of method LDGM_session_cpu::encode ----- */
unsigned short max_row_weight
static char * xor_using_sse(char *source, char *dest, int packet_size)
#define aligned_free

References aligned_free, aligned_malloc(), LDGM_session::max_row_weight, LDGM_session::packet_size, LDGM_session::param_k, LDGM_session::param_m, LDGM_session::pcm, and xor_using_sse().

Here is the call graph for this function:

◆ encode_naive()

void LDGM_session_cpu::encode_naive ( char * data_ptr,
char * parity_ptr )
virtual

Implements LDGM_session.

Definition at line 198 of file ldgm-session-cpu.cpp.

199{
200// start encoding
201
202 void *ppacket;
203 char *parity_packet;
204
205 for ( int m = 0; m < param_m; ++m) {
206
207 ppacket = aligned_malloc(packet_size, 16);
208 if (!ppacket)
209 {
210 printf ( "Error while using posix_memalign\n" );
211 return;
212 }
213 memset(ppacket, 0, packet_size);
214 parity_packet = (char*)ppacket;
215
216 //Find out which packets to XOR
217 for ( int k = 0; k < max_row_weight+2; ++k) {
218 int idx = pcm[m*(max_row_weight+2) + k];
219 if (idx > -1 && idx < param_k) {
220 char *ptr = data_ptr + idx*packet_size;
221// parity_packet = xor_using_sse(ptr, parity_packet, packet_size);
222 for ( int i = 0; i < packet_size; i++)
223 parity_packet[i] ^= *(ptr+i);
224 }
225 }
226
227 //Apply inverted staircase matrix
228 if( m > 0) {
229 char *prev_parity = parity_ptr + (m-1)*packet_size;
230// parity_packet = xor_using_sse(prev_parity, parity_packet, packet_size);
231 for ( int i = 0; i < packet_size; i++)
232 parity_packet[i] ^= *(prev_parity+i);
233 }
234
235
236 //Add the new parity packet to overall parity
237 memcpy ( parity_ptr + m*packet_size, parity_packet, packet_size );
238 aligned_free(ppacket);
239
240 }
241 return ;
242} /* ----- end of method LDGM_session_cpu::encode ----- */

References aligned_free, aligned_malloc(), LDGM_session::max_row_weight, LDGM_session::packet_size, LDGM_session::param_k, LDGM_session::param_m, and LDGM_session::pcm.

Here is the call graph for this function:

◆ free_out_buf()

void LDGM_session_cpu::free_out_buf ( char * buf)
virtual

Implements LDGM_session.

Definition at line 192 of file ldgm-session-cpu.cpp.

193{
194 if ( buf != NULL )
195 aligned_free(buf);
196}

References aligned_free.

Referenced by demo().

◆ iterate()

void LDGM_session_cpu::iterate ( Tanner_graph * graph)

Definition at line 446 of file ldgm-session-cpu.cpp.

447{
448 map<int, Node>::iterator it_c;
449 vector<int> vec;
450
451 //static int recovered = 0;
452
453 //select the first constraint node
454 it_c = graph->nodes.find ( param_k + param_m );
455
456 //iterate through constraint nodes
457 while ( it_c != graph->nodes.end() ) {
458 //iterate the node's neighbours to find out how many of them are not decoded
459 for(vector<int>::iterator j = it_c->second.neighbours.begin();
460 j != it_c->second.neighbours.end(); ++j) {
461 const auto it_v = graph->nodes.find(*j);
462 if ( !it_v->second.isDone() )
463 vec.push_back(*j);
464 }
465// printf ( "node %d has %d undecoded neighbours\n", it_c->first, vec.size() );
466
467 //we can restore the missing packet
468 if ( vec.size() == 1)
469 {
470 int r_index = vec.front();
471
472// if ( r_index == 0 )
473// {
474// printf ( "repairing first block\n" );
475// }
476 auto &node = graph->nodes.at(r_index);
477 memset(node.getDataPtr(), 0, packet_size);
478 char *r_data = node.getDataPtr();
479 //find other nodes connected to this constraint node and XOR their values
480 int count = 0;
481 for(vector<int>::iterator j = it_c->second.neighbours.begin();
482 j != it_c->second.neighbours.end(); ++j)
483 {
484 if ( *j != r_index )
485 {
486// printf ( "decode, packet_size: %d\n", packet_size );
487 char *g_data = (graph->nodes.find(*j))->second.getDataPtr();
488 //XOR
489 xor_using_sse(g_data, r_data, packet_size);
490 count++;
491 }
492 }
493 /* //validate recovered packet
494 * for ( int i = 0; i < param_k; ++i) {
495 * if(!memcmp(r_data, lost_ptr + i*packet_size, packet_size)) {
496 * printf ( "packet ok\n" );
497 * break;
498 * }
499 * }
500 */
501 if ( count > 0 )
502 node.setDone(true);
503 //recovered++;
504 /* printf ( "restored data: \n" );
505 * for ( int i = 0; i < packet_size; ++i)
506 * printf ( "%2d|", (unsigned char)(*(it_v->second.getDataPtr() + i)) );
507 * printf ( "---\n" );
508 */
509
510
511 }
512 vec.clear();
513
514 ++it_c;
515 }
516// printf ( "recovered: %d\n", recovered );
517
518 return;
519
520}
int count
Definition hd-rum.c:44

References count, Tanner_graph::nodes, LDGM_session::packet_size, LDGM_session::param_k, LDGM_session::param_m, and xor_using_sse().

Referenced by decode_frame().

Here is the call graph for this function:

Member Data Documentation

◆ elapsed_sum

double LDGM_session_cpu::elapsed_sum
private

Definition at line 69 of file ldgm-session-cpu.h.

Referenced by LDGM_session_cpu().

◆ no_frames

long LDGM_session_cpu::no_frames
private

Definition at line 70 of file ldgm-session-cpu.h.

Referenced by LDGM_session_cpu(), and decode_frame().


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