Chinaunix首页 | 论坛 | 博客
  • 博客访问: 856612
  • 博文数量: 1384
  • 博客积分: 27795
  • 博客等级: 上将
  • 技术积分: 16887
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-12 09:28
个人简介

只是心态,抓住机会。

文章分类

全部博文(1384)

文章存档

2014年(3)

2013年(403)

2012年(978)

分类: LINUX

2012-12-24 16:38:13

利用FFmpeg和管道(pipe),解决非URL和非文件的输入形式
、http://my.oschina.net/michaelyuanyuan/blog/66275

0人收藏此文章, 发表于5个月前(2012-07-10 11:41) , 已有290次阅读 ,共1个评论

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

问题描述:利用FFmpeg来解码,但是输入方式不是URL,也不是文件系统中的文件,而是内存中的buffer。

解决此问题有两个思路,首先明确一点,libavformat中有几个类,有URLProtocol(虽然叫URLxxx,但是不仅仅是URL的,它可是掌管了所有的输入方式),AVOutputFormat(有muxer也有demuxer),AVInputFormat(有muxer也有demu xer)。

它们对应实例可以举几个例子:

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

阅读(4668) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~