[libav-devel] [RFC] Getting rid of the global log callback

wm4 nfxjfg at googlemail.com
Sun Dec 17 16:09:04 CET 2017


On Sun, 17 Dec 2017 16:17:47 +0200
Rémi Denis-Courmont <remi at remlab.net> wrote:

> Le sunnuntaina 17. joulukuuta 2017, 14.35.13 EET Luca Barbato a écrit :
> > On 11/12/2017 14:48, wm4 wrote:  
> > > The log callback, set with av_log_set_callback(), is global mutable
> > > state, and as such not something we want in Libav, at all. but getting
> > > rid of it is very complicated, because in most cases, av_log() does not
> > > have enough context available to find per-context log callbacks.
> > > 
> > > av_log() has a context pointer as first argument. This is just a void*.
> > > If it's non-NULL, then it's assumed to be a struct, with a AVClass*
> > > field as first member (e.g. AVCodecContext.av_class). This points to
> > > const memory, so it's not mutable state, and there's no way to put a
> > > private log callback there.
> > > 
> > > So this whole problem boils down to how to change AVClass to store a
> > > per-context log callback in structs using AVClass.
> > > 
> > > You can pass a NULL context to av_log() too. This would inherently
> > > require a global log callback, so we have to deprecate this usage
> > > entirely.
> > > 
> > > A log callback would include a pointer, and a user pointer:
> > > 
> > > struct AVLogCallback {
> > > 
> > >    void *user_context;
> > >    // context is the caller (a struct with AVClass* as first field)
> > >    // user_context as the same value as the field above.
> > >    void (*callback)(void *context, void *user_context, int level,
> > >    
> > >                     const char *fmt, va_list vl);
> > > 
> > > }  
> > 
> > user_context may need a user_free(),  
> 
> Why oh why?
> 
> There should be a point when the libavcodec user application can safely assume 
> that the callback will no longer be used - e.g. when the context is closed. 
> Using a free callback is only making things needlessly brittle and complicated 
> on both sides.
> 

Well, he has a point. Some things live on as long something keeps a
reference to it. This can be quite non-obvious (like an AVFrame
implicitly holding a decoder frame pool and such, after the decoder
was closed).

So maybe the callback should be refcounted, if only to give the API
user the chance to safely free whatever resource the callback needs.

But it does feel a bit like getting into some bikeshed downwards spiral.


More information about the libav-devel mailing list