mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
v4l2bufferpool: add gst_v4l2_buffer_pool_flush
STREAMOFF set all v4l2buffers to DEQUEUE state. Then for CAPTURE we call QBUF on each buffer. For OUTPUT the buffers are just push back in the GstBufferPool base class 's queue. But the loop actually looks like the same. https://bugzilla.gnome.org/show_bug.cgi?id=720568
This commit is contained in:
parent
062f4f8710
commit
c701dcd16c
2 changed files with 125 additions and 0 deletions
|
@ -663,6 +663,43 @@ gst_v4l2_buffer_pool_free_buffers (GstV4l2BufferPool * pool)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stop_streaming (GstV4l2BufferPool * pool)
|
||||
{
|
||||
GstV4l2Object *obj = pool->obj;
|
||||
|
||||
GST_DEBUG_OBJECT (pool, "stopping stream");
|
||||
|
||||
gst_poll_set_flushing (obj->poll, TRUE);
|
||||
|
||||
switch (obj->mode) {
|
||||
case GST_V4L2_IO_RW:
|
||||
break;
|
||||
case GST_V4L2_IO_MMAP:
|
||||
case GST_V4L2_IO_USERPTR:
|
||||
case GST_V4L2_IO_DMABUF:
|
||||
GST_DEBUG_OBJECT (pool, "STREAMOFF");
|
||||
if (v4l2_ioctl (pool->video_fd, VIDIOC_STREAMOFF, &obj->type) < 0)
|
||||
goto stop_failed;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
pool->streaming = FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
stop_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (pool, "error with STREAMOFF %d (%s)", errno,
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_v4l2_buffer_pool_stop (GstBufferPool * bpool)
|
||||
{
|
||||
|
@ -1513,3 +1550,89 @@ start_failed:
|
|||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_v4l2_buffer_pool_flush:
|
||||
* @bpool: a #GstBufferPool
|
||||
*
|
||||
* First, set obj->poll to be flushing
|
||||
* Call STREAMOFF to clear QUEUED flag on every driver buffers.
|
||||
* Then release all buffers that are in pool->buffers array.
|
||||
* Finally call STREAMON if CAPTURE type
|
||||
* The caller is responsible to unset flushing on obj->pool
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
gst_v4l2_buffer_pool_flush (GstV4l2BufferPool * pool)
|
||||
{
|
||||
GstBufferPool *bpool = GST_BUFFER_POOL_CAST (pool);
|
||||
GstV4l2Object *obj = pool->obj;
|
||||
gint i = 0;
|
||||
|
||||
GST_DEBUG_OBJECT (pool, "flush");
|
||||
|
||||
stop_streaming (pool);
|
||||
|
||||
switch (obj->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
|
||||
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
|
||||
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
|
||||
switch (obj->mode) {
|
||||
case GST_V4L2_IO_RW:
|
||||
break;
|
||||
case GST_V4L2_IO_MMAP:
|
||||
case GST_V4L2_IO_USERPTR:
|
||||
case GST_V4L2_IO_DMABUF:
|
||||
{
|
||||
for (i = 0; i < pool->num_buffers; i++) {
|
||||
GstBuffer *buf = pool->buffers[i];
|
||||
if (buf) {
|
||||
/* it's necessary to set to NULL before to call
|
||||
* gst_v4l2_buffer_pool_release_buffer
|
||||
* otherwise it won't go back to the pool */
|
||||
pool->buffers[i] = NULL;
|
||||
|
||||
/* dicrease counter */
|
||||
pool->num_queued--;
|
||||
|
||||
/* in CAPTURE mode the pool->num_queued will be re-incremented
|
||||
* because the buffers are queued when released */
|
||||
if (buf->pool)
|
||||
gst_buffer_unref (buf);
|
||||
else
|
||||
gst_v4l2_buffer_pool_release_buffer (bpool, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* do not set pool->num_queued to 0 because
|
||||
* the buffers are queued when released */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
/* we can start capturing now, we wait for the playback
|
||||
* case until we queued the first buffer */
|
||||
if (!V4L2_TYPE_IS_OUTPUT (obj->type))
|
||||
if (!start_streaming (pool))
|
||||
goto start_failed;
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
start_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (pool, "failed to start streaming");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,8 @@ GstBufferPool * gst_v4l2_buffer_pool_new (GstV4l2Object *obj, GstCaps *c
|
|||
|
||||
GstFlowReturn gst_v4l2_buffer_pool_process (GstV4l2BufferPool * bpool, GstBuffer * buf);
|
||||
|
||||
gboolean gst_v4l2_buffer_pool_flush (GstV4l2BufferPool * pool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /*__GST_V4L2_BUFFER_POOL_H__ */
|
||||
|
|
Loading…
Reference in a new issue