v4l2src: Calculate framerate from DV timings

And use this framerate in our preference. Note that we also flush
the probed caps as it seems that the format enumeration may change
when a new source change event get triggered.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/870>
This commit is contained in:
Nicolas Dufresne 2021-02-10 16:37:01 -05:00
parent 25696203c3
commit b530c0ef4e
2 changed files with 25 additions and 4 deletions

View file

@ -493,19 +493,39 @@ gst_v4l2src_query_preferred_dv_timings (GstV4l2Src * v4l2src,
{ {
GstV4l2Object *obj = v4l2src->v4l2object; GstV4l2Object *obj = v4l2src->v4l2object;
struct v4l2_dv_timings dv_timings = { 0, }; struct v4l2_dv_timings dv_timings = { 0, };
const struct v4l2_bt_timings *bt = &dv_timings.bt;
gint tot_width, tot_height;
gint gcd;
if (!gst_v4l2_query_dv_timings (obj, &dv_timings)) if (!gst_v4l2_query_dv_timings (obj, &dv_timings))
return FALSE; return FALSE;
pref->width = dv_timings.bt.width; pref->width = bt->width;
pref->height = dv_timings.bt.height; pref->height = bt->height;
/* FIXME calculate frame rate */
tot_height = bt->height +
bt->vfrontporch + bt->vsync + bt->vbackporch +
bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch;
tot_width = bt->width + bt->hfrontporch + bt->hsync + bt->hbackporch;
pref->fps_n = bt->pixelclock;
pref->fps_d = tot_width * tot_height;
if (bt->interlaced)
pref->fps_d /= 2;
gcd = gst_util_greatest_common_divisor (pref->fps_n, pref->fps_d);
pref->fps_n /= gcd;
pref->fps_d /= gcd;
/* If are are not streaming (e.g. we received source-change event), lock the /* If are are not streaming (e.g. we received source-change event), lock the
* new timing immediatly so that TRY_FMT can properly work */ * new timing immediatly so that TRY_FMT can properly work */
if (!obj->pool || !GST_V4L2_BUFFER_POOL_IS_STREAMING (obj->pool)) if (!obj->pool || !GST_V4L2_BUFFER_POOL_IS_STREAMING (obj->pool))
gst_v4l2_set_dv_timings (obj, &dv_timings); gst_v4l2_set_dv_timings (obj, &dv_timings);
GST_INFO_OBJECT (v4l2src, "Using DV Timings: %i x %i (%i/%i fps)",
pref->width, pref->height, pref->fps_n, pref->fps_d);
return TRUE; return TRUE;
} }
@ -922,6 +942,7 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
* streamoff in order to allow locking a new DV_TIMING which will * streamoff in order to allow locking a new DV_TIMING which will
* influence the output of TRY_FMT */ * influence the output of TRY_FMT */
gst_v4l2src_stop (GST_BASE_SRC (src)); gst_v4l2src_stop (GST_BASE_SRC (src));
gst_caps_replace (&obj->probed_caps, NULL);
/* Force renegotiation */ /* Force renegotiation */
v4l2src->renegotiation_adjust = v4l2src->offset + 1; v4l2src->renegotiation_adjust = v4l2src->offset + 1;

View file

@ -1352,7 +1352,7 @@ gst_v4l2_query_dv_timings (GstV4l2Object * v4l2object,
return FALSE; return FALSE;
} }
GST_INFO_OBJECT (v4l2object->dbg_obj, "Detected DV Timings (%i x %i)", GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Detected DV Timings (%i x %i)",
timings->bt.width, timings->bt.height); timings->bt.width, timings->bt.height);
return TRUE; return TRUE;