? ? ffmpeg是一套多媒體音視頻處理工具,集成了采集、轉碼、轉流、編解碼等的功能,最近遇到了需要替換ffmpeg中傳輸協(xié)議的問題(添加自定義的編解碼器道理是一樣的),苦于網上沒有詳細教程,所以費了好大周章才搞清楚這一套流程。 所以特別寫了這個帖子,希望其他小伙伴們遇到相同問題時可以參考一下,編寫的時間比較倉促,不詳細的地方還請見諒。
私有傳輸協(xié)議編寫:
1. 當我們想要添加私有協(xié)議到ffmpeg中時,需要按照ffmpeg框架的要求實現對外的一些數據結構和接口,首先需要再libavformat目錄下新建一個協(xié)議的源文件(如果想要添加私有的編解碼器,那么就添加在libavcodec目錄中),例如:XXXprotocols.c。在源文件中實現URLProtocol和AVClass的結構體, 以及一些對外訪問的接口,如圖所示:被紅色部分蓋住的地方為協(xié)議的名字
其中.name是ffmpeg在解析完url后,查找對應協(xié)議的匹配字符。
.url_open .url_read .url_write .url_close是ffmpeg對外開放的四個接口函數,等號的右邊為函數名稱,需要在這個源文件中實現成靜態(tài)函數,詳細參數實現過程,請參考源碼中的rtmpproto.c文件。
2.? 如果自身的協(xié)議是用c++編寫,那么編譯成的庫就是用g++編譯的,但是ffmpeg默認是用gcc編譯的,所以在ffmpeg源碼編譯的最后鏈接的過程會出現一些問題。作者建議,可以參照x265編解碼的方法,將私有協(xié)議打包成動態(tài)庫,并且實現好對外的C的接口,然后通過dlopen 和 dlsym找到動態(tài)庫的起始地址,尋找對應接口函數。
dlopne用法詳細參考教程:http://www.cnblogs.com/Anker/p/3746802.html
x256源碼: https://github.com/videolan/x265 (詳細參考encoder目錄下的api.cpp)
源碼編譯過程:
1. 最新版FFmpeg需要在 libavformat/protocols.c中添加ff_XXX_protocol的全局變量, 如下圖所示:
2. 在libavformat/protocol_list.c的全局數組中添加ff_XXX_protocol,如下圖所示:
(注意: 在舊版ffmpeg中,協(xié)議的聲明是在ibavformat/allformats.c中注冊的,在/* protocols */后面添加
REGISTER_PROTOCOL (XXX, xxx); ?完成私有協(xié)議的全局聲明和注冊步驟
開頭聲明如下:其中##是字符串連接的意思。
#define REGISTER_PROTOCOL(X,x) { \
externURLProtocol?ff_##x##_protocol;?\
if(CONFIG_##X##_PROTOCOL)?ffurl_register_protocol(&ff_##x##_protocol,sizeof(ff_##x##_protocol));?})
3. 修改libavformat 目錄下的makefile,在#protocols I/O 下面添加定義的
OBJS-$(CONFIG_XXX_PROTOCOL)+=XXXnameXXX.o, 將預先實現的C接口文件編譯成對應的目標文件。
4. 修改ffmeg根目錄下的config.h和config.mak文件:
在config.h文件中添加 #define CONFIG_XXX_PROTOCOL 1
在config.mak文件中添加CONFIG_XXX_PROTOCOL=yes. ?修改完這兩處后,就不用重新./configure了。
5. 進行 make 操作(然后 make install 之后 make clean)
6. 通過命令 ./ffmpeg -protocols 查看自己編寫的私有協(xié)議是否添加進了ffmpeg體系中。