13 int main(int argc, char *argv[]) {
14 static const struct option longopts[] = {
15 {"verify", 0, NULL, 'v'},
16 {"rate", 1, NULL, 'r'},
17 {"fps", 1, NULL, 'f'},
18 {"total", 1, NULL, 't'},
26 float total = 1.0 / 0.0;
28 while((opt = getopt_long(argc, argv, "vr:f:t:", longopts, &optind)) != -1) {
47 fprintf(stderr, "Usage: %s [-v] [-r bitrate] [-f frames_per_second]\n", argv[0]);
52 size_t framesize = rate / fps / 8;
54 long interval = 1e9 / fps;
56 if(!framesize || interval <= 0) {
57 err(1, "invalid parameters");
60 char *buf = malloc(framesize + 16);
63 err(1, "malloc(%zu)", framesize);
67 struct timespec now, next = {0};
68 clock_gettime(CLOCK_REALTIME, &now);
72 size_t tosend = framesize;
75 memcpy(buf, &now, sizeof(now));
76 clock_gettime(CLOCK_REALTIME, &now);
78 for(uint64_t *q = (uint64_t *)(buf + sizeof(now)); (char *)q < buf + framesize; q++) {
83 ssize_t sent = write(1, p, tosend);
86 err(1, "write(1, %p, %zu)", (void *)p, tosend);
94 next.tv_nsec = interval;
96 while(next.tv_nsec >= 1000000000) {
97 next.tv_nsec -= 1000000000;
101 nanosleep(&next, NULL);
104 struct timespec *ts = (struct timespec *)buf;
105 size_t toread = sizeof(*ts);
109 ssize_t result = read(0, p, toread);
112 err(1, "read(1, %p, %zu)", (void *)p, toread);
119 clock_gettime(CLOCK_REALTIME, &now);
121 toread = framesize - sizeof(now);
124 ssize_t result = read(0, p, toread);
127 err(1, "read(1, %p, %zu)", (void *)p, toread);
134 clock_gettime(CLOCK_REALTIME, &next);
136 for(uint64_t *q = (uint64_t *)(buf + sizeof(now)); (char *)q < buf + framesize; q++) {
137 if(*q != counter++) {
138 uint64_t offset = (counter - 1) * 8;
139 offset += ((counter * 8) / (framesize - sizeof(now))) * sizeof(now);
140 err(1, "verification failed at offset %lu", (unsigned long)offset);
144 float dt1 = now.tv_sec - ts->tv_sec + 1e-9 * (now.tv_nsec - ts->tv_nsec);
145 float dt2 = next.tv_sec - now.tv_sec + 1e-9 * (next.tv_nsec - now.tv_nsec);
147 fprintf(stderr, "\rDelay: %8.3f ms, burst bandwidth: %8.0f Mbit/s", dt1 * 1e3, (framesize - sizeof(now)) / dt2 * 8 / 1e6);
154 fprintf(stderr, "\n");