mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
v4l2codecs: Add remove buffers helpers
Add helpers function to call VIDIOC_REMOVE_BUFS ioctl. If the driver support this feature buffers are removed from the queue when: - the pool when is detached from the decoded. - the pool is released. - allocation failed. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7684>
This commit is contained in:
parent
fecdfe18ca
commit
ad537ef934
3 changed files with 81 additions and 3 deletions
|
@ -173,6 +173,7 @@ gst_v4l2_codec_allocator_prepare (GstV4l2CodecAllocator * self)
|
|||
{
|
||||
GstV4l2Decoder *decoder = self->decoder;
|
||||
GstPadDirection direction = self->direction;
|
||||
GstV4l2CodecBuffer *buf;
|
||||
guint i;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Try to create %d buffers", self->pool_size);
|
||||
|
@ -198,7 +199,16 @@ gst_v4l2_codec_allocator_prepare (GstV4l2CodecAllocator * self)
|
|||
return TRUE;
|
||||
|
||||
failed:
|
||||
gst_v4l2_decoder_request_buffers (decoder, direction, 0);
|
||||
/* If buffer allocation failed remove them all either by
|
||||
* calling delete_buffers IOCTL if the driver support it,
|
||||
* either by using legacy request_buf IOCTL with 0 has parameter */
|
||||
if (gst_v4l2_decoder_has_remove_bufs (decoder)) {
|
||||
while (i-- && (buf = g_queue_pop_tail (&self->pool))) {
|
||||
gst_v4l2_decoder_remove_buffers (decoder, direction, buf->index, 1);
|
||||
}
|
||||
} else {
|
||||
gst_v4l2_decoder_request_buffers (decoder, direction, 0);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -212,10 +222,16 @@ static void
|
|||
gst_v4l2_codec_allocator_dispose (GObject * object)
|
||||
{
|
||||
GstV4l2CodecAllocator *self = GST_V4L2_CODEC_ALLOCATOR (object);
|
||||
GstV4l2Decoder *decoder = self->decoder;
|
||||
GstPadDirection direction = self->direction;
|
||||
GstV4l2CodecBuffer *buf;
|
||||
|
||||
while ((buf = g_queue_pop_head (&self->pool)))
|
||||
while ((buf = g_queue_pop_head (&self->pool))) {
|
||||
if (gst_v4l2_decoder_has_remove_bufs (decoder)) {
|
||||
gst_v4l2_decoder_remove_buffers (decoder, direction, buf->index, 1);
|
||||
}
|
||||
gst_v4l2_codec_buffer_free (buf);
|
||||
}
|
||||
|
||||
if (self->decoder) {
|
||||
gst_v4l2_codec_allocator_detach (self);
|
||||
|
@ -349,10 +365,21 @@ gst_v4l2_codec_allocator_get_pool_size (GstV4l2CodecAllocator * self)
|
|||
void
|
||||
gst_v4l2_codec_allocator_detach (GstV4l2CodecAllocator * self)
|
||||
{
|
||||
GstV4l2Decoder *decoder = self->decoder;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
if (!self->detached) {
|
||||
self->detached = TRUE;
|
||||
gst_v4l2_decoder_request_buffers (self->decoder, self->direction, 0);
|
||||
if (!gst_v4l2_decoder_has_remove_bufs (decoder)) {
|
||||
gst_v4l2_decoder_request_buffers (self->decoder, self->direction, 0);
|
||||
} else {
|
||||
GstV4l2CodecBuffer *buf;
|
||||
|
||||
while ((buf = g_queue_pop_tail (&self->pool)))
|
||||
gst_v4l2_decoder_remove_buffers (self->decoder, self->direction,
|
||||
buf->index, 1);
|
||||
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ struct _GstV4l2Decoder
|
|||
GstVecDeque *request_pool;
|
||||
GstVecDeque *pending_requests;
|
||||
guint version;
|
||||
GstVideoInfo *info;
|
||||
|
||||
enum v4l2_buf_type src_buf_type;
|
||||
enum v4l2_buf_type sink_buf_type;
|
||||
|
@ -90,6 +91,7 @@ struct _GstV4l2Decoder
|
|||
|
||||
/* detected features */
|
||||
gboolean supports_holding_capture;
|
||||
gboolean supports_remove_buffers;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GstV4l2Decoder, gst_v4l2_decoder, GST_TYPE_OBJECT,
|
||||
|
@ -225,6 +227,11 @@ gst_v4l2_decoder_open (GstV4l2Decoder * self)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (createbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS)
|
||||
self->supports_remove_buffers = TRUE;
|
||||
else
|
||||
self->supports_remove_buffers = FALSE;
|
||||
|
||||
self->opened = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -550,6 +557,31 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
|
|||
return caps;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_v4l2_decoder_remove_buffers (GstV4l2Decoder * self,
|
||||
GstPadDirection direction, guint index, guint num_buffers)
|
||||
{
|
||||
gint ret;
|
||||
struct v4l2_remove_buffers remove_bufs = {
|
||||
.type = direction_to_buffer_type (self, direction),
|
||||
.index = index,
|
||||
.count = num_buffers,
|
||||
};
|
||||
|
||||
if (!self->supports_remove_buffers)
|
||||
return FALSE;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "remove buffers %d from index %d", remove_bufs.count,
|
||||
remove_bufs.index);
|
||||
ret = ioctl (self->video_fd, VIDIOC_REMOVE_BUFS, &remove_bufs);
|
||||
if (ret < 0) {
|
||||
GST_ERROR_OBJECT (self, "VIDIOC_REMOVE_BUF failed: %s", g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
|
||||
GstVideoInfo * vinfo, GstVideoInfoDmaDrm * vinfo_drm)
|
||||
|
@ -1233,6 +1265,19 @@ gst_v4l2_decoder_get_render_delay (GstV4l2Decoder * self)
|
|||
return self->render_delay;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_v4l2_decoder_has_remove_bufs:
|
||||
* @self: a #GstV4l2Decoder pointer
|
||||
*
|
||||
* Returns: TRUE if the video decoder driver allows to remove
|
||||
* buffers from CAPTURE queue.
|
||||
*/
|
||||
gboolean
|
||||
gst_v4l2_decoder_has_remove_bufs (GstV4l2Decoder * self)
|
||||
{
|
||||
return self->supports_remove_buffers;
|
||||
}
|
||||
|
||||
GstV4l2Request *
|
||||
gst_v4l2_request_ref (GstV4l2Request * request)
|
||||
{
|
||||
|
|
|
@ -90,6 +90,11 @@ gint gst_v4l2_decoder_create_buffers (GstV4l2Decoder * self,
|
|||
GstPadDirection direction,
|
||||
guint num_buffers);
|
||||
|
||||
gint gst_v4l2_decoder_remove_buffers (GstV4l2Decoder * self,
|
||||
GstPadDirection direction,
|
||||
guint index,
|
||||
guint num_buffers);
|
||||
|
||||
gboolean gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self,
|
||||
GstPadDirection directon,
|
||||
gint index,
|
||||
|
@ -145,6 +150,7 @@ void gst_v4l2_decoder_set_render_delay (GstV4l2Decoder * self,
|
|||
|
||||
guint gst_v4l2_decoder_get_render_delay (GstV4l2Decoder * self);
|
||||
|
||||
gboolean gst_v4l2_decoder_has_remove_bufs (GstV4l2Decoder * self);
|
||||
|
||||
GstV4l2Request * gst_v4l2_request_ref (GstV4l2Request * request);
|
||||
|
||||
|
|
Loading…
Reference in a new issue