内存中数据输出到stdout, ffmpeg如何直接读取stdio

    我们知道,ffmpeg可以读取本地文件, 网络数据http,ftp, udp, http, rtsp等, 但是这些都只需要一个简单的-i参数,后面接所需要的数据地址就可以了.之所以如此方便, 是因为ffmpeg的open_intput_file()等函数封装了很多特性,以至于我们不需要关注这些细节.

    但是, 当我们需要开发特定的程序时, 即所需要的数据, 既不是本地的, 也不是从网络传输过来的, 这样就无法直接使用ffmpeg的上述方便的特性. 比如, 我们接收的是pcie传输过来的数据, 总不能先把传输过来的数据先存入本地, 然后接收完毕后再通过ffmpeg或者ffplay来操作吧. 这样肯定是不允许或者是不实际的.

    如何解决上述问题, 首先想到的是改写ffmpeg的avformat_open_input()函数, 具体到如何处理filename这个数据, 这将异常麻烦. 但ffmpeg可以直接接收标准输入和管道里的数据,这样,我们可以通过管道转化,实现ffmpeg直接从内存中读取数据

      具体应用 

这里,用本地文件模拟, 读取本地文件到内存, 当然, 这里内存的数据,可以是从其它地方获取, 下面只是一个简单的将内存的数据写入stdin的小程序, 无实际意义. 作用是把内存的数据放入到标准输出

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAX_LINE 1024*1024

int main()
{
	int ret;
	char buf[MAX_LINE];
	FILE *fp = fopen("aa.h264","r");
   // ret = mkfifo("pipe:1",0777);
   // if(ret !=0)
   //     printf("pipe error
");
   // fpp = fopen("pipe:1","r");
	while((ret=fread(buf,1,1024,fp))!=0)
	{
        fwrite(buf,1,ret,stdout);
	}
	return 0;
}

下一步, ffmpeg或者ffplay可以直接接收这些数据而不需要作任何改进.

命令是:

./test | ffplay -i -

./test | ffmpeg -i - -s 1920x1080 test.h264

这样就可以直接播放或者用ffmpeg处理这些数据了   

      当然, 这里的fwrite()函数只是一个简单的示例, 你可以换成特定的写入stdio的操作, 可以实现特定的协议


每天早上叫醒你的不是闹钟,而是心中的梦~
原文地址:https://www.cnblogs.com/vintion/p/4116901.html