mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
v4l2object: set streamparm for outputs that support it
Without a specified framerate from the sink, the decoder frame interval should be set using the framerate of the encoded video stream. Therefore, the v4l2object should be able to change the framerate on the output if the V4L2 device accepts it. This is also necessary for mem2mem encoders so that their bitrate calculation code may work correctly and they may report the correct frame duration on the capture queue. https://bugzilla.gnome.org/show_bug.cgi?id=779466
This commit is contained in:
parent
1d43f6d852
commit
ce5c0b8f92
1 changed files with 53 additions and 10 deletions
|
@ -3460,13 +3460,14 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
|||
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
|
||||
|| v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
GST_DEBUG_OBJECT (v4l2object->element, "Got framerate: %u/%u",
|
||||
GST_VIDEO_INFO_FPS_N (&info) =
|
||||
streamparm.parm.capture.timeperframe.denominator;
|
||||
GST_VIDEO_INFO_FPS_D (&info) =
|
||||
streamparm.parm.capture.timeperframe.numerator;
|
||||
|
||||
GST_DEBUG_OBJECT (v4l2object->element, "Got capture framerate: %u/%u",
|
||||
streamparm.parm.capture.timeperframe.denominator,
|
||||
streamparm.parm.capture.timeperframe.numerator);
|
||||
|
||||
|
@ -3475,13 +3476,13 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
|||
* 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);
|
||||
GST_LOG_OBJECT (v4l2object->element, "Setting capture 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)");
|
||||
"Not setting capture framerate (not supported)");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -3499,14 +3500,56 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
|||
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 capture framerate to %u/%u",
|
||||
fps_n, fps_d);
|
||||
} else {
|
||||
/* fix v4l2 capture driver to provide framerate values */
|
||||
GST_WARNING_OBJECT (v4l2object->element,
|
||||
"Reuse caps framerate %u/%u - fix v4l2 capture driver", fps_n, fps_d);
|
||||
}
|
||||
|
||||
GST_VIDEO_INFO_FPS_N (&info) = fps_n;
|
||||
GST_VIDEO_INFO_FPS_D (&info) = fps_d;
|
||||
} else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT
|
||||
|| v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
GST_VIDEO_INFO_FPS_N (&info) =
|
||||
streamparm.parm.output.timeperframe.denominator;
|
||||
GST_VIDEO_INFO_FPS_D (&info) =
|
||||
streamparm.parm.output.timeperframe.numerator;
|
||||
|
||||
GST_DEBUG_OBJECT (v4l2object->element, "Got output framerate: %u/%u",
|
||||
streamparm.parm.output.timeperframe.denominator,
|
||||
streamparm.parm.output.timeperframe.numerator);
|
||||
|
||||
GST_LOG_OBJECT (v4l2object->element, "Setting output framerate to %u/%u",
|
||||
fps_n, fps_d);
|
||||
if ((streamparm.parm.output.capability & V4L2_CAP_TIMEPERFRAME) == 0) {
|
||||
GST_DEBUG_OBJECT (v4l2object->element,
|
||||
"Not setting output framerate (not supported)");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Note: V4L2 wants the frame interval, we have the frame rate */
|
||||
streamparm.parm.output.timeperframe.numerator = fps_d;
|
||||
streamparm.parm.output.timeperframe.denominator = fps_n;
|
||||
|
||||
if (v4l2_ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
|
||||
goto set_parm_failed;
|
||||
|
||||
if (streamparm.parm.output.timeperframe.numerator > 0 &&
|
||||
streamparm.parm.output.timeperframe.denominator > 0) {
|
||||
/* get new values */
|
||||
fps_d = streamparm.parm.output.timeperframe.numerator;
|
||||
fps_n = streamparm.parm.output.timeperframe.denominator;
|
||||
|
||||
GST_INFO_OBJECT (v4l2object->element, "Set output framerate to %u/%u",
|
||||
fps_n, fps_d);
|
||||
} else {
|
||||
/* fix v4l2 output driver to provide framerate values */
|
||||
GST_WARNING_OBJECT (v4l2object->element,
|
||||
"Reuse caps framerate %u/%u - fix v4l2 output driver", fps_n, fps_d);
|
||||
}
|
||||
|
||||
GST_VIDEO_INFO_FPS_N (&info) = fps_n;
|
||||
GST_VIDEO_INFO_FPS_D (&info) = fps_d;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue