[Decoders] fix the mem leaks of the external decoders
authorHyoung Joo Ahn <hello.ahn@samsung.com>
Mon, 26 Apr 2021 02:45:03 +0000 (11:45 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Fri, 30 Apr 2021 06:13:36 +0000 (15:13 +0900)
Since the ref count is raised when `gst_buffer_get_all_memory ()` is used, `gst_memory_unref ()` has to be called after using the memory.

Signed-off-by: Hyoung Joo Ahn <hello.ahn@samsung.com>
ext/nnstreamer/extra/nnstreamer_protobuf.cc
ext/nnstreamer/tensor_decoder/tensordec-boundingbox.c
ext/nnstreamer/tensor_decoder/tensordec-directvideo.c
ext/nnstreamer/tensor_decoder/tensordec-flatbuf.cc
ext/nnstreamer/tensor_decoder/tensordec-flexbuf.cc
ext/nnstreamer/tensor_decoder/tensordec-imagelabel.c
ext/nnstreamer/tensor_decoder/tensordec-imagesegment.c
ext/nnstreamer/tensor_decoder/tensordec-pose.c
tests/nnstreamer_decoder/unittest_decoder.cc

index 4c08bc3..722662f 100644 (file)
@@ -99,6 +99,7 @@ gst_tensor_decoder_protobuf (const GstTensorsConfig *config,
 
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
     nns_loge ("Cannot map output memory / tensordec-protobuf");
+    gst_memory_unref (out_mem);
     return GST_FLOW_ERROR;
   }
 
@@ -106,9 +107,10 @@ gst_tensor_decoder_protobuf (const GstTensorsConfig *config,
 
   gst_memory_unmap (out_mem, &out_info);
 
-  if (gst_buffer_get_size (outbuf) == 0) {
+  if (outbuf_size == 0)
     gst_buffer_append_memory (outbuf, out_mem);
-  }
+  else
+    gst_memory_unref (out_mem);
 
   return GST_FLOW_OK;
 }
index d216914..3d55b86 100644 (file)
@@ -1075,9 +1075,11 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
   GstMemory *out_mem;
   GArray *results = NULL;
   const guint num_tensors = config->info.num_tensors;
+  gboolean need_output_alloc;
 
   start_time = g_get_monotonic_time ();
   g_assert (outbuf);
+  need_output_alloc = gst_buffer_get_size (outbuf) == 0;
 
   if (_check_label_props (bdata))
     bdata->flag_use_label = TRUE;
@@ -1085,7 +1087,7 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
     bdata->flag_use_label = FALSE;
 
   /* Ensure we have outbuf properly allocated */
-  if (gst_buffer_get_size (outbuf) == 0) {
+  if (need_output_alloc) {
     out_mem = gst_allocator_alloc (NULL, size, NULL);
   } else {
     if (gst_buffer_get_size (outbuf) < size) {
@@ -1095,7 +1097,7 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
   }
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
     ml_loge ("Cannot map output memory / tensordec-bounding_boxes.\n");
-    return GST_FLOW_ERROR;
+    goto error_free;
   }
 
   /** reset the buffer with alpha 0 / black */
@@ -1103,7 +1105,6 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
 
   if (_check_mode_is_mobilenet_ssd (bdata->mode)) {
     const GstTensorMemory *boxes, *detections = NULL;
-    results = g_array_sized_new (FALSE, TRUE, sizeof (detectedObject), 100);
     /**
      * @todo 100 is a heuristic number of objects in a picture frame
      *       We may have better "heuristics" than this.
@@ -1112,6 +1113,7 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
 
     /* Already checked with getOutCaps. Thus, this is an internal bug */
     g_assert (num_tensors >= MOBILENET_SSD_MAX_TENSORS);
+    results = g_array_sized_new (FALSE, TRUE, sizeof (detectedObject), 100);
 
     boxes = &input[0];
     if (num_tensors >= MOBILENET_SSD_MAX_TENSORS)
@@ -1135,9 +1137,6 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
   } else if (_check_mode_is_mobilenet_ssd_pp (bdata->mode)) {
     const GstTensorMemory *mem_num, *mem_classes, *mem_scores, *mem_boxes;
     int locations_idx, classes_idx, scores_idx, num_idx;
-    results =
-        g_array_sized_new (FALSE, TRUE, sizeof (detectedObject),
-        MOBILENET_SSD_PP_DETECTION_MAX);
 
     /* Already checked with getOutCaps. Thus, this is an internal bug */
     g_assert (num_tensors >= MOBILENET_SSD_PP_MAX_TENSORS);
@@ -1168,12 +1167,11 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
     }
   } else if ((bdata->mode == OV_PERSON_DETECTION_BOUNDING_BOX) ||
       (bdata->mode == OV_FACE_DETECTION_BOUNDING_BOX)) {
-    results = g_array_sized_new (FALSE, TRUE, sizeof (detectedObject),
-        OV_PERSON_DETECTION_MAX);
-
     /* Already checked with getOutCaps. Thus, this is an internal bug */
     g_assert (num_tensors >= OV_PERSON_DETECTION_MAX_TENSORS);
 
+    results = g_array_sized_new (FALSE, TRUE, sizeof (detectedObject),
+        OV_PERSON_DETECTION_MAX);
     switch (config->info.info[0].type) {
         _get_persons_ov (bdata, uint8_t, input[0].data, _NNS_UINT8, results);
         _get_persons_ov (bdata, int8_t, input[0].data, _NNS_INT8, results);
@@ -1190,19 +1188,28 @@ bb_decode (void **pdata, const GstTensorsConfig * config,
     }
   } else {
     GST_ERROR ("Failed to get output buffer, unknown mode %d.", bdata->mode);
-    return GST_FLOW_ERROR;
+    goto error_unmap;
   }
 
   draw (&out_info, bdata, results);
-  g_array_free (results, FALSE);
+  g_array_free (results, TRUE);
 
   gst_memory_unmap (out_mem, &out_info);
 
-  if (gst_buffer_get_size (outbuf) == 0)
+  if (need_output_alloc)
     gst_buffer_append_memory (outbuf, out_mem);
+  else
+    gst_memory_unref (out_mem);
 
   stop_time = g_get_monotonic_time ();
   return GST_FLOW_OK;
+
+error_unmap:
+  gst_memory_unmap (out_mem, &out_info);
+error_free:
+  gst_memory_unref (out_mem);
+
+  return GST_FLOW_ERROR;
 }
 
 static gchar decoder_subplugin_bounding_box[] = "bounding_boxes";
index 1e400a9..99f5e52 100644 (file)
@@ -303,13 +303,14 @@ dv_decode (void **pdata, const GstTensorsConfig * config,
   }
   g_assert (config->info.info[0].type == _NNS_UINT8);
 
-  if (gst_buffer_get_size (outbuf) == size) {
+  if (gst_buffer_get_size (outbuf) == 0) {
+    out_mem = gst_allocator_alloc (NULL, size, NULL);
+  } else {
     /* Don't reallocate. Reuse what's already given */
     out_mem = gst_buffer_get_all_memory (outbuf);
-  } else {
-    out_mem = gst_allocator_alloc (NULL, size, NULL);
   }
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
+    gst_memory_unref (out_mem);
     ml_loge ("Cannot map output memory / tensordec-directvideo.\n");
     return GST_FLOW_ERROR;
   }
@@ -334,6 +335,8 @@ dv_decode (void **pdata, const GstTensorsConfig * config,
 
   if (gst_buffer_get_size (outbuf) == 0)
     gst_buffer_append_memory (outbuf, out_mem);
+  else
+    gst_memory_unref (out_mem);
 
   /** @todo Caller of dv_decode in tensordec.c should call gst_memory_unmap to inbuf */
 
index 435c962..fd69db3 100644 (file)
@@ -137,6 +137,7 @@ fbd_decode (void **pdata, const GstTensorsConfig *config,
   }
 
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
+    gst_memory_unref (out_mem);
     nns_loge ("Cannot map gst memory (tensor decoder flatbuf)\n");
     return GST_FLOW_ERROR;
   }
@@ -147,6 +148,8 @@ fbd_decode (void **pdata, const GstTensorsConfig *config,
 
   if (gst_buffer_get_size (outbuf) == 0)
     gst_buffer_append_memory (outbuf, out_mem);
+  else
+    gst_memory_unref (out_mem);
 
   return GST_FLOW_OK;
 }
index f1f98ca..45efcfb 100644 (file)
@@ -162,8 +162,7 @@ flxd_decode (void **pdata, const GstTensorsConfig *config,
   }
 
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
-    if (need_alloc)
-      gst_allocator_free (NULL, out_mem);
+    gst_memory_unref (out_mem);
     nns_loge ("Cannot map gst memory (tensor decoder flexbuf)\n");
     return GST_FLOW_ERROR;
   }
@@ -174,6 +173,8 @@ flxd_decode (void **pdata, const GstTensorsConfig *config,
 
   if (need_alloc)
     gst_buffer_append_memory (outbuf, out_mem);
+  else
+    gst_memory_unref (out_mem);
 
   return GST_FLOW_OK;
 }
index 0d56ea7..9789554 100644 (file)
@@ -218,6 +218,7 @@ il_decode (void **pdata, const GstTensorsConfig * config,
 
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
     ml_loge ("Cannot map output memory / tensordec-imagelabel.\n");
+    gst_memory_unref (out_mem);
     return GST_FLOW_ERROR;
   }
 
@@ -227,6 +228,8 @@ il_decode (void **pdata, const GstTensorsConfig * config,
 
   if (gst_buffer_get_size (outbuf) == 0)
     gst_buffer_append_memory (outbuf, out_mem);
+  else
+    gst_memory_unref (out_mem);
 
   return GST_FLOW_OK;
 }
index da46057..42948ac 100644 (file)
@@ -612,14 +612,15 @@ is_decode (void **pdata, const GstTensorsConfig * config,
 
   if (need_output_alloc)
     gst_buffer_append_memory (outbuf, out_mem);
+  else
+    gst_memory_unref (out_mem);
 
   return GST_FLOW_OK;
 
 error_unmap:
   gst_memory_unmap (out_mem, &out_info);
 error_free:
-  if (need_output_alloc)
-    gst_allocator_free (NULL, out_mem);
+  gst_memory_unref (out_mem);
 
   return GST_FLOW_ERROR;
 }
index 9540b22..f259560 100644 (file)
@@ -717,6 +717,7 @@ pose_decode (void **pdata, const GstTensorsConfig * config,
     out_mem = gst_buffer_get_all_memory (outbuf);
   }
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
+    gst_memory_unref (out_mem);
     ml_loge ("Cannot map output memory / tensordec-pose.\n");
     return GST_FLOW_ERROR;
   }
@@ -780,6 +781,9 @@ pose_decode (void **pdata, const GstTensorsConfig * config,
   gst_memory_unmap (out_mem, &out_info);
   if (gst_buffer_get_size (outbuf) == 0)
     gst_buffer_append_memory (outbuf, out_mem);
+  else
+    gst_memory_unref (out_mem);
+
   return GST_FLOW_OK;
 }
 
index 50e5dc7..9d4f1d2 100644 (file)
@@ -76,8 +76,7 @@ tensor_decoder_custom_cb (const GstTensorMemory *input,
   }\r
 \r
   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {\r
-    if (need_alloc)\r
-      gst_allocator_free (NULL, out_mem);\r
+    gst_memory_unref (out_mem);\r
     nns_loge ("Cannot map gst memory (tensor decoder custom)\n");\r
     return GST_FLOW_ERROR;\r
   }\r
@@ -88,6 +87,8 @@ tensor_decoder_custom_cb (const GstTensorMemory *input,
 \r
   if (need_alloc)\r
     gst_buffer_append_memory (out_buf, out_mem);\r
+  else\r
+    gst_memory_unref (out_mem);\r
 \r
   return GST_FLOW_OK;\r
 }\r