mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
v4l2codecs: Make request structure ref-counted
This adds a non-thread safe refcount to the GstV4l2Request. This will allow holding on more then one request in order to implement render delay. This is made non-thread safe for speed as we know this will all happen on the same streaming thread. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1881>
This commit is contained in:
parent
3db6f45ca9
commit
1c2f391b57
4 changed files with 46 additions and 16 deletions
|
@ -1002,12 +1002,12 @@ gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self,
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_h264_picture_set_user_data (picture, g_steal_pointer (&request),
|
gst_h264_picture_set_user_data (picture, g_steal_pointer (&request),
|
||||||
(GDestroyNotify) gst_v4l2_request_free);
|
(GDestroyNotify) gst_v4l2_request_unref);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (request)
|
if (request)
|
||||||
gst_v4l2_request_free (request);
|
gst_v4l2_request_unref (request);
|
||||||
|
|
||||||
gst_v4l2_codec_h264_dec_reset_picture (self);
|
gst_v4l2_codec_h264_dec_reset_picture (self);
|
||||||
|
|
||||||
|
|
|
@ -571,7 +571,7 @@ gst_v4l2_codec_vp8_dec_end_picture (GstVp8Decoder * decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_vp8_picture_set_user_data (picture, request,
|
gst_vp8_picture_set_user_data (picture, request,
|
||||||
(GDestroyNotify) gst_v4l2_request_free);
|
(GDestroyNotify) gst_v4l2_request_unref);
|
||||||
|
|
||||||
if (!gst_v4l2_decoder_set_controls (self->decoder, request, control,
|
if (!gst_v4l2_decoder_set_controls (self->decoder, request, control,
|
||||||
G_N_ELEMENTS (control))) {
|
G_N_ELEMENTS (control))) {
|
||||||
|
|
|
@ -47,6 +47,9 @@ enum
|
||||||
|
|
||||||
struct _GstV4l2Request
|
struct _GstV4l2Request
|
||||||
{
|
{
|
||||||
|
/* non-thread safe */
|
||||||
|
gint ref_count;
|
||||||
|
|
||||||
GstV4l2Decoder *decoder;
|
GstV4l2Decoder *decoder;
|
||||||
gint fd;
|
gint fd;
|
||||||
guint32 frame_num;
|
guint32 frame_num;
|
||||||
|
@ -85,6 +88,8 @@ G_DEFINE_TYPE_WITH_CODE (GstV4l2Decoder, gst_v4l2_decoder, GST_TYPE_OBJECT,
|
||||||
GST_DEBUG_CATEGORY_INIT (v4l2_decoder_debug, "v4l2codecs-decoder", 0,
|
GST_DEBUG_CATEGORY_INIT (v4l2_decoder_debug, "v4l2codecs-decoder", 0,
|
||||||
"V4L2 stateless decoder helper"));
|
"V4L2 stateless decoder helper"));
|
||||||
|
|
||||||
|
static void gst_v4l2_request_free (GstV4l2Request * request);
|
||||||
|
|
||||||
static guint32
|
static guint32
|
||||||
direction_to_buffer_type (GstV4l2Decoder * self, GstPadDirection direction)
|
direction_to_buffer_type (GstV4l2Decoder * self, GstPadDirection direction)
|
||||||
{
|
{
|
||||||
|
@ -199,6 +204,9 @@ gst_v4l2_decoder_close (GstV4l2Decoder * self)
|
||||||
{
|
{
|
||||||
GstV4l2Request *request;
|
GstV4l2Request *request;
|
||||||
|
|
||||||
|
while ((request = gst_queue_array_pop_head (self->pending_requests)))
|
||||||
|
gst_v4l2_request_unref (request);
|
||||||
|
|
||||||
while ((request = gst_queue_array_pop_head (self->request_pool)))
|
while ((request = gst_queue_array_pop_head (self->request_pool)))
|
||||||
gst_v4l2_request_free (request);
|
gst_v4l2_request_free (request);
|
||||||
|
|
||||||
|
@ -243,6 +251,7 @@ gst_v4l2_decoder_streamoff (GstV4l2Decoder * self, GstPadDirection direction)
|
||||||
while ((pending_req = gst_queue_array_pop_head (self->pending_requests))) {
|
while ((pending_req = gst_queue_array_pop_head (self->pending_requests))) {
|
||||||
g_clear_pointer (&pending_req->bitstream, gst_memory_unref);
|
g_clear_pointer (&pending_req->bitstream, gst_memory_unref);
|
||||||
pending_req->pending = FALSE;
|
pending_req->pending = FALSE;
|
||||||
|
gst_v4l2_request_unref (pending_req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,6 +863,7 @@ gst_v4l2_decoder_alloc_request (GstV4l2Decoder * self, guint32 frame_num,
|
||||||
request->bitstream = gst_memory_ref (bitstream);
|
request->bitstream = gst_memory_ref (bitstream);
|
||||||
request->pic_buf = gst_buffer_ref (pic_buf);
|
request->pic_buf = gst_buffer_ref (pic_buf);
|
||||||
request->frame_num = frame_num;
|
request->frame_num = frame_num;
|
||||||
|
request->ref_count = 1;
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
@ -900,23 +910,42 @@ gst_v4l2_decoder_alloc_sub_request (GstV4l2Decoder * self,
|
||||||
request->pic_buf = gst_buffer_ref (prev_request->pic_buf);
|
request->pic_buf = gst_buffer_ref (prev_request->pic_buf);
|
||||||
request->frame_num = prev_request->frame_num;
|
request->frame_num = prev_request->frame_num;
|
||||||
request->sub_request = TRUE;
|
request->sub_request = TRUE;
|
||||||
|
request->ref_count = 1;
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GstV4l2Request *
|
||||||
|
gst_v4l2_request_ref (GstV4l2Request * request)
|
||||||
|
{
|
||||||
|
request->ref_count++;
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_v4l2_request_free (GstV4l2Request * request)
|
||||||
|
{
|
||||||
|
GstV4l2Decoder *decoder = request->decoder;
|
||||||
|
|
||||||
|
request->decoder = NULL;
|
||||||
|
close (request->fd);
|
||||||
|
gst_poll_free (request->poll);
|
||||||
|
g_free (request);
|
||||||
|
|
||||||
|
if (decoder)
|
||||||
|
g_object_unref (decoder);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_v4l2_request_free (GstV4l2Request * request)
|
gst_v4l2_request_unref (GstV4l2Request * request)
|
||||||
{
|
{
|
||||||
GstV4l2Decoder *decoder = request->decoder;
|
GstV4l2Decoder *decoder = request->decoder;
|
||||||
gint ret;
|
gint ret;
|
||||||
|
|
||||||
if (!decoder) {
|
g_return_if_fail (request->ref_count > 0);
|
||||||
close (request->fd);
|
|
||||||
gst_poll_free (request->poll);
|
if (--request->ref_count > 0)
|
||||||
g_free (request);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_pointer (&request->bitstream, gst_memory_unref);
|
g_clear_pointer (&request->bitstream, gst_memory_unref);
|
||||||
g_clear_pointer (&request->pic_buf, gst_buffer_unref);
|
g_clear_pointer (&request->pic_buf, gst_buffer_unref);
|
||||||
|
@ -924,7 +953,6 @@ gst_v4l2_request_free (GstV4l2Request * request)
|
||||||
request->failed = FALSE;
|
request->failed = FALSE;
|
||||||
request->hold_pic_buf = FALSE;
|
request->hold_pic_buf = FALSE;
|
||||||
request->sub_request = FALSE;
|
request->sub_request = FALSE;
|
||||||
request->decoder = NULL;
|
|
||||||
|
|
||||||
if (request->pending) {
|
if (request->pending) {
|
||||||
gint idx;
|
gint idx;
|
||||||
|
@ -936,7 +964,6 @@ gst_v4l2_request_free (GstV4l2Request * request)
|
||||||
gst_queue_array_drop_element (decoder->pending_requests, idx);
|
gst_queue_array_drop_element (decoder->pending_requests, idx);
|
||||||
|
|
||||||
gst_v4l2_request_free (request);
|
gst_v4l2_request_free (request);
|
||||||
g_object_unref (decoder);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,12 +974,11 @@ gst_v4l2_request_free (GstV4l2Request * request)
|
||||||
GST_ERROR_OBJECT (request->decoder, "MEDIA_REQUEST_IOC_REINIT failed: %s",
|
GST_ERROR_OBJECT (request->decoder, "MEDIA_REQUEST_IOC_REINIT failed: %s",
|
||||||
g_strerror (errno));
|
g_strerror (errno));
|
||||||
gst_v4l2_request_free (request);
|
gst_v4l2_request_free (request);
|
||||||
g_object_unref (decoder);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_queue_array_push_tail (decoder->request_pool, request);
|
gst_queue_array_push_tail (decoder->request_pool, request);
|
||||||
g_object_unref (decoder);
|
g_clear_object (&request->decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -986,11 +1012,12 @@ gst_v4l2_request_queue (GstV4l2Request * request, guint flags)
|
||||||
request->hold_pic_buf = TRUE;
|
request->hold_pic_buf = TRUE;
|
||||||
|
|
||||||
request->pending = TRUE;
|
request->pending = TRUE;
|
||||||
gst_queue_array_push_tail (decoder->pending_requests, request);
|
gst_queue_array_push_tail (decoder->pending_requests,
|
||||||
|
gst_v4l2_request_ref (request));
|
||||||
|
|
||||||
/* FIXME to support more then one pending requests, we need the request to
|
/* FIXME to support more then one pending requests, we need the request to
|
||||||
* be refcounted */
|
* be refcounted */
|
||||||
if (gst_queue_array_get_length (decoder->pending_requests) > 1) {
|
if (gst_queue_array_get_length (decoder->pending_requests) > 6) {
|
||||||
GstV4l2Request *pending_req;
|
GstV4l2Request *pending_req;
|
||||||
|
|
||||||
pending_req = gst_queue_array_peek_head (decoder->pending_requests);
|
pending_req = gst_queue_array_peek_head (decoder->pending_requests);
|
||||||
|
@ -1036,6 +1063,7 @@ gst_v4l2_request_set_done (GstV4l2Request * request)
|
||||||
|
|
||||||
g_clear_pointer (&pending_req->pic_buf, gst_buffer_unref);
|
g_clear_pointer (&pending_req->pic_buf, gst_buffer_unref);
|
||||||
pending_req->pending = FALSE;
|
pending_req->pending = FALSE;
|
||||||
|
gst_v4l2_request_unref (pending_req);
|
||||||
|
|
||||||
if (pending_req == request)
|
if (pending_req == request)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -108,7 +108,9 @@ GstV4l2Request *gst_v4l2_decoder_alloc_sub_request (GstV4l2Decoder * self,
|
||||||
GstV4l2Request * prev_request,
|
GstV4l2Request * prev_request,
|
||||||
GstMemory *bitstream);
|
GstMemory *bitstream);
|
||||||
|
|
||||||
void gst_v4l2_request_free (GstV4l2Request * request);
|
GstV4l2Request * gst_v4l2_request_ref (GstV4l2Request * request);
|
||||||
|
|
||||||
|
void gst_v4l2_request_unref (GstV4l2Request * request);
|
||||||
|
|
||||||
gboolean gst_v4l2_request_queue (GstV4l2Request * request,
|
gboolean gst_v4l2_request_queue (GstV4l2Request * request,
|
||||||
guint flags);
|
guint flags);
|
||||||
|
|
Loading…
Reference in a new issue