mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
v4l2rc: Add DV_TIMINGS query and locking
This adds support to DV_TIMINGS query and locking. The timing width and height is then used as a preference. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/870>
This commit is contained in:
parent
b750fb2d5b
commit
25696203c3
4 changed files with 95 additions and 2 deletions
|
@ -41,6 +41,10 @@ G_BEGIN_DECLS
|
||||||
#define GST_V4L2_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_BUFFER_POOL, GstV4l2BufferPool))
|
#define GST_V4L2_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_BUFFER_POOL, GstV4l2BufferPool))
|
||||||
#define GST_V4L2_BUFFER_POOL_CAST(obj) ((GstV4l2BufferPool*)(obj))
|
#define GST_V4L2_BUFFER_POOL_CAST(obj) ((GstV4l2BufferPool*)(obj))
|
||||||
|
|
||||||
|
/* Returns true if the pool is streaming. Must be called with stream lock
|
||||||
|
* held. */
|
||||||
|
#define GST_V4L2_BUFFER_POOL_IS_STREAMING(obj) (GST_V4L2_BUFFER_POOL (obj)->streaming)
|
||||||
|
|
||||||
/* This flow return is used to indicate that the last buffer has been dequeued
|
/* This flow return is used to indicate that the last buffer has been dequeued
|
||||||
* during draining. This should normally only occur for mem-2-mem devices. */
|
* during draining. This should normally only occur for mem-2-mem devices. */
|
||||||
#define GST_V4L2_FLOW_LAST_BUFFER GST_FLOW_CUSTOM_SUCCESS
|
#define GST_V4L2_FLOW_LAST_BUFFER GST_FLOW_CUSTOM_SUCCESS
|
||||||
|
|
|
@ -330,6 +330,10 @@ gboolean gst_v4l2_query_input (GstV4l2Object * v4l2object, struct v4l2_in
|
||||||
gboolean gst_v4l2_get_output (GstV4l2Object * v4l2object, guint32 * output);
|
gboolean gst_v4l2_get_output (GstV4l2Object * v4l2object, guint32 * output);
|
||||||
gboolean gst_v4l2_set_output (GstV4l2Object * v4l2object, guint32 output);
|
gboolean gst_v4l2_set_output (GstV4l2Object * v4l2object, guint32 output);
|
||||||
|
|
||||||
|
/* dv timings */
|
||||||
|
gboolean gst_v4l2_set_dv_timings (GstV4l2Object * v4l2object, struct v4l2_dv_timings *timings);
|
||||||
|
gboolean gst_v4l2_query_dv_timings (GstV4l2Object * v4l2object, struct v4l2_dv_timings *timings);
|
||||||
|
|
||||||
/* frequency control */
|
/* frequency control */
|
||||||
gboolean gst_v4l2_get_frequency (GstV4l2Object * v4l2object, gint tunernum, gulong * frequency);
|
gboolean gst_v4l2_get_frequency (GstV4l2Object * v4l2object, gint tunernum, gulong * frequency);
|
||||||
gboolean gst_v4l2_set_frequency (GstV4l2Object * v4l2object, gint tunernum, gulong frequency);
|
gboolean gst_v4l2_set_frequency (GstV4l2Object * v4l2object, gint tunernum, gulong frequency);
|
||||||
|
|
|
@ -491,8 +491,22 @@ static gboolean
|
||||||
gst_v4l2src_query_preferred_dv_timings (GstV4l2Src * v4l2src,
|
gst_v4l2src_query_preferred_dv_timings (GstV4l2Src * v4l2src,
|
||||||
struct PreferredCapsInfo *pref)
|
struct PreferredCapsInfo *pref)
|
||||||
{
|
{
|
||||||
GST_FIXME_OBJECT (v4l2src, "query dv_timings not implements");
|
GstV4l2Object *obj = v4l2src->v4l2object;
|
||||||
return NULL;
|
struct v4l2_dv_timings dv_timings = { 0, };
|
||||||
|
|
||||||
|
if (!gst_v4l2_query_dv_timings (obj, &dv_timings))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pref->width = dv_timings.bt.width;
|
||||||
|
pref->height = dv_timings.bt.height;
|
||||||
|
/* FIXME calculate frame rate */
|
||||||
|
|
||||||
|
/* If are are not streaming (e.g. we received source-change event), lock the
|
||||||
|
* new timing immediatly so that TRY_FMT can properly work */
|
||||||
|
if (!obj->pool || !GST_V4L2_BUFFER_POOL_IS_STREAMING (obj->pool))
|
||||||
|
gst_v4l2_set_dv_timings (obj, &dv_timings);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -1286,3 +1286,74 @@ gst_v4l2_dequeue_event (GstV4l2Object * v4l2object, struct v4l2_event * event)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_set_dv_timings (GstV4l2Object * v4l2object,
|
||||||
|
struct v4l2_dv_timings * timings)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ret = v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_DV_TIMINGS, timings);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
GST_ERROR_OBJECT (v4l2object->dbg_obj, "S_DV_TIMINGS failed: %s (%i)",
|
||||||
|
g_strerror (errno), errno);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_query_dv_timings (GstV4l2Object * v4l2object,
|
||||||
|
struct v4l2_dv_timings * timings)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ret = v4l2object->ioctl (v4l2object->video_fd, VIDIOC_QUERY_DV_TIMINGS,
|
||||||
|
timings);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
switch (errno) {
|
||||||
|
case ENODATA:
|
||||||
|
GST_DEBUG_OBJECT (v4l2object->dbg_obj,
|
||||||
|
"QUERY_DV_TIMINGS not supported for this input/output");
|
||||||
|
break;
|
||||||
|
case ENOLINK:
|
||||||
|
GST_DEBUG_OBJECT (v4l2object->dbg_obj,
|
||||||
|
"No timings could be detected because no signal was found.");
|
||||||
|
break;
|
||||||
|
case ENOLCK:
|
||||||
|
GST_INFO_OBJECT (v4l2object->dbg_obj,
|
||||||
|
"The signal was unstable and the hardware could not lock on to it.");
|
||||||
|
break;
|
||||||
|
case ERANGE:
|
||||||
|
GST_INFO_OBJECT (v4l2object->dbg_obj,
|
||||||
|
"Timings were found, but they are out of range of the hardware capabilities.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GST_ERROR_OBJECT (v4l2object->dbg_obj,
|
||||||
|
"QUERY_DV_TIMINGS failed: %s (%i)", g_strerror (errno), errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timings->type != V4L2_DV_BT_656_1120) {
|
||||||
|
GST_FIXME_OBJECT (v4l2object->dbg_obj, "Unsupported DV Timings type (%i)",
|
||||||
|
timings->type);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (v4l2object->dbg_obj, "Detected DV Timings (%i x %i)",
|
||||||
|
timings->bt.width, timings->bt.height);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue