更新记录(2014.7.24):

1.为了使本文更通俗易懂,更新了部分内容,将例子改为从内存中打开。

2.增加了将数据输出到内存的方法。

从内存中读取数据

ffmpeg一般情况下支持打开一个本地文件,例如“C:\test.avi”

或者是一个流媒体协议的URL,例如“rtmp://222.31.64.208/vod/test.flv”

其打开文件的函数是avformat_open_input(),直接将文件路径或者流媒体URL的字符串传递给该函数就可以了。

但其是否支持从内存中读取数据呢?这个问题困扰了我很长时间。当时在做项目的时候,通过Winpcap抓取网络上的RTP包,打算直接送给ffmpeg进行解码。一直没能找到合适的方法。因为抓取的数据包是存在内存中的,所以无法传递给avformat_open_input()函数其路径(根本没有路径= =)。当然也可以将抓取的数据报存成文件,然后用ffmpeg打开这个文件,但是这样的话,程序的就太难控制了。

后来经过分析ffmpeg的源代码,发现其竟然是可以从内存中读取数据的,代码很简单,如下所示:

AVFormatContext *ic = NULL;
ic = avformat_alloc_context();
unsigned char * iobuffer=(unsigned char *)av_malloc(32768);
AVIOContext *avio =avio_alloc_context(iobuffer, 32768,0,NULL,fill_iobuffer,NULL,NULL);
ic->pb=avio;
err = avformat_open_input(&ic, "nothing", NULL, NULL);

关键要在avformat_open_input()之前初始化一个AVIOContext,而且将原本的AVFormatContext的指针pb(AVIOContext类型)指向这个自行初始化AVIOContext。当自行指定了AVIOContext之后,avformat_open_input()里面的URL参数就不起作用了。示例代码开辟了一块空间iobuffer作为AVIOContext的缓存。

fill_iobuffer则是将数据读取至iobuffer的回调函数。fill_iobuffer()形式(参数,返回值)是固定的,是一个回调函数,如下所示(只是个例子,具体怎么读取数据可以自行设计)。示例中回调函数将文件中的内容通过fread()读入内存。

//读取数据的回调函数-------------------------
//AVIOContext使用的回调函数!
//注意:返回值是读取的字节数
//手动初始化AVIOContext只需要两个东西:内容来源的buffer,和读取这个Buffer到FFmpeg中的函数
//回调函数,功能就是:把buf_size字节数据送入buf即可
//第一个参数(void *opaque)一般情况下可以不用
int fill_iobuffer(void * opaque,uint8_t *buf, int bufsize){if(!feof(fp_open)){int true_size=fread(buf,1,buf_size,fp_open);return true_size;}else{return -1;}
}

整体结构大致如下:

FILE *fp_open;int fill_iobuffer(void *opaque, uint8_t *buf, int buf_size){
...
}int main(){...fp_open=fopen("test.h264","rb+");AVFormatContext *ic = NULL;ic = avformat_alloc_context();unsigned char * iobuffer=(unsigned char *)av_malloc(32768);AVIOContext *avio =avio_alloc_context(iobuffer, 32768,0,NULL,fill_iobuffer,NULL,NULL);ic->pb=avio;err = avformat_open_input(&ic, "nothing", NULL, NULL);...//解码
}

将数据输出到内存

和从内存中读取数据类似,ffmpeg也可以将处理后的数据输出到内存。

回调函数如下示例,可以将输出到内存的数据写入到文件中。

//写文件的回调函数
int write_buffer(void *opaque, uint8_t *buf, int buf_size){if(!feof(fp_write)){int true_size=fwrite(buf,1,buf_size,fp_write);return true_size;}else{return -1;}
}

主函数如下所示。

FILE *fp_write;int write_buffer(void *opaque, uint8_t *buf, int buf_size){
...
}main(){...fp_write=fopen("src01.h264","wb+"); //输出文件...AVFormatContext* ofmt_ctx=NULL;avformat_alloc_output_context2(&ofmt_ctx, NULL, "h264", NULL);unsigned char* outbuffer=(unsigned char*)av_malloc(32768);AVIOContext *avio_out =avio_alloc_context(outbuffer, 32768,0,NULL,NULL,write_buffer,NULL);  ofmt_ctx->pb=avio_out; ofmt_ctx->flags=AVFMT_FLAG_CUSTOM_IO;...
}

ffmpeg 从内存中读取数据(或将数据输出到内存)相关推荐

  1. C# 操作地址 从内存中读取写入数据(初级)

    本示例以植物大战僵尸为例, 实现功能为 每1秒让阳光刷新为 9999.本示例使用的游戏版本为 [植物大战僵尸2010年度版], 使用的辅助查看内存地址的工具是  CE. 由于每次启动游戏, 游戏中阳光 ...

  2. 深度解剖数据在内存中的存储!!数据在内存中原来是这样表示的?为什么浮点数和整数的存储方式差距这么大?

    文章目录 Data Storage 1. 数据类型 1.1 整型家族 1.2 浮点数家族 1.3 指针类型 1.4 构造类型 2. 整型在内存中的存储 2.1 二进制表示形式 2.1.1 正数 2.1 ...

  3. 在内存中读取函数的ShellCode并执行

    在内存中读取函数的ShellCode并执行 下面是一个例子,实现的效果是将fun1函数的十六进制读取出来,在内存中将str1的地址改成str2,分配一块内存,将改好的函数的ShellCode写入并执行 ...

  4. 查看mysql是否内存中读取数据_MySQL中的内存临时表

    //MySQL中的内存临时表// 这两天事情稍微有点多,公众号也停止更新了几天,结果有读者催更了,也是,说明还是有人关注,利己及人,挺好. 今天分享的内容是MySQL中的临时表,对于临时表,之前我其实 ...

  5. python二进制文件 删除尾部数据_在Python中读取和切片二进制数据文件的最快方法...

    我有一个处理脚本,用于提取"uint16"类型的二进制数据文件,并一次以6400块的形式进行各种处理.该代码最初是用Matlab编写的,但由于分析代码是用 Python编写的,我们 ...

  6. c++怎么可以在二进制文件中读取带string的数据_文件处理 | csv文件读写

    欢迎关注公众号 学习资料不会少 文件处理 在我们做自动化测试的过程中,常常会将数据文件存放在csv或者Excel文件里边.这一章节内容将给大家介绍,如何使用python进行csv和Excel文件的处理 ...

  7. c语言中读取内存的文件,c++从内存中读取文件内容,内容写到内存 实现文件的内存共享代码实例...

    使用c++代码进行内存共享操作,内存共享可以通过key value的形式来保存内存,后面可以使用key值来直接读取内存,效率会很高/ 函数说明: shmget(key_t key, size_t si ...

  8. c语言结构体在内存中的存储,C语言结构体在内存中的存储情况探究------内存对齐...

    条件(先看一下各个基本类型都占几个字节): voidsize_(){ printf("char类型:%d", sizeof(char)); printf("int类型:% ...

  9. MATLAB中批量从txt文件中读取指定行的数据保存为txt文件

    经常遇到,我们想要读取的数据,不是从头开始读取的,我们往往要求从固定的行开始读取,MATLAB代码如下: function readData() %从指定行开始读取数据 readFilePath='C ...

最新文章

  1. Lombok!代码简洁神器还是代码“亚健康”元凶?
  2. UILabel中的多行文本
  3. Unix网络协议分析
  4. [译]Java 设计模式之命令
  5. OAM K8s 标准实现 Crossplane 项目进入 CNCF Sandbox
  6. CCNA Discovery第二学期 (版本 4.1)
  7. ensp静态路由的配置及分析
  8. 怎么将pdf转换成word
  9. 删除一个程序Linux,一天一个Linux基础命令删除文件或目录命令rm
  10. 小程序中ajax返回数据,微信小程序调用接口返回数据或提交数据
  11. SQL 创建数据库、表以及索引
  12. 国产游戏版号时隔8个月重启 游戏公司董事长喜极而泣
  13. 数据结构与算法 汉诺塔问题和列车车厢重排问题
  14. 联合 5 位大佬送 210 本实体书,包邮到家!
  15. 基于u-boot源码的简单shell软件实现
  16. 鲸会务,多场景覆盖数字化会议管家
  17. css 清除表单样式,css form表单样式清除
  18. 计算机没有打字键盘显示不出来,电脑无法打字键盘没有反应怎么办 win10电脑屏幕键盘怎么打开...
  19. 假设检验及在机器学习中的应用
  20. HALCON算子函数总结(中)

热门文章

  1. HDU2571 命运【动态规划DP】
  2. Bailian2747 Bailian4146 数字方格【暴力】
  3. CCF201604-1 折点计数(解法二)(100分)(废除!!!)
  4. Java实现的大整数分解Pollard's rho算法程序
  5. matlab 工具函数 —— logdet(A)
  6. 从 RNN 到 LSTM (Short-Term Memory)
  7. auxiliary variable(辅助变量)的引入
  8. python从入门到精通 明日科技 电子书-Python从入门到精通(明日科技出版) 源代码+课件+视频 全套...
  9. 学python买什么书-19年学习Python有什么好的书籍推荐吗?
  10. python安装-在Python中安装包的三种方法