Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 29 Aug 2011 11:43:59 +0000 (13:43 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 29 Aug 2011 11:43:59 +0000 (13:43 +0200)
Conflicts:
sys/v4l2/v4l2src_calls.c

1  2 
sys/v4l2/gstv4l2object.c

@@@ -2226,117 -2129,38 +2226,118 @@@ gst_v4l2_object_set_format (GstV4l2Obje
    if (v4l2_ioctl (fd, VIDIOC_G_FMT, &format) < 0)
      goto get_fmt_failed;
  
 -  if (format.type == v4l2object->type &&
 -      format.fmt.pix.width == width &&
 -      format.fmt.pix.height == height &&
 -      format.fmt.pix.pixelformat == pixelformat &&
 -      format.fmt.pix.field == field) {
 -    /* Nothing to do. We want to succeed immediately
 -     * here because setting the same format back
 -     * can still fail due to EBUSY. By short-circuiting
 -     * here, we allow pausing and re-playing pipelines
 -     * with changed caps, as long as the changed caps
 -     * do not change the webcam's format. Otherwise,
 -     * any caps change would require us to go to NULL
 -     * state to close the device and set format.
 -     */
 -    return TRUE;
 +  GST_DEBUG_OBJECT (v4l2object->element, "Got format to %dx%d, format "
 +      "%" GST_FOURCC_FORMAT " bytesperline %d, colorspace %d",
 +      format.fmt.pix.width, format.fmt.pix.height,
 +      GST_FOURCC_ARGS (format.fmt.pix.pixelformat), format.fmt.pix.bytesperline,
 +      format.fmt.pix.colorspace);
 +
 +  if (format.type != v4l2object->type ||
 +      format.fmt.pix.width != width ||
 +      format.fmt.pix.height != height ||
 +      format.fmt.pix.pixelformat != pixelformat ||
 +      format.fmt.pix.field != field || format.fmt.pix.bytesperline != stride) {
 +    /* something different, set the format */
 +    GST_DEBUG_OBJECT (v4l2object->element, "Setting format to %dx%d, format "
 +        "%" GST_FOURCC_FORMAT " bytesperline %d", width, height,
 +        GST_FOURCC_ARGS (pixelformat), stride);
 +
 +    format.type = v4l2object->type;
 +    format.fmt.pix.width = width;
 +    format.fmt.pix.height = height;
 +    format.fmt.pix.pixelformat = pixelformat;
 +    format.fmt.pix.field = field;
 +    /* try to ask our prefered stride */
 +    format.fmt.pix.bytesperline = stride;
 +
 +    if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
 +      goto set_fmt_failed;
 +
 +    GST_DEBUG_OBJECT (v4l2object->element, "Got format to %dx%d, format "
 +        "%" GST_FOURCC_FORMAT " stride %d", format.fmt.pix.width,
 +        format.fmt.pix.height, GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
 +        format.fmt.pix.bytesperline);
 +
 +    if (format.fmt.pix.width != width || format.fmt.pix.height != height)
 +      goto invalid_dimensions;
 +
 +    if (format.fmt.pix.pixelformat != pixelformat)
 +      goto invalid_pixelformat;
    }
  
 -  format.type = v4l2object->type;
 -  format.fmt.pix.width = width;
 -  format.fmt.pix.height = height;
 -  format.fmt.pix.pixelformat = pixelformat;
 -  format.fmt.pix.field = field;
 +  /* figure out the frame layout */
 +  v4l2object->bytesperline = format.fmt.pix.bytesperline;
 +  v4l2object->sizeimage = format.fmt.pix.sizeimage;
 +
 +  GST_DEBUG_OBJECT (v4l2object->element, "Got sizeimage %u",
 +      v4l2object->sizeimage);
 +
 +  /* Is there a reason we require the caller to always specify a framerate? */
 +  GST_DEBUG_OBJECT (v4l2object->element, "Desired framerate: %u/%u", fps_n,
 +      fps_d);
 +
 +  memset (&streamparm, 0x00, sizeof (struct v4l2_streamparm));
 +  streamparm.type = v4l2object->type;
 +
 +  if (v4l2_ioctl (fd, VIDIOC_G_PARM, &streamparm) < 0)
 +    goto get_parm_failed;
 +
 +  GST_VIDEO_INFO_FPS_N (&info) =
 +      streamparm.parm.capture.timeperframe.denominator;
 +  GST_VIDEO_INFO_FPS_D (&info) = streamparm.parm.capture.timeperframe.numerator;
 +
 +  if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 +    GST_DEBUG_OBJECT (v4l2object->element, "Got framerate: %u/%u",
 +        streamparm.parm.capture.timeperframe.denominator,
 +        streamparm.parm.capture.timeperframe.numerator);
 +
-     /* Note: V4L2 provides the frame interval, we have the frame rate */
-     if (!fractions_are_equal (streamparm.parm.capture.timeperframe.numerator,
-             streamparm.parm.capture.timeperframe.denominator, fps_d, fps_n)) {
-       GST_LOG_OBJECT (v4l2object->element, "Setting framerate to %u/%u", fps_n,
-           fps_d);
-       /* We want to change the frame rate, so check whether we can. Some cheap USB
-        * cameras don't have the capability */
-       if ((streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) == 0) {
-         GST_DEBUG_OBJECT (v4l2object->element,
-             "Not setting framerate (not supported)");
-         goto done;
-       }
++    /* We used to skip frame rate setup if the camera was already setup
++     * with the requested frame rate. This breaks some cameras though,
++     * causing them to not output data (several models of Thinkpad cameras
++     * have this problem at least).
++     * So, don't skip. */
++    GST_LOG_OBJECT (v4l2object->element, "Setting framerate to %u/%u", fps_n,
++        fps_d);
++    /* We want to change the frame rate, so check whether we can. Some cheap USB
++     * cameras don't have the capability */
++    if ((streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) == 0) {
++      GST_DEBUG_OBJECT (v4l2object->element,
++          "Not setting framerate (not supported)");
++      goto done;
++    }
 +
-       /* Note: V4L2 wants the frame interval, we have the frame rate */
-       streamparm.parm.capture.timeperframe.numerator = fps_d;
-       streamparm.parm.capture.timeperframe.denominator = fps_n;
++    /* Note: V4L2 wants the frame interval, we have the frame rate */
++    streamparm.parm.capture.timeperframe.numerator = fps_d;
++    streamparm.parm.capture.timeperframe.denominator = fps_n;
  
-       /* some cheap USB cam's won't accept any change */
-       if (v4l2_ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
-         goto set_parm_failed;
 -  if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0) {
 -    goto set_fmt_failed;
++    /* some cheap USB cam's won't accept any change */
++    if (v4l2_ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
++      goto set_parm_failed;
 +
-       /* get new values */
-       fps_d = streamparm.parm.capture.timeperframe.numerator;
-       fps_n = streamparm.parm.capture.timeperframe.denominator;
++    /* get new values */
++    fps_d = streamparm.parm.capture.timeperframe.numerator;
++    fps_n = streamparm.parm.capture.timeperframe.denominator;
 +
-       GST_INFO_OBJECT (v4l2object->element, "Set framerate to %u/%u", fps_n,
-           fps_d);
++    GST_INFO_OBJECT (v4l2object->element, "Set framerate to %u/%u", fps_n,
++        fps_d);
 +
-       GST_VIDEO_INFO_FPS_N (&info) = fps_n;
-       GST_VIDEO_INFO_FPS_D (&info) = fps_d;
-     }
++    GST_VIDEO_INFO_FPS_N (&info) = fps_n;
++    GST_VIDEO_INFO_FPS_D (&info) = fps_d;
    }
  
 -  if (format.fmt.pix.width != width || format.fmt.pix.height != height)
 -    goto invalid_dimensions;
 +done:
 +  /* if we have a framerate pre-calculate duration */
 +  if (fps_n > 0 && fps_d > 0) {
 +    v4l2object->duration = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
 +  } else {
 +    v4l2object->duration = GST_CLOCK_TIME_NONE;
 +  }
 +  v4l2object->info = info;
 +  v4l2object->fmtdesc = fmtdesc;
  
 -  if (format.fmt.pix.pixelformat != pixelformat)
 -    goto invalid_pixelformat;
 +  /* now configure ther pools */
 +  if (!gst_v4l2_object_setup_pool (v4l2object, caps))
 +    goto pool_failed;
  
    return TRUE;