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 <mich...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".