利用FFmpeg和管道(pipe),解決非URL和非文件的輸入形式

利用FFmpeg和管道(pipe),解決非URL和非文件的輸入形式函數

問題描述:利用FFmpeg來解碼,可是輸入方式不是URL,也不是文件系統中的文件,而是內存中的buffer。線程

解決此問題有兩個思路,首先明確一點,libavformat中有幾個類,有URLProtocol(雖然叫URLxxx,可是不單單是URL的,它但是掌管了全部的輸入方式),AVOutputFormat(有muxer也有demuxer),AVInputFormat(有muxer也有demuxer)。設計

它們對應實例能夠舉幾個例子:指針

URLProtocol::ff_pipe_protocol、ff_http_protocol、ff_file_protocol。。。orm

AVOutputFormat:ff_mpegts_demuxer、ff_mp3_demuxer。。。接口

AVInputFormat:ff_mpegts_demuxer、ff_mp3_demuxer。。。ip

而後來講int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);函數,它的filename參數只接受URL或者文件名,可是對於問題中所說的狀況,就不適合了,因此咱們能夠用第一個簡單的辦法來解決。內存

下面舉實例說明。get

如今假如是要用mpegts流的數據來源,每次咱們都能調用某個接口(例如:get_ts_packet(fd, ts_buf, 188);)來得到一個完整的188字節的ts包存入buf裏面,如何傳給FFmpeg呢?input

假設線程1是主線程,線程2是獲取ts包的線程,不斷調用get_ts_packet接口,線程3來調用FFmpeg。思路是

線程1:利用mkfifo新建一個命名管道(MY_FIFO_PIPE);

線程2:不斷去得到ts包,而後就轉存到MY_FIFO_PIPE裏面;

線程3:設計爲FFmpeg,直接調用avformat_open_input(&avfmtctx, MY_FIFO_PIPE, NULL, NULL);

這樣在不修改FFmpeg的前提下使用FFmpeg來進行解複用解碼。

還有另外一種思路,就是修改URLProtocol中的某一個實例(好比file.c中的ff_file_protocol),或者新建一個URLProtocol的實例(ff_xxx_protocol),而後實現下列幾個函數指針:open、read、seek(如不須要seek可不用實現),以此來適配相應的數據來源方式,最終達到使用ffmpeg標準流程來編解碼的目的。

相關文章
相關標籤/搜索