Commit 885fe18f authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab
Browse files

[media] pwc: Replace private buffer management code with videobuf2



Looking at the pwc buffer management code has made it clear to me it needed
some serious fixing. Not only was there a ton of code duplication even
internally to pwc (read and mmap wait for frame code was duplicated), the
code also was outright buggy. With the worst offender being dqbuf, which
just round robin returned all the mmap buffers, without paying any attention
to them being queued by the app with qbuf or not. And qbuf itself was a noop.

So I set out to fix this and already had some cleanups in place when
I read Jonathan Corbet's lwn article on videobuf2, this inspired me to just
rip out the buffer management code and replace it with videobuf2, greatly
reducing the amount of code, and fixing all bugs in one go:

Many thanks to Jonathan for the timely article on this !

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5f40d915
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
config USB_PWC
	tristate "USB Philips Cameras"
	depends on VIDEO_V4L2
	select VIDEOBUF2_VMALLOC
	---help---
	  Say Y or M here if you want to use one of these Philips & OEM
	  webcams:
+1 −18
Original line number Diff line number Diff line
@@ -511,13 +511,9 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i
	return ret;
}

#define BLACK_Y 0
#define BLACK_U 128
#define BLACK_V 128

static void pwc_set_image_buffer_size(struct pwc_device *pdev)
{
	int i, factor = 0;
	int factor = 0;

	/* for V4L2_PIX_FMT_YUV420 */
	switch (pdev->pixfmt) {
@@ -541,22 +537,9 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev)
	 */
	pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
	pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;

	/* Fill buffers with black colors */
	for (i = 0; i < pwc_mbufs; i++) {
		unsigned char *p = pdev->image_data + pdev->images[i].offset;
		memset(p, BLACK_Y, pdev->view.x * pdev->view.y);
		p += pdev->view.x * pdev->view.y;
		memset(p, BLACK_U, pdev->view.x * pdev->view.y/4);
		p += pdev->view.x * pdev->view.y/4;
		memset(p, BLACK_V, pdev->view.x * pdev->view.y/4);
	}
}



/* BRIGHTNESS */

int pwc_get_brightness(struct pwc_device *pdev)
{
	char buf;
+233 −614

File changed.

Preview size limit exceeded, changes collapsed.

+0 −4
Original line number Diff line number Diff line
@@ -126,8 +126,4 @@ void pwc_construct(struct pwc_device *pdev)
	pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */
	pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
	pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
	/* length of image, in YUV format; always allocate enough memory. */
	pdev->len_per_image = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
}

+6 −5
Original line number Diff line number Diff line
@@ -34,17 +34,14 @@
#include "pwc-dec1.h"
#include "pwc-dec23.h"

int pwc_decompress(struct pwc_device *pdev)
int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
{
	struct pwc_frame_buf *fbuf;
	int n, line, col, stride;
	void *yuv, *image;
	u16 *src;
	u16 *dsty, *dstu, *dstv;

	fbuf = pdev->read_frame;
	image  = pdev->image_data;
	image += pdev->images[pdev->fill_image].offset;
	image = vb2_plane_vaddr(&fbuf->vb, 0);

	yuv = fbuf->data + pdev->frame_header_size;  /* Skip header */

@@ -59,9 +56,13 @@ int pwc_decompress(struct pwc_device *pdev)
			 * determine this using the type of the webcam */
		memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
		memcpy(raw_frame+1, yuv, pdev->frame_size);
		vb2_set_plane_payload(&fbuf->vb, 0,
			pdev->frame_size + sizeof(struct pwc_raw_frame));
		return 0;
	}

	vb2_set_plane_payload(&fbuf->vb, 0, pdev->view.size);

	if (pdev->vbandlength == 0) {
		/* Uncompressed mode.
		 * We copy the data into the output buffer, using the viewport
Loading