]> git.sesse.net Git - kdenlive/blob - src/v4l/v4lcapture.cpp
cf0e247cce0ce27e2315d7ab7b4f657c26dce8f1
[kdenlive] / src / v4l / v4lcapture.cpp
1 /***************************************************************************
2  *   Copyright (C) 2010 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
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.                                   *
8  *                                                                         *
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.                          *
13  *                                                                         *
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  ***************************************************************************/
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <pthread.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26
27 #include <QDebug>
28 #include <QImage>
29 #include <QTimer>
30 #include <QPainter>
31
32 #include <KDebug>
33 #include <KLocale>
34
35 #include "v4lcapture.h"
36 #include "kdenlivesettings.h"
37
38 #include <linux/videodev2.h>
39 #include <sys/ioctl.h>
40
41 V4lCaptureHandler::V4lCaptureHandler()
42 {
43 }
44
45 //static
46
47 QStringList V4lCaptureHandler::getDeviceName(const QString &input)
48 {
49
50     char *src = strdup(input.toUtf8().constData());
51     QString pixelformatdescription;
52     int fd = open(src, O_RDWR | O_NONBLOCK);
53     if(fd < 0) {
54         free(src);
55         return QStringList();
56     }
57     struct v4l2_capability cap;
58
59     char *devName = NULL;
60     int captureEnabled = 1;
61     if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
62         fprintf(stderr, "Cannot get capabilities.");
63         //return NULL;
64     }
65     else {
66         devName = strdup((char*) cap.card);
67         if(!cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
68             // Device cannot capture
69             captureEnabled = 0;
70         }
71     }
72
73     if (captureEnabled) {
74         struct v4l2_format format;
75         memset(&format,0,sizeof(format));
76         format.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
77
78         struct v4l2_fmtdesc fmt;
79         memset(&fmt,0,sizeof(fmt));
80         fmt.index = 0;
81         fmt.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
82
83         struct v4l2_frmsizeenum sizes;
84         memset(&sizes,0,sizeof(sizes));
85
86         struct v4l2_frmivalenum rates;
87         memset(&rates,0,sizeof(rates));
88         char value[200];
89
90         while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) != -1)
91         {
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);
96
97             sizes.pixel_format = fmt.pixelformat;
98             sizes.index = 0;
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
103                 rates.index = 0;
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);
116                     rates.index ++;
117                 }
118                 fprintf(stderr, "\n");
119                 sizes.index++;
120             }
121             fmt.index++;
122         }
123     }
124     close(fd);
125     free(src);
126
127     QStringList result;
128     if (devName == NULL)
129         return result;
130     QString deviceName(devName);
131     result << (deviceName.isEmpty() ? input : deviceName) << pixelformatdescription;
132     return result;
133 }
134
135
136