summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yavta.c118
1 files changed, 72 insertions, 46 deletions
diff --git a/yavta.c b/yavta.c
index b4ff34b..7dcec8e 100644
--- a/yavta.c
+++ b/yavta.c
@@ -77,8 +77,8 @@ struct device
unsigned char num_planes;
struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES];
- void *pattern;
- unsigned int patternsize;
+ void *pattern[VIDEO_MAX_PLANES];
+ unsigned int patternsize[VIDEO_MAX_PLANES];
};
static bool video_is_mplane(struct device *dev)
@@ -276,7 +276,11 @@ static int video_open(struct device *dev, const char *devname, int no_query)
static void video_close(struct device *dev)
{
- free(dev->pattern);
+ unsigned int i;
+
+ for (i = 0; i < dev->num_planes; i++)
+ free(dev->pattern[i]);
+
free(dev->buffers);
close(dev->fd);
}
@@ -428,6 +432,9 @@ static int video_get_format(struct device *dev)
dev->imagesize = fmt.fmt.pix.bytesperline ? fmt.fmt.pix.sizeimage : 0;
dev->num_planes = 1;
+ dev->plane_fmt[0].bytesperline = fmt.fmt.pix.bytesperline;
+ dev->plane_fmt[0].sizeimage = fmt.fmt.pix.bytesperline ? fmt.fmt.pix.sizeimage : 0;
+
printf("Video format: %s (%08x) %ux%u (stride %u) buffer size %u\n",
v4l2_format_name(fmt.fmt.pix.pixelformat), fmt.fmt.pix.pixelformat,
fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.bytesperline,
@@ -806,15 +813,24 @@ static int video_queue_buffer(struct device *dev, int index, enum buffer_fill_mo
}
}
- if (video_is_output(dev)) {
- buf.bytesused = dev->patternsize;
- memcpy(dev->buffers[buf.index].mem[0], dev->pattern, dev->patternsize);
- } else {
- if (fill & BUFFER_FILL_FRAME)
- memset(dev->buffers[buf.index].mem[0], 0x55, dev->buffers[index].size[0]);
- if (fill & BUFFER_FILL_PADDING)
- memset(dev->buffers[buf.index].mem[0] + dev->buffers[index].size[0],
- 0x55, dev->buffers[index].padding[0]);
+ for (i = 0; i < dev->num_planes; i++) {
+ if (video_is_output(dev)) {
+ if (video_is_mplane(dev))
+ buf.m.planes[i].bytesused = dev->patternsize[i];
+ else
+ buf.bytesused = dev->patternsize[i];
+
+ memcpy(dev->buffers[buf.index].mem[i], dev->pattern[i],
+ dev->patternsize[i]);
+ } else {
+ if (fill & BUFFER_FILL_FRAME)
+ memset(dev->buffers[buf.index].mem[i], 0x55,
+ dev->buffers[index].size[i]);
+ if (fill & BUFFER_FILL_PADDING)
+ memset(dev->buffers[buf.index].mem[i] +
+ dev->buffers[index].size[i],
+ 0x55, dev->buffers[index].padding[i]);
+ }
}
ret = ioctl(dev->fd, VIDIOC_QBUF, &buf);
@@ -1150,52 +1166,62 @@ static int video_set_quality(struct device *dev, unsigned int quality)
static int video_load_test_pattern(struct device *dev, const char *filename)
{
- unsigned int size = dev->buffers[0].size[0];
- unsigned int x, y;
- uint8_t *data;
+ unsigned int plane;
+ unsigned int size;
+ int fd = -1;
int ret;
- int fd;
- /* Load or generate the test pattern */
- dev->pattern = malloc(size);
- if (dev->pattern == NULL)
- return -ENOMEM;
+ if (filename != NULL) {
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ printf("Unable to open test pattern file '%s': %s (%d).\n",
+ filename, strerror(errno), errno);
+ return -errno;
+ }
+ }
- if (filename == NULL) {
- if (dev->bytesperline == 0) {
- printf("Compressed format detect and no test pattern filename given.\n"
- "The test pattern can't be generated automatically.\n");
- return -EINVAL;
+ /* Load or generate the test pattern */
+ for (plane = 0; plane < dev->num_planes; plane++) {
+ size = dev->buffers[0].size[plane];
+ dev->pattern[plane] = malloc(size);
+ if (dev->pattern[plane] == NULL) {
+ ret = -ENOMEM;
+ goto done;
}
- data = dev->pattern;
+ if (filename != NULL) {
+ ret = read(fd, dev->pattern[plane], size);
+ if (ret != (int)size && dev->plane_fmt[plane].bytesperline != 0) {
+ printf("Test pattern file size %u doesn't match image size %u\n",
+ ret, size);
+ ret = -EINVAL;
+ goto done;
+ }
+ } else {
+ uint8_t *data = dev->pattern[plane];
+ unsigned int i;
- for (y = 0; y < dev->height; ++y) {
- for (x = 0; x < dev->bytesperline; ++x)
- *data++ = x + y;
- }
+ if (dev->plane_fmt[plane].bytesperline == 0) {
+ printf("Compressed format detected for plane %u and no test pattern filename given.\n"
+ "The test pattern can't be generated automatically.\n", plane);
+ ret = -EINVAL;
+ goto done;
+ }
- return 0;
- }
+ for (i = 0; i < dev->plane_fmt[plane].sizeimage; ++i)
+ *data++ = i;
+ }
- fd = open(filename, O_RDONLY);
- if (fd == -1) {
- printf("Unable to open test pattern file '%s': %s (%d).\n",
- filename, strerror(errno), errno);
- return -errno;
+ dev->patternsize[plane] = size;
}
- ret = read(fd, dev->pattern, size);
- close(fd);
+ ret = 0;
- if (ret != (int)size && dev->bytesperline != 0) {
- printf("Test pattern file size %u doesn't match image size %u\n",
- ret, size);
- return -EINVAL;
- }
+done:
+ if (fd != -1)
+ close(fd);
- dev->patternsize = ret;
- return 0;
+ return ret;
}
static int video_prepare_capture(struct device *dev, int nbufs, unsigned int offset,