mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +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;
|
||||
GstPadDirection direction = self->direction;
|
||||
gint ret;
|
||||
guint i;
|
||||
|
||||
ret = gst_v4l2_decoder_request_buffers (decoder, direction, self->pool_size);
|
||||
if (ret < self->pool_size) {
|
||||
if (ret >= 0)
|
||||
GST_DEBUG_OBJECT (self, "Try to create %d buffers", self->pool_size);
|
||||
|
||||
/* 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,
|
||||
"%i buffer was needed, but only %i could be allocated",
|
||||
self->pool_size, ret);
|
||||
goto failed;
|
||||
}
|
||||
self->pool_size, i);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (i = 0; i < self->pool_size; i++) {
|
||||
GstV4l2CodecBuffer *buf = gst_v4l2_codec_buffer_new (GST_ALLOCATOR (self),
|
||||
decoder, direction, i);
|
||||
buf =
|
||||
gst_v4l2_codec_buffer_new (GST_ALLOCATOR (self), decoder, direction,
|
||||
index);
|
||||
g_queue_push_tail (&self->pool, buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -659,14 +659,43 @@ gst_v4l2_decoder_request_buffers (GstV4l2Decoder * self,
|
|||
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 (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;
|
||||
else
|
||||
self->supports_holding_capture = FALSE;
|
||||
}
|
||||
|
||||
return reqbufs.count;
|
||||
return createbufs.index;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
@ -86,6 +86,10 @@ gint gst_v4l2_decoder_request_buffers (GstV4l2Decoder * self,
|
|||
GstPadDirection direction,
|
||||
guint num_buffers);
|
||||
|
||||
gint gst_v4l2_decoder_create_buffers (GstV4l2Decoder * self,
|
||||
GstPadDirection direction,
|
||||
guint num_buffers);
|
||||
|
||||
gboolean gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self,
|
||||
GstPadDirection directon,
|
||||
gint index,
|
||||
|
|
Loading…
Reference in a new issue