Commit 0fd7c0c2 authored by Hans Verkuil's avatar Hans Verkuil
Browse files

media: vivid: fix wrong sizeimage value for mplane



In several places a division by fmt->vdownsampling[p] was
missing in the sizeimage[p] calculation, causing incorrect
behavior for multiplanar formats were some planes are smaller
than the first plane.

Found by new v4l2-compliance tests.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 7603ac5a
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -106,7 +106,8 @@ static int vid_cap_queue_setup(struct vb2_queue *vq,
		if (*nplanes != buffers)
			return -EINVAL;
		for (p = 0; p < buffers; p++) {
			if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h +
			if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h /
					dev->fmt_cap->vdownsampling[p] +
					dev->fmt_cap->data_offset[p])
				return -EINVAL;
		}
+9 −7
Original line number Diff line number Diff line
@@ -63,13 +63,15 @@ static int vid_out_queue_setup(struct vb2_queue *vq,
		if (sizes[0] < size)
			return -EINVAL;
		for (p = 1; p < planes; p++) {
			if (sizes[p] < dev->bytesperline_out[p] * h +
			if (sizes[p] < dev->bytesperline_out[p] * h /
					vfmt->vdownsampling[p] +
					vfmt->data_offset[p])
				return -EINVAL;
		}
	} else {
		for (p = 0; p < planes; p++)
			sizes[p] = p ? dev->bytesperline_out[p] * h +
			sizes[p] = p ? dev->bytesperline_out[p] * h /
					vfmt->vdownsampling[p] +
					vfmt->data_offset[p] : size;
	}

@@ -124,7 +126,7 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb)

	for (p = 0; p < planes; p++) {
		if (p)
			size = dev->bytesperline_out[p] * h;
			size = dev->bytesperline_out[p] * h / vfmt->vdownsampling[p];
		size += vb->planes[p].data_offset;

		if (vb2_get_plane_payload(vb, p) < size) {
@@ -331,8 +333,8 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv,
	for (p = 0; p < mp->num_planes; p++) {
		mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
		mp->plane_fmt[p].sizeimage =
			mp->plane_fmt[p].bytesperline * mp->height +
			fmt->data_offset[p];
			mp->plane_fmt[p].bytesperline * mp->height /
			fmt->vdownsampling[p] + fmt->data_offset[p];
	}
	for (p = fmt->buffers; p < fmt->planes; p++) {
		unsigned stride = dev->bytesperline_out[p];