[FFmpeg-devel] [PATCH 1/2] avutil/log: Add av_log_once() for printing a message just once per instance
Anton Khirnov
anton at khirnov.net
Tue Jan 21 13:24:50 EET 2020
Quoting Michael Niedermayer (2020-01-16 17:51:28)
> Compared to ad-hoc if(printed) ... code this allows the user to disable
> it with a flag and see all repeated messages, it is also simpler
That flag is global state - it should be deprecated and removed, not
embedded further into the API.
>
> TODO: APIChanges & version bump
>
> Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
> ---
> libavutil/log.c | 15 +++++++++++++++
> libavutil/log.h | 19 +++++++++++++++++++
> 2 files changed, 34 insertions(+)
>
> diff --git a/libavutil/log.c b/libavutil/log.c
> index e8a0db7716..7646e18cfa 100644
> --- a/libavutil/log.c
> +++ b/libavutil/log.c
> @@ -372,6 +372,21 @@ void av_log(void* avcl, int level, const char *fmt, ...)
> va_end(vl);
> }
>
> +void av_log_once(void* avcl, int level, int *state, const char *fmt, ...)
> +{
> + if (!((flags & AV_LOG_SKIP_REPEATED) && *state)) {
> + AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
> + va_list vl;
> + va_start(vl, fmt);
> + if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
> + avc->log_level_offset_offset && level >= AV_LOG_FATAL)
> + level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
This logic is duplicated with av_log(). Why is this not done in av_vlog
anyway?
> + av_vlog(avcl, level, fmt, vl);
> + va_end(vl);
> + *state = 1;
> + }
> +}
> +
> void av_vlog(void* avcl, int level, const char *fmt, va_list vl)
> {
> void (*log_callback)(void*, int, const char*, va_list) = av_log_callback;
> diff --git a/libavutil/log.h b/libavutil/log.h
> index d9554e609d..618d0d1817 100644
> --- a/libavutil/log.h
> +++ b/libavutil/log.h
> @@ -233,6 +233,25 @@ typedef struct AVClass {
> */
> void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);
>
> +/**
> + * Send the specified message to the log once if the level is less than or equal
> + * to the current av_log_level. By default, all logging messages are sent to
> + * stderr. This behavior can be altered by setting a different logging callback
> + * function.
> + * If AV_LOG_SKIP_REPEATED is set each message (each unique state) will only be
> + * printed once. If its not set then this behaves live av_log()
> + * @see av_log
> + *
> + * @param avcl A pointer to an arbitrary struct of which the first field is a
> + * pointer to an AVClass struct or NULL if general log.
> + * @param level The importance level of the message expressed using a @ref
> + * lavu_log_constants "Logging Constant".
> + * @param fmt The format string (printf-compatible) that specifies how
> + * subsequent arguments are converted to output.
> + * @param state a variable to keep trak of if a message has already been printed
> + * this must be initialized to 0 before the first use.
We should either demand that the caller ensures this does not get called
simultaneously with the same state, or make the above check-and-set
atomic.
--
Anton Khirnov
More information about the ffmpeg-devel
mailing list