博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用FFmpeg和管道(pipe),解决非URL和非文件的输入形式
阅读量:6832 次
发布时间:2019-06-26

本文共 1191 字,大约阅读时间需要 3 分钟。

hot3.png

利用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。。。

AVOutputFormat:ff_mpegts_demuxer、ff_mp3_demuxer。。。

AVInputFormat:ff_mpegts_demuxer、ff_mp3_demuxer。。。

然后来说int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);函数,它的filename参数只接受URL或者文件名,但是对于问题中所说的情况,就不适合了,所以我们可以用第一个简单的办法来解决。

下面举实例说明。

现在假如是要用mpegts流的数据来源,每次我们都能调用某个接口(例如:get_ts_packet(fd, ts_buf, 188);)来获得一个完整的188字节的ts包存入buf里面,如何传给FFmpeg呢?

假设线程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标准流程来编解码的目的。

转载于:https://my.oschina.net/michaelyuanyuan/blog/66275

你可能感兴趣的文章