aboutsummaryrefslogtreecommitdiffstats
path: root/src/v4l.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-07-24 12:49:09 (GMT)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-07-24 14:19:19 (GMT)
commitcbc8d0905488d9efe5c9ecb2e97076e27049c6b3 (patch)
tree51580318fbcd908b972f1fb74f90655afad41e81 /src/v4l.c
parent343b5eb4ae59dbf5583de087326fa3423c923595 (diff)
Allow selecting the image resolution instead of "small/midium/large"resolution_improvement
The concept of small, midium, large is relative, as it depends on whatever the camera supports. Instead of using it, it is a way better to show a list of the supported resolutions. That works fine for most cameras, with uses a fixed set. On cameras with a scale, the Kernel actually exports the resolution range. On this case, let's present 4 resolutions between the minimum and maximum one. That should be reasonable for most usecases. Nowadays, all drivers should be reporting resolutions via VIDIOC_ENUM_FRAMESIZES. Yet, as one might run camorama with very legacy kernels, provide backward support, using small/midium/large resolutions just like before. Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'src/v4l.c')
-rw-r--r--src/v4l.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/v4l.c b/src/v4l.c
index f2eff32..5a00b13 100644
--- a/src/v4l.c
+++ b/src/v4l.c
@@ -2,6 +2,7 @@
#include<time.h>
#include<errno.h>
#include<gnome.h>
+#include<stdlib.h>
#include <sys/select.h>
#include "support.h"
@@ -20,6 +21,73 @@ void print_cam(cam *cam){
}
+void insert_resolution(cam * cam, int x, int y)
+{
+ int i;
+
+ try_set_win_info(cam, &x, &y);
+ for (i = 0; i++; i < cam->n_res) {
+ if (cam->res[i].x == x && cam->res[i].y == y)
+ return;
+ }
+
+ cam->res = realloc(cam->res, (cam->n_res + 1) * sizeof(struct resolutions));
+
+ cam->res[cam->n_res].x = x;
+ cam->res[cam->n_res].y = y;
+ cam->n_res++;
+}
+
+static int sort_func(const void *__b,
+ const void *__a)
+{
+ const struct resolutions *a = __a;
+ const struct resolutions *b = __b;
+ int r;
+
+ r = b->x - a->x;
+ if (!r)
+ r = b->y - a->y;
+
+ return r;
+}
+
+void get_supported_resolutions(cam * cam)
+{
+ struct v4l2_fmtdesc fmt;
+ struct v4l2_frmsizeenum frmsize;
+ struct v4l2_frmivalenum frmival;
+ int i, x, y;
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ for (fmt.index = 0;
+ !v4l2_ioctl(cam->dev, VIDIOC_ENUM_FMT, &fmt);
+ fmt.index++) {
+ if (cam->pixformat != fmt.pixelformat)
+ continue;
+
+ frmsize.pixel_format = fmt.pixelformat;
+ frmsize.index = 0;
+ while (!v4l2_ioctl(cam->dev, VIDIOC_ENUM_FRAMESIZES, &frmsize)) {
+ if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+ insert_resolution(cam, frmsize.discrete.width,
+ frmsize.discrete.height);
+ } else if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
+ for (i = 0; i < 4; i++) {
+ x = frmsize.stepwise.min_width +
+ i * (frmsize.stepwise.max_width - frmsize.stepwise.min_width) / 4;
+ y = frmsize.stepwise.min_height +
+ i * (frmsize.stepwise.max_height - frmsize.stepwise.min_height) / 4;
+ insert_resolution(cam, x, y);
+ }
+ }
+ frmsize.index++;
+ }
+ }
+ qsort(cam->res, cam->n_res, sizeof(struct resolutions), sort_func);
+}
+
void camera_cap(cam * cam)
{
char *msg;

Privacy Policy