mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11: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_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
|
||||
* during draining. This should normally only occur for mem-2-mem devices. */
|
||||
#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_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 */
|
||||
gboolean gst_v4l2_get_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,
|
||||
struct PreferredCapsInfo *pref)
|
||||
{
|
||||
GST_FIXME_OBJECT (v4l2src, "query dv_timings not implements");
|
||||
return NULL;
|
||||
GstV4l2Object *obj = v4l2src->v4l2object;
|
||||
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
|
||||
|
|
|
@ -1286,3 +1286,74 @@ gst_v4l2_dequeue_event (GstV4l2Object * v4l2object, struct v4l2_event * event)
|
|||
|
||||
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