63
69
typedef struct setup_s setup_t;
88
void Usage(int argc, char* const argv[], const char *format, ...) {
93
printf("Error %i: ", errno);
104
" -o <file|device> - Output to file/device [/dev/null]\n"
105
" use %%zu to replace with frame number\n"
106
" -f <number> - Number of frames per file [all]\n"
107
" -b size - Buffer Size (MB)\n"
108
" -r rate - Write rate (MB/s)\n"
109
" -s size - Total size of data to write (GB)\n"
110
" -t run_time - Run time (s)\n"
111
" -n frames - Number of frames to write\n"
112
" -g <width>x<height> - Geometry [1024]\n"
113
" -g <pixels> - Number of megapixels [0.7]\n"
114
" -m <percent> - Tolerable missing frames [100%%]\n"
66
124
#ifdef USE_UFO_GENERATOR
67
125
static void handle_error(GError *error) {
68
126
if (error != NULL) {
74
132
#endif /* USE_UFO_GENERATOR */
134
static void set_verbosity(setup_t *setup, int level) {
135
setup->verbose = level;
138
static void set_current_output(setup_t *setup, size_t frame) {
139
sprintf(setup->current_output, setup->output, frame);
142
static void set_output(setup_t *setup, const char *name) {
143
setup->output = name;
145
setup->current_output = malloc(strlen(setup->output) + 32);
146
g_assert(setup->current_output);
147
set_current_output(setup, 0);
77
150
static void set_dim(setup_t *setup, size_t width, size_t height) {
78
151
setup->bpp = sizeof(float);
82
155
setup->frame_size = setup->width * setup->height * setup->bpp;
158
static void set_pixels(setup_t *setup, size_t pixels) {
159
int width = sqrt(4 * pixels / 3);
160
set_dim(setup, width, width * 3 / 4);
85
163
static void set_speed(setup_t *setup, size_t speed) {
86
164
setup->fps = 1 + speed / setup->width / setup->height / setup->bpp;
167
static void set_iters(setup_t *setup, size_t iters) {
168
setup->iters = iters;
171
static void set_time(setup_t *setup, size_t run_time) {
172
setup->iters = run_time * setup->fps;
89
175
static void set_size(setup_t *setup, size_t size) {
90
setup->iters = size / setup->width / setup->height / setup->bpp;
93
static void set_time(setup_t *setup, size_t time) {
94
setup->iters = time * setup->fps;
176
setup->iters = size / setup->frame_size + (size % setup->frame_size)?1:0;
179
static void set_frames_per_file(setup_t *setup, size_t fpf) {
183
static void set_fail_tolerance(setup_t *setup, double fail_rate) {
184
setup->tolerance = fail_rate;
97
188
static int callback(setup_t *s, size_t result, void *buffer);
191
282
size_t duration, last_duration, expected;
285
gettimeofday(&tv, NULL);
195
287
if (!s->broken_frame) {
196
288
err = fastwriter_push(fw, result, buffer);
198
290
if (err == EWOULDBLOCK) {
292
if (s->verbose >= 0) printf("Lost frame...\n");
199
296
if (s->num_read) fastwriter_cancel(fw);
200
297
s->broken_frame = 1;
218
315
err = fastwriter_commit(fw);
222
gettimeofday(&tv, NULL);
318
if ((s->fpf)&&((s->frames%s->fpf) == 0)) {
319
fastwriter_close(s->fw);
320
set_current_output(s, s->frames);
321
err = fastwriter_open(s->fw, s->current_output, FASTWRITER_FLAGS_OVERWRITE);
323
printf("FastWriter returned error %i\n", err);
223
332
if (!s->tv_started.tv_sec) {
224
333
memcpy(&s->tv_started, &tv, sizeof(struct timeval));
225
334
if (s->tv_started.tv_usec >= (1000000 / s->fps))
235
344
if (stats.buffer_used > s->buf_max) s->buf_max = stats.buffer_used;
237
346
if ((tv.tv_sec - s->tv_last_written.tv_sec) >= WRITE_INTERVAL) {
238
last_duration = (tv.tv_sec - s->tv_last_written.tv_sec) * 1000000 + (tv.tv_usec - s->tv_last_written.tv_usec);
240
printf("Lost %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100.*(s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames), s->lost - s->last_lost, s->lost + s->frames - (s->last_lost + s->last_frames), 1. * s->frame_size * (s->frames - s->last_frames) / 1024 / 1024 / 1024, 1000000. * s->frame_size * (s->frames - s->last_frames) / last_duration / 1024 / 1024, 100.*s->buf_max/stats.buffer_size);
347
if ((s->tolerance > 0)&&(s->tolerance < 100)) {
348
double lost = (100. * s->lost / (s->lost + s->frames));
349
double last_lost = (100. * (s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames));
350
if ((lost > s->tolerance)||(last_lost > s->tolerance)) {
352
printf("Lost %.2lf%% (%lu) frames, total: %.2lf%% (%lu)\n", last_lost, s->lost - s->last_lost, lost, s->lost);
357
if (s->verbose >= 0) {
358
last_duration = (tv.tv_sec - s->tv_last_written.tv_sec) * 1000000 + (tv.tv_usec - s->tv_last_written.tv_usec);
359
printf("Lost %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100.*(s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames), s->lost - s->last_lost, s->lost + s->frames - (s->last_lost + s->last_frames), 1. * s->frame_size * (s->frames - s->last_frames) / 1024 / 1024 / 1024, 1000000. * s->frame_size * (s->frames - s->last_frames) / last_duration / 1024 / 1024, 100.*s->buf_max/stats.buffer_size);
242
362
if (((++s->writeouts)%WRITE_SUMMARY)==0) {
243
363
duration = (tv.tv_sec - s->tv_started.tv_sec) * 1000000 + (tv.tv_usec - s->tv_started.tv_usec);
246
366
if ((delta > DELTA_TOLERANCE)||(delta < -DELTA_TOLERANCE))
247
367
printf(" *** Unexpected frame rate: %.2lf (%lu), delta: %li (%lu, %lu)\n", 1000000. * (s->frames + s->lost) / duration, s->fps, delta, s->lost + s->frames, expected);
249
printf("Total %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100. * s->lost / (s->lost + s->frames), s->lost, s->lost + s->frames, 1. * s->frames * s->frame_size / 1024 / 1024 / 1024, 1000000. * s->frames * s->frame_size / duration / 1024 / 1024, 100.*stats.buffer_max / stats.buffer_size);
369
if (s->verbose >= 0) {
370
printf("Total %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100. * s->lost / (s->lost + s->frames), s->lost, s->lost + s->frames, 1. * s->frames * s->frame_size / 1024 / 1024 / 1024, 1000000. * s->frames * s->frame_size / duration / 1024 / 1024, 100.*stats.buffer_max / stats.buffer_size);
296
466
g_assert(!mkfifo(fifo_name, S_IWUSR | S_IRUSR));
297
467
#endif /* USE_FIFO */
299
fw = fastwriter_init(out, FASTWRITER_FLAGS_OVERWRITE);
302
err = fastwriter_open(fw, out, FASTWRITER_FLAGS_OVERWRITE);
470
memset(&setup, 0, sizeof(setup_t));
472
if (quiet) set_verbosity(&setup, -1);
473
set_output(&setup, out);
475
if (mpix) set_pixels(&setup, mpix * 1000000);
476
else set_dim(&setup, width, height);
478
set_speed(&setup, speed * 1024 * 1024);
480
if (size) set_size(&setup, size * 1024 * 1024 * 1024);
481
else if (run_time) set_time(&setup, run_time);
482
else set_iters(&setup, iters);
484
set_fail_tolerance(&setup, fail_rate);
485
set_frames_per_file(&setup, fpf);
488
setup.fw = fastwriter_init(setup.fs, FASTWRITER_FLAGS_OVERWRITE);
492
fastwriter_set_buffer_size(setup.fw, fw_buffer * 1024 * 1024);
494
fastwriter_set_buffer_size(setup.fw, FASTWRITER_BUFFER_MAX);
496
err = fastwriter_open(setup.fw, setup.current_output, FASTWRITER_FLAGS_OVERWRITE);
303
497
if (err) printf("FastWriter returned error %i\n", err);
306
fastwriter_set_buffer_size(fw, FW_BUFFER * 1024 * 1024);
308
fastwriter_get_stats(fw, &stats);
310
memset(&setup, 0, sizeof(setup_t));
313
set_dim(&setup, width, height);
314
set_speed(&setup, speed * 1024 * 1024);
315
set_size(&setup, run_time * speed * 1024 * 1024);
317
printf("*** Writing to %s, rate: %lu, data: %lu MB/s, buffer: %lu MB\n", out, setup.fps, speed, stats.buffer_size);
501
fastwriter_get_stats(setup.fw, &stats);
503
printf("*** Writing to %s, rate: %lu, data: %lu MB/s, buffer: %lu MB\n", out, setup.fps, speed, stats.buffer_size/1024/1024);
319
505
void *buffer = malloc(setup.frame_size);
320
506
g_assert(buffer);