/* vector.c */ #include "videoport.h" int main(int argc, char **argv) { videoport p; int direction = (tolower(*argv[1]) == 'v') ? VIDEOPORT_DIRECTION_VM : VIDEOPORT_DIRECTION_MV; char *filename = argv[2]; int issue_count; diskperformance diskperf = diskperformance_open(); int fd; int nbytes, totalbytes; struct dioattr dioinfo; int vector_chunksize; int vector_memalign; int nvectors = 10; /* number of fields per readv/writev */ videofield **fields; struct iovec *vectors; NC(p = videoport_open(direction, 30, VIDEOPORT_ADVISE_NOACCESS)); NC(fields = malloc(nvectors * sizeof(videofield *))); NC(vectors = malloc(nvectors * sizeof(struct iovec))); if (direction == VIDEOPORT_DIRECTION_VM) { printf("writing input video to file %s\n", filename); OC(fd = open(filename, O_RDWR|O_TRUNC|O_CREAT|O_DIRECT, 0644)); } else /* direction == VIDEOPORT_DIRECTION_MV */ { printf("reading video from file %s for output\n", filename); OC(fd = open(filename, O_RDONLY|O_DIRECT, 0644)); } nbytes = p->max_valid_bytes_per_field; totalbytes = nbytes * nvectors; /* get direct I/O constraints for this fd */ OC(fcntl(fd, F_DIOINFO, &dioinfo)); vector_chunksize = max(dioinfo.d_miniosz, getpagesize()); vector_memalign = max(dioinfo.d_mem, getpagesize()); assert(totalbytes >= vector_chunksize); assert(totalbytes <= dioinfo.d_maxiosz); assert((nbytes % vector_chunksize) == 0); issue_count = 0; diskperformance_datapoint(diskperf, 0, p); for(;;) { int i, rc; for(i=0; i < nvectors; i++) { videoport_wait_for_space_or_data(p); fields[i] = videoport_get_one_field(p); assert((((uintptr_t)fields[i]->pixels) % vector_memalign) == 0); vectors[i].iov_base = fields[i]->pixels; vectors[i].iov_len = nbytes; } if (direction == VIDEOPORT_DIRECTION_VM) { OC(rc = writev(fd, vectors, nvectors)); } else { OC(rc = readv(fd, vectors, nvectors)); } if (rc != totalbytes) error_exit("EOF or out of disk space"); ++issue_count; diskperformance_datapoint(diskperf, ((off64_t)issue_count) * totalbytes, p); for(i=0; i < nvectors; i++) { videoport_put_one_field(p, fields[i]); } } }