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"
41 QImage add_image_png(src_t *src)
44 im.loadFromData((uchar *)src->img, src->length, "PNG");
48 QImage add_image_jpeg(src_t *src)
54 /* MJPEG data may lack the DHT segment required for decoding... */
55 verify_jpeg_dht((uint8_t *) src->img, src->length, &himg, &hlength);
57 im.loadFromData(himg, hlength, "JPG");
62 class MyDisplay : public QLabel
65 MyDisplay(QWidget *parent = 0);
66 void setImage(QImage img);
67 virtual void paintEvent(QPaintEvent *);
68 virtual void resizeEvent(QResizeEvent *);
75 MyDisplay::MyDisplay(QWidget *parent):
79 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
80 setAttribute(Qt::WA_PaintOnScreen);
81 setAttribute(Qt::WA_OpaquePaintEvent);
84 void MyDisplay::resizeEvent(QResizeEvent *)
89 void MyDisplay::paintEvent(QPaintEvent *)
93 // widget resized, cleanup
94 p.fillRect(0, 0, width(), height(), palette().background());
97 if (m_img.isNull()) return;
98 QImage img = m_img.scaled(width(), height(), Qt::KeepAspectRatio);
99 p.drawImage((width() - img.width()) / 2, (height() - img.height()) / 2, img);
103 void MyDisplay::setImage(QImage img)
111 V4lCaptureHandler::V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent):
112 CaptureHandler(lay, parent)
114 , m_device(KdenliveSettings::video4vdevice())
118 if (lay == NULL) return;
119 m_display = new MyDisplay;
120 lay->addWidget(m_display);
123 QStringList V4lCaptureHandler::getDeviceName(QString input)
125 fswebcam_config_t *config;
126 /* Prepare the configuration structure. */
127 config = (fswebcam_config_t *) calloc(sizeof(fswebcam_config_t), 1);
129 /*WARN("Out of memory.");*/
130 fprintf(stderr, "Out of MEM....");
131 return QStringList() << input;
134 /* Set the defaults. */
137 config->background = 0;
138 config->pidfile = NULL;
139 config->logfile = NULL;
142 config->device = strdup(input.toUtf8().constData());
143 config->input = NULL;
145 config->frequency = 0;
147 config->use_read = 0;
149 if (m_width > 0) config->width = m_width;
150 else config->width = 384;
151 if (m_height > 0) config->height = m_height;
152 else config->height = 288;
155 config->skipframes = 0;
156 config->palette = SRC_PAL_ANY;
157 config->option = NULL;
158 config->dumpframe = NULL;
162 /* Set defaults and parse the command line. */
163 /*if(fswc_getopts(config, argc, argv)) return(-1);*/
166 /* Record the start time. */
167 config->start = time(NULL);
168 /* Set source options... */
169 memset(&v4lsrc, 0, sizeof(v4lsrc));
170 v4lsrc.input = config->input;
171 v4lsrc.tuner = config->tuner;
172 v4lsrc.frequency = config->frequency;
173 v4lsrc.delay = config->delay;
174 v4lsrc.timeout = 10; /* seconds */
175 v4lsrc.use_read = config->use_read;
176 v4lsrc.list = config->list;
177 v4lsrc.palette = config->palette;
178 v4lsrc.width = config->width;
179 v4lsrc.height = config->height;
180 v4lsrc.fps = config->fps;
181 v4lsrc.option = config->option;
182 char *source = config->device;
185 char *pixelformatdescription;
186 QString deviceName(src_query(&v4lsrc, source, &width, &height, &pixelformatdescription));
189 result << (deviceName.isEmpty() ? input : deviceName) << (width == 0 ? QString() : QString("%1x%2").arg(width).arg(height)) << QString(pixelformatdescription);
193 void V4lCaptureHandler::setDevice(const QString input, QString size)
196 if (!size.isEmpty()) {
197 m_width = size.section('x', 0, 0).toInt();
198 m_height = size.section('x', -1).toInt();
203 void V4lCaptureHandler::startPreview(int /*deviceId*/, int /*captureMode*/, bool)
205 m_display->setHidden(false);
206 fswebcam_config_t *config;
207 /* Prepare the configuration structure. */
208 config = (fswebcam_config_t *) calloc(sizeof(fswebcam_config_t), 1);
210 /*WARN("Out of memory.");*/
211 fprintf(stderr, "Out of MEM....");
215 /* Set the defaults. */
218 config->background = 0;
219 config->pidfile = NULL;
220 config->logfile = NULL;
223 config->device = strdup(m_device.toUtf8().constData());
224 config->input = NULL;
226 config->frequency = 0;
228 config->use_read = 0;
230 if (m_width > 0) config->width = m_width;
231 else config->width = KdenliveSettings::video4size().section("x", 0, 0).toInt();/*384;*/
232 if (m_height > 0) config->height = m_height;
233 else config->height = KdenliveSettings::video4size().section("x", -1).toInt();/*288;*/
236 config->skipframes = 0;
237 config->palette = SRC_PAL_ANY;
238 config->option = NULL;
239 config->dumpframe = NULL;
243 /* Set defaults and parse the command line. */
244 /*if(fswc_getopts(config, argc, argv)) return(-1);*/
247 /* Record the start time. */
248 config->start = time(NULL);
249 /* Set source options... */
250 memset(&v4lsrc, 0, sizeof(v4lsrc));
251 v4lsrc.input = config->input;
252 v4lsrc.tuner = config->tuner;
253 v4lsrc.frequency = config->frequency;
254 v4lsrc.delay = config->delay;
255 v4lsrc.timeout = 10; /* seconds */
256 v4lsrc.use_read = config->use_read;
257 v4lsrc.list = config->list;
258 v4lsrc.palette = config->palette;
259 v4lsrc.width = config->width;
260 v4lsrc.height = config->height;
261 v4lsrc.fps = config->fps;
262 v4lsrc.option = config->option;
263 char *source = config->device;
265 if (src_open(&v4lsrc, source) != 0) return;
268 QTimer::singleShot(200, this, SLOT(slotUpdate()));
271 V4lCaptureHandler::~V4lCaptureHandler()
276 void V4lCaptureHandler::slotUpdate()
278 if (!m_update) return;
280 QImage qimg(v4lsrc.width, v4lsrc.height, QImage::Format_RGB888);
281 switch (v4lsrc.palette) {
283 qimg = add_image_png(&v4lsrc);
287 qimg = add_image_jpeg(&v4lsrc);
290 fswc_add_image_s561(qimg.bits(), (uchar *)v4lsrc.img, v4lsrc.length, v4lsrc.width, v4lsrc.height, v4lsrc.palette);
293 fswc_add_image_rgb32(&v4lsrc, qimg.bits());
296 fswc_add_image_bgr32(&v4lsrc, qimg.bits());
299 fswc_add_image_rgb24(&v4lsrc, qimg.bits());
302 fswc_add_image_bgr24(&v4lsrc, qimg.bits());
307 fswc_add_image_bayer(qimg.bits(), (uchar *)v4lsrc.img, v4lsrc.length, v4lsrc.width, v4lsrc.height, v4lsrc.palette);
311 fswc_add_image_yuyv(&v4lsrc, (avgbmp_t *)qimg.bits());
313 case SRC_PAL_YUV420P:
314 fswc_add_image_yuv420p(&v4lsrc, qimg.bits());
317 fswc_add_image_nv12mb(&v4lsrc, qimg.bits());
320 fswc_add_image_rgb565(&v4lsrc, qimg.bits());
323 fswc_add_image_rgb555(&v4lsrc, qimg.bits());
326 fswc_add_image_y16(&v4lsrc, qimg.bits());
329 fswc_add_image_grey(&v4lsrc, qimg.bits());
332 if (m_analyseFrame) {
335 if (!m_captureFramePath.isEmpty()) {
336 qimg.save(m_captureFramePath);
337 emit frameSaved(m_captureFramePath);
338 m_captureFramePath.clear();
340 if (!m_overlayImage.isNull()) {
344 p.drawImage(0, 0, m_overlayImage);
347 m_display->setImage(qimg);
348 if (m_update) QTimer::singleShot(50, this, SLOT(slotUpdate()));
351 void V4lCaptureHandler::startCapture(const QString &/*path*/)
355 void V4lCaptureHandler::stopCapture()
359 void V4lCaptureHandler::captureFrame(const QString &fname)
361 m_captureFramePath = fname;
364 void V4lCaptureHandler::showOverlay(QImage img, bool /*transparent*/)
366 m_overlayImage = img;
369 void V4lCaptureHandler::hideOverlay()
371 m_overlayImage = QImage();
374 void V4lCaptureHandler::hidePreview(bool hide)
376 m_display->setHidden(hide);
379 void V4lCaptureHandler::stopPreview()
381 m_display->setHidden(true);
382 if (!m_update) return;