mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
Fixed framerate negotiation.
Original commit message from CVS: Fixed framerate negotiation.
This commit is contained in:
parent
924cccc726
commit
4a30124701
3 changed files with 106 additions and 14 deletions
|
@ -755,13 +755,9 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
|
||||||
gst_structure_set (structure,
|
gst_structure_set (structure,
|
||||||
"width", GST_TYPE_INT_RANGE, min_w, max_w,
|
"width", GST_TYPE_INT_RANGE, min_w, max_w,
|
||||||
"height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
|
"height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
|
||||||
if (fps_n > 0) {
|
|
||||||
gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
|
|
||||||
fps_n, fps_d, NULL);
|
|
||||||
} else {
|
|
||||||
gst_structure_set (structure, "framerate", GST_TYPE_FRACTION_RANGE,
|
gst_structure_set (structure, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||||
1, 1, 100, 1, NULL);
|
1, 1, 100, 1, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
|
|
||||||
|
@ -778,6 +774,8 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
||||||
gint w, h;
|
gint w, h;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
struct v4l2_fmtdesc *format;
|
struct v4l2_fmtdesc *format;
|
||||||
|
const GValue *framerate;
|
||||||
|
guint fps_n, fps_d;
|
||||||
|
|
||||||
v4l2src = GST_V4L2SRC (src);
|
v4l2src = GST_V4L2SRC (src);
|
||||||
|
|
||||||
|
@ -803,18 +801,37 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
||||||
|
|
||||||
gst_structure_get_int (structure, "width", &w);
|
gst_structure_get_int (structure, "width", &w);
|
||||||
gst_structure_get_int (structure, "height", &h);
|
gst_structure_get_int (structure, "height", &h);
|
||||||
|
framerate = gst_structure_get_value (structure, "framerate");
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2src, "trying to set_capture %dx%d, format %s",
|
GST_DEBUG_OBJECT (v4l2src, "trying to set_capture %dx%d, format %s",
|
||||||
w, h, format->description);
|
w, h, format->description);
|
||||||
/* this only fills in v4l2src->mmap values */
|
|
||||||
if (!gst_v4l2src_set_capture (v4l2src, format, &w, &h)) {
|
if (framerate) {
|
||||||
|
fps_n = gst_value_get_fraction_numerator (framerate);
|
||||||
|
fps_d = gst_value_get_fraction_denominator (framerate);
|
||||||
|
} else {
|
||||||
|
fps_n = 0;
|
||||||
|
fps_d = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_v4l2src_set_capture (v4l2src, format, &w, &h, &fps_n, &fps_d)) {
|
||||||
GST_WARNING_OBJECT (v4l2src, "could not set_capture %dx%d, format %s",
|
GST_WARNING_OBJECT (v4l2src, "could not set_capture %dx%d, format %s",
|
||||||
w, h, format->description);
|
w, h, format->description);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_structure_set (structure, "width", G_TYPE_INT, w, "height", G_TYPE_INT, h,
|
if (fps_n) {
|
||||||
NULL);
|
gst_structure_set (structure,
|
||||||
|
"width", G_TYPE_INT, w,
|
||||||
|
"height", G_TYPE_INT, h,
|
||||||
|
"framerate", GST_TYPE_FRACTION,
|
||||||
|
gst_value_get_fraction_numerator (framerate),
|
||||||
|
gst_value_get_fraction_denominator (framerate), NULL);
|
||||||
|
} else {
|
||||||
|
gst_structure_set (structure,
|
||||||
|
"width", G_TYPE_INT, w,
|
||||||
|
"height", G_TYPE_INT, h, "framerate", GST_TYPE_FRACTION, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (!gst_v4l2src_capture_init (v4l2src))
|
if (!gst_v4l2src_capture_init (v4l2src))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -822,6 +839,20 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
||||||
if (!gst_v4l2src_capture_start (v4l2src))
|
if (!gst_v4l2src_capture_start (v4l2src))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (v4l2src->fps_n != fps_n || v4l2src->fps_d != fps_d) {
|
||||||
|
GST_WARNING_OBJECT (v4l2src,
|
||||||
|
"framerate changed after start capturing from %u/%u to %u/%u", fps_n,
|
||||||
|
fps_d, v4l2src->fps_n, v4l2src->fps_d);
|
||||||
|
if (fps_n) {
|
||||||
|
gst_structure_set (structure,
|
||||||
|
"width", G_TYPE_INT, w,
|
||||||
|
"height", G_TYPE_INT, h,
|
||||||
|
"framerate", GST_TYPE_FRACTION,
|
||||||
|
gst_value_get_fraction_numerator (framerate),
|
||||||
|
gst_value_get_fraction_denominator (framerate), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,7 +979,7 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
|
||||||
|
|
||||||
if (v4l2src->use_fixed_fps && v4l2src->fps_n == 0) {
|
if (v4l2src->use_fixed_fps && v4l2src->fps_n == 0) {
|
||||||
GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
|
GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
|
||||||
("could not get frame rate for element"));
|
("could not get frame rate for element, try to set use-fixed-fps property to false"));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -240,8 +240,13 @@ gst_v4l2src_get_capture (GstV4l2Src * v4l2src)
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
|
gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
|
||||||
struct v4l2_fmtdesc * fmt, gint * width, gint * height)
|
struct v4l2_fmtdesc * fmt, gint * width, gint * height,
|
||||||
|
guint * fps_n, guint * fps_d)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
guint new_fps_n = *fps_n;
|
||||||
|
guint new_fps_d = *fps_d;
|
||||||
|
|
||||||
DEBUG ("Setting capture format to %dx%d, format %s",
|
DEBUG ("Setting capture format to %dx%d, format %s",
|
||||||
*width, *height, fmt->description);
|
*width, *height, fmt->description);
|
||||||
|
|
||||||
|
@ -279,9 +284,31 @@ gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmt->pixelformat != v4l2src->format.fmt.pix.pixelformat) {
|
if (fmt->pixelformat != v4l2src->format.fmt.pix.pixelformat) {
|
||||||
|
GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
|
||||||
|
("failed to set pixelformat to %s @ %dx%d for device %s: %s",
|
||||||
|
fmt->description, *width, *height,
|
||||||
|
v4l2src->v4l2object->videodev, g_strerror (errno)));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*fps_n) {
|
||||||
|
if (gst_v4l2src_set_fps (v4l2src, &new_fps_n, &new_fps_d)) {
|
||||||
|
if (new_fps_n != *fps_n || new_fps_d != *fps_d) {
|
||||||
|
DEBUG ("Updating framerate from %u/%u to %u%u",
|
||||||
|
*fps_n, *fps_d, new_fps_n, new_fps_d);
|
||||||
|
*fps_n = new_fps_n;
|
||||||
|
*fps_d = new_fps_d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (gst_v4l2src_get_fps (v4l2src, &new_fps_n, &new_fps_d)) {
|
||||||
|
DEBUG ("framerate is %u/%u", new_fps_n, new_fps_d);
|
||||||
|
*fps_n = new_fps_n;
|
||||||
|
*fps_d = new_fps_d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*width = v4l2src->format.fmt.pix.width;
|
*width = v4l2src->format.fmt.pix.width;
|
||||||
*height = v4l2src->format.fmt.pix.height;
|
*height = v4l2src->format.fmt.pix.height;
|
||||||
|
|
||||||
|
@ -644,6 +671,34 @@ gst_v4l2src_update_fps (GstV4l2Object * v4l2object)
|
||||||
return gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d);
|
return gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2src_set_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d)
|
||||||
|
{
|
||||||
|
|
||||||
|
GstV4l2Object *v4l2object = v4l2src->v4l2object;
|
||||||
|
struct v4l2_streamparm stream;
|
||||||
|
|
||||||
|
memset (&stream, 0x00, sizeof (struct v4l2_streamparm));
|
||||||
|
stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
if (ioctl (v4l2object->video_fd, VIDIOC_G_PARM, &stream) == 0 &&
|
||||||
|
stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
|
||||||
|
|
||||||
|
stream.parm.capture.timeperframe.denominator = *fps_n;
|
||||||
|
stream.parm.capture.timeperframe.numerator = *fps_d;
|
||||||
|
|
||||||
|
if (ioctl (v4l2object->video_fd, VIDIOC_S_PARM, &stream) == 0) {
|
||||||
|
*fps_n = stream.parm.capture.timeperframe.denominator;
|
||||||
|
*fps_d = stream.parm.capture.timeperframe.numerator;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d)
|
gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d)
|
||||||
{
|
{
|
||||||
|
@ -656,6 +711,7 @@ gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Try to get the frame rate directly from the device using VIDIOC_G_PARM */
|
/* Try to get the frame rate directly from the device using VIDIOC_G_PARM */
|
||||||
|
memset (&stream, 0x00, sizeof (struct v4l2_streamparm));
|
||||||
stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
if (ioctl (v4l2object->video_fd, VIDIOC_G_PARM, &stream) == 0 &&
|
if (ioctl (v4l2object->video_fd, VIDIOC_G_PARM, &stream) == 0 &&
|
||||||
stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
|
stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
|
||||||
|
|
|
@ -28,7 +28,8 @@
|
||||||
gboolean gst_v4l2src_get_capture (GstV4l2Src * v4l2src);
|
gboolean gst_v4l2src_get_capture (GstV4l2Src * v4l2src);
|
||||||
gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
|
gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
|
||||||
struct v4l2_fmtdesc *fmt,
|
struct v4l2_fmtdesc *fmt,
|
||||||
gint * width, gint * height);
|
gint * width, gint * height,
|
||||||
|
guint *fps_n, guint * fps_d);
|
||||||
gboolean gst_v4l2src_capture_init (GstV4l2Src * v4l2src);
|
gboolean gst_v4l2src_capture_init (GstV4l2Src * v4l2src);
|
||||||
gboolean gst_v4l2src_capture_start (GstV4l2Src * v4l2src);
|
gboolean gst_v4l2src_capture_start (GstV4l2Src * v4l2src);
|
||||||
gint gst_v4l2src_grab_frame (GstV4l2Src * v4l2src);
|
gint gst_v4l2src_grab_frame (GstV4l2Src * v4l2src);
|
||||||
|
@ -54,6 +55,10 @@ gst_v4l2src_update_fps (GstV4l2Object * v4l2object);
|
||||||
extern gboolean
|
extern gboolean
|
||||||
gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d);
|
gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d);
|
||||||
|
|
||||||
|
|
||||||
|
extern gboolean
|
||||||
|
gst_v4l2src_set_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d);
|
||||||
|
|
||||||
GValue *gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src);
|
GValue *gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src);
|
||||||
|
|
||||||
GstBuffer *gst_v4l2src_buffer_new (GstV4l2Src * v4l2src,
|
GstBuffer *gst_v4l2src_buffer_new (GstV4l2Src * v4l2src,
|
||||||
|
|
Loading…
Reference in a new issue