summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2021-02-04 14:13:32 -0500
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2021-02-19 16:02:02 -0500
commitbb1d9b398e418d3c4cc8552c4a73556c4241ff8e (patch)
treead14d65995d19a33a607b96355c0a44b9a60ef32 /sys
parent4be9bf4085de241e4d755d86da583b41460b6094 (diff)
v4l2bufferpool: Handle resolution change event
This patch adds the detection, dequeuing and reporting of the SOURCE_CHANGE event when the CH_RESOLUTION flag is set. The acquire function will now return a new custom success called GST_V4L2_FLOW_RESOLUTION_CHANGE. In order to use this new feature, elements must enable it by calling: gst_v4l2_buffer_pool_enable_resolution_change (pool); Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/870>
Diffstat (limited to 'sys')
-rw-r--r--sys/v4l2/gstv4l2bufferpool.c49
-rw-r--r--sys/v4l2/gstv4l2bufferpool.h11
2 files changed, 56 insertions, 4 deletions
diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c
index 21efd3572..8d2481902 100644
--- a/sys/v4l2/gstv4l2bufferpool.c
+++ b/sys/v4l2/gstv4l2bufferpool.c
@@ -1115,6 +1115,22 @@ again:
if (gst_poll_fd_has_error (pool->poll, &pool->pollfd))
goto select_error;
+ /* PRI is used to signal that events are available */
+ if (gst_poll_fd_has_pri (pool->poll, &pool->pollfd)) {
+ struct v4l2_event event = { 0, };
+
+ if (!gst_v4l2_dequeue_event (pool->obj, &event))
+ goto dqevent_failed;
+
+ if (event.type != V4L2_EVENT_SOURCE_CHANGE ||
+ (event.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION) == 0) {
+ GST_INFO_OBJECT (pool, "Received unhandled event, ignoring.");
+ goto again;
+ }
+
+ return GST_V4L2_FLOW_RESOLUTION_CHANGE;
+ }
+
if (ret == 0)
goto no_buffers;
@@ -1134,7 +1150,15 @@ select_error:
return GST_FLOW_ERROR;
}
no_buffers:
- return GST_V4L2_FLOW_LAST_BUFFER;
+ {
+ return GST_V4L2_FLOW_LAST_BUFFER;
+ }
+dqevent_failed:
+ {
+ GST_ELEMENT_ERROR (pool->obj->element, RESOURCE, READ, (NULL),
+ ("dqevent error: %s (%d)", g_strerror (errno), errno));
+ return GST_FLOW_ERROR;
+ }
}
static GstFlowReturn
@@ -1241,6 +1265,11 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
goto done;
}
+ if (res == GST_V4L2_FLOW_RESOLUTION_CHANGE) {
+ GST_INFO_OBJECT (pool, "Resolution change detected.");
+ goto done;
+ }
+
GST_LOG_OBJECT (pool, "dequeueing a buffer");
res = gst_v4l2_allocator_dqbuf (pool->vallocator, &group);
@@ -2159,3 +2188,21 @@ gst_v4l2_buffer_pool_flush (GstBufferPool * bpool)
return ret;
}
+
+/**
+ * gst_v4l2_buffer_pool_enable_resolution_change:
+ * @pool: a #GstBufferPool
+ *
+ * When this is called, the pool will subscribe to the
+ * %V4L2_EVENT_SOURCE_CHANGE. Upon receiving this event, it will notify
+ * the element acquiring buffer with the special flow return
+ * %GST_V4L2_FLOW_RESOLUTION_CHANGE.
+ */
+void
+gst_v4l2_buffer_pool_enable_resolution_change (GstV4l2BufferPool * pool)
+{
+ g_return_if_fail (!gst_buffer_pool_is_active (GST_BUFFER_POOL (pool)));
+
+ if (gst_v4l2_subscribe_event (pool->obj, V4L2_EVENT_SOURCE_CHANGE))
+ gst_poll_fd_ctl_pri (pool->poll, &pool->pollfd, TRUE);
+}
diff --git a/sys/v4l2/gstv4l2bufferpool.h b/sys/v4l2/gstv4l2bufferpool.h
index f8972b641..b61a6ea82 100644
--- a/sys/v4l2/gstv4l2bufferpool.h
+++ b/sys/v4l2/gstv4l2bufferpool.h
@@ -41,9 +41,8 @@ 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))
-/* This flow return is used to indicated that the last buffer of a
- * drain or a resoltuion change has been found. This should normally
- * only occur for mem-2-mem devices. */
+/* 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
/* This flow return is used to indicated that the returned buffer was marked
@@ -51,6 +50,10 @@ G_BEGIN_DECLS
* simply waiting for next buffer. */
#define GST_V4L2_FLOW_CORRUPTED_BUFFER GST_FLOW_CUSTOM_SUCCESS_1
+/* This flow return is used to indicate that a SOURCE_CHANGE event with the
+ * resolution change flag set was received. */
+#define GST_V4L2_FLOW_RESOLUTION_CHANGE GST_FLOW_CUSTOM_SUCCESS_2
+
struct _GstV4l2BufferPool
{
GstBufferPool parent;
@@ -114,6 +117,8 @@ gboolean gst_v4l2_buffer_pool_flush (GstBufferPool *pool);
gboolean gst_v4l2_buffer_pool_orphan (GstBufferPool ** pool);
+void gst_v4l2_buffer_pool_enable_resolution_change (GstV4l2BufferPool *self);
+
G_END_DECLS
#endif /*__GST_V4L2_BUFFER_POOL_H__ */