1 /***************************************************************************
2 * Copyright (C) 2010 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
35 #include "v4lcapture.h"
36 #include "kdenlivesettings.h"
38 #include <linux/videodev2.h>
39 #include <sys/ioctl.h>
41 V4lCaptureHandler::V4lCaptureHandler()
47 QStringList V4lCaptureHandler::getDeviceName(const QString &input)
50 char *src = strdup(input.toUtf8().constData());
51 QString pixelformatdescription;
52 int fd = open(src, O_RDWR | O_NONBLOCK);
57 struct v4l2_capability cap;
60 int captureEnabled = 1;
61 if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
62 fprintf(stderr, "Cannot get capabilities.");
66 devName = strdup((char*) cap.card);
67 if(!cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
68 // Device cannot capture
74 struct v4l2_format format;
75 memset(&format,0,sizeof(format));
76 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
78 struct v4l2_fmtdesc fmt;
79 memset(&fmt,0,sizeof(fmt));
81 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
83 struct v4l2_frmsizeenum sizes;
84 memset(&sizes,0,sizeof(sizes));
86 struct v4l2_frmivalenum rates;
87 memset(&rates,0,sizeof(rates));
90 while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) != -1)
92 if (pixelformatdescription.length() > 2000) break;
93 if (snprintf( value, sizeof(value), ">%c%c%c%c", fmt.pixelformat >> 0, fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24 ) > 0)
94 pixelformatdescription.append(value);
95 fprintf(stderr, "detected format: %s: %c%c%c%c\n", fmt.description, fmt.pixelformat >> 0, fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24);
97 sizes.pixel_format = fmt.pixelformat;
99 // Query supported frame size
100 while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &sizes) != -1) {
101 struct v4l2_frmsize_discrete image_size = sizes.discrete;
102 // Query supported frame rates
104 rates.pixel_format = fmt.pixelformat;
105 rates.width = image_size.width;
106 rates.height = image_size.height;
107 if (pixelformatdescription.length() > 2000) break;
108 if (snprintf( value, sizeof(value), ":%dx%d=", image_size.width, image_size.height ) > 0)
109 pixelformatdescription.append(value);
110 fprintf(stderr, "Size: %dx%d: ", image_size.width, image_size.height);
111 while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &rates) != -1) {
112 if (pixelformatdescription.length() > 2000) break;
113 if (snprintf( value, sizeof(value), "%d/%d,", rates.discrete.denominator, rates.discrete.numerator ) > 0)
114 pixelformatdescription.append(value);
115 fprintf(stderr, "%d/%d, ", rates.discrete.numerator, rates.discrete.denominator);
118 fprintf(stderr, "\n");
128 if (devName == NULL) return result;
129 QString deviceName(devName);
130 result << (deviceName.isEmpty() ? input : deviceName) << pixelformatdescription;