nvcodec: nvdecoder: Move to refcount based GstNvDecoderFrame
authorSeungha Yang <seungha@centricular.com>
Fri, 30 Oct 2020 12:20:57 +0000 (21:20 +0900)
committerSeungha Yang <seungha@centricular.com>
Tue, 10 Nov 2020 14:39:40 +0000 (14:39 +0000)
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>

sys/nvcodec/gstnvdecoder.c
sys/nvcodec/gstnvdecoder.h
sys/nvcodec/gstnvh264dec.c
sys/nvcodec/gstnvh265dec.c
sys/nvcodec/gstnvvp8dec.c

index 902db4d0715a936a9a6329928755d5b5e143448b..19a710073f59f2faabf58d3faf10d620f73dfbe5 100644 (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);
+      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
index befbb8ec27265ba23a7909f94a5e96c0b3544975..c3d4473bea7d514a5e551c256ec3173b5bcf85ab 100644 (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);
index 8712b24996ef652a42397e0f89f420fdbdb4d89e..f09c5d25887b4399cf5f1aa68dfabb58635fe7b1 100644 (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;
 }
index 1440cd26f60a0b54b26737fc71cb793b7c8aa5dc..33bb94d0b45f0b1a0ee47dc8c4d8781ad4efc6f5 100644 (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;
 }
index b47298087af26ce5a6ec19a4dc4e388880d67f58..da200d930fe21e3d2e1149db6e58ebb2447f3f1b 100644 (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;
 }