利用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标准流程来编解码的目的。

相关文章
相关标签/搜索