mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-14 13:21:28 +00:00
v4l2: encoder: Add dynamic framerate support
This is not trully supported in V4L2, but we can emulate this similar to what other elements do. In this patch we ensure that 0/1 is supported by encoders (caps query),and uses a default of 30fps whenever we need to set a framerate into the driver. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7352>
This commit is contained in:
parent
5182cac9be
commit
ee925c506c
2 changed files with 38 additions and 9 deletions
|
@ -4380,15 +4380,25 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
|||
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;
|
||||
/* Variable framerate is not a V4L2 concept, simply default to 30fps */
|
||||
if (fps_n == 0 && fps_d == 1) {
|
||||
GST_DEBUG_OBJECT (v4l2object->dbg_obj,
|
||||
"Variable framerate not supported, assuming 30fps");
|
||||
streamparm.parm.capture.timeperframe.numerator = 1;
|
||||
streamparm.parm.capture.timeperframe.denominator = 30;
|
||||
} else {
|
||||
/* 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 (v4l2object->ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
|
||||
goto set_parm_failed;
|
||||
|
||||
if (streamparm.parm.capture.timeperframe.numerator > 0 &&
|
||||
if (fps_n == 0 && fps_d == 1) {
|
||||
/* just keep reporting variable framerate */
|
||||
} else if (streamparm.parm.capture.timeperframe.numerator > 0 &&
|
||||
streamparm.parm.capture.timeperframe.denominator > 0) {
|
||||
/* get new values */
|
||||
fps_d = streamparm.parm.capture.timeperframe.numerator;
|
||||
|
@ -4423,14 +4433,24 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
|||
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;
|
||||
/* Variable framerate is not a V4L2 concept, simply default to 30fps */
|
||||
if (fps_n == 0 && fps_d == 1) {
|
||||
GST_DEBUG_OBJECT (v4l2object->dbg_obj,
|
||||
"Variable framerate not supported, assuming 30fps");
|
||||
streamparm.parm.output.timeperframe.numerator = 1;
|
||||
streamparm.parm.output.timeperframe.denominator = 30;
|
||||
} else {
|
||||
/* 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 (v4l2object->ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
|
||||
goto set_parm_failed;
|
||||
|
||||
if (streamparm.parm.output.timeperframe.numerator > 0 &&
|
||||
if (fps_n == 0 && fps_d == 1) {
|
||||
/* just keep reporting variable framerate */
|
||||
} else if (streamparm.parm.output.timeperframe.numerator > 0 &&
|
||||
streamparm.parm.output.timeperframe.denominator > 0) {
|
||||
/* get new values */
|
||||
fps_d = streamparm.parm.output.timeperframe.numerator;
|
||||
|
|
|
@ -111,7 +111,7 @@ gst_v4l2_video_enc_open (GstVideoEncoder * encoder)
|
|||
{
|
||||
GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
|
||||
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||
GstCaps *codec_caps;
|
||||
GstCaps *tmp_caps, *codec_caps;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Opening");
|
||||
|
||||
|
@ -124,6 +124,15 @@ gst_v4l2_video_enc_open (GstVideoEncoder * encoder)
|
|||
self->probed_sinkcaps = gst_v4l2_object_probe_caps (self->v4l2output,
|
||||
gst_v4l2_object_get_raw_caps ());
|
||||
|
||||
/*
|
||||
* Relax the framerate to always allow 0/1 regardless of what the driver
|
||||
* wants. This improve compatibility of the encoder with sources which may
|
||||
* not know the frame rate
|
||||
*/
|
||||
tmp_caps = gst_caps_copy (self->probed_sinkcaps);
|
||||
gst_caps_set_simple (tmp_caps, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
|
||||
gst_caps_append (self->probed_sinkcaps, tmp_caps);
|
||||
|
||||
if (gst_caps_is_empty (self->probed_sinkcaps))
|
||||
goto no_raw_format;
|
||||
|
||||
|
|
Loading…
Reference in a new issue