nvcodec: nvdecoder: Move to refcount based GstNvDecoderFrame

This refcount based way would be helpful for sharing nvdec frame among
multiple codec pictures and later zero-copy use case.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1738>
This commit is contained in:
Seungha Yang 2020-10-30 21:20:57 +09:00
parent 2a04fe5403
commit 71564f471d
5 changed files with 38 additions and 21 deletions

View file

@ -306,6 +306,7 @@ gst_nv_decoder_new_frame (GstNvDecoder * decoder)
frame = g_new0 (GstNvDecoderFrame, 1);
frame->index = index_to_use;
frame->decoder = gst_object_ref (decoder);
frame->ref_count = 1;
GST_LOG_OBJECT (decoder, "New frame %p (index %d)", frame, frame->index);
@ -369,33 +370,45 @@ gst_nv_decoder_frame_unmap (GstNvDecoderFrame * frame)
frame->mapped = FALSE;
}
GstNvDecoderFrame *
gst_nv_decoder_frame_ref (GstNvDecoderFrame * frame)
{
g_assert (frame != NULL);
g_atomic_int_add (&frame->ref_count, 1);
return frame;
}
void
gst_nv_decoder_frame_free (GstNvDecoderFrame * frame)
gst_nv_decoder_frame_unref (GstNvDecoderFrame * frame)
{
GstNvDecoder *self;
g_assert (frame != NULL);
GST_LOG ("Free frame %p (index %d)", frame, frame->index);
if (g_atomic_int_dec_and_test (&frame->ref_count)) {
GST_LOG ("Free frame %p (index %d)", frame, frame->index);
if (frame->decoder) {
self = frame->decoder;
if (frame->mapped && gst_cuda_context_push (self->context)) {
gst_nv_decoder_frame_unmap (frame);
gst_cuda_context_pop (NULL);
if (frame->decoder) {
self = frame->decoder;
if (frame->mapped && gst_cuda_context_push (self->context)) {
gst_nv_decoder_frame_unmap (frame);
gst_cuda_context_pop (NULL);
}
if (frame->index < self->pool_size) {
self->frame_pool[frame->index].available = TRUE;
} else {
GST_WARNING_OBJECT (self,
"Frame %p has invalid index %d", frame, frame->index);
}
gst_object_unref (self);
}
if (frame->index < self->pool_size) {
self->frame_pool[frame->index].available = TRUE;
} else {
GST_WARNING_OBJECT (self,
"Frame %p has invalid index %d", frame, frame->index);
}
gst_object_unref (self);
g_free (frame);
}
g_free (frame);
}
gboolean

View file

@ -42,6 +42,8 @@ typedef struct _GstNvDecoderFrame
/*< private >*/
GstNvDecoder *decoder;
gint ref_count;
} GstNvDecoderFrame;
typedef enum
@ -59,7 +61,9 @@ GstNvDecoder * gst_nv_decoder_new (GstCudaContext * context,
GstNvDecoderFrame * gst_nv_decoder_new_frame (GstNvDecoder * decoder);
void gst_nv_decoder_frame_free (GstNvDecoderFrame * frame);
GstNvDecoderFrame * gst_nv_decoder_frame_ref (GstNvDecoderFrame * frame);
void gst_nv_decoder_frame_unref (GstNvDecoderFrame * frame);
gboolean gst_nv_decoder_decode_picture (GstNvDecoder * decoder,
CUVIDPICPARAMS * params);

View file

@ -432,7 +432,7 @@ gst_nv_h264_dec_new_picture (GstH264Decoder * decoder,
"New decoder frame %p (index %d)", nv_frame, nv_frame->index);
gst_h264_picture_set_user_data (picture,
nv_frame, (GDestroyNotify) gst_nv_decoder_frame_free);
nv_frame, (GDestroyNotify) gst_nv_decoder_frame_unref);
return TRUE;
}

View file

@ -430,7 +430,7 @@ gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
GST_LOG_OBJECT (self, "New decoder frame %p (index %d)", frame, frame->index);
gst_h265_picture_set_user_data (picture,
frame, (GDestroyNotify) gst_nv_decoder_frame_free);
frame, (GDestroyNotify) gst_nv_decoder_frame_unref);
return TRUE;
}

View file

@ -300,7 +300,7 @@ gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
"New decoder frame %p (index %d)", nv_frame, nv_frame->index);
gst_vp8_picture_set_user_data (picture,
nv_frame, (GDestroyNotify) gst_nv_decoder_frame_free);
nv_frame, (GDestroyNotify) gst_nv_decoder_frame_unref);
return TRUE;
}