73using std::ostringstream;
74using std::setprecision;
79#define MOD_NAME "[ldgm] "
102 std::numeric_limits<double>::min(),
108#define JPEG60_SIZE (144 * 1000)
109#define JPEG80_SIZE (177 * 1000)
110#define JPEG90_SIZE (217 * 1000)
112#define UNCOMPRESSED_SIZE (1920 * 1080 * 2)
138#define MINIMAL_VALUE 64
145#define MAX_K (1<<13) - 1
148static void usage(
void);
153 if (stat(filename, &sb)) {
176 TCHAR tmpPath[MAX_PATH];
177 UINT ret = GetTempPath(MAX_PATH, tmpPath);
178 if(ret == 0 || ret > MAX_PATH) {
179 fprintf(stderr,
"Unable to get temporary directory name.\n");
182 snprintf(path, 256,
"%s\\ultragrid\\", tmpPath);
184 snprintf(path, 256,
"/var/tmp/ultragrid-%d/", (
int) getuid());
187 res = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
189 if(errno != EEXIST) {
191 fprintf(stderr,
"[LDGM] Unable to create data directory.\n");
195 snprintf(filename, 512,
"%s/ldgm_matrix-%u-%u-%u-%u.bin", path, k, m, c, seed);
199 fprintf(stderr,
"[LDGM] Unable to initialize LDGM matrix.\n");
206 MSG(INFO,
"Using LDGM with k=%u m=%u c=%u\n",
m_k,
m_m,
m_c);
210 " specify whether use CPU or GPU for LDGM\n");
212void ldgm::init(
unsigned int k,
unsigned int m,
unsigned int c,
unsigned int seed)
214 bool ldgm_device_gpu =
false;
220 if (ldgm_device_gpu) {
227 throw string(
"GPU accelerated LDGM support is not compiled in");
239ldgm::ldgm(
unsigned int k,
unsigned int m,
unsigned int c,
unsigned int seed)
244bool ldgm::decode(
char *
frame,
int size,
char **out,
int *out_size,
const map<int, int> &packets) {
261 printf(
"\nwhere:\n");
263 "\t" TBOLD(
"<k>")
" - matrix width\n"
264 "\t" TBOLD(
"<m>")
" - matrix height\n"
265 "\t" TBOLD(
"<c>")
" - number of ones per column\n"
266 "\t\tthe bigger ratio m/k, the better correction (but also "
267 "needed bandwidth)\n"
268 "\t\tk,m should be in interval [%d, %d]; c in [%d, %d]\n"
269 "\t\tdefault: k = %d, m = %d, c = %d\n"
270 "\t" TBOLD(
"<expected_loss>")
" - expected maximal loss "
271 TBOLD(
"per frame")
" in percent\n"
272 "\t\t(including '%%'-sign)¹\n"
277 "¹ Please note that there are only a few presets for FullHD "
279 "that will work correctly for JPEG and uncompressed, see wiki:\n"
280 "<https://github.com/CESNET/UltraGrid/wiki/FEC-Settings#ldgm>\n\n");
288 if(cfg && strlen(cfg) > 0) {
289 if(strcasecmp(cfg,
"help") == 0) {
293 char *save_ptr = NULL;
295 char *tmp = strdup(cfg);
296 item = strtok_r(tmp,
":", &save_ptr);
300 item = strtok_r(NULL,
":", &save_ptr);
303 item = strtok_r(NULL,
":", &save_ptr);
308 throw string(
"[LDGM] Was set k value but not m.");
313 if(c < MIN_C || c >
MAX_C) {
315 oss <<
"[LDGM] C value shoud be inside interval [" <<
MIN_C <<
", " <<
MAX_C <<
"]";
321 oss <<
"[LDGM] K value exceeds maximal value " <<
MAX_K;
327 oss <<
"[LDGM] Either k or m is lower than minimal value " <<
MINIMAL_VALUE;
331 printf(
"[LDGM] Using values k = %u, m = %u, c = %u.\n", k, m, c);
336ldgm::ldgm(
int packet_size,
int frame_size,
double max_expected_loss)
339 int nearest = INT_MAX;
343 assert(max_expected_loss >= 0.0 && max_expected_loss <= 100.0);
346 throw string(
"LDGM: with frames smaller than 2M you should use standard Ethernet frames.");
355 for(
unsigned int i = 1; i <
sizeof(
losses) /
sizeof(
loss_t); ++i) {
356 if(max_expected_loss >=
losses[i - 1] && max_expected_loss <=
losses[i]) {
364 oss <<
"LDGM: Cannot provide predefined settings for correction of loss of " << setprecision(2)
365 << max_expected_loss << endl <<
366 "LDGM: You have to try and set LDGM parameters manually. You can inform us if you need better protection.";
370 printf(
"LDGM: Choosing maximal loss %2.2f percent.\n",
loss);
384 if (nearest == INT_MAX) {
385 throw string(
"LDGM: Could not find matching configuration for your request.\n"
386 "Please, set LDGM parameters manually.");
389 double difference_from_frame_size =
abs(nearest - frame_size) / (double) frame_size;
390 if(difference_from_frame_size > 0.2) {
391 LOG(
LOG_LEVEL_WARNING) <<
"LDGM: Chosen LDGM setting for frame size that is " << difference_from_frame_size * 100.0 <<
"% " << (nearest - frame_size > 0 ?
"higher" :
"lower") <<
" than your frame size.\n";
395 if(difference_from_frame_size > 0.5) {
405 enum { SHMEM_SIZE = 48 * 1024 };
406 static bool printed =
false;
410 const size_t packet_size =
len / k + 4;
411 if (packet_size < SHMEM_SIZE) {
417 if (dev ==
nullptr|| strcasecmp(dev,
"GPU") != 0) {
421 "Packet size is %zu B, which may exceed GPU memory, which is "
422 "usually %d.\nYou can try to increase the parameter K.\n",
423 packet_size, SHMEM_SIZE);
434 for (unsigned int i = 0; i < frame->tile_count; ++i) {
435 coding_session->free_out_buf(frame->tiles[i].data);
440 for (
unsigned int i = 0; i < tx_frame->tile_count; ++i) {
447 char *output = m_coding_session->encode_hdr_frame((
char *) video_hdr,
sizeof(video_hdr),
448 tx_frame->tiles[i].data, tx_frame->tiles[i].data_len, &out_size);
450 out->tiles[i].data = output;
451 out->tiles[i].data_len = out_size;
455 out->fec_params.k = m_k;
456 out->fec_params.m = m_m;
457 out->fec_params.c = m_c;
458 out->fec_params.seed = m_seed;
459 out->fec_params.symbol_size = m_coding_session->get_packet_size();
struct video_frame * frame
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.
int color_printf(const char *format,...)
static __device__ vec2 abs(const vec2 &v)
#define LOG_LEVEL_WARNING
less severe errors
const char * get_commandline_param(const char *key)
#define ADD_TO_PARAM(param, doc)
#define UNCOMPRESSED_SIZE
static void check_packet_size(size_t len, int k)
const configuration_t suggested_configurations[]
static bool file_exists(char *filename)
#define LDGM_GPU_API_VERSION
const void * load_library(const char *name, enum library_class cls, int abi_version)
@ LIBRARY_CLASS_UNDEFINED
int generate_ldgm_matrix(char *fname, unsigned int k, unsigned int m, unsigned int column_weight, unsigned int seed, unsigned int extend_rows)
uint32_t video_payload_hdr_t[6]
packet_type_t packet_type
std::shared_ptr< video_frame > encode(std::shared_ptr< video_frame >)
void init(unsigned int k, unsigned int m, unsigned int c, unsigned int seed=DEFAULT_LDGM_SEED)
std::shared_ptr< LDGM_session > m_coding_session
bool decode(char *in, int in_len, char **out, int *len, const std::map< int, int > &)
ldgm(unsigned int k, unsigned int m, unsigned int c, unsigned int seed)
void set_params(unsigned int k, unsigned int m, unsigned int c, unsigned int seed)
Struct video_frame represents a video frame and contains video description.
static struct @51 loss[MAX_HISTORY]
void format_video_header(struct video_frame *frame, int tile_idx, int buffer_idx, uint32_t *video_hdr)
This is an umbrella header for video functions.