From 71564f471d2e40226f4a1c3885892a5d70e170c7 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 30 Oct 2020 21:20:57 +0900 Subject: [PATCH] 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: --- sys/nvcodec/gstnvdecoder.c | 45 +++++++++++++++++++++++++++++---------------- sys/nvcodec/gstnvdecoder.h | 6 +++++- sys/nvcodec/gstnvh264dec.c | 2 +- sys/nvcodec/gstnvh265dec.c | 2 +- sys/nvcodec/gstnvvp8dec.c | 2 +- 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/sys/nvcodec/gstnvdecoder.c b/sys/nvcodec/gstnvdecoder.c index 902db4d..19a7100 100644 --- a/sys/nvcodec/gstnvdecoder.c +++ b/sys/nvcodec/gstnvdecoder.c @@ -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); + 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); } - gst_object_unref (self); + g_free (frame); } - - g_free (frame); } gboolean diff --git a/sys/nvcodec/gstnvdecoder.h b/sys/nvcodec/gstnvdecoder.h index befbb8e..c3d4473 100644 --- a/sys/nvcodec/gstnvdecoder.h +++ b/sys/nvcodec/gstnvdecoder.h @@ -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); diff --git a/sys/nvcodec/gstnvh264dec.c b/sys/nvcodec/gstnvh264dec.c index 8712b24..f09c5d2 100644 --- a/sys/nvcodec/gstnvh264dec.c +++ b/sys/nvcodec/gstnvh264dec.c @@ -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; } diff --git a/sys/nvcodec/gstnvh265dec.c b/sys/nvcodec/gstnvh265dec.c index 1440cd2..33bb94d 100644 --- a/sys/nvcodec/gstnvh265dec.c +++ b/sys/nvcodec/gstnvh265dec.c @@ -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; } diff --git a/sys/nvcodec/gstnvvp8dec.c b/sys/nvcodec/gstnvvp8dec.c index b472980..da200d9 100644 --- a/sys/nvcodec/gstnvvp8dec.c +++ b/sys/nvcodec/gstnvvp8dec.c @@ -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; } -- 2.7.4