2 #define _POSIX_C_SOURCE 200809L
14 int main(int argc, char *argv[]) {
15 static const struct option longopts[] = {
16 {"verify", 0, NULL, 'v'},
17 {"rate", 1, NULL, 'r'},
18 {"fps", 1, NULL, 'f'},
19 {"total", 1, NULL, 't'},
27 float total = 1.0 / 0.0;
29 while((opt = getopt_long(argc, argv, "vr:f:t:", longopts, &optind)) != -1) {
48 fprintf(stderr, "Usage: %s [-v] [-r bitrate] [-f frames_per_second]\n", argv[0]);
53 size_t framesize = rate / fps / 8;
55 long interval = 1e9 / fps;
57 if(!framesize || interval <= 0) {
58 err(1, "invalid parameters");
61 char *buf = malloc(framesize + 16);
64 err(1, "malloc(%zu)", framesize);
68 struct timespec now, next = {0};
69 clock_gettime(CLOCK_REALTIME, &now);
73 size_t tosend = framesize;
76 memcpy(buf, &now, sizeof(now));
77 clock_gettime(CLOCK_REALTIME, &now);
79 for(uint64_t *q = (uint64_t *)(buf + sizeof(now)); (char *)q < buf + framesize; q++) {
84 ssize_t sent = write(1, p, tosend);
87 err(1, "write(1, %p, %zu)", (void *)p, tosend);
95 next.tv_nsec = interval;
97 while(next.tv_nsec >= 1000000000) {
98 next.tv_nsec -= 1000000000;
102 nanosleep(&next, NULL);
105 struct timespec *ts = (struct timespec *)buf;
106 size_t toread = sizeof(*ts);
110 ssize_t result = read(0, p, toread);
113 err(1, "read(1, %p, %zu)", (void *)p, toread);
120 clock_gettime(CLOCK_REALTIME, &now);
122 toread = framesize - sizeof(now);
125 ssize_t result = read(0, p, toread);
128 err(1, "read(1, %p, %zu)", (void *)p, toread);
135 clock_gettime(CLOCK_REALTIME, &next);
137 for(uint64_t *q = (uint64_t *)(buf + sizeof(now)); (char *)q < buf + framesize; q++) {
138 if(*q != counter++) {
139 uint64_t offset = (counter - 1) * 8;
140 offset += ((counter * 8) / (framesize - sizeof(now))) * sizeof(now);
141 err(1, "verification failed at offset %lu", (unsigned long)offset);
145 float dt1 = now.tv_sec - ts->tv_sec + 1e-9 * (now.tv_nsec - ts->tv_nsec);
146 float dt2 = next.tv_sec - now.tv_sec + 1e-9 * (next.tv_nsec - now.tv_nsec);
148 fprintf(stderr, "\rDelay: %8.3f ms, burst bandwidth: %8.0f Mbit/s", dt1 * 1e3, (framesize - sizeof(now)) / dt2 * 8 / 1e6);
155 fprintf(stderr, "\n");