用ffmpeg写过一个自己的播放器,对ffmpeg如何打开打开文件,匹配demux,提取stream,匹配decode及渲染有一个感性的认识,目前想做一个网络接口支持多路远程摄像头的播放,起初的解决方案是dshow打开摄像头+x264编码+live555(RSTP)传输,发现编码速度太慢,达不到实时要求,于是将编码改成多线程,发现速度没什么提升(可能是拿出了问题吧)后来想起了ffmpeg(强悍的东东)于是暂停原来的方案,再次研究ffmpeg;这次的重点是配置io即用从自己设定的io中读取数据,想直接用socket发送编码数据,然后在客户端进行数据整合,传输到ffmpeg里进行解码输出;通常我们是按照下列步骤进行解码的:
1打开视频文件:
首先第一件事情--让我们来看看怎样打开一个视频文件并从中得到流。我们要做的第一件事情就是初始化libavformat/libavcodec:
av_register_all();
这一步注册库中含有的所有可用的文件格式和编码器,这样当打开一个文件时,它们才能够自动选择相应的文件格式和编码器。要注意你只需调用一次 av_register_all(),所以,尽可能的在你的初始代码中使用它。如果你愿意,你可以仅仅注册个人的文件格式和编码,不过,通常你不得不这么做却没有什么原因。
2下一步,打开文件:
AVFormatContext *pFormatCtx;
const char *filename="myvideo.mpg";
// 打开视频文件
if(av_open_input_file(&pFormatCtx,filename, NULL, 0, NULL)!=0)
handle_error(); // 不能打开此文件
最后三个参数描述了文件格式,缓冲区大小(size)和格式参数;我们通过简单地指明NULL或0告诉 libavformat去自动探测文件格式并且使用默认的缓冲区大小。请在你的程序中用合适的出错处理函数替换掉handle_error()。
3下一步,我们需要取出包含在文件中的流信息:
// 取出流信息
if(av_find_stream_info(pFormatCtx)<0)
handle_error(); // 不能够找到流信息
这一步会用有效的信息把 AVFormatContext 的流域(streams field)填满。作为一个可调试的诊断,我们会将这些信息全盘输出到标准错误输出中,不过你在一个应用程序的产品中并不用这么做:
dump_format(pFormatCtx, 0, filename, false);