UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
ldgm-session.cpp
Go to the documentation of this file.
1/*
2 * =====================================================================================
3 *
4 * Filename: ldgm-session.cpp
5 *
6 * Description:
7 *
8 * Version: 1.0
9 * Created: 04/12/2012 01:03:23 PM
10 * Revision: none
11 * Compiler: gcc
12 *
13 * Author: Milan Kabat (), kabat@ics.muni.cz
14 * Organization:
15 *
16 * =====================================================================================
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <map>
22#include <sstream>
23#include <string>
24#include <string.h>
25#include "ldgm-session.h"
26#include "timer-util.h"
27
28constexpr const int MAX_W = 128;
29
30using namespace std;
31
32/*
33 *--------------------------------------------------------------------------------------
34 * Class: LDGM_session
35 * Method: LDGM_session
36 * Description: constructor
37 *--------------------------------------------------------------------------------------
38 */
39void
41{
42 FILE *f;
43
44 f = fopen(fname, "rb");
45 if (!f)
46 {
47 printf ( "Error opening matrix file\n" );
48 printf ( "exiting\n" );
49 abort();
50 }
51 unsigned int k_f, m_f, w_f;
52 if (fscanf(f, "%d %d %d", &k_f, &m_f, &w_f) != 3) {
53 throw string("Parity matrix read error!");
54 }
55// printf ( "In matrix file: K %d M %d Columns %d\n", k_f, m_f, w_f );
56
57 if (w_f < 2 || w_f > MAX_W) {
58 throw string("Invalid parameter in parity matrix (allowed range [2.." + to_string(MAX_W) + "])!");
59 }
60
61 if ( k_f != param_k || m_f != param_m)
62 {
63 ostringstream oss;
64 oss << "Parity matrix size mismatch\nExpected K = " << param_k << "% M = " << param_m <<
65 "\nReceived K = " << k_f << ", M = " << m_f << "\n";
66 throw oss.str();
67 }
68 if (fseek (f, 1, SEEK_CUR ) != 0) {
69 perror("fseek");
70 }
71
72 pcm = (int*) malloc(w_f*param_m*sizeof(int));
73 for ( int i = 0; i < (int)w_f*param_m; i++) {
74 if (fread ( pcm+i, sizeof(int), 1, f) != 1) {
75 throw string("Parity matrix read error!");
76 }
77 }
78 this->max_row_weight = w_f - 2; //w_f stores number of columns in adjacency list
79
80 /* for ( int i = 0; i < param_m; i++)
81 * {
82 * for ( int j = 0; j < w_f; j++)
83 * printf ( "[%3d]", (unsigned int)(pcm[i*w_f+j]) );
84 * printf ( "\n" );
85 * }
86 */
87
88
89
90
91 fclose(f);
92
93
94
95 /*
96 * this->max_row_weight = 0;
97 * int max_weight = 0;
98 * for ( int i = 0; i < param_m; ++i) {
99 * for ( int j = 0; j < param_k; ++j) {
100 * if(*(matrix + i*param_k + j) == 1) {
101 * *(pcMatrix + i*param_k + j) = *(matrix + i*param_k + j);
102 * max_weight++;
103 * }
104 * }
105 * if ( max_weight > this->max_row_weight )
106 * this->max_row_weight = max_weight;
107 * max_weight = 0;
108 * }
109 *
110 * pcm = (int*) malloc (m*(max_row_weight+2)*sizeof(int*));
111 * struct coding_params params;
112 * params.m = m;
113 * params.k = k;
114 * params.max_row_weight = max_row_weight;
115 *
116 * make_compact_pcm ( matrix, pcm, params);
117 */
118
119
120 return ;
121} /* ----- end of method Coding_session::set_pcMatrix ----- */
122
123char*
124LDGM_session::encode_frame ( char* frame, int frame_size, int* out_buf_size )
125{
126 //printf("encode_frame\n");
127 Timer_util interval;
128 interval.start();
129
130 int buf_size;
131 int ps;
132 short header_size = LDGM_session::HEADER_SIZE;
133 int align_coef = param_k*sizeof(int);
134
135 if ( (frame_size + header_size) % align_coef == 0 )
136 buf_size = frame_size + header_size;
137 else
138 buf_size = ( ( (frame_size + header_size) / align_coef ) + 1 ) * align_coef;
139
140 ps = buf_size/param_k;
141
142 packet_size = ps;
143 //printf ( "ps: %d\n", ps );
144 buf_size += param_m*ps;
145 *out_buf_size = buf_size;
146
147 void *out_buf;
148 out_buf = alloc_buf(buf_size);
149 if (!out_buf)
150 {
151 printf ( "Unable to allocate memory\n" );
152 return NULL;
153 }
154 memset(out_buf, 0, header_size);
155 memset((char*)out_buf + frame_size + header_size, 0, align_coef);
156
157 //Insert frame size and copy input data into buffer
158
159 int *hdr = (int*)out_buf;
160 *hdr = frame_size;
161
162 memcpy( ((char*)out_buf) + header_size, frame, frame_size);
163
164 //Timer_util t;
165 //printf("2buf_size %d\n",buf_size);
166 //printf("2packet_size %d\n",packet_size);
167 this->encode ( (char*)out_buf, ((char*)out_buf)+param_k*ps );
168
169
170 interval.end();
171 // printf("time: %e\n",elapsed/1000.0 );
172 this->elapsed_sum2 += interval.elapsed_time_ms();
173 this->no_frames2++;
174
175 return (char*)out_buf;
176
177// printf ( "SSE: %.3lf\n", t.elapsed_time(start, end) );
178
179 /* void *out_buf_check;
180 * error = posix_memalign(&out_buf_check, 16, buf_size);
181 * memset(out_buf_check, 0, buf_size);
182 * hdr = (int*)out_buf_check;
183 * *hdr = frame_size;
184 * memcpy(((char*)out_buf_check)+header_size, frame, frame_size);
185 * clock_gettime(CLOCK_MONOTONIC, &start);
186 * encode_naive ( (char*)out_buf, ((char*)out_buf_check)+param_k*ps );
187 * clock_gettime(CLOCK_MONOTONIC, &end);
188 * printf ( "CPU: %.3lf\n", t.elapsed_time(start, end) );
189 *
190 * int e = memcmp(out_buf, out_buf_check, buf_size);
191 * printf ( "memcpy on parities: %d\n", e );
192 * char *a = (char*)out_buf;
193 * char *b = (char*)out_buf_check;
194 * bool equal = true;
195 * int idx = 0;
196 * for ( int i = 0; i < param_m*ps; i++)
197 * {
198 * if(a[i] != b[i])
199 * {
200 * idx = i;
201 * printf ( "Error at index %d: %d vs %d\n", i, (unsigned char)a[i],
202 * (unsigned char)b[i] );
203 * equal = false;
204 * }
205 * }
206 *
207 * printf ( "Parities %s match.\n", (equal)?"":"do not" );
208 */
209
210// printf ( "\n\nEncoded block:\n" );
211// printf ( "%-13s\v%10d B\n", "Frame hdr size:", header_size );
212// printf ( "%-13s\v%10d B\n", "Frame size:", frame_size );
213// printf ( "Padding size:\t%-d B\n", buf_size-frame_size-header_size-param_m*ps );
214// printf ( "Parity size:\t%-d B\n", param_m*ps );
215// printf ( "-------------------------------\n");
216// printf ( "Total block size:\t%d B\n", buf_size );
217// printf ( "Symbol size:\t%d\n\n\n", ps );
218
219
220
221
222}
223
224char*
225LDGM_session::encode_hdr_frame ( char *my_hdr, int my_hdr_size, char* frame, int frame_size, int* out_buf_size )
226{
227 int buf_size;
228 int ps;
229 short header_size = LDGM_session::HEADER_SIZE;
230 int overall_size = my_hdr_size + frame_size;
231 int align_coef = param_k*sizeof(int);
232
233 if ( (overall_size + header_size) % align_coef == 0 )
234 buf_size = overall_size + header_size;
235 else
236 buf_size = ( ( (overall_size + header_size) / align_coef ) + 1 ) * align_coef;
237
238 ps = buf_size/param_k;
239
240 packet_size = ps;
241// printf ( "ps: %d\n", ps );
242 buf_size += param_m*ps;
243 *out_buf_size = buf_size;
244
245 void *out_buf;
246 out_buf = alloc_buf(buf_size);
247 if (!out_buf)
248 {
249 printf ( "Unable to allocate aligned memory\n" );
250 return NULL;
251 }
252 memset(out_buf, 0, buf_size);
253
254 //Insert frame size and copy input data into buffer
255
256 int32_t *hdr = (int32_t*)out_buf;
257 *hdr = overall_size;
258
259 memcpy( ((char*)out_buf) + header_size, my_hdr, my_hdr_size);
260 memcpy( ((char*)out_buf) + header_size + my_hdr_size, frame, frame_size);
261
262#if 0
263 int my_frame_size=my_hdr_size+frame_size;
264
265 // printf("my_frame_size: %d\n",my_frame_size );
266
267 int crc;
268 crc = crc32buf((char*)out_buf+header_size,my_frame_size);
269
270 memcpy( ((char*)out_buf) + 4, &crc, 4);
271 memcpy( ((char*)out_buf) + 8, &my_frame_size, 4);
272 assert(LDGM_session::HEADER_SIZE >= 12);
273#endif
274
275 Timer_util interval;
276 interval.start();
277
278 this->encode ( (char*)out_buf, ((char*)out_buf)+param_k*ps );
279
280 interval.end();
281 long elapsed;
282
283 elapsed = interval.elapsed_time_us();
284 // printf("time: %e\n",elapsed/1000.0 );
285 this->elapsed_sum2+=elapsed/1000.0;
286 this->no_frames2++;
287
288
289 // gettimeofday(&t1,0);
290 // long elapsed;
291
292 // elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec;
293 // // printf("time: %e\n",elapsed/1000.0 );
294 // this->elapsed_sum2+=elapsed/1000.0;
295 // this->no_frames2++;
296 // i++;
297
298 // if(i%100==0){
299 // printf("TIME GPU: %f ms\n",this->elapsed_sum2/(double)this->no_frames2 );
300 // printf("time: %f ms\n",elapsed/1000.0 );
301 // }
302
303// printf ( "SSE: %.3lf\n", t.elapsed_time(start, end) );
304
305 /* void *out_buf_check;
306 * error = posix_memalign(&out_buf_check, 16, buf_size);
307 * memset(out_buf_check, 0, buf_size);
308 * hdr = (int*)out_buf_check;
309 * *hdr = frame_size;
310 * memcpy(((char*)out_buf_check)+header_size, frame, frame_size);
311 * clock_gettime(CLOCK_MONOTONIC, &start);
312 * encode_naive ( (char*)out_buf, ((char*)out_buf_check)+param_k*ps );
313 * clock_gettime(CLOCK_MONOTONIC, &end);
314 * printf ( "CPU: %.3lf\n", t.elapsed_time(start, end) );
315 *
316 * int e = memcmp(out_buf, out_buf_check, buf_size);
317 * printf ( "memcpy on parities: %d\n", e );
318 * char *a = (char*)out_buf;
319 * char *b = (char*)out_buf_check;
320 * bool equal = true;
321 * int idx = 0;
322 * for ( int i = 0; i < param_m*ps; i++)
323 * {
324 * if(a[i] != b[i])
325 * {
326 * idx = i;
327 * printf ( "Error at index %d: %d vs %d\n", i, (unsigned char)a[i],
328 * (unsigned char)b[i] );
329 * equal = false;
330 * }
331 * }
332 *
333 * printf ( "Parities %s match.\n", (equal)?"":"do not" );
334 */
335
336// printf ( "\n\nEncoded block:\n" );
337// printf ( "%-13s\v%10d B\n", "Frame hdr size:", header_size );
338// printf ( "%-13s\v%10d B\n", "Frame size:", frame_size );
339// printf ( "Padding size:\t%-d B\n", buf_size-frame_size-header_size-param_m*ps );
340// printf ( "Parity size:\t%-d B\n", param_m*ps );
341// printf ( "-------------------------------\n");
342// printf ( "Total block size:\t%d B\n", buf_size );
343// printf ( "Symbol size:\t%d\n\n\n", ps );
344
345
346 return (char*)out_buf;
347
348}
349
350/*
351 * === FUNCTION ======================================================================
352 * Name: create_edges
353 * Description:
354 * =====================================================================================
355 */
356void
358{
359// printf ( "graph: %p, param_k: %d, param_m: %d\n", graph, param_k, param_m );
360 for ( int m = 0; m < param_m; ++m) {
361 for ( int k = 0; k < max_row_weight+2; ++k ) {
362 int idx = pcm [ m*(max_row_weight+2) + k];
363 if( idx > -1 ) {
364 auto &node = graph->nodes.at(idx);
365 node.neighbours.push_back(param_k + param_m + m);
366 auto &n2 = graph->nodes.at(param_k + param_m + m);
367 n2.neighbours.push_back(idx);
368 }
369 }
370 }
371 /* it = graph->nodes.find(0);
372 * while ( it != graph->nodes.end() )
373 * {
374 * printf ( "\nneighbours of node %d: ", it->first );
375 * for (vector<int>::iterator i = it->second.neighbours.begin();
376 * i != it->second.neighbours.end(); ++i)
377 * printf ( "%d, ", *i );
378 * it++;
379 * }
380 */
381
382 //add edges representing the staircase matrix
383 /* for ( int i = param_k + param_m; i < param_k + 2*param_m; ++i) {
384 * it = graph->nodes.find(i);
385 * (*it).second.neighbours.push_back(i - param_m);
386 * it = graph->nodes.find(i - param_m);
387 * (*it).second.neighbours.push_back(i);
388 * if(i > param_m + param_k) {
389 * it = graph->nodes.find(i);
390 * (*it).second.neighbours.push_back(i - param_m - 1);
391 * it = graph->nodes.find(i - param_m - 1);
392 * (*it).second.neighbours.push_back(i);
393 * }
394 * }
395 */
396 return ;
397} /* ----- end of function create_edges ----- */
398
399bool
401{
402 for ( int i = 0; i < param_k; i++)
403 if( ! graph->nodes.at(i).isDone() ) {
404 return true;
405 }
406 return false;
407} /* ----- end of method LDGM_session::needs_decoding ----- */
408
409
struct video_frame * frame
static const int HEADER_SIZE
unsigned short param_m
virtual void * alloc_buf(int size)=0
double elapsed_sum2
void set_pcMatrix(char *matrix)
virtual void encode(char *data, char *parity)=0
bool needs_decoding(Tanner_graph *tanner_graph)
unsigned short max_row_weight
char * encode_frame(char *frame, int frame_size, int *out_buf_size)
unsigned short param_k
char * encode_hdr_frame(char *hdr, int hdr_size, char *frame, int frame_size, int *out_buf_size)
unsigned short packet_size
virtual ~LDGM_session()
void create_edges(Tanner_graph *g)
std::map< int, Node > nodes
Definition tanner.h:145
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
long elapsed_time_us() const
Definition timer-util.h:58
uint32_t crc32buf(const char *buf, size_t len)
Definition crc_32.c:176
constexpr const int MAX_W