From dcd395f77ec30dae0658d1055944b64c2556a961 Mon Sep 17 00:00:00 2001
From: fryshorts <leonhard@in-verted.de>
Date: Tue, 16 Sep 2014 00:06:42 +0200
Subject: [PATCH] Use helper function to set framerate in v4l2 input.

---
 plugins/linux-v4l2/v4l2-helpers.c | 30 ++++++++++++++++++++++++++++++
 plugins/linux-v4l2/v4l2-helpers.h | 12 ++++++++++++
 plugins/linux-v4l2/v4l2-input.c   | 14 ++++----------
 3 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/plugins/linux-v4l2/v4l2-helpers.c b/plugins/linux-v4l2/v4l2-helpers.c
index 88551b89c..657b221b9 100644
--- a/plugins/linux-v4l2/v4l2-helpers.c
+++ b/plugins/linux-v4l2/v4l2-helpers.c
@@ -169,3 +169,33 @@ int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution,
 	*bytesperline = fmt.fmt.pix.bytesperline;
 	return 0;
 }
+
+int_fast32_t v4l2_set_framerate(int_fast32_t dev, int *framerate)
+{
+	bool set = false;
+	int num, denom;
+	struct v4l2_streamparm par;
+
+	if (!dev || !framerate)
+		return -1;
+
+	/* We need to set the type in order to query the stream settings */
+	par.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	if (v4l2_ioctl(dev, VIDIOC_G_PARM, &par) < 0)
+		return -1;
+
+	if (*framerate != -1) {
+		v4l2_unpack_tuple(&num, &denom, *framerate);
+		par.parm.capture.timeperframe.numerator   = num;
+		par.parm.capture.timeperframe.denominator = denom;
+		set = true;
+	}
+
+	if (set && (v4l2_ioctl(dev, VIDIOC_S_PARM, &par) < 0))
+		return -1;
+
+	*framerate = v4l2_pack_tuple(par.parm.capture.timeperframe.numerator,
+			par.parm.capture.timeperframe.denominator);
+	return 0;
+}
diff --git a/plugins/linux-v4l2/v4l2-helpers.h b/plugins/linux-v4l2/v4l2-helpers.h
index f4a835f86..6b5d862e7 100644
--- a/plugins/linux-v4l2/v4l2-helpers.h
+++ b/plugins/linux-v4l2/v4l2-helpers.h
@@ -235,6 +235,18 @@ int_fast32_t v4l2_set_input(int_fast32_t dev, int *input);
 int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution,
 		int *pixelformat, int *bytesperline);
 
+/**
+ * Set the framerate on the device.
+ *
+ * If the action succeeds framerate is set to the used value.
+ *
+ * @param dev handle to the v4l2 device
+ * @param framerate packed value of the framerate or -1 to leave as is
+ *
+ * @return negative on failure
+ */
+int_fast32_t v4l2_set_framerate(int_fast32_t dev, int *framerate);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c
index 15aa69237..d82b5ed68 100644
--- a/plugins/linux-v4l2/v4l2-input.c
+++ b/plugins/linux-v4l2/v4l2-input.c
@@ -64,7 +64,7 @@ struct v4l2_data {
 	int set_input;
 	int set_pixfmt;
 	int set_res;
-	int_fast32_t set_fps;
+	int set_fps;
 
 	/* data used within the capture thread */
 	int_fast32_t dev;
@@ -582,7 +582,6 @@ static void v4l2_destroy(void *vptr)
  */
 static void v4l2_init(struct v4l2_data *data)
 {
-	struct v4l2_streamparm par;
 	struct dstr fps;
 	int fps_num, fps_denom;
 
@@ -614,18 +613,13 @@ static void v4l2_init(struct v4l2_data *data)
 	blog(LOG_INFO, "Linesize: %d Bytes", data->linesize);
 
 	/* set framerate */
-	v4l2_unpack_tuple(&fps_num, &fps_denom, data->set_fps);
-	par.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	par.parm.capture.timeperframe.numerator = fps_num;
-	par.parm.capture.timeperframe.denominator = fps_denom;
-	if (v4l2_ioctl(data->dev, VIDIOC_S_PARM, &par) < 0) {
+	if (v4l2_set_framerate(data->dev, &data->set_fps) < 0) {
 		blog(LOG_ERROR, "Unable to set framerate");
 		goto fail;
 	}
+	v4l2_unpack_tuple(&fps_num, &fps_denom, data->set_fps);
 	dstr_init(&fps);
-	dstr_printf(&fps, "%.2f",
-		(float) par.parm.capture.timeperframe.denominator
-		/ par.parm.capture.timeperframe.numerator);
+	dstr_printf(&fps, "%.2f", (float) fps_denom / fps_num);
 	blog(LOG_INFO, "Framerate: %s fps", fps.array);
 	dstr_free(&fps);
 
-- 
GitLab