<html><head></head><body>Hi, <br><br><br>I refuse to change the existing API which works, follows a well-known convention (indeed libavutil works the same way), and does not add heap overhead and failure modes - which is a MUST for *debug* logs.<br><br>Also this creates a reverse abstraction anti-pattern in the stdio handler and existing apps.<br><br><div class="gmail_quote">Le 20 mai 2019 23:58:40 GMT+03:00, "Jérémy VIGNELLES" <jeremy.vignelles@dev3i.fr> a écrit :<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="k9mail"><hr> include/vlc/libvlc.h  | 25 ++++++++++++-------------<br> lib/libvlc.sym        |  2 +-<br> lib/libvlc_internal.h |  3 ++-<br> lib/log.c             | 29 +++++++++++++++++++----------<br> 4 files changed, 34 insertions(+), 25 deletions(-)<br><br>diff --git a/include/vlc/libvlc.h b/include/vlc/libvlc.h<br>index 0ec0045..aac2c7f 100644<br>--- a/include/vlc/libvlc.h<br>+++ b/include/vlc/libvlc.h<br>@@ -410,19 +410,18 @@ LIBVLC_API void libvlc_log_get_object(const libvlc_log_t *ctx,<br>                         const char **name, const char **header, uintptr_t *id);<br> <br> /**<br>- * Callback prototype for LibVLC log message handler.<br>+ * Callback prototype for LibVLC preformatted log message handler.<br>  *<br>  * \param data data pointer as given to libvlc_log_set()<br>  * \param level message level (@ref libvlc_log_level)<br>  * \param ctx message context (meta-information about the message)<br>- * \param fmt printf() format string (as defined by ISO C11)<br>- * \param args variable argument list for the format<br>+ * \param message the message, already formatted<br>  * \note Log message handlers <b>must</b> be thread-safe.<br>- * \warning The message context pointer, the format string parameters and the<br>- *          variable arguments are only valid until the callback returns.<br>+ * \warning The message context pointer, and the message string parameters<br>+ *          are only valid until the callback returns.<br>  */<br>-typedef void (*libvlc_log_cb)(void *data, int level, const libvlc_log_t *ctx,<br>-                              const char *fmt, va_list args);<br>+typedef void (*libvlc_log_preformatted_cb)(void *data, int level, const libvlc_log_t *ctx,<br>+                              const char *message);<br> <br> /**<br>  * Unsets the logging callback.<br>@@ -440,11 +439,13 @@ typedef void (*libvlc_log_cb)(void *data, int level, const libvlc_log_t *ctx,<br> LIBVLC_API void libvlc_log_unset( libvlc_instance_t *p_instance );<br> <br> /**<br>- * Sets the logging callback for a LibVLC instance.<br>+ * Sets the logging callback for a LibVLC instance, that takes a preformatted message as input.<br>  *<br>  * This function is thread-safe: it will wait for any pending callbacks<br>  * invocation to complete.<br>  *<br>+ * \param p_instance libvlc instance<br>+ * \param min_level the callback will only be called if the message level is above this level, 0 means "get all messages" (@ref libvlc_log_level)<br>  * \param cb callback function pointer<br>  * \param data opaque data pointer for the callback function<br>  *<br>@@ -453,12 +454,10 @@ LIBVLC_API void libvlc_log_unset( libvlc_instance_t *p_instance );<br>  *<br>  * \warning A deadlock may occur if this function is called from the callback.<br>  *<br>- * \param p_instance libvlc instance<br>- * \version LibVLC 2.1.0 or later<br>+ * \version LibVLC 4.0.0 or later<br>  */<br>-LIBVLC_API void libvlc_log_set( libvlc_instance_t *p_instance,<br>-                                libvlc_log_cb cb, void *data );<br>-<br>+LIBVLC_API void libvlc_log_set_preformatted(libvlc_instance_t *p_instance, int min_level,<br>+                                            libvlc_log_preformatted_cb cb, void* data );<br> <br> /**<br>  * Sets up logging to a file.<br>diff --git a/lib/libvlc.sym b/lib/libvlc.sym<br>index 456f9c2..59208c8 100644<br>--- a/lib/libvlc.sym<br>+++ b/lib/libvlc.sym<br>@@ -55,8 +55,8 @@ libvlc_get_fullscreen<br> libvlc_get_version<br> libvlc_log_get_context<br> libvlc_log_get_object<br>-libvlc_log_set<br> libvlc_log_set_file<br>+libvlc_log_set_preformatted<br> libvlc_log_unset<br> libvlc_media_add_option<br> libvlc_media_add_option_flag<br>diff --git a/lib/libvlc_internal.h b/lib/libvlc_internal.h<br>index 5c1107b..8c39aa2 100644<br>--- a/lib/libvlc_internal.h<br>+++ b/lib/libvlc_internal.h<br>@@ -65,7 +65,8 @@ struct libvlc_instance_t<br>     struct libvlc_callback_entry_list_t *p_callback_list;<br>     struct<br>     {<br>-        void (*cb) (void *, int, const libvlc_log_t *, const char *, va_list);<br>+        void (*cb) (void *, int, const libvlc_log_t *, const char *);<br>+        int min_level;<br>         void *data;<br>     } log;<br>     struct<br>diff --git a/lib/log.c b/lib/log.c<br>index 66e0d99..1e57602 100644<br>--- a/lib/log.c<br>+++ b/lib/log.c<br>@@ -73,7 +73,16 @@ static void libvlc_logf (void *data, int level, const vlc_log_t *item,<br>         case VLC_MSG_DBG:  level = LIBVLC_DEBUG;   break;<br>     }<br> <br>-    inst->log.cb (inst->log.data, level, item, fmt, ap);<br>+    if(level >= inst->log.min_level)<br>+    {<br>+        char* msg;<br>+        int msgSize = vasprintf(&msg, fmt, ap);<br>+        if (unlikely(msgSize < 0))<br>+            return;<br>+<br>+        inst->log.cb(inst->log.data, level, item, msg);<br>+        free(msg);<br>+    }<br> }<br> <br> static const struct vlc_logger_operations libvlc_log_ops = {<br>@@ -85,28 +94,28 @@ void libvlc_log_unset (libvlc_instance_t *inst)<br>     vlc_LogSet (inst->p_libvlc_int, NULL, NULL);<br> }<br> <br>-void libvlc_log_set (libvlc_instance_t *inst, libvlc_log_cb cb, void *data)<br>+void libvlc_log_set_preformatted (libvlc_instance_t *p_instance, int min_level, libvlc_log_preformatted_cb cb, void* data )<br> {<br>-    libvlc_log_unset (inst); /* <- Barrier before modifying the callback */<br>-    inst->log.cb = cb;<br>-    inst->log.data = data;<br>-    vlc_LogSet(inst->p_libvlc_int, &libvlc_log_ops, inst);<br>+    libvlc_log_unset (p_instance); /* <- Barrier before modifying the callback */<br>+    p_instance->log.cb = cb;<br>+    p_instance->log.min_level = min_level;<br>+    p_instance->log.data = data;<br>+    vlc_LogSet(p_instance->p_libvlc_int, &libvlc_log_ops, p_instance);<br> }<br> <br> /*** Helpers for logging to files ***/<br> static void libvlc_log_file (void *data, int level, const libvlc_log_t *log,<br>-                             const char *fmt, va_list ap)<br>+                             const char *msg)<br> {<br>     FILE *stream = data;<br> <br>     flockfile (stream);<br>-    vfprintf (stream, fmt, ap);<br>-    fputc ('\n', stream);<br>+    fprintf (stream, "%s\n", msg);<br>     funlockfile (stream);<br>     (void) level; (void) log;<br> }<br> <br> void libvlc_log_set_file (libvlc_instance_t *inst, FILE *stream)<br> {<br>-    libvlc_log_set (inst, libvlc_log_file, stream);<br>+    libvlc_log_set_preformatted (inst, LIBVLC_DEBUG, libvlc_log_file, stream);<br> }</pre></blockquote></div><br>-- <br>Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.</body></html>