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;
|
GstV4l2Decoder *decoder = self->decoder;
|
||||||
GstPadDirection direction = self->direction;
|
GstPadDirection direction = self->direction;
|
||||||
|
GstV4l2CodecBuffer *buf;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Try to create %d buffers", self->pool_size);
|
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;
|
return TRUE;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
/* 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);
|
gst_v4l2_decoder_request_buffers (decoder, direction, 0);
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,10 +222,16 @@ static void
|
||||||
gst_v4l2_codec_allocator_dispose (GObject * object)
|
gst_v4l2_codec_allocator_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
GstV4l2CodecAllocator *self = GST_V4L2_CODEC_ALLOCATOR (object);
|
GstV4l2CodecAllocator *self = GST_V4L2_CODEC_ALLOCATOR (object);
|
||||||
|
GstV4l2Decoder *decoder = self->decoder;
|
||||||
|
GstPadDirection direction = self->direction;
|
||||||
GstV4l2CodecBuffer *buf;
|
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);
|
gst_v4l2_codec_buffer_free (buf);
|
||||||
|
}
|
||||||
|
|
||||||
if (self->decoder) {
|
if (self->decoder) {
|
||||||
gst_v4l2_codec_allocator_detach (self);
|
gst_v4l2_codec_allocator_detach (self);
|
||||||
|
@ -349,10 +365,21 @@ gst_v4l2_codec_allocator_get_pool_size (GstV4l2CodecAllocator * self)
|
||||||
void
|
void
|
||||||
gst_v4l2_codec_allocator_detach (GstV4l2CodecAllocator * self)
|
gst_v4l2_codec_allocator_detach (GstV4l2CodecAllocator * self)
|
||||||
{
|
{
|
||||||
|
GstV4l2Decoder *decoder = self->decoder;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (self);
|
GST_OBJECT_LOCK (self);
|
||||||
if (!self->detached) {
|
if (!self->detached) {
|
||||||
self->detached = TRUE;
|
self->detached = TRUE;
|
||||||
|
if (!gst_v4l2_decoder_has_remove_bufs (decoder)) {
|
||||||
gst_v4l2_decoder_request_buffers (self->decoder, self->direction, 0);
|
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);
|
GST_OBJECT_UNLOCK (self);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ struct _GstV4l2Decoder
|
||||||
GstVecDeque *request_pool;
|
GstVecDeque *request_pool;
|
||||||
GstVecDeque *pending_requests;
|
GstVecDeque *pending_requests;
|
||||||
guint version;
|
guint version;
|
||||||
|
GstVideoInfo *info;
|
||||||
|
|
||||||
enum v4l2_buf_type src_buf_type;
|
enum v4l2_buf_type src_buf_type;
|
||||||
enum v4l2_buf_type sink_buf_type;
|
enum v4l2_buf_type sink_buf_type;
|
||||||
|
@ -90,6 +91,7 @@ struct _GstV4l2Decoder
|
||||||
|
|
||||||
/* detected features */
|
/* detected features */
|
||||||
gboolean supports_holding_capture;
|
gboolean supports_holding_capture;
|
||||||
|
gboolean supports_remove_buffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstV4l2Decoder, gst_v4l2_decoder, GST_TYPE_OBJECT,
|
G_DEFINE_TYPE_WITH_CODE (GstV4l2Decoder, gst_v4l2_decoder, GST_TYPE_OBJECT,
|
||||||
|
@ -225,6 +227,11 @@ gst_v4l2_decoder_open (GstV4l2Decoder * self)
|
||||||
return FALSE;
|
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;
|
self->opened = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -550,6 +557,31 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
|
||||||
return caps;
|
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
|
gboolean
|
||||||
gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
|
gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
|
||||||
GstVideoInfo * vinfo, GstVideoInfoDmaDrm * vinfo_drm)
|
GstVideoInfo * vinfo, GstVideoInfoDmaDrm * vinfo_drm)
|
||||||
|
@ -1233,6 +1265,19 @@ gst_v4l2_decoder_get_render_delay (GstV4l2Decoder * self)
|
||||||
return self->render_delay;
|
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 *
|
GstV4l2Request *
|
||||||
gst_v4l2_request_ref (GstV4l2Request * request)
|
gst_v4l2_request_ref (GstV4l2Request * request)
|
||||||
{
|
{
|
||||||
|
|
|
@ -90,6 +90,11 @@ gint gst_v4l2_decoder_create_buffers (GstV4l2Decoder * self,
|
||||||
GstPadDirection direction,
|
GstPadDirection direction,
|
||||||
guint num_buffers);
|
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,
|
gboolean gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self,
|
||||||
GstPadDirection directon,
|
GstPadDirection directon,
|
||||||
gint index,
|
gint index,
|
||||||
|
@ -145,6 +150,7 @@ void gst_v4l2_decoder_set_render_delay (GstV4l2Decoder * self,
|
||||||
|
|
||||||
guint gst_v4l2_decoder_get_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);
|
GstV4l2Request * gst_v4l2_request_ref (GstV4l2Request * request);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue