frei0r C++ 필터 DLL은 ffmpeg에 로드되지 않지만 C 필터는 로드되는 이유는 무엇입니까?

frei0r C++ 필터 DLL은 ffmpeg에 로드되지 않지만 C 필터는 로드되는 이유는 무엇입니까?

Windows 10에 대한 frei0r 지원을 사용하여 ffmpeg를 크로스컴파일하려고 합니다. Linux(Ubuntu 18.04)에서는 모든 것이 완벽하게 진행됩니다. Windows(Ubuntu의 Mingw-w64 7.3.0)에서는 빌드가 잘 됩니다. 그러나 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의 경로/이름을 호출한 후 null 처리기를 반환합니다. 다시 말하지만 C++에만 해당됩니다.

나는 그것이 C++의 이름 변경과 관련된 것일 수도 있다고 생각하지만 frei0r hpp는 dlopen이 호출하는 모든 C 함수를 외부로 내보냅니다.

이 문제에 대한 힌트나 아이디어가 있나요? 감사해요.

답변1

내 자신의 질문에 대답합니다.

생성된 바이너리를 살펴본 후 어떤 이유로 mingw32-w64 g++ 컴파일러가 frei0r.h 포함을 둘러싼 "외부 C"를 무시하고 있음을 발견했습니다. 이로 인해 내보낸 기호의 이름은 C++ 컴파일러의 지시에 따라 손상되고 ffmpeg의 C 코드에서 호출할 때 찾을 수 없습니다 .

업데이트: 좀 더 조사한 결과 C 컴파일러도 기호 이름 장식을 수행한다는 사실을 알게 되었으며 이를 방지하는 한 가지 방법은 함수의 내보낸 이름을 정의하는 .def 파일(Visual Studio용)을 사용하는 것입니다.

관련 정보