Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On 1/16/2015 12:47 AM, Stephen Hutchinson wrote: There have been times I've run into issues because a shared library FFmpeg was linked against somehow got removed or was updated and broke compatibility. [...] Dynamic loading allows the main binary to still function correctly if this occurs, with the issue only arising if the user attempts to use the missing library, in which case the methodology of doing dynamic loading allows for a graceful exit rather than the program crashing. This is definitely wrong. An ABI break would still have the *exact* same issues as before, when the wrong library is loaded. In fact, it's worse, since it potentially ignores the soname. - Derek ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On Wed, Jan 14, 2015 at 06:26:06PM +0100, Michael Niedermayer wrote: ive no idea how portable it is but one way to avoid most of the mess would be to use attribute weak / lazy linking that way as long as lib functions arent called nothing should try to load the lib and so it should work with unresolved references something like dlopen would need to be used to detect if the lib is available or not before registering the lib wraper if that would work it should be alot cleaner / require significantly less code per lib, but its quite possible that this simply wouldnt work on some platforms, ive no idea, ive never tried it It's also possible to do similar things without linker tricks. E.g. define all functions as macros to add a ff_dl_wrap prefix, then you can implement those wrappers in a different file and from there do all the dlopen handling (making them function pointers would probably be an option, too). There are many options how to do things in detail from there on, though most likely it would make sense to try to dlopen/dlsym all libraries when registering the codecs (and not register those where dlopen or one dlsym fails). Adding a header that contains those defines should then be the only change besides the dlopen logic itself that should be necessary. There might even be some way to auto-generate some of the code. If you rely on Bsymbolic linking (possible even without it), the macros to rename the functions might not even be necessary. The lazy linking even where supported has the risk that dlopen or whatever you used worked but the symbol then isn't found in the end, and then you get crashes... It's a least-impact approach, but it seems risky. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
Hi Nicolas, On Wed, 14 Jan 2015 21:33:25 +0100 Nicolas George geo...@nsup.org wrote: Le quintidi 25 nivôse, an CCXXIII, Marc Giger a écrit : For example if they want use libfaac then they should be able to do so without that much hassle a full compilation inclusive all dependencies can be. I was expecting something like that. Unfortunately, it does not work that way: dlopen()ing libfaac will not allow you to omit --enable-nonfree and to redistribute the resulting binary, because the libfaac wrapper still includes the faac headers, which contain non-trivial code (including a big structure definition) that get translated into the resulting object file. That's a very good point. Never thought about it in this detail. Given that fact I have to admin that dynamic loading makes less sense. There may still be some usecases e.g. vaapi where it would make sense, but this seems to be the minority. Apart from that, I fully agree with Michael's last comment: using dynamic linker black magic to make this lazy linking transparent is the best option to implement that feature if it is deemed useful. libffi ? Thanks for the clarification. Marc On Linux/OpenSource OS's things are easy, on proprietary platforms ... Nothing prevents users on proprietary platforms from adopting automated repositories like Debian's apt system and everything that imitated it since to install Libre software, except the users' habits. Using such a repository to distribute your project is a good way of pushing users to change their habits for the better. Regards, -- Nicolas George ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On Thu, 15 Jan 2015 18:37:57 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi Nicolas, On Wed, 14 Jan 2015 21:33:25 +0100 Nicolas George geo...@nsup.org wrote: Le quintidi 25 nivôse, an CCXXIII, Marc Giger a écrit : For example if they want use libfaac then they should be able to do so without that much hassle a full compilation inclusive all dependencies can be. I was expecting something like that. Unfortunately, it does not work that way: dlopen()ing libfaac will not allow you to omit --enable-nonfree and to redistribute the resulting binary, because the libfaac wrapper still includes the faac headers, which contain non-trivial code (including a big structure definition) that get translated into the resulting object file. That's a very good point. Never thought about it in this detail. Given that fact I have to admin that dynamic loading makes less sense. There may still be some usecases e.g. vaapi where it would make sense, but this seems to be the minority. Apart from that, I fully agree with Michael's last comment: using dynamic linker black magic to make this lazy linking transparent is the best option to implement that feature if it is deemed useful. libffi ? libavdynamiclinker? (Just joking...) Thanks for the clarification. Marc On Linux/OpenSource OS's things are easy, on proprietary platforms ... Nothing prevents users on proprietary platforms from adopting automated repositories like Debian's apt system and everything that imitated it since to install Libre software, except the users' habits. Using such a repository to distribute your project is a good way of pushing users to change their habits for the better. Regards, -- Nicolas George ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On Thu, Jan 15, 2015 at 12:37 PM, Marc Giger gigerst...@gmx.ch wrote: That's a very good point. Never thought about it in this detail. Given that fact I have to admin that dynamic loading makes less sense. There may still be some usecases e.g. vaapi where it would make sense, but this seems to be the minority. I think the most obvious benefit at this point is something that was alluded to at the beginning of the discussion: avoidance of hard dependencies. There have been times I've run into issues because a shared library FFmpeg was linked against somehow got removed or was updated and broke compatibility. Dynamic loading allows the main binary to still function correctly if this occurs, with the issue only arising if the user attempts to use the missing library, in which case the methodology of doing dynamic loading allows for a graceful exit rather than the program crashing. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
Le quintidi 25 nivôse, an CCXXIII, Marc Giger a écrit : For example if they want use libfaac then they should be able to do so without that much hassle a full compilation inclusive all dependencies can be. I was expecting something like that. Unfortunately, it does not work that way: dlopen()ing libfaac will not allow you to omit --enable-nonfree and to redistribute the resulting binary, because the libfaac wrapper still includes the faac headers, which contain non-trivial code (including a big structure definition) that get translated into the resulting object file. Apart from that, I fully agree with Michael's last comment: using dynamic linker black magic to make this lazy linking transparent is the best option to implement that feature if it is deemed useful. On Linux/OpenSource OS's things are easy, on proprietary platforms ... Nothing prevents users on proprietary platforms from adopting automated repositories like Debian's apt system and everything that imitated it since to install Libre software, except the users' habits. Using such a repository to distribute your project is a good way of pushing users to change their habits for the better. Regards, -- Nicolas George signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
Hi, On Wed, 14 Jan 2015 10:49:23 +0100 wm4 nfx...@googlemail.com wrote: On Tue, 13 Jan 2015 19:45:01 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, On Tue, 13 Jan 2015 14:54:33 +0100 wm4 nfx...@googlemail.com wrote: On Mon, 12 Jan 2015 18:59:33 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? What's the point? Linux distros link everything anyway, they don't need to care. Gigix is not released yet ;-) and therefore I don't build a Linux distro myself but do still have interest in this feature... Other projects (distributing executables on windows etc.) restrict themselves to what they need anyway. That's my category and still have a demand for it... OK, but for what reason exactly? Simply because I don't want to restrict users of what codecs they have to use (I'm not the iXXX company and don't want to restrict user wherever I can...). For example if they want use libfaac then they should be able to do so without that much hassle a full compilation inclusive all dependencies can be. On Linux/OpenSource OS's things are easy, on proprietary platforms ... In a perfect world, the user should be able to just click on the download button and everything inclusive all codecs are magically working. But since I don't live in a perfect world (e.g. Patent, Licensing and License issues) I try to simplify things as much as I can so that the user gets the best out of the box as possible. And if he want's more he should be able to add that little piece without building the whole thing. I think it's a little bit comparable with the Linux Kernel. Do you want to recompile the kernel and update the bootloader everytime you plug-in a new device or need a firmware update for a device? A good example is the nvidia driver. Because it is proprietary it means it can't be redistributed with the Linux Kernel. So when you need it you only need to compile the wrapper code and link it against your kernel. No whole kernel rebuild needed not even a reboot (maybe after you loaded the nvidia module ;-) ). For example, I need about 10 to 15 minutes to compile and install a new kernel, but it takes me 1 to 2 days to compile my whole project inclusive ffmpeg and all libs on a windows system. And if I have to setup the whole compiler toolchain, jdk and all other stuff that I need it takes even a lot more time. If every user needs to do that just because he needs codec xyz, good night... So dynamic loading would help a lot. It also adds more global mutable state, which is not nice IMHO, although that's an implementation detail as used in your patch. A I'm open for better solutions. Please advice. library usage counter is maintained by dlopen/dlclose already, by the way. Yep, I'm aware of it. But look for example at the vaapi code then you will notice that the code is shared between multiple vaapi hwaccel's. If a deregister_hwaccel function will be implemented (makes most probably sense to be able to release the loaded lib) we need to take care that the function pointers are still valid as long as hwaccels are registered that uses the vaapi code. My intention was to memset to zero the function pointer struct when deregistering to prevent undeterministic behavior. Maybe a bad idea? You have two choices: 1. use a global table, and protect it with a mutex, plus your own usage counter if you want to use dlclose(), or 2. store the function table in each codec context (or whereever it's used), no need for a mutex or refcounting then. But still I wonder what's the purpose of this. libva and libmp3lame are not that big, and the mess resulting from having to duplicate much of the libs' headers makes maintenance harder. Is this going to be done for all external libs? Even a bigger mess. I chose libva and libmp3lame at random. Yes, it was my intention to do it for every external lib. If you ffmpeg-devs think that it is an unnecessary feature and will result in a mess, then I'm absolutely fine with this decision. All I wanted to know is how welcome such a contribution is. And if there is a chance that it will be accepted by you when it is implemented properly, I'm willing to spend more time on it. Otherwise we can stop the discussion here and I will use my time
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On Wed, Jan 14, 2015 at 10:49:23AM +0100, wm4 wrote: On Tue, 13 Jan 2015 19:45:01 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, On Tue, 13 Jan 2015 14:54:33 +0100 wm4 nfx...@googlemail.com wrote: On Mon, 12 Jan 2015 18:59:33 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? What's the point? Linux distros link everything anyway, they don't need to care. Gigix is not released yet ;-) and therefore I don't build a Linux distro myself but do still have interest in this feature... Other projects (distributing executables on windows etc.) restrict themselves to what they need anyway. That's my category and still have a demand for it... OK, but for what reason exactly? It also adds more global mutable state, which is not nice IMHO, although that's an implementation detail as used in your patch. A I'm open for better solutions. Please advice. library usage counter is maintained by dlopen/dlclose already, by the way. Yep, I'm aware of it. But look for example at the vaapi code then you will notice that the code is shared between multiple vaapi hwaccel's. If a deregister_hwaccel function will be implemented (makes most probably sense to be able to release the loaded lib) we need to take care that the function pointers are still valid as long as hwaccels are registered that uses the vaapi code. My intention was to memset to zero the function pointer struct when deregistering to prevent undeterministic behavior. Maybe a bad idea? You have two choices: 1. use a global table, and protect it with a mutex, plus your own usage counter if you want to use dlclose(), or 2. store the function table in each codec context (or whereever it's used), no need for a mutex or refcounting then. But still I wonder what's the purpose of this. libva and libmp3lame are not that big, and the mess resulting from having to duplicate much of the libs' headers makes maintenance harder. Is this going to be done for all external libs? Even a bigger mess. ive no idea how portable it is but one way to avoid most of the mess would be to use attribute weak / lazy linking that way as long as lib functions arent called nothing should try to load the lib and so it should work with unresolved references something like dlopen would need to be used to detect if the lib is available or not before registering the lib wraper if that would work it should be alot cleaner / require significantly less code per lib, but its quite possible that this simply wouldnt work on some platforms, ive no idea, ive never tried it [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Many things microsoft did are stupid, but not doing something just because microsoft did it is even more stupid. If everything ms did were stupid they would be bankrupt already. signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On Tue, 13 Jan 2015 19:45:01 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, On Tue, 13 Jan 2015 14:54:33 +0100 wm4 nfx...@googlemail.com wrote: On Mon, 12 Jan 2015 18:59:33 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? What's the point? Linux distros link everything anyway, they don't need to care. Gigix is not released yet ;-) and therefore I don't build a Linux distro myself but do still have interest in this feature... Other projects (distributing executables on windows etc.) restrict themselves to what they need anyway. That's my category and still have a demand for it... OK, but for what reason exactly? It also adds more global mutable state, which is not nice IMHO, although that's an implementation detail as used in your patch. A I'm open for better solutions. Please advice. library usage counter is maintained by dlopen/dlclose already, by the way. Yep, I'm aware of it. But look for example at the vaapi code then you will notice that the code is shared between multiple vaapi hwaccel's. If a deregister_hwaccel function will be implemented (makes most probably sense to be able to release the loaded lib) we need to take care that the function pointers are still valid as long as hwaccels are registered that uses the vaapi code. My intention was to memset to zero the function pointer struct when deregistering to prevent undeterministic behavior. Maybe a bad idea? You have two choices: 1. use a global table, and protect it with a mutex, plus your own usage counter if you want to use dlclose(), or 2. store the function table in each codec context (or whereever it's used), no need for a mutex or refcounting then. But still I wonder what's the purpose of this. libva and libmp3lame are not that big, and the mess resulting from having to duplicate much of the libs' headers makes maintenance harder. Is this going to be done for all external libs? Even a bigger mess. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
Hi Stephen, On Tue, 13 Jan 2015 08:26:10 -0500 Stephen Hutchinson qyo...@gmail.com wrote: On general principle, the idea would be nice. I'll leave broader critiques on the code to others, but I do have one thing to say: diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1ec5cae..2520e69 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -69,6 +69,25 @@ #include libavutil/ffversion.h const char av_codec_ffversion[] = FFmpeg version FFMPEG_VERSION; +#if CONFIG_DYNAMIC_LOADING + #ifdef _WIN32 +#include windows.h +#undef EXTERN_C +#define AVISYNTH_LIB avisynth + #else +#include dlfcn.h +#if defined (__APPLE__) + #define AVISYNTH_LIB libavxsynth.dylib +#else + #define AVISYNTH_LIB libavxsynth.so +#endif /* __APPLE__ */ + +#define LoadLibrary(x) dlopen(x, RTLD_LAZY) +#define GetProcAddress dlsym +#define FreeLibrary dlclose + #endif /* _WIN32 */ +#endif /* CONFIG_DYNAMIC_LOADING */ + #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS static int default_lockmgr_cb(void **arg, enum AVLockOp op) { What? One, that's a weird place to put a pruned-down version of the lib/header handler from libavformat/avisynth.c. And IMO, dynamic loading setup for a specific library belongs in that library's wrapper, since too much is liable to vary from library-to-library in what you need to be aware of. Two, AviSynth and AvxSynth are *always* dynamically loaded as it is. You cannot even build them as static (well, AvxSynth might be capable of that, but standard AviSynth is not, and currently, standard AviSynth can only be built by MSVC; good luck trying to link that against a MinGW-GCC built FFmpeg). Putting them inside this new block would be incorrect. Three, it changes the RTLD value once again? It just got changed to RTLD_LOCAL a week or two ago. Will have a look at this one. The loading block in libavofrmat/avisynth.c already handles the AviSynth case correctly. It also has examples of how to deal with different versions, since it supports two different versions of AviSynth (2.5 and AvxSynth on one hand, and 2.6 and AviSynth+ on the other). I would generally recommend looking at how libavformat/avisynth.c is set up to get a feel for how to do this for other libraries, but the support for AviSynth using dynamic loading should not rely on other libraries doing so. That's just not how AviSynth is intended to work. Please ignore all of the avisynth stuff in my patch. It's a copypaste error from myside. Sorry for the confusion... It would also possibly make sense to allow the user to specify a list of libs to dynamically load, just in case they want to use loading for some but not all. In essence, --enable-dynamic-loading would default to 'all', but the user could also do --enable-dynamic-loading=libname which would only activate it for X lib. I also thought about this one but for simplicity I left it away for the moment. Will have a look at it when there is a consens about the basic stuff. Also many thanks to you for your valuable feedback! Marc ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel -- Lesson 1: Cryptographic protocols should not be developed by a committee. -- Niels Ferguson and Bruce Schneier -- ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
Hi Michael, On Mon, 12 Jan 2015 22:57:35 +0100 Michael Niedermayer michae...@gmx.at wrote: On Mon, Jan 12, 2015 at 06:59:33PM +0100, Marc Giger wrote: Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm tested building 32bit binaries on 64bit linux: LD ffmpeg_g /usr/bin/ld: cannot find -lva collect2: ld returned 1 exit status make: *** [ffmpeg_g] Error 1 Interesting... replace my last point with - only tested on Linux x86_64 with gcc 4.8.3 atm :-) - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? I think binary based distros (and some of their users) might like this feature as it would allow them to build packages which have fewer hard dependencies but can still use all the libs if they are available and installed about the code, i think it looks ugly, too many #if too many changes interspaced with existing code. Could this be implemeted in a nicer way ? I am thinking here of keeping (almost) all changes outside of existing files I totally agree. As I already noted the purpose of the patch is to have basis for discussion and to get a feeling if such a feature will be accepted by you ffmpeg-devs. In addition I wanted to discuss it as early as possible so that you can point me in the right direction so that everybody is happy in the end. Many thanks for the valuable feedback! Marc [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Those who are too smart to engage in politics are punished by being governed by those who are dumber. -- Plato ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On general principle, the idea would be nice. I'll leave broader critiques on the code to others, but I do have one thing to say: diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1ec5cae..2520e69 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -69,6 +69,25 @@ #include libavutil/ffversion.h const char av_codec_ffversion[] = FFmpeg version FFMPEG_VERSION; +#if CONFIG_DYNAMIC_LOADING + #ifdef _WIN32 +#include windows.h +#undef EXTERN_C +#define AVISYNTH_LIB avisynth + #else +#include dlfcn.h +#if defined (__APPLE__) + #define AVISYNTH_LIB libavxsynth.dylib +#else + #define AVISYNTH_LIB libavxsynth.so +#endif /* __APPLE__ */ + +#define LoadLibrary(x) dlopen(x, RTLD_LAZY) +#define GetProcAddress dlsym +#define FreeLibrary dlclose + #endif /* _WIN32 */ +#endif /* CONFIG_DYNAMIC_LOADING */ + #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS static int default_lockmgr_cb(void **arg, enum AVLockOp op) { What? One, that's a weird place to put a pruned-down version of the lib/header handler from libavformat/avisynth.c. And IMO, dynamic loading setup for a specific library belongs in that library's wrapper, since too much is liable to vary from library-to-library in what you need to be aware of. Two, AviSynth and AvxSynth are *always* dynamically loaded as it is. You cannot even build them as static (well, AvxSynth might be capable of that, but standard AviSynth is not, and currently, standard AviSynth can only be built by MSVC; good luck trying to link that against a MinGW-GCC built FFmpeg). Putting them inside this new block would be incorrect. Three, it changes the RTLD value once again? It just got changed to RTLD_LOCAL a week or two ago. The loading block in libavofrmat/avisynth.c already handles the AviSynth case correctly. It also has examples of how to deal with different versions, since it supports two different versions of AviSynth (2.5 and AvxSynth on one hand, and 2.6 and AviSynth+ on the other). I would generally recommend looking at how libavformat/avisynth.c is set up to get a feel for how to do this for other libraries, but the support for AviSynth using dynamic loading should not rely on other libraries doing so. That's just not how AviSynth is intended to work. It would also possibly make sense to allow the user to specify a list of libs to dynamically load, just in case they want to use loading for some but not all. In essence, --enable-dynamic-loading would default to 'all', but the user could also do --enable-dynamic-loading=libname which would only activate it for X lib. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On Mon, 12 Jan 2015 18:59:33 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? What's the point? Linux distros link everything anyway, they don't need to care. Other projects (distributing executables on windows etc.) restrict themselves to what they need anyway. It also adds more global mutable state, which is not nice IMHO, although that's an implementation detail as used in your patch. A library usage counter is maintained by dlopen/dlclose already, by the way. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On 13 January 2015 at 14:54, wm4 nfx...@googlemail.com wrote: On Mon, 12 Jan 2015 18:59:33 +0100 Marc Giger gigerst...@gmx.ch wrote: Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? What's the point? Loading library on demand saves some time on application start and possibly saves memory. I is not relevant, on modern desktops, but on mobile devices it can make a difference. I haven't looked at patch, but idea as a whole is OK IMHO ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
On Mon, Jan 12, 2015 at 06:59:33PM +0100, Marc Giger wrote: Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm tested building 32bit binaries on 64bit linux: LD ffmpeg_g /usr/bin/ld: cannot find -lva collect2: ld returned 1 exit status make: *** [ffmpeg_g] Error 1 - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? I think binary based distros (and some of their users) might like this feature as it would allow them to build packages which have fewer hard dependencies but can still use all the libs if they are available and installed about the code, i think it looks ugly, too many #if too many changes interspaced with existing code. Could this be implemeted in a nicer way ? I am thinking here of keeping (almost) all changes outside of existing files [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Those who are too smart to engage in politics are punished by being governed by those who are dumber. -- Plato signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [RFC] Support dynamic loading of third-party libs
Hi, Attached is a preliminary patch that enables runtime loading of external libraries via dlopen and friends. Dynamic loading is a build time option (--enable-dynamic-loading) and if it is not activated the libs are linked as usual (still no dependency to dlopen required). The patch is intended as a basis for a discussion and therefore the following applies: - only libmp3lame and libva will by dynamically loaded atm - only tested on linux atm - deregistering not implemented (dlclose) - versioning (which version of a lib should be loaded?) - library usage counter missing - ...? What do you think? Thanks, Marc diff --git a/configure b/configure index 94f9432..5787101 100755 --- a/configure +++ b/configure @@ -101,6 +101,8 @@ Licensing options: Configuration options: --disable-static do not build static libraries [no] --enable-shared build shared libraries [no] + --enable-dynamic-loading enable runtime detection of installed libraries + (disables compile time linking of third party libs) --enable-small optimize for size instead of speed --disable-runtime-cpudetect disable detecting cpu capabilities at runtime (smaller binary) --enable-grayenable full grayscale support (slower color) @@ -1079,6 +1081,15 @@ check_lib(){ check_header $header check_func $func $@ add_extralibs $@ } +check_ext_lib() { +log check_ext_lib $@ +header=$1 +func=$2 +shift 2 +check_header $header check_func $func $@ +enabled dynamic_loading || add_extralibs $@ +} + check_lib2(){ log check_lib2 $@ headers=$1 @@ -1192,6 +1203,14 @@ require(){ check_lib $header $func $@ || die ERROR: $name not found } +require_extlib(){ +name=$1 +header=$2 +func=$3 +shift 3 +check_ext_lib $header $func $@ || die ERROR: $name not found +} + require2(){ name=$1 headers=$2 @@ -1432,6 +1451,7 @@ FEATURE_LIST= small static swscale_alpha +dynamic_loading HWACCEL_LIST= @@ -4855,6 +4875,10 @@ for func in $MATH_FUNCS; do eval check_mathfunc $func \${${func}_args:-1} done +enabled dynamic_loading{ { check_lib2 windows.h LoadLibrary; } || + { check_lib2 dlfcn.h dlopen -ldl; } || + die ERROR: LoadLibrary/dlopen not found for dynamic-loading; } + # these are off by default, so fail if requested and not available enabled avfoundation_indev { check_header_oc AVFoundation/AVFoundation.h || disable avfoundation_indev; } enabled avisynth { { check_lib2 windows.h LoadLibrary; } || @@ -4887,7 +4911,7 @@ enabled libgsm { for gsm_hdr in gsm.h gsm/gsm.h; do done || die ERROR: libgsm not found; } enabled libilbcrequire libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc enabled libmodplug require_pkg_config libmodplug libmodplug/modplug.h ModPlug_Load -enabled libmp3lame require libmp3lame = 3.98.3 lame/lame.h lame_set_VBR_quality -lmp3lame +enabled libmp3lame require_extlib libmp3lame = 3.98.3 lame/lame.h lame_set_VBR_quality -lmp3lame enabled libnut require libnut libnut.h nut_demuxer_init -lnut enabled libopencore_amrnb require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb enabled libopencore_amrwb require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb @@ -5109,7 +5133,7 @@ int main(void) { IDirectXVideoDecoder *o = NULL; IDirectXVideoDecoder_Release(o) EOF enabled vaapi -check_lib va/va.h vaInitialize -lva || +check_ext_lib va/va.h vaInitialize -lva || disable vaapi enabled vdpau diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 99467bb..4928b20 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3228,7 +3228,7 @@ typedef struct AVCodec { /** * Initialize codec static data, called from avcodec_register(). */ -void (*init_static_data)(struct AVCodec *codec); +int (*init_static_data)(struct AVCodec *codec); int (*init)(AVCodecContext *); int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size, @@ -3373,6 +3373,11 @@ typedef struct AVHWAccel { void (*decode_mb)(struct MpegEncContext *s); /** +* Initialize codec static data, called from av_register_hwaccel(). +*/ +int (*init_static_data)(struct AVHWAccel *hwaccel); + +/** * Initialize the hwaccel private data. * * This will be called from ff_get_format(), after hwaccel and diff --git a/libavcodec/internal.h b/libavcodec/internal.h index f4e12e8..fbfb8b8 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -45,6 +45,20 @@ # define STRIDE_ALIGN 8 #endif + +#if CONFIG_DYNAMIC_LOADING +#define FUNC_DEF(struct_name, func_name) {#func_name, (void **)struct_name.func_name, NULL} +#else +#define FUNC_DEF(struct_name, func_name) {#func_name, (void