X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fv4l%2Fv4lcapture.cpp;h=8e6a63b42329a70d35a96ee8420a400a5f73f8e0;hb=56aee6aedeeed3efd10ada8fe3c229eddc01ef05;hp=be7b22be04d1e2d7ca03c8835ca62fc13eeaae17;hpb=cfa07b88701544776e846c5ce97877e815ad0ef5;p=kdenlive diff --git a/src/v4l/v4lcapture.cpp b/src/v4l/v4lcapture.cpp index be7b22be..8e6a63b4 100644 --- a/src/v4l/v4lcapture.cpp +++ b/src/v4l/v4lcapture.cpp @@ -27,218 +27,110 @@ #include #include #include +#include #include -#include +#include #include "v4lcapture.h" #include "kdenlivesettings.h" +#include +#include -static src_t v4lsrc; - -void yuv2rgb_int3(unsigned char *yuv_buffer, unsigned char *rgb_buffer, int width, int height) +V4lCaptureHandler::V4lCaptureHandler() { - int len; - int r, g, b; - int Y, U, V, Y2; - int rgb_ptr, y_ptr, t; - - len = width * height / 2; - - rgb_ptr = 0; - y_ptr = 0; - - for(t = 0; t < len; t++) { /* process 2 pixels at a time */ - /* Compute parts of the UV components */ - - U = yuv_buffer[y_ptr]; - Y = yuv_buffer[y_ptr+1]; - V = yuv_buffer[y_ptr+2]; - Y2 = yuv_buffer[y_ptr+3]; - y_ptr += 4; - - - /*r = 1.164*(Y-16) + 1.596*(V-128); - g = 1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128); - b = 1.164*(Y-16) + 2.018*(U-128);*/ - - - r = ((298 * (Y - 16) + 409 * (V - 128) + 128) >> 8); - - g = ((298 * (Y - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8); - - b = ((298 * (Y - 16) + 516 * (U - 128) + 128) >> 8); - - if(r > 255) r = 255; - if(g > 255) g = 255; - if(b > 255) b = 255; - - if(r < 0) r = 0; - if(g < 0) g = 0; - if(b < 0) b = 0; - - rgb_buffer[rgb_ptr] = b; - rgb_buffer[rgb_ptr+1] = g; - rgb_buffer[rgb_ptr+2] = r; - rgb_buffer[rgb_ptr+3] = 255; - - rgb_ptr += 4; - /*r = 1.164*(Y2-16) + 1.596*(V-128); - g = 1.164*(Y2-16) - 0.813*(V-128) - 0.391*(U-128); - b = 1.164*(Y2-16) + 2.018*(U-128);*/ - - - r = ((298 * (Y2 - 16) + 409 * (V - 128) + 128) >> 8); - - g = ((298 * (Y2 - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8); - - b = ((298 * (Y2 - 16) + 516 * (U - 128) + 128) >> 8); - - if(r > 255) r = 255; - if(g > 255) g = 255; - if(b > 255) b = 255; - - if(r < 0) r = 0; - if(g < 0) g = 0; - if(b < 0) b = 0; - - rgb_buffer[rgb_ptr] = b; - rgb_buffer[rgb_ptr+1] = g; - rgb_buffer[rgb_ptr+2] = r; - rgb_buffer[rgb_ptr+3] = 255; - rgb_ptr += 4; - } } -V4lCaptureHandler::V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent): - CaptureHandler(lay, parent) - , m_update(false) -{ - m_display = new QLabel; - lay->addWidget(m_display); -} +//static -void V4lCaptureHandler::startPreview(int /*deviceId*/, int /*captureMode*/) +QStringList V4lCaptureHandler::getDeviceName(const QString &input) { - m_display->setHidden(false); - fswebcam_config_t *config; - /* Prepare the configuration structure. */ - config = (fswebcam_config_t *) calloc(sizeof(fswebcam_config_t), 1); - if(!config) { - /*WARN("Out of memory.");*/ - fprintf(stderr, "Out of MEM...."); - return; - } - /* Set the defaults. */ - config->loop = 0; - config->offset = 0; - config->background = 0; - config->pidfile = NULL; - config->logfile = NULL; - config->gmt = 0; - config->start = 0; - config->device = strdup(KdenliveSettings::video4vdevice().toUtf8().constData()); - config->input = NULL; - config->tuner = 0; - config->frequency = 0; - config->delay = 0; - config->use_read = 0; - config->list = 0; - config->width = KdenliveSettings::video4size().section("x", 0, 0).toInt();/*384;*/ - config->height = KdenliveSettings::video4size().section("x", -1).toInt();/*288;*/ - config->fps = 0; - config->frames = 1; - config->skipframes = 0; - config->palette = SRC_PAL_ANY; - config->option = NULL; - config->dumpframe = NULL; - config->jobs = 0; - config->job = NULL; - - /* Set defaults and parse the command line. */ - /*if(fswc_getopts(config, argc, argv)) return(-1);*/ - - - /* Record the start time. */ - config->start = time(NULL); - /* Set source options... */ - memset(&v4lsrc, 0, sizeof(v4lsrc)); - v4lsrc.input = config->input; - v4lsrc.tuner = config->tuner; - v4lsrc.frequency = config->frequency; - v4lsrc.delay = config->delay; - v4lsrc.timeout = 10; /* seconds */ - v4lsrc.use_read = config->use_read; - v4lsrc.list = config->list; - v4lsrc.palette = config->palette; - v4lsrc.width = config->width; - v4lsrc.height = config->height; - v4lsrc.fps = config->fps; - v4lsrc.option = config->option; - char *source = config->device; - - if(src_open(&v4lsrc, source) != 0) return; - m_update = true; - QTimer::singleShot(200, this, SLOT(slotUpdate())); -} - -V4lCaptureHandler::~V4lCaptureHandler() -{ - stopCapture(); -} - -void V4lCaptureHandler::slotUpdate() -{ - if(!m_update) return; - src_grab(&v4lsrc); - uint8_t *img = (uint8_t *) v4lsrc.img; - uint32_t i = v4lsrc.width * v4lsrc.height; - - if(v4lsrc.length << 2 < i) return; - - QImage qimg(v4lsrc.width, v4lsrc.height, QImage::Format_RGB32); - //Format_ARGB32_Premultiplied - //convert from uyvy422 to rgba - yuv2rgb_int3((uchar *)img, (uchar *)qimg.bits(), v4lsrc.width, v4lsrc.height); - if(!m_captureFramePath.isEmpty()) { - qimg.save(m_captureFramePath); - m_captureFramePath.clear(); + char *src = strdup(input.toUtf8().constData()); + QString pixelformatdescription; + int fd = open(src, O_RDWR | O_NONBLOCK); + if(fd < 0) { + free(src); + return QStringList(); } - m_display->setPixmap(QPixmap::fromImage(qimg)); - if(m_update) QTimer::singleShot(200, this, SLOT(slotUpdate())); -} - -void V4lCaptureHandler::startCapture(const QString &/*path*/) -{ -} - -void V4lCaptureHandler::stopCapture() -{ -} + struct v4l2_capability cap; -void V4lCaptureHandler::captureFrame(const QString &fname) -{ - m_captureFramePath = fname; -} + char *devName = NULL; + int captureEnabled = 1; + if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { + fprintf(stderr, "Cannot get capabilities."); + //return NULL; + } + else { + devName = strdup((char*) cap.card); + if(!cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { + // Device cannot capture + captureEnabled = 0; + } + } -void V4lCaptureHandler::showOverlay(QImage /*img*/, bool /*transparent*/) -{ + if (captureEnabled) { + struct v4l2_format format; + memset(&format,0,sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + struct v4l2_fmtdesc fmt; + memset(&fmt,0,sizeof(fmt)); + fmt.index = 0; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + struct v4l2_frmsizeenum sizes; + memset(&sizes,0,sizeof(sizes)); + + struct v4l2_frmivalenum rates; + memset(&rates,0,sizeof(rates)); + char value[200]; + + while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) != -1) + { + if (pixelformatdescription.length() > 2000) break; + if (snprintf( value, sizeof(value), ">%c%c%c%c", fmt.pixelformat >> 0, fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24 ) > 0) + pixelformatdescription.append(value); + fprintf(stderr, "detected format: %s: %c%c%c%c\n", fmt.description, fmt.pixelformat >> 0, fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24); + + sizes.pixel_format = fmt.pixelformat; + sizes.index = 0; + // Query supported frame size + while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &sizes) != -1) { + struct v4l2_frmsize_discrete image_size = sizes.discrete; + // Query supported frame rates + rates.index = 0; + rates.pixel_format = fmt.pixelformat; + rates.width = image_size.width; + rates.height = image_size.height; + if (pixelformatdescription.length() > 2000) break; + if (snprintf( value, sizeof(value), ":%dx%d=", image_size.width, image_size.height ) > 0) + pixelformatdescription.append(value); + fprintf(stderr, "Size: %dx%d: ", image_size.width, image_size.height); + while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &rates) != -1) { + if (pixelformatdescription.length() > 2000) break; + if (snprintf( value, sizeof(value), "%d/%d,", rates.discrete.denominator, rates.discrete.numerator ) > 0) + pixelformatdescription.append(value); + fprintf(stderr, "%d/%d, ", rates.discrete.numerator, rates.discrete.denominator); + rates.index ++; + } + fprintf(stderr, "\n"); + sizes.index++; + } + fmt.index++; + } + } + close(fd); + free(src); + + QStringList result; + if (devName == NULL) + return result; + QString deviceName(devName); + result << (deviceName.isEmpty() ? input : deviceName) << pixelformatdescription; + return result; } -void V4lCaptureHandler::hideOverlay() -{ -} -void V4lCaptureHandler::hidePreview(bool hide) -{ - m_display->setHidden(hide); -} -void V4lCaptureHandler::stopPreview() -{ - if(!m_update) return; - m_update = false; - src_close(&v4lsrc); -}