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 void yuv2rgb_int3(unsigned char *yuv_buffer, unsigned char *rgb_buffer, int width, int height)
46 int rgb_ptr, y_ptr, t;
48 len = width * height / 2;
53 for(t = 0; t < len; t++) { /* process 2 pixels at a time */
54 /* Compute parts of the UV components */
56 U = yuv_buffer[y_ptr];
57 Y = yuv_buffer[y_ptr+1];
58 V = yuv_buffer[y_ptr+2];
59 Y2 = yuv_buffer[y_ptr+3];
63 /*r = 1.164*(Y-16) + 1.596*(V-128);
64 g = 1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128);
65 b = 1.164*(Y-16) + 2.018*(U-128);*/
68 r = ((298 * (Y - 16) + 409 * (V - 128) + 128) >> 8);
70 g = ((298 * (Y - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8);
72 b = ((298 * (Y - 16) + 516 * (U - 128) + 128) >> 8);
82 rgb_buffer[rgb_ptr] = b;
83 rgb_buffer[rgb_ptr+1] = g;
84 rgb_buffer[rgb_ptr+2] = r;
85 rgb_buffer[rgb_ptr+3] = 255;
88 /*r = 1.164*(Y2-16) + 1.596*(V-128);
89 g = 1.164*(Y2-16) - 0.813*(V-128) - 0.391*(U-128);
90 b = 1.164*(Y2-16) + 2.018*(U-128);*/
93 r = ((298 * (Y2 - 16) + 409 * (V - 128) + 128) >> 8);
95 g = ((298 * (Y2 - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8);
97 b = ((298 * (Y2 - 16) + 516 * (U - 128) + 128) >> 8);
107 rgb_buffer[rgb_ptr] = b;
108 rgb_buffer[rgb_ptr+1] = g;
109 rgb_buffer[rgb_ptr+2] = r;
110 rgb_buffer[rgb_ptr+3] = 255;
115 V4lCaptureHandler::V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent):
116 CaptureHandler(lay, parent)
119 m_display = new QLabel;
120 lay->addWidget(m_display);
123 void V4lCaptureHandler::startPreview(int /*deviceId*/, int /*captureMode*/)
125 m_display->setHidden(false);
126 fswebcam_config_t *config;
127 /* Prepare the configuration structure. */
128 config = (fswebcam_config_t *) calloc(sizeof(fswebcam_config_t), 1);
130 /*WARN("Out of memory.");*/
131 fprintf(stderr, "Out of MEM....");
135 /* Set the defaults. */
138 config->background = 0;
139 config->pidfile = NULL;
140 config->logfile = NULL;
143 config->device = strdup(KdenliveSettings::video4vdevice().toUtf8().constData());
144 config->input = NULL;
146 config->frequency = 0;
148 config->use_read = 0;
150 config->width = KdenliveSettings::video4size().section("x", 0, 0).toInt();/*384;*/
151 config->height = KdenliveSettings::video4size().section("x", -1).toInt();/*288;*/
154 config->skipframes = 0;
155 config->palette = SRC_PAL_ANY;
156 config->option = NULL;
157 config->dumpframe = NULL;
161 /* Set defaults and parse the command line. */
162 /*if(fswc_getopts(config, argc, argv)) return(-1);*/
165 /* Record the start time. */
166 config->start = time(NULL);
167 /* Set source options... */
168 memset(&v4lsrc, 0, sizeof(v4lsrc));
169 v4lsrc.input = config->input;
170 v4lsrc.tuner = config->tuner;
171 v4lsrc.frequency = config->frequency;
172 v4lsrc.delay = config->delay;
173 v4lsrc.timeout = 10; /* seconds */
174 v4lsrc.use_read = config->use_read;
175 v4lsrc.list = config->list;
176 v4lsrc.palette = config->palette;
177 v4lsrc.width = config->width;
178 v4lsrc.height = config->height;
179 v4lsrc.fps = config->fps;
180 v4lsrc.option = config->option;
181 char *source = config->device;
183 if(src_open(&v4lsrc, source) != 0) return;
185 QTimer::singleShot(200, this, SLOT(slotUpdate()));
188 V4lCaptureHandler::~V4lCaptureHandler()
193 void V4lCaptureHandler::slotUpdate()
195 if(!m_update) return;
197 uint8_t *img = (uint8_t *) v4lsrc.img;
198 uint32_t i = v4lsrc.width * v4lsrc.height;
200 if(v4lsrc.length << 2 < i) return;
202 QImage qimg(v4lsrc.width, v4lsrc.height, QImage::Format_RGB32);
203 //Format_ARGB32_Premultiplied
204 //convert from uyvy422 to rgba
205 yuv2rgb_int3((uchar *)img, (uchar *)qimg.bits(), v4lsrc.width, v4lsrc.height);
206 if(!m_captureFramePath.isEmpty()) {
207 qimg.save(m_captureFramePath);
208 emit frameSaved(m_captureFramePath);
209 m_captureFramePath.clear();
211 if(!m_overlayImage.isNull()) {
215 p.drawImage(0, 0, m_overlayImage);
218 m_display->setPixmap(QPixmap::fromImage(qimg));
219 if(m_update) QTimer::singleShot(200, this, SLOT(slotUpdate()));
222 void V4lCaptureHandler::startCapture(const QString &/*path*/)
226 void V4lCaptureHandler::stopCapture()
230 void V4lCaptureHandler::captureFrame(const QString &fname)
232 m_captureFramePath = fname;
235 void V4lCaptureHandler::showOverlay(QImage img, bool /*transparent*/)
237 m_overlayImage = img;
240 void V4lCaptureHandler::hideOverlay()
242 m_overlayImage = QImage();
245 void V4lCaptureHandler::hidePreview(bool hide)
247 m_display->setHidden(hide);
250 void V4lCaptureHandler::stopPreview()
252 if(!m_update) return;