mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-09 08:55:33 +00:00
v4l2codecs: Replace VIDIOC_REQBUFS calls by VIDIOC_CREATE_BUFS
Use VIDIOC_CREATE_BUFS ioctl to create buffers instead of VIDIOC_REQBUFS because it allows to create buffers also while streaming. To prepare the introduction of VIDIOC_REMOVE_BUFFERS create the buffers one per one instead of a range of them. This way it can, in the futur, fill the holes. gst_v4l2_decoder_request_buffers() is stil used to remove all the buffers of the queue. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7684>
This commit is contained in:
parent
c25c4355b1
commit
2753a8f0c1
3 changed files with 49 additions and 12 deletions
|
@ -173,21 +173,25 @@ gst_v4l2_codec_allocator_prepare (GstV4l2CodecAllocator * self)
|
||||||
{
|
{
|
||||||
GstV4l2Decoder *decoder = self->decoder;
|
GstV4l2Decoder *decoder = self->decoder;
|
||||||
GstPadDirection direction = self->direction;
|
GstPadDirection direction = self->direction;
|
||||||
gint ret;
|
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
ret = gst_v4l2_decoder_request_buffers (decoder, direction, self->pool_size);
|
GST_DEBUG_OBJECT (self, "Try to create %d buffers", self->pool_size);
|
||||||
if (ret < self->pool_size) {
|
|
||||||
if (ret >= 0)
|
/* Allocate buffers one by one to avoid fragmentation issue and
|
||||||
|
* use the possible holes in v4l2 queue array */
|
||||||
|
for (i = 0; i < self->pool_size; i++) {
|
||||||
|
GstV4l2CodecBuffer *buf;
|
||||||
|
gint index = gst_v4l2_decoder_create_buffers (decoder, direction, 1);
|
||||||
|
if (index < 0) {
|
||||||
GST_ERROR_OBJECT (self,
|
GST_ERROR_OBJECT (self,
|
||||||
"%i buffer was needed, but only %i could be allocated",
|
"%i buffer was needed, but only %i could be allocated",
|
||||||
self->pool_size, ret);
|
self->pool_size, i);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < self->pool_size; i++) {
|
buf =
|
||||||
GstV4l2CodecBuffer *buf = gst_v4l2_codec_buffer_new (GST_ALLOCATOR (self),
|
gst_v4l2_codec_buffer_new (GST_ALLOCATOR (self), decoder, direction,
|
||||||
decoder, direction, i);
|
index);
|
||||||
g_queue_push_tail (&self->pool, buf);
|
g_queue_push_tail (&self->pool, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -659,14 +659,43 @@ gst_v4l2_decoder_request_buffers (GstV4l2Decoder * self,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return reqbufs.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
gst_v4l2_decoder_create_buffers (GstV4l2Decoder * self,
|
||||||
|
GstPadDirection direction, guint num_buffers)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
struct v4l2_create_buffers createbufs = {
|
||||||
|
.count = num_buffers,
|
||||||
|
.memory = V4L2_MEMORY_MMAP,
|
||||||
|
.format.type = direction_to_buffer_type (self, direction),
|
||||||
|
};
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (self, "Creating %u buffers", num_buffers);
|
||||||
|
|
||||||
|
ret = ioctl (self->video_fd, VIDIOC_G_FMT, &createbufs.format);
|
||||||
|
if (ret < 0) {
|
||||||
|
GST_ERROR_OBJECT (self, "VIDIOC_G_FMT failed: %s", g_strerror (errno));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ioctl (self->video_fd, VIDIOC_CREATE_BUFS, &createbufs);
|
||||||
|
if (ret < 0) {
|
||||||
|
GST_ERROR_OBJECT (self, "VIDIOC_CREATE_BUFS failed: %s",
|
||||||
|
g_strerror (errno));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (direction == GST_PAD_SINK) {
|
if (direction == GST_PAD_SINK) {
|
||||||
if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF)
|
if (createbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF)
|
||||||
self->supports_holding_capture = TRUE;
|
self->supports_holding_capture = TRUE;
|
||||||
else
|
else
|
||||||
self->supports_holding_capture = FALSE;
|
self->supports_holding_capture = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return reqbufs.count;
|
return createbufs.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|
|
@ -86,6 +86,10 @@ gint gst_v4l2_decoder_request_buffers (GstV4l2Decoder * self,
|
||||||
GstPadDirection direction,
|
GstPadDirection direction,
|
||||||
guint num_buffers);
|
guint num_buffers);
|
||||||
|
|
||||||
|
gint gst_v4l2_decoder_create_buffers (GstV4l2Decoder * self,
|
||||||
|
GstPadDirection direction,
|
||||||
|
guint num_buffers);
|
||||||
|
|
||||||
gboolean gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self,
|
gboolean gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self,
|
||||||
GstPadDirection directon,
|
GstPadDirection directon,
|
||||||
gint index,
|
gint index,
|
||||||
|
|
Loading…
Reference in a new issue