Explorar o código

avcodec/refstruct: Allow checking for exclusive ownership

This is the analog of av_buffer_is_writable();
it will be used in the next commit.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Andreas Rheinhardt %!s(int64=3) %!d(string=hai) anos
pai
achega
56dd585146
Modificáronse 2 ficheiros con 25 adicións e 0 borrados
  1. 16 0
      libavcodec/refstruct.c
  2. 9 0
      libavcodec/refstruct.h

+ 16 - 0
libavcodec/refstruct.c

@@ -71,6 +71,13 @@ static RefCount *get_refcount(void *obj)
     return ref;
 }
 
+static const RefCount *cget_refcount(const void *obj)
+{
+    const RefCount *ref = (const RefCount*)((const char*)obj - REFCOUNT_OFFSET);
+    ff_assert(ref->cookie == REFSTRUCT_COOKIE);
+    return ref;
+}
+
 static void *get_userdata(void *buf)
 {
     return (char*)buf + REFCOUNT_OFFSET;
@@ -164,3 +171,12 @@ void ff_refstruct_replace(void *dstp, const void *src)
         memcpy(dstp, &dst, sizeof(dst));
     }
 }
+
+int ff_refstruct_exclusive(const void *obj)
+{
+    const RefCount *ref = cget_refcount(obj);
+    /* Casting const away here is safe, because it is a load.
+     * It is necessary because atomic_load_explicit() does not
+     * accept const atomics in C11 (see also N1807). */
+    return atomic_load_explicit((atomic_uintptr_t*)&ref->refcount, memory_order_acquire) == 1;
+}

+ 9 - 0
libavcodec/refstruct.h

@@ -142,4 +142,13 @@ const void *ff_refstruct_ref_c(const void *obj);
  */
 void ff_refstruct_replace(void *dstp, const void *src);
 
+/**
+ * Check whether the reference count of an object managed
+ * via this API is 1.
+ *
+ * @param obj A pointer to an object managed via this API.
+ * @return 1 if the reference count of obj is 1; 0 otherwise.
+ */
+int ff_refstruct_exclusive(const void *obj);
+
 #endif /* AVCODEC_REFSTRUCT_H */