Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[media] pwc: Fix pixfmt handling



Before this patch various code in the mode setting patch checked
pdev->pixfmt, but that was not set until the mode setting succeeded, so
it was looking at the old pixfmt! This patch fixes this by making the
pixfmt a parameter to set_video_mode, and setting it from set_video_mode
on success.

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 56ae24aa
Loading
Loading
Loading
Loading
+20 −19
Original line number Diff line number Diff line
@@ -168,8 +168,8 @@ int send_control_msg(struct pwc_device *pdev,
		request, value, pdev->vcinterface, buf, buflen);
}

static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames,
			       int *compression)
static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
			       int frames, int *compression)
{
	unsigned char buf[3];
	int ret, fps;
@@ -212,14 +212,14 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames,
		PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
		return ret;
	}
	if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
	if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420)
		pwc_dec1_init(pdev, buf);
	}

	pdev->cmd_len = 3;
	memcpy(pdev->cmd_buf, buf, 3);

	/* Set various parameters */
	pdev->pixfmt = pixfmt;
	pdev->vframes = frames;
	pdev->valternate = pEntry->alternate;
	pdev->width  = pwc_image_sizes[size][0];
@@ -245,8 +245,8 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames,
}


static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames,
	int *compression)
static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt,
				int frames, int *compression)
{
	unsigned char buf[13];
	const struct Timon_table_entry *pChoose;
@@ -278,14 +278,14 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames,
	if (ret < 0)
		return ret;

	if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
	if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
		pwc_dec23_init(pdev, buf);
	}

	pdev->cmd_len = 13;
	memcpy(pdev->cmd_buf, buf, 13);

	/* Set various parameters */
	pdev->pixfmt = pixfmt;
	pdev->vframes = (fps + 1) * 5;
	pdev->valternate = pChoose->alternate;
	pdev->width  = pwc_image_sizes[size][0];
@@ -299,8 +299,8 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames,
}


static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames,
	int *compression)
static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt,
				int frames, int *compression)
{
	const struct Kiara_table_entry *pChoose = NULL;
	int fps, ret;
@@ -336,13 +336,13 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames,
	if (ret < 0)
		return ret;

	if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
	if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
		pwc_dec23_init(pdev, buf);
	}

	pdev->cmd_len = 12;
	memcpy(pdev->cmd_buf, buf, 12);
	/* All set and go */
	pdev->pixfmt = pixfmt;
	pdev->vframes = (fps + 1) * 5;
	pdev->valternate = pChoose->alternate;
	pdev->width  = pwc_image_sizes[size][0];
@@ -358,23 +358,24 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames,
}

int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
	int frames, int *compression)
	int pixfmt, int frames, int *compression)
{
	int ret, size;

	PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n",
		       width, height, frames, pdev->pixfmt);
		       width, height, frames, pixfmt);
	size = pwc_get_size(pdev, width, height);
	PWC_TRACE("decode_size = %d.\n", size);

	if (DEVICE_USE_CODEC1(pdev->type)) {
		ret = set_video_mode_Nala(pdev, size, frames, compression);

		ret = set_video_mode_Nala(pdev, size, pixfmt, frames,
					  compression);
	} else if (DEVICE_USE_CODEC3(pdev->type)) {
		ret = set_video_mode_Kiara(pdev, size, frames, compression);

		ret = set_video_mode_Kiara(pdev, size, pixfmt, frames,
					   compression);
	} else {
		ret = set_video_mode_Timon(pdev, size, frames, compression);
		ret = set_video_mode_Timon(pdev, size, pixfmt, frames,
					   compression);
	}
	if (ret < 0) {
		PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
+3 −2
Original line number Diff line number Diff line
@@ -386,7 +386,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
	/* We first try with low compression and then retry with a higher
	   compression setting if there is not enough bandwidth. */
	ret = pwc_set_video_mode(pdev, pdev->width, pdev->height,
				 pdev->vframes, &compression);
				 pdev->pixfmt, pdev->vframes, &compression);

	/* Get the current alternate interface, adjust packet size */
	intf = usb_ifnum_to_if(udev, 0);
@@ -1128,7 +1128,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
	pwc_set_leds(pdev, 0, 0);

	/* Setup intial videomode */
	rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, 30, &compression);
	rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
				V4L2_PIX_FMT_YUV420, 30, &compression);
	if (rc)
		goto err_free_mem;

+0 −1
Original line number Diff line number Diff line
@@ -90,5 +90,4 @@ void pwc_construct(struct pwc_device *pdev)
		pdev->frame_header_size = 0;
		pdev->frame_trailer_size = 0;
	}
	pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */
}
+4 −9
Original line number Diff line number Diff line
@@ -493,16 +493,11 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
			(pixelformat>>24)&255);

	ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height,
				 30, &compression);
				 pixelformat, 30, &compression);

	PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);

	if (ret == 0) {
		pdev->pixfmt = pixelformat;
		pwc_vidioc_fill_fmt(f, pdev->width, pdev->height,
				    pdev->pixfmt);
	}

	pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
leave:
	mutex_unlock(&pdev->udevlock);
	return ret;
@@ -1141,8 +1136,8 @@ static int pwc_s_parm(struct file *file, void *fh,
		goto leave;
	}

	ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, fps,
				 &compression);
	ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
				 fps, &compression);

	pwc_g_parm(file, fh, parm);

+1 −1
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ void pwc_construct(struct pwc_device *pdev);
/** Functions in pwc-ctrl.c */
/* Request a certain video mode. Returns < 0 if not possible */
extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
			      int frames, int *compression);
			      int pixfmt, int frames, int *compression);
extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);