gboolean gst_v4l2sink_set_output (GstV4l2Sink * v4l2sink, guint32 pixelformat, guint32 width, guint32 height, guint fps_n, guint fps_d) { gint fd = v4l2sink->v4l2object->video_fd; struct v4l2_streamparm stream; if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G')) return TRUE; if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, pixelformat, width, height)) { /* error already reported */ return FALSE; } /* Is there a reason we require the caller to always specify a framerate? */ GST_LOG_OBJECT (v4l2sink, "Desired framerate: %u/%u", fps_n, fps_d); memset (&stream, 0x00, sizeof (struct v4l2_streamparm)); stream.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (v4l2_ioctl (fd, VIDIOC_G_PARM, &stream) < 0) { GST_ELEMENT_WARNING (v4l2sink, RESOURCE, SETTINGS, (_("Could not get parameters on device '%s'"), v4l2sink->v4l2object->videodev), GST_ERROR_SYSTEM); goto done; } /* Note: V4L2 provides the frame interval, we have the frame rate */ if (fractions_are_equal (stream.parm.output.timeperframe.numerator, stream.parm.output.timeperframe.denominator, fps_d, fps_n)) { GST_LOG_OBJECT (v4l2sink, "Desired framerate already set"); v4l2sink->fps_n = fps_n; v4l2sink->fps_d = fps_d; goto done; } /* We want to change the frame rate, so check whether we can. Some cheap USB * cameras don't have the capability */ if ((stream.parm.output.capability & V4L2_CAP_TIMEPERFRAME) == 0) { GST_DEBUG_OBJECT (v4l2sink, "Not setting framerate (not supported)"); goto done; } GST_LOG_OBJECT (v4l2sink, "Setting framerate to %u/%u", fps_n, fps_d); /* Note: V4L2 wants the frame interval, we have the frame rate */ stream.parm.output.timeperframe.numerator = fps_n; stream.parm.output.timeperframe.denominator = fps_d; /* some cheap USB cam's won't accept any change */ if (v4l2_ioctl (fd, VIDIOC_S_PARM, &stream) < 0) { GST_ELEMENT_WARNING (v4l2sink, RESOURCE, SETTINGS, (_("Video input device did not accept new frame rate setting.")), GST_ERROR_SYSTEM); goto done; } v4l2sink->fps_n = fps_n; v4l2sink->fps_d = fps_d; /* if we have a framerate pre-calculate duration */ if (fps_n > 0 && fps_d > 0) { v4l2sink->duration = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n); } else { v4l2sink->duration = GST_CLOCK_TIME_NONE; } GST_INFO_OBJECT (v4l2sink, "Set framerate to %u/%u and duration to %" GST_TIME_FORMAT, fps_n, fps_d, GST_TIME_ARGS (v4l2sink->duration)); done: return TRUE; }
/****************************************************** * gst_v4l2src_set_capture(): * set capture parameters * return value: TRUE on success, FALSE on error ******************************************************/ gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat, guint32 width, guint32 height, guint fps_n, guint fps_d) { gint fd = v4l2src->v4l2object->video_fd; struct v4l2_streamparm stream; if (!gst_v4l2_object_set_format (v4l2src->v4l2object, pixelformat, width, height)) { /* error already reported */ return FALSE; } /* Is there a reason we require the caller to always specify a framerate? */ GST_LOG_OBJECT (v4l2src, "Desired framerate: %u/%u", fps_n, fps_d); memset (&stream, 0x00, sizeof (struct v4l2_streamparm)); stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (v4l2_ioctl (fd, VIDIOC_G_PARM, &stream) < 0) { GST_ELEMENT_WARNING (v4l2src, RESOURCE, SETTINGS, (_("Could not get parameters on device '%s'"), v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM); goto done; } /* Note: V4L2 provides the frame interval, we have the frame rate */ if (fractions_are_equal (stream.parm.capture.timeperframe.numerator, stream.parm.capture.timeperframe.denominator, fps_d, fps_n)) { GST_LOG_OBJECT (v4l2src, "Desired framerate already set"); v4l2src->fps_n = fps_n; v4l2src->fps_d = fps_d; goto done; } /* We want to change the frame rate, so check whether we can. Some cheap USB * cameras don't have the capability */ if ((stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) == 0) { GST_DEBUG_OBJECT (v4l2src, "Not setting framerate (not supported)"); goto done; } GST_LOG_OBJECT (v4l2src, "Setting framerate to %u/%u", fps_n, fps_d); /* Note: V4L2 wants the frame interval, we have the frame rate */ stream.parm.capture.timeperframe.numerator = fps_d; stream.parm.capture.timeperframe.denominator = fps_n; /* some cheap USB cam's won't accept any change */ if (v4l2_ioctl (fd, VIDIOC_S_PARM, &stream) < 0) { GST_ELEMENT_WARNING (v4l2src, RESOURCE, SETTINGS, (_("Video input device did not accept new frame rate setting.")), GST_ERROR_SYSTEM); goto done; } v4l2src->fps_n = fps_n; v4l2src->fps_d = fps_d; GST_INFO_OBJECT (v4l2src, "Set framerate to %u/%u", fps_n, fps_d); done: return TRUE; }