Почему DLL-файлы фильтров frei0r C++ не загружаются в ffmpeg, а фильтры C загружаются?

Почему DLL-файлы фильтров frei0r C++ не загружаются в ffmpeg, а фильтры C загружаются?

Я пытаюсь кросс-компилировать ffmpeg с поддержкой frei0r для windows 10. На linux (Ubuntu 18.04) все идет безупречно. На Windows (Mingw-w64 7.3.0 на Ubuntu) сборка проходит нормально. Однако при запуске на Windows с этой командной строкой:

ffmpeg -i http://lb.streaming.sk/fashiontv/stream/playlist.m3u8 -vf frei0r=pixeliz0r -loglevel debug -f mpegts pipe:play | ffplay -loglevel quiet -i pipe:play

Я получаю правильное поведение, но с

ffmpeg -i http://lb.streaming.sk/fashiontv/stream/playlist.m3u8 -vf frei0r=vignette -loglevel debug -f mpegts pipe:play | ffplay -loglevel quiet -i pipe:play

Я получаю сообщение об ошибке, что DLL не найден.

[Parsed_frei0r_0 @ 000000000347ef00] Could not find module 'vignette'.
[AVFilterGraph @ 00000000029074c0] Error initializing filter 'frei0r' with args 'vignette'
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:1
[AVIOContext @ 00000000028d8f40] Statistics: 0 seeks, 0 writeouts
[AVIOContext @ 00000000028c5480] Statistics: 133422 bytes read, 0 seeks
[AVIOContext @ 00000000028d1b00] Statistics: 0 bytes read, 0 seeks
[AVIOContext @ 00000000006ccd80] Statistics: 201 bytes read, 0 seeks
[AVIOContext @ 00000000028a8100] Statistics: 137 bytes read, 0 seeks

Такое же поведение наблюдается и в Windows, все плагины C работают, но ни один из плагинов C++ dll не найден. В сборке linux все они работают без проблем.

Вот моя конфигурация сборки для ffmpeg:

./configure --arch=x86_64 --target-os=mingw32 --cross-prefix=x86_64-w64-mingw32- --disable-doc --enable-nonfree --enable-gpl --enable-version3 --enable-static --disable-shared --enable-frei0r --extra-cflags='-I../frei0r/include -I/usr/local/include -I/usr/share/mingw-w64/include' --extra-ldflags="-static -static-libstdc++ -static-libgcc" --extra-libs='-lstdc++ /usr/local/lib/libdl.dll.a'

Я попытался отследить проблему и обнаружил, что по какой-то причине фильтр ffmpeg vf_frei0r не может открыть эти dll. Точнее, dlopen возвращает нулевой обработчик после вызова с путем/именем dll. Опять же, только для C++.

Подозреваю, что это связано с искажением имен в C++, но, насколько я вижу, frei0r hpp экспортирует все функции C, вызываемые dlopen, как внешние.

Есть ли подсказка, идея по этому вопросу? Спасибо.

решение1

Отвечаю на свой собственный вопрос.

Посмотрев на сгенерированные двоичные файлы, я обнаружил, что по какой-то причине компилятор mingw32-w64 g++ игнорирует "внешний C", который окружает include frei0r.h. Из-за этого экспортированные символы имеют искаженные имена, как того требует компилятор c++, и не обнаруживаются при вызове из кода C из ffmpeg .

Обновлять: После более глубокого изучения я узнал, что даже компилятор C выполняет декорирование имен символов, и один из способов предотвратить это — использовать файлы .def (для Visual Studio), в которых определяются экспортируемые имена ваших функций.

Связанный контент