mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-02 08:42:32 +00:00
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:
parent
4be9bf4085
commit
bb1d9b398e
2 changed files with 56 additions and 4 deletions
|
@ -1115,6 +1115,22 @@ again:
|
||||||
if (gst_poll_fd_has_error (pool->poll, &pool->pollfd))
|
if (gst_poll_fd_has_error (pool->poll, &pool->pollfd))
|
||||||
goto select_error;
|
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)
|
if (ret == 0)
|
||||||
goto no_buffers;
|
goto no_buffers;
|
||||||
|
|
||||||
|
@ -1134,7 +1150,15 @@ select_error:
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
no_buffers:
|
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
|
static GstFlowReturn
|
||||||
|
@ -1241,6 +1265,11 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
|
||||||
goto done;
|
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");
|
GST_LOG_OBJECT (pool, "dequeueing a buffer");
|
||||||
|
|
||||||
res = gst_v4l2_allocator_dqbuf (pool->vallocator, &group);
|
res = gst_v4l2_allocator_dqbuf (pool->vallocator, &group);
|
||||||
|
@ -2159,3 +2188,21 @@ gst_v4l2_buffer_pool_flush (GstBufferPool * bpool)
|
||||||
|
|
||||||
return ret;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -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(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))
|
||||||
|
|
||||||
/* This flow return is used to indicated that the last buffer of a
|
/* This flow return is used to indicate that the last buffer has been dequeued
|
||||||
* drain or a resoltuion change has been found. This should normally
|
* during draining. This should normally only occur for mem-2-mem devices. */
|
||||||
* 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
|
||||||
|
|
||||||
/* This flow return is used to indicated that the returned buffer was marked
|
/* 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. */
|
* simply waiting for next buffer. */
|
||||||
#define GST_V4L2_FLOW_CORRUPTED_BUFFER GST_FLOW_CUSTOM_SUCCESS_1
|
#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
|
struct _GstV4l2BufferPool
|
||||||
{
|
{
|
||||||
GstBufferPool parent;
|
GstBufferPool parent;
|
||||||
|
@ -114,6 +117,8 @@ gboolean gst_v4l2_buffer_pool_flush (GstBufferPool *pool);
|
||||||
|
|
||||||
gboolean gst_v4l2_buffer_pool_orphan (GstBufferPool ** pool);
|
gboolean gst_v4l2_buffer_pool_orphan (GstBufferPool ** pool);
|
||||||
|
|
||||||
|
void gst_v4l2_buffer_pool_enable_resolution_change (GstV4l2BufferPool *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /*__GST_V4L2_BUFFER_POOL_H__ */
|
#endif /*__GST_V4L2_BUFFER_POOL_H__ */
|
||||||
|
|
Loading…
Reference in a new issue