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>
This commit is contained in:
Nicolas Dufresne 2021-02-04 14:13:32 -05:00
parent 4be9bf4085
commit bb1d9b398e
2 changed files with 56 additions and 4 deletions

View file

@ -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);
}

View file

@ -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__ */