Esempio n. 1
0
void enumerateControls(struct vdIn *vd, globals *pglobal, int id)
{
    // enumerating v4l2 controls
    struct v4l2_queryctrl ctrl;
    pglobal->in[id].parametercount = 0;
    pglobal->in[id].in_parameters = NULL;
    /* Enumerate the v4l2 controls
     Try the extended control API first */
#ifdef V4L2_CTRL_FLAG_NEXT_CTRL
    DBG("V4L2 API's V4L2_CTRL_FLAG_NEXT_CTRL is supported\n");
    ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
    if(0 == IOCTL_VIDEO(vd->fd, VIDIOC_QUERYCTRL, &ctrl)) {
        do {
            control_readed(vd, &ctrl, pglobal, id);
            ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
        } while(0 == IOCTL_VIDEO(vd->fd, VIDIOC_QUERYCTRL, &ctrl));
        // note: use simple ioctl or v4l2_ioctl instead of the xioctl
    } else
#endif
    {
        DBG("V4L2 API's V4L2_CTRL_FLAG_NEXT_CTRL is NOT supported\n");
        /* Fall back on the standard API */
        /* Check all the standard controls */
        int i;
        for(i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
            ctrl.id = i;
            if(IOCTL_VIDEO(vd->fd, VIDIOC_QUERYCTRL, &ctrl) == 0) {
                control_readed(vd, &ctrl, pglobal, id);
            }
        }

        /* Check any custom controls */
        for(i = V4L2_CID_PRIVATE_BASE; ; i++) {
            ctrl.id = i;
            if(IOCTL_VIDEO(vd->fd, VIDIOC_QUERYCTRL, &ctrl) == 0) {
                control_readed(vd, &ctrl, pglobal, id);
            } else {
                break;
            }
        }
    }

    memset(&pglobal->in[id].jpegcomp, 0, sizeof(struct v4l2_jpegcompression));
    if(xioctl(vd->fd, VIDIOC_G_JPEGCOMP, &pglobal->in[id].jpegcomp) != EINVAL) {
        DBG("JPEG compression details:\n");
        DBG("Quality: %d\n", pglobal->in[id].jpegcomp.quality);
        DBG("APPn: %d\n", pglobal->in[id].jpegcomp.APPn);
        DBG("APP length: %d\n", pglobal->in[id].jpegcomp.APP_len);
        DBG("APP data: %s\n", pglobal->in[id].jpegcomp.APP_data);
        DBG("COM length: %d\n", pglobal->in[id].jpegcomp.COM_len);
        DBG("COM data: %s\n", pglobal->in[id].jpegcomp.COM_data);
        struct v4l2_queryctrl ctrl_jpeg;
        ctrl_jpeg.id = 1;
        sprintf((char*)&ctrl_jpeg.name, "JPEG quality");
        ctrl_jpeg.minimum = 0;
        ctrl_jpeg.maximum = 100;
        ctrl_jpeg.step = 1;
        ctrl_jpeg.default_value = 50;
        ctrl_jpeg.flags = 0;
        ctrl_jpeg.type = V4L2_CTRL_TYPE_INTEGER;
        if (pglobal->in[id].in_parameters == NULL) {
            pglobal->in[id].in_parameters = (control*)calloc(1, sizeof(control));
        } else {
            pglobal->in[id].in_parameters = (control*)realloc(pglobal->in[id].in_parameters,(pglobal->in[id].parametercount + 1) * sizeof(control));
        }

        if (pglobal->in[id].in_parameters == NULL) {
            DBG("Calloc/realloc failed\n");
            return;
        }

        memcpy(&pglobal->in[id].in_parameters[pglobal->in[id].parametercount].ctrl, &ctrl_jpeg, sizeof(struct v4l2_queryctrl));
        pglobal->in[id].in_parameters[pglobal->in[id].parametercount].group = IN_CMD_JPEG_QUALITY;
        pglobal->in[id].in_parameters[pglobal->in[id].parametercount].value = pglobal->in[id].jpegcomp.quality;
        pglobal->in[id].parametercount++;
    } else {
        DBG("Modifying the setting of the JPEG compression is not supported\n");
        pglobal->in[id].jpegcomp.quality = -1;
    }

}
Esempio n. 2
0
int init_videoIn(struct vdIn *vd, char *device, int width,
                 int height, int fps, int format, int grabmethod, globals *pglobal)
{
    if (vd == NULL || device == NULL)
        return -1;
    if (width == 0 || height == 0)
        return -1;
    if (grabmethod < 0 || grabmethod > 1)
        grabmethod = 1;		//mmap by default;
    vd->videodevice = NULL;
    vd->status = NULL;
    vd->pictName = NULL;
    vd->videodevice = (char *) calloc (1, 16 * sizeof (char));
    vd->status = (char *) calloc (1, 100 * sizeof (char));
    vd->pictName = (char *) calloc (1, 80 * sizeof (char));
    snprintf (vd->videodevice, 16-1, "%s", device);
    vd->toggleAvi = 0;
    vd->getPict = 0;
    vd->signalquit = 1;
    vd->width = width;
    vd->height = height;
    vd->fps = fps;
    vd->formatIn = format;
    vd->grabmethod = grabmethod;
    if (init_v4l2 (vd) < 0) {
        fprintf (stderr, " Init v4L2 failed !! exit fatal \n");
        goto error;;
    }

    // enumerating v4l2 controls
    struct v4l2_queryctrl ctrl;
    pglobal->in.parametercount = 0;
    pglobal->in.in_parameters = malloc(0 * sizeof(input_control));
    /* Enumerate the v4l2 controls
     Try the extended control API first */
    #ifdef V4L2_CTRL_FLAG_NEXT_CTRL
    ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
    if(0 == IOCTL_VIDEO(vd->fd, VIDIOC_QUERYCTRL, &ctrl)) {
        do {
            control_readed(vd, &ctrl, pglobal);
            ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
        } while(0 == ioctl (vd->fd, VIDIOC_QUERYCTRL, &ctrl));
    } else
    #endif
    {
        /* Fall back on the standard API */
        /* Check all the standard controls */
        int i;
        for(i = V4L2_CID_BASE; i<V4L2_CID_LASTP1; i++) {
            ctrl.id = i;
            if(IOCTL_VIDEO(vd->fd, VIDIOC_QUERYCTRL, &ctrl) == 0) {
                control_readed(vd, &ctrl, pglobal);
            }
        }

        /* Check any custom controls */
        for(i=V4L2_CID_PRIVATE_BASE; ; i++) {
            ctrl.id = i;
            if(IOCTL_VIDEO(vd->fd, VIDIOC_QUERYCTRL, &ctrl) == 0) {
                control_readed(vd, &ctrl, pglobal);
            } else {
                break;
            }
        }
    }

    // enumerating formats
    int currentWidth, currentHeight = 0;
    struct v4l2_format currentFormat;
    currentFormat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (IOCTL_VIDEO(vd->fd, VIDIOC_G_FMT, &currentFormat) == 0) {
        currentWidth = currentFormat.fmt.pix.width;
        currentHeight = currentFormat.fmt.pix.height;
        DBG("%Current size: dx%d\n", currentWidth, currentHeight);
    }

    pglobal->in.in_formats = malloc(0 * sizeof(struct v4l2_fmtdesc));
    for (pglobal->in.formatCount = 0; 1; pglobal->in.formatCount++) {
         struct v4l2_fmtdesc fmtdesc;
         fmtdesc.index = pglobal->in.formatCount;
         fmtdesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
         if (IOCTL_VIDEO(vd->fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
             break;
         }
         pglobal->in.in_formats =
            (input_format*)realloc(pglobal->in.in_formats, (pglobal->in.formatCount + 1) * sizeof(input_format));
        memcpy(&pglobal->in.in_formats[pglobal->in.formatCount], &fmtdesc, sizeof(input_format));

        if (fmtdesc.pixelformat == format)
            pglobal->in.currentFormat = pglobal->in.formatCount;

        DBG("Supported format: %s\n", fmtdesc.description);
        struct v4l2_frmsizeenum fsenum;
        fsenum.index = pglobal->in.formatCount;
        fsenum.pixel_format = fmtdesc.pixelformat;
        int j = 0;
        pglobal->in.in_formats[pglobal->in.formatCount].supportedResolutions = malloc(0);
        pglobal->in.in_formats[pglobal->in.formatCount].resolutionCount = 0;
        pglobal->in.in_formats[pglobal->in.formatCount].currentResolution = -1;
        while (1) {
            fsenum.index = j;
            j++;
            if(IOCTL_VIDEO(vd->fd, VIDIOC_ENUM_FRAMESIZES, &fsenum) == 0) {
                pglobal->in.in_formats[pglobal->in.formatCount].resolutionCount++;
                pglobal->in.in_formats[pglobal->in.formatCount].supportedResolutions = (input_resolution*)
                realloc(pglobal->in.in_formats[pglobal->in.formatCount].supportedResolutions, j * sizeof(input_resolution));
                pglobal->in.in_formats[pglobal->in.formatCount].supportedResolutions[j-1].width = fsenum.discrete.width;
                pglobal->in.in_formats[pglobal->in.formatCount].supportedResolutions[j-1].height = fsenum.discrete.height;
                if (format == fmtdesc.pixelformat) {
                    pglobal->in.in_formats[pglobal->in.formatCount].currentResolution = (j-1);
                    DBG("\tSupported size with the current format: %dx%d\n", fsenum.discrete.width, fsenum.discrete.height);
                } else {
                    DBG("\tSupported size: %dx%d\n", fsenum.discrete.width, fsenum.discrete.height);
                }
            } else {
                break;
            }
        }
     }

  /* alloc a temp buffer to reconstruct the pict */
  vd->framesizeIn = (vd->width * vd->height << 1);
  switch (vd->formatIn) {
  case V4L2_PIX_FMT_MJPEG:
    vd->tmpbuffer = (unsigned char *) calloc(1, (size_t) vd->framesizeIn);
    if (!vd->tmpbuffer)
      goto error;
    vd->framebuffer =
        (unsigned char *) calloc(1, (size_t) vd->width * (vd->height + 8) * 2);
    break;
  case V4L2_PIX_FMT_YUYV:
    vd->framebuffer =
        (unsigned char *) calloc(1, (size_t) vd->framesizeIn);
    break;
  default:
    fprintf(stderr, " should never arrive exit fatal !!\n");
    goto error;
    break;

  }

  if (!vd->framebuffer)
    goto error;
  return 0;
error:
  free(pglobal->in.in_parameters);
  free(vd->videodevice);
  free(vd->status);
  free(vd->pictName);
  close(vd->fd);
  return -1;
}