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 ***************************************************************************/
34 #include "v4lcapture.h"
35 #include "kdenlivesettings.h"
40 void yuv2rgb_int3(unsigned char *yuv_buffer, unsigned char *rgb_buffer, int width, int height)
45 int rgb_ptr, y_ptr, t;
47 len = width * height / 2;
52 for(t = 0; t < len; t++) { /* process 2 pixels at a time */
53 /* Compute parts of the UV components */
55 U = yuv_buffer[y_ptr];
56 Y = yuv_buffer[y_ptr+1];
57 V = yuv_buffer[y_ptr+2];
58 Y2 = yuv_buffer[y_ptr+3];
62 /*r = 1.164*(Y-16) + 1.596*(V-128);
63 g = 1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128);
64 b = 1.164*(Y-16) + 2.018*(U-128);*/
67 r = ((298 * (Y - 16) + 409 * (V - 128) + 128) >> 8);
69 g = ((298 * (Y - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8);
71 b = ((298 * (Y - 16) + 516 * (U - 128) + 128) >> 8);
81 rgb_buffer[rgb_ptr] = b;
82 rgb_buffer[rgb_ptr+1] = g;
83 rgb_buffer[rgb_ptr+2] = r;
84 rgb_buffer[rgb_ptr+3] = 255;
87 /*r = 1.164*(Y2-16) + 1.596*(V-128);
88 g = 1.164*(Y2-16) - 0.813*(V-128) - 0.391*(U-128);
89 b = 1.164*(Y2-16) + 2.018*(U-128);*/
92 r = ((298 * (Y2 - 16) + 409 * (V - 128) + 128) >> 8);
94 g = ((298 * (Y2 - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8);
96 b = ((298 * (Y2 - 16) + 516 * (U - 128) + 128) >> 8);
106 rgb_buffer[rgb_ptr] = b;
107 rgb_buffer[rgb_ptr+1] = g;
108 rgb_buffer[rgb_ptr+2] = r;
109 rgb_buffer[rgb_ptr+3] = 255;
114 V4lCaptureHandler::V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent):
115 CaptureHandler(lay, parent)
118 m_display = new QLabel;
119 lay->addWidget(m_display);
122 void V4lCaptureHandler::startPreview(int /*deviceId*/, int /*captureMode*/)
124 m_display->setHidden(false);
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....");
134 /* Set the defaults. */
137 config->background = 0;
138 config->pidfile = NULL;
139 config->logfile = NULL;
142 config->device = strdup(KdenliveSettings::video4vdevice().toUtf8().constData());
143 config->input = NULL;
145 config->frequency = 0;
147 config->use_read = 0;
149 config->width = KdenliveSettings::video4size().section("x", 0, 0).toInt();/*384;*/
150 config->height = KdenliveSettings::video4size().section("x", -1).toInt();/*288;*/
153 config->skipframes = 0;
154 config->palette = SRC_PAL_ANY;
155 config->option = NULL;
156 config->dumpframe = NULL;
160 /* Set defaults and parse the command line. */
161 /*if(fswc_getopts(config, argc, argv)) return(-1);*/
164 /* Record the start time. */
165 config->start = time(NULL);
166 /* Set source options... */
167 memset(&v4lsrc, 0, sizeof(v4lsrc));
168 v4lsrc.input = config->input;
169 v4lsrc.tuner = config->tuner;
170 v4lsrc.frequency = config->frequency;
171 v4lsrc.delay = config->delay;
172 v4lsrc.timeout = 10; /* seconds */
173 v4lsrc.use_read = config->use_read;
174 v4lsrc.list = config->list;
175 v4lsrc.palette = config->palette;
176 v4lsrc.width = config->width;
177 v4lsrc.height = config->height;
178 v4lsrc.fps = config->fps;
179 v4lsrc.option = config->option;
180 char *source = config->device;
182 if(src_open(&v4lsrc, source) != 0) return;
184 QTimer::singleShot(200, this, SLOT(slotUpdate()));
187 V4lCaptureHandler::~V4lCaptureHandler()
192 void V4lCaptureHandler::slotUpdate()
194 if(!m_update) return;
196 uint8_t *img = (uint8_t *) v4lsrc.img;
197 uint32_t i = v4lsrc.width * v4lsrc.height;
199 if(v4lsrc.length << 2 < i) return;
201 QImage qimg(v4lsrc.width, v4lsrc.height, QImage::Format_RGB32);
202 //Format_ARGB32_Premultiplied
203 //convert from uyvy422 to rgba
204 yuv2rgb_int3((uchar *)img, (uchar *)qimg.bits(), v4lsrc.width, v4lsrc.height);
205 if(!m_captureFramePath.isEmpty()) {
206 qimg.save(m_captureFramePath);
207 m_captureFramePath.clear();
209 m_display->setPixmap(QPixmap::fromImage(qimg));
210 if(m_update) QTimer::singleShot(200, this, SLOT(slotUpdate()));
213 void V4lCaptureHandler::startCapture(const QString &/*path*/)
217 void V4lCaptureHandler::stopCapture()
221 void V4lCaptureHandler::captureFrame(const QString &fname)
223 m_captureFramePath = fname;
226 void V4lCaptureHandler::showOverlay(QImage /*img*/, bool /*transparent*/)
230 void V4lCaptureHandler::hideOverlay()
234 void V4lCaptureHandler::hidePreview(bool hide)
236 m_display->setHidden(hide);
239 void V4lCaptureHandler::stopPreview()
241 if(!m_update) return;