為什麼 frei0r C++ 過濾器 DLL 未在 ffmpeg 中加載,但 C 過濾器卻可以

為什麼 frei0r C++ 過濾器 DLL 未在 ffmpeg 中加載,但 C 過濾器卻可以

我正在嘗試交叉編譯 ffmpeg 與 frei0r 支援 Windows 10。在 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 的路徑/名稱呼叫後會傳回一個空處理程序。再次強調,僅適用於 C++。

我懷疑這可能與 C++ 中的名稱修改有關,但就我所見,frei0r hpp 將 dlopen 呼叫的所有 C 函數匯出為外部函數。

關於這個問題有什麼提示、想法嗎?謝謝。

答案1

回答我自己的問題。

查看生成的二進位檔案後,我發現由於某種原因,mingw32-w64 g++ 編譯器忽略了 frei0r.h 包含周圍的「外部 C」。因此,導出的符號的名稱按照 C++ 編譯器的指示進行了修改,並且在從 ffmpeg 的 C 程式碼呼叫時找不到

更新:經過更多挖掘,我了解到即使 C 編譯器也會進行符號名稱修飾,防止這種情況的一種方法是使用 .def 檔案(對於 Visual Studio)來定義函數的匯出名稱。

相關內容