This is patch catch the biggest frame size and calculate compression
ratio.

Usage:
modprobe statistic=1

start capture some thing. The best possability to catch biggest frame is
to record lots of moving text. Point your camera to monitore and open
terminal with dmesg or some thing :D

After stop, result will be in dmesg.

Testers are welcome.
-- 
Regards,
        Alexey
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 78e70d2..8fd20fc 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -46,6 +46,7 @@ unsigned int uvc_no_drop_param;
 static unsigned int uvc_quirks_param = -1;
 unsigned int uvc_trace_param;
 unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
+unsigned int uvc_statistic_param;
 
 /* ------------------------------------------------------------------------
  * Video formats
@@ -1953,6 +1954,8 @@ module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(trace, "Trace level bitmask");
 module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
+module_param_named(statistic, uvc_statistic_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(statistic, "Gether framesize/compressions statistic");
 
 /* ------------------------------------------------------------------------
  * Driver initialization and cleanup
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 36f3c58..03ed66e 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -347,8 +347,9 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
 	if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0)
 		goto done;
 
-	uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n",
-		buf->buf.index, buf->state, buf->buf.bytesused);
+	uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u/%u bytes).\n",
+		  buf->buf.index, buf->state,
+		  buf->buf.length, buf->buf.bytesused);
 
 	switch (buf->state) {
 	case UVC_BUF_STATE_ERROR:
@@ -370,6 +371,9 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
 		goto done;
 	}
 
+	if (buf->buf.bytesused > queue->max_used_lengh)
+		queue->max_used_lengh = buf->buf.bytesused;
+
 	list_del(&buf->stream);
 	__uvc_query_buffer(buf, v4l2_buf);
 
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 0ea7adf..cf27f7f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -872,6 +872,43 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
 
 	if (free_buffers)
 		uvc_free_urb_buffers(stream);
+
+	if (stream->print_statistic) {
+		struct uvc_format *cur_format = stream->cur_format;
+		struct uvc_frame *cur_frame = stream->cur_frame;
+		struct uvc_streaming_control *ctrl = &stream->ctrl;
+		unsigned int fps = 10000000/ctrl->dwFrameInterval;
+		unsigned int bandwidth;
+
+		bandwidth = stream->queue.max_used_lengh;
+		bandwidth *= fps + 1;
+		bandwidth /= 1000;
+		if (stream->dev->udev->speed == USB_SPEED_HIGH)
+                        bandwidth /= 8;
+		bandwidth += 12;
+
+
+		pr_info("%s: Statistic for %s %ux%u@%u", __func__,
+			cur_format->name,
+			cur_frame->wWidth,
+			cur_frame->wHeight, fps);
+		pr_info("provided dwMaxVideoFrameBufferSize %u, "
+			"calculated bpp %u",
+			cur_frame->dwMaxVideoFrameBufferSize,
+			cur_frame->dwMaxVideoFrameBufferSize /
+			(cur_frame->wWidth * cur_frame->wHeight / 8));
+		pr_info("collected max_used_size %u, calculated bpp %d",
+			stream->queue.max_used_lengh,
+			stream->queue.max_used_lengh /
+			(cur_frame->wWidth * cur_frame->wHeight / 8));
+		pr_info("provided dwMaxPayloadTransferSize %u",
+			ctrl->dwMaxPayloadTransferSize);
+		pr_info("calculated dwMaxPayloadTransferSize %u",
+			bandwidth);
+
+		stream->queue.max_used_lengh = 0;
+		stream->print_statistic = 0;
+	}
 }
 
 /*
@@ -1070,6 +1107,9 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
 		}
 	}
 
+	if (uvc_statistic_param)
+		stream->print_statistic = 1;
+
 	return 0;
 }
 
diff --git a/include/linux/uvcvideo.h b/include/linux/uvcvideo.h
index 4b53343..77d2ab5 100644
--- a/include/linux/uvcvideo.h
+++ b/include/linux/uvcvideo.h
@@ -413,6 +413,9 @@ struct uvc_video_queue {
 
 	struct list_head mainqueue;
 	struct list_head irqqueue;
+
+	/* collect statistic */
+	unsigned int max_used_lengh;
 };
 
 struct uvc_video_chain {
@@ -472,6 +475,8 @@ struct uvc_streaming {
 
 	__u32 sequence;
 	__u8 last_fid;
+
+	bool print_statistic;
 };
 
 enum uvc_device_state {
@@ -547,6 +552,7 @@ extern unsigned int uvc_clock_param;
 extern unsigned int uvc_no_drop_param;
 extern unsigned int uvc_trace_param;
 extern unsigned int uvc_timeout_param;
+extern unsigned int uvc_statistic_param;
 
 #define uvc_trace(flag, msg...) \
 	do { \
_______________________________________________
Linux-uvc-devel mailing list
Linux-uvc-devel@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to