v4l2src: Add input signal status detection

As part of the support to select a preferred size, we can also
detect the signal status. This is a split patch so that feature
is separated to ease review.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/870>
This commit is contained in:
Nicolas Dufresne 2021-02-08 17:26:20 -05:00
parent 293abe0675
commit c386aa43cc
2 changed files with 43 additions and 5 deletions

View file

@ -405,9 +405,6 @@ gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps, GstStructure * pref_s)
GST_DEBUG_OBJECT (basesrc, "fixating caps %" GST_PTR_FORMAT, caps);
/* We consider the first structure from peercaps to be a preference. This is
* useful for matching a reported native display, or simply to avoid
* transformation to happen downstream. */
if (pref_s) {
pref_s = gst_structure_copy (pref_s);
gst_v4l2_src_fixate_struct_with_preference (pref_s, &pref);
@ -502,6 +499,36 @@ gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps, GstStructure * pref_s)
return fcaps;
}
static GstStructure *
gst_v4l2src_query_preferred_size (GstV4l2Src * v4l2src)
{
struct v4l2_input in = { 0, };
GstStructure *pref = NULL;
if (!gst_v4l2_get_input (v4l2src->v4l2object, &in.index))
return NULL;
if (!gst_v4l2_query_input (v4l2src->v4l2object, &in))
return NULL;
GST_INFO_OBJECT (v4l2src, "Detect input %u as `%s`", in.index, in.name);
/* Notify signal status using WARNING/INFO messages */
if (in.status & (V4L2_IN_ST_NO_POWER | V4L2_IN_ST_NO_SIGNAL)) {
if (!v4l2src->no_signal)
/* note: taken from decklinksrc element */
GST_ELEMENT_WARNING (v4l2src, RESOURCE, READ, ("Signal lost"),
("No input source was detected - video frames invalid"));
v4l2src->no_signal = TRUE;
} else if (v4l2src->no_signal) {
if (v4l2src->no_signal)
GST_ELEMENT_INFO (v4l2src, RESOURCE, READ,
("Signal recovered"), ("Input source detected"));
v4l2src->no_signal = FALSE;
}
return pref;
}
static gboolean
gst_v4l2src_negotiate (GstBaseSrc * basesrc)
{
@ -539,10 +566,18 @@ gst_v4l2src_negotiate (GstBaseSrc * basesrc)
if (!gst_caps_is_empty (caps)) {
GstStructure *pref = NULL;
if (peercaps && !gst_caps_is_any (peercaps))
pref = gst_caps_get_structure (peercaps, 0);
/* For drivers that has DV timings or other default size query
* capabilities, we will prefer that resolution. */
pref = gst_v4l2src_query_preferred_size (GST_V4L2SRC (basesrc));
/* otherwise consider the first structure from peercaps to be a
* preference. This is useful for matching a reported native display,
* or simply to avoid transformation to happen downstream. */
if (!pref && peercaps && !gst_caps_is_any (peercaps))
pref = gst_structure_copy (gst_caps_get_structure (peercaps, 0));
caps = gst_v4l2src_fixate (basesrc, caps, pref);
gst_structure_free (pref);
/* Fixating may fail as we now set the selected format */
if (!caps) {

View file

@ -68,6 +68,9 @@ struct _GstV4l2Src
/* Timestamp sanity check */
GstClockTime last_timestamp;
gboolean has_bad_timestamp;
/* maintain signal status, updated during negotiation */
gboolean no_signal;
};
struct _GstV4l2SrcClass