static int video_do_capture(struct device *dev, unsigned int nframes, unsigned int skip, unsigned int delay, const char *filename_prefix, int do_requeue_last) { char *filename = NULL; struct timeval start = { 0, 0 }; struct timeval end, ts; struct v4l2_buffer buf; unsigned int size; unsigned int i; FILE *file; double bps; double fps; int ret; if (filename_prefix != NULL) { filename = malloc(strlen(filename_prefix) + 12); if (filename == NULL) return -ENOMEM; } /* Start streaming. */ video_enable(dev, 1); size = 0; for (i = 0; i < nframes; ++i) { /* Dequeue a buffer. */ memset(&buf, 0, sizeof buf); buf.type = dev->type; buf.memory = dev->memtype; ret = ioctl(dev->fd, VIDIOC_DQBUF, &buf); if (ret < 0) { if (errno != EIO) { printf("Unable to dequeue buffer (%d).\n", errno); goto done; } buf.type = dev->type; buf.memory = dev->memtype; if (dev->memtype == V4L2_MEMORY_USERPTR) buf.m.userptr = (unsigned long)dev->buffers[i].mem; } if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->imagesize != 0 && buf.bytesused != dev->imagesize) printf("Warning: bytes used %u != image size %u\n", buf.bytesused, dev->imagesize); size += buf.bytesused; gettimeofday(&ts, NULL); printf("%u (%u) [%c] %u %u bytes %ld.%06ld %ld.%06ld\n", i, buf.index, (buf.flags & V4L2_BUF_FLAG_ERROR) ? 'E' : '-', buf.sequence, buf.bytesused, buf.timestamp.tv_sec, buf.timestamp.tv_usec, ts.tv_sec, ts.tv_usec); if (i == 0) start = ts; /* Save the image. */ if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && filename_prefix && !skip) { sprintf(filename, "%s-%06u.bin", filename_prefix, i); file = fopen(filename, "wb"); if (file != NULL) { ret = fwrite(dev->buffers[buf.index].mem, buf.bytesused, 1, file); fclose(file); } } if (skip) --skip; /* Requeue the buffer. */ if (delay > 0) usleep(delay * 1000); fflush(stdout); if (i == nframes - dev->nbufs && !do_requeue_last) continue; ret = video_queue_buffer(dev, buf.index); if (ret < 0) { printf("Unable to requeue buffer (%d).\n", errno); goto done; } } gettimeofday(&end, NULL); /* Stop streaming. */ video_enable(dev, 0); if (nframes == 0) { printf("No frames captured.\n"); goto done; } if (end.tv_sec == start.tv_sec && end.tv_usec == start.tv_usec) goto done; end.tv_sec -= start.tv_sec; end.tv_usec -= start.tv_usec; if (end.tv_usec < 0) { end.tv_sec--; end.tv_usec += 1000000; } bps = size/(end.tv_usec+1000000.0*end.tv_sec)*1000000.0; fps = (i-1)/(end.tv_usec+1000000.0*end.tv_sec)*1000000.0; printf("Captured %u frames in %lu.%06lu seconds (%f fps, %f B/s).\n", i-1, end.tv_sec, end.tv_usec, fps, bps); done: free(filename); return video_free_buffers(dev); }
int video_do_capture(struct device *dev, unsigned int nframes, unsigned int skip, unsigned int delay, const char *pattern, int do_requeue_last, enum buffer_fill_mode fill) { struct timespec start; struct timeval last; struct timespec ts; struct v4l2_buffer buf; unsigned int size; unsigned int i; double bps; double fps; int ret; /* Start streaming. */ ret = video_enable(dev, 1); if (ret < 0) goto done; size = 0; clock_gettime(CLOCK_MONOTONIC, &start); last.tv_sec = start.tv_sec; last.tv_usec = start.tv_nsec / 1000; for (i = 0; i < nframes; ++i) { /* Dequeue a buffer. */ memset(&buf, 0, sizeof buf); buf.type = dev->type; buf.memory = dev->memtype; ret = ioctl(dev->fd, VIDIOC_DQBUF, &buf); if (ret < 0) { if (errno != EIO) { printf("Unable to dequeue buffer: %s (%d).\n", strerror(errno), errno); goto done; } buf.type = dev->type; buf.memory = dev->memtype; if (dev->memtype == V4L2_MEMORY_USERPTR) buf.m.userptr = (unsigned long)dev->buffers[i].mem; } if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->imagesize != 0 && buf.bytesused != dev->imagesize) printf("Warning: bytes used %u != image size %u\n", buf.bytesused, dev->imagesize); if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) video_verify_buffer(dev, buf.index); size += buf.bytesused; fps = (buf.timestamp.tv_sec - last.tv_sec) * 1000000 + buf.timestamp.tv_usec - last.tv_usec; fps = fps ? 1000000.0 / fps : 0.0; clock_gettime(CLOCK_MONOTONIC, &ts); printf("%u (%u) [%c] %u %u bytes %ld.%06ld %ld.%06ld %.3f fps\n", i, buf.index, (buf.flags & V4L2_BUF_FLAG_ERROR) ? 'E' : '-', buf.sequence, buf.bytesused, buf.timestamp.tv_sec, buf.timestamp.tv_usec, ts.tv_sec, ts.tv_nsec/1000, fps); last = buf.timestamp; /* Save the image. */ if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pattern && !skip) video_save_image(dev, &buf, pattern, i); if (skip) --skip; /* Requeue the buffer. */ if (delay > 0) usleep(delay * 1000); fflush(stdout); if (i == nframes - dev->nbufs && !do_requeue_last) continue; ret = video_queue_buffer(dev, buf.index, fill); if (ret < 0) { printf("Unable to requeue buffer: %s (%d).\n", strerror(errno), errno); goto done; } } /* Stop streaming. */ video_enable(dev, 0); if (nframes == 0) { printf("No frames captured.\n"); goto done; } if (ts.tv_sec == start.tv_sec && ts.tv_nsec == start.tv_nsec) goto done; ts.tv_sec -= start.tv_sec; ts.tv_nsec -= start.tv_nsec; if (ts.tv_nsec < 0) { ts.tv_sec--; ts.tv_nsec += 1000000000; } bps = size/(ts.tv_nsec/1000.0+1000000.0*ts.tv_sec)*1000000.0; fps = i/(ts.tv_nsec/1000.0+1000000.0*ts.tv_sec)*1000000.0; printf("Captured %u frames in %lu.%06lu seconds (%f fps, %f B/s).\n", i, ts.tv_sec, ts.tv_nsec/1000, fps, bps); done: return video_free_buffers(dev); }