Hi Jon,

On Saturday 30 May 2009 10:27:19 Jon Fairbairn wrote:
> Laurent Pinchart <[email protected]> writes:
> > I'll try to get a patch ready for the end of the week. If
> > I don't feel free to (nicely) remind me.
>
> Before i can decide to remind you, I need to know whether
> you regard the week as ending on Saturday or Sunday ;-)

On Monday of course ;-)

Here's a patch that implements VIDIOC_[GS]_JPEGCOMP. It seems to work with a 
Logitech QuickCam Pro for Notebooks. Could you please test it with your 
camera(s) and report the results ?

Best regards,

Laurent Pinchart

diff -r 66a270023c26 linux/drivers/media/video/uvc/uvc_v4l2.c
--- a/linux/drivers/media/video/uvc/uvc_v4l2.c	Sun May 31 22:05:55 2009 +0200
+++ b/linux/drivers/media/video/uvc/uvc_v4l2.c	Tue Jun 02 00:49:55 2009 +0200
@@ -179,6 +179,7 @@
 	probe->bFormatIndex = format->index;
 	probe->bFrameIndex = frame->bFrameIndex;
 	probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
+	probe->wCompQuality = 10000;
 	/* Some webcams stall the probe control set request when the
 	 * dwMaxVideoFrameSize field is set to zero. The UVC specification
 	 * clearly states that the field is read-only from the host, so this
@@ -345,6 +346,40 @@
 	return 0;
 }
 
+static int uvc_v4l2_get_jpegcomp(struct uvc_video_device *video,
+		struct v4l2_jpegcompression *jpeg)
+{
+	memset(jpeg, 0, sizeof *jpeg);
+	jpeg->quality = video->streaming->ctrl.wCompQuality / 100;
+	jpeg->jpeg_markers = V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
+static int uvc_v4l2_set_jpegcomp(struct uvc_video_device *video,
+		struct v4l2_jpegcompression *jpeg)
+{
+	struct uvc_streaming_control probe;
+	unsigned int quality;
+	int ret;
+
+	/* The buffer size must be renegotiated when changing quality. */
+	if (uvc_queue_streaming(&video->queue))
+		return -EBUSY;
+
+	memcpy(&probe, &video->streaming->ctrl, sizeof probe);
+	quality = clamp(jpeg->quality, 0, 100) * 100;
+
+	uvc_trace(UVC_TRACE_FORMAT, "Setting jpeg quality to %u.\n", quality);
+	probe.wCompQuality = quality;
+
+	/* Probe the device with the new settings. */
+	if ((ret = uvc_probe_video(video, &probe)) < 0)
+		return ret;
+
+	memcpy(&video->streaming->ctrl, &probe, sizeof probe);
+	return 0;
+}
+
 /* ------------------------------------------------------------------------
  * Privilege management
  */
@@ -829,6 +864,16 @@
 		break;
 	}
 
+	/* Get & Set JPEG compression parameters */
+	case VIDIOC_G_JPEGCOMP:
+		return uvc_v4l2_get_jpegcomp(video, arg);
+	
+	case VIDIOC_S_JPEGCOMP:
+		if ((ret = uvc_acquire_privileges(handle)) < 0)
+			return ret;
+
+		return uvc_v4l2_set_jpegcomp(video, arg);
+	
 	/* Get & Set streaming parameters */
 	case VIDIOC_G_PARM:
 		return uvc_v4l2_get_streamparm(video, arg);
diff -r 66a270023c26 linux/drivers/media/video/uvc/uvc_video.c
--- a/linux/drivers/media/video/uvc/uvc_video.c	Sun May 31 22:05:55 2009 +0200
+++ b/linux/drivers/media/video/uvc/uvc_video.c	Tue Jun 02 00:49:55 2009 +0200
@@ -276,7 +276,9 @@
 		if (ret < 0)
 			goto done;
 
-		probe->wCompQuality = probe_max.wCompQuality;
+		probe->wCompQuality = clamp(probe->wCompQuality,
+					    probe_min.wCompQuality,
+					    probe_max.wCompQuality);
 	}
 
 	for (i = 0; i < 2; ++i) {
@@ -299,7 +301,7 @@
 		/* TODO: negotiate compression parameters */
 		probe->wKeyFrameRate = probe_min.wKeyFrameRate;
 		probe->wPFrameRate = probe_min.wPFrameRate;
-		probe->wCompQuality = probe_max.wCompQuality;
+		probe->wCompQuality = probe_min.wCompQuality;
 		probe->wCompWindowSize = probe_min.wCompWindowSize;
 	}
 
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to