Add GstBufferMapInfo to be used with g_auto()
authorXavier Claessens <xavier.claessens@collabora.com>
Fri, 13 May 2022 15:51:09 +0000 (11:51 -0400)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 20 Jun 2022 16:17:50 +0000 (16:17 +0000)
We need a separate typedef for this feature because GstMapInfo itself
can be initialized by gst_memory_map() in which case info.memory should
not be unreffed.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2412>

subprojects/gstreamer/gst/gstbuffer.c
subprojects/gstreamer/gst/gstbuffer.h
subprojects/gstreamer/tests/check/gst/gstbuffer.c

index d3d0898..b6ea6a1 100644 (file)
@@ -1907,12 +1907,7 @@ gst_buffer_unmap (GstBuffer * buffer, GstMapInfo * info)
   g_return_if_fail (GST_IS_BUFFER (buffer));
   g_return_if_fail (info != NULL);
 
-  /* we need to check for NULL, it is possible that we tried to map a buffer
-   * without memory and we should be able to unmap that fine */
-  if (G_LIKELY (info->memory)) {
-    gst_memory_unmap (info->memory, info);
-    gst_memory_unref (info->memory);
-  }
+  _gst_buffer_map_info_clear ((GstBufferMapInfo *) info);
 }
 
 /**
index 12ad5f2..3de019c 100644 (file)
@@ -798,6 +798,37 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBuffer, gst_buffer_unref)
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBufferPool, gst_object_unref)
 
+/**
+ * GstBufferMapInfo: (skip):
+ *
+ * Alias for #GstMapInfo to be used with g_auto():
+ * ```c
+ * void my_func(GstBuffer *buf)
+ * {
+ *   g_auto(GstBufferMapInfo) map = GST_MAP_INFO_INIT;
+ *   if (!gst_buffer_map(buf, &map, GST_MAP_READWRITE))
+ *     return;
+ *   ...
+ *   // No need to call gst_buffer_unmap()
+ * }
+ * ```
+ *
+ * Since: 1.22
+ */
+typedef GstMapInfo GstBufferMapInfo;
+
+static inline void _gst_buffer_map_info_clear(GstBufferMapInfo *info)
+{
+  /* we need to check for NULL, it is possible that we tried to map a buffer
+   * without memory and we should be able to unmap that fine */
+  if (G_LIKELY (info->memory)) {
+    gst_memory_unmap (info->memory, info);
+    gst_memory_unref (info->memory);
+  }
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GstBufferMapInfo, _gst_buffer_map_info_clear)
+
 G_END_DECLS
 
 #endif /* __GST_BUFFER_H__ */
index b9cc35f..647dcb6 100644 (file)
@@ -944,6 +944,29 @@ GST_START_TEST (test_new_memdup)
 
 GST_END_TEST;
 
+GST_START_TEST (test_auto_unmap)
+{
+#ifdef g_auto
+  g_autoptr (GstBuffer) buf = NULL;
+  g_autoptr (GstMemory) mem = NULL;
+
+  buf = gst_buffer_new_memdup (ro_memory, sizeof (ro_memory));
+
+  {
+    g_auto (GstBufferMapInfo) map = GST_MAP_INFO_INIT;
+    fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
+    mem = gst_memory_ref (map.memory);
+    /* mem should be reffed by buffer, map and us */
+    fail_unless_equals_int (GST_MINI_OBJECT_REFCOUNT (mem), 3);
+  }
+
+  /* mem should have been unreffed by g_auto() */
+  fail_unless_equals_int (GST_MINI_OBJECT_REFCOUNT (mem), 2);
+#endif
+}
+
+GST_END_TEST;
+
 static Suite *
 gst_buffer_suite (void)
 {
@@ -970,6 +993,7 @@ gst_buffer_suite (void)
   tcase_add_test (tc_chain, test_writable_memory);
   tcase_add_test (tc_chain, test_wrapped_bytes);
   tcase_add_test (tc_chain, test_new_memdup);
+  tcase_add_test (tc_chain, test_auto_unmap);
 
   return s;
 }