diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 2afe73b1ba6615b8a1fdd70b710ecf68c17c0d28..86a88938a190aa0566058283ff2b3084015e7491 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -594,17 +594,14 @@ VLC_API void vlc_once_complete(vlc_once_t *restrict once);
  * \param cb callback to execute (the first time)
  * \param opaque data pointer for the callback
  */
-VLC_API void vlc_once(vlc_once_t *restrict once, void (*cb)(void *),
-                      void *opaque);
-
-static inline void vlc_once_inline(vlc_once_t *restrict once,
-                                   void (*cb)(void *), void *opaque)
+static inline void vlc_once(vlc_once_t *restrict once, void (*cb)(void *),
+                            void *opaque)
 {
-    /* Fast path: check if already initialized */
-    if (unlikely(atomic_load_explicit(&once->value, memory_order_acquire) < 3))
-        vlc_once(once, cb, opaque);
+    if (unlikely(!vlc_once_begin(once))) {
+        cb(opaque);
+        vlc_once_complete(once);
+    }
 }
-#define vlc_once(once, cb, opaque) vlc_once_inline(once, cb, opaque)
 #endif
 
 /**
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 1ae6a898f9ca957e797d241e9cfc722f8a44d6db..1c795d5ba4df5c8759f0f0714a1df312522f9f4f 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -660,7 +660,6 @@ vlc_object_parent
 vlc_object_get_tracer
 vlc_object_Log
 vlc_object_vaLog
-vlc_once
 vlc_once_begin
 vlc_once_complete
 vlc_rand_bytes
diff --git a/src/misc/threads.c b/src/misc/threads.c
index 3c7565b21024ee09df0a12d92c186b0b3dc917d5..3247e40cf1eb394495ea3cd192850c457b3c650f 100644
--- a/src/misc/threads.c
+++ b/src/misc/threads.c
@@ -440,39 +440,3 @@ void vlc_once_complete(vlc_once_t *restrict once)
             vlc_assert_unreachable();
     }
 }
-
-void (vlc_once)(vlc_once_t *restrict once, void (*cb)(void *), void *opaque)
-{
-    unsigned int value = VLC_ONCE_UNDONE;
-
-    if (atomic_compare_exchange_strong_explicit(&once->value, &value,
-                                                VLC_ONCE_DOING,
-                                                memory_order_acquire,
-                                                memory_order_acquire)) {
-        /* First time: run the callback */
-        cb(opaque);
-
-        if (atomic_exchange_explicit(&once->value, VLC_ONCE_DONE,
-                                     memory_order_release) == VLC_ONCE_CONTEND)
-            /* Notify waiters if any */
-            vlc_atomic_notify_all(&once->value);
-
-        return;
-    }
-
-    assert(value >= VLC_ONCE_DOING);
-
-    if (unlikely(value == VLC_ONCE_DOING)
-     && atomic_compare_exchange_strong_explicit(&once->value, &value,
-                                                VLC_ONCE_CONTEND,
-                                                memory_order_acquire,
-                                                memory_order_acquire))
-        value = VLC_ONCE_CONTEND;
-
-    assert(value >= VLC_ONCE_CONTEND);
-
-    while (unlikely(value != VLC_ONCE_DONE)) {
-        vlc_atomic_wait(&once->value, VLC_ONCE_CONTEND);
-        value = atomic_load_explicit(&once->value, memory_order_acquire);
-    }
-}