ffmpeg 从内存中读取数据(或将数据输出到内存)
更新记录(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 从内存中读取数据(或将数据输出到内存)相关推荐
- C# 操作地址 从内存中读取写入数据(初级)
本示例以植物大战僵尸为例, 实现功能为 每1秒让阳光刷新为 9999.本示例使用的游戏版本为 [植物大战僵尸2010年度版], 使用的辅助查看内存地址的工具是 CE. 由于每次启动游戏, 游戏中阳光 ...
- 深度解剖数据在内存中的存储!!数据在内存中原来是这样表示的?为什么浮点数和整数的存储方式差距这么大?
文章目录 Data Storage 1. 数据类型 1.1 整型家族 1.2 浮点数家族 1.3 指针类型 1.4 构造类型 2. 整型在内存中的存储 2.1 二进制表示形式 2.1.1 正数 2.1 ...
- 在内存中读取函数的ShellCode并执行
在内存中读取函数的ShellCode并执行 下面是一个例子,实现的效果是将fun1函数的十六进制读取出来,在内存中将str1的地址改成str2,分配一块内存,将改好的函数的ShellCode写入并执行 ...
- 查看mysql是否内存中读取数据_MySQL中的内存临时表
//MySQL中的内存临时表// 这两天事情稍微有点多,公众号也停止更新了几天,结果有读者催更了,也是,说明还是有人关注,利己及人,挺好. 今天分享的内容是MySQL中的临时表,对于临时表,之前我其实 ...
- python二进制文件 删除尾部数据_在Python中读取和切片二进制数据文件的最快方法...
我有一个处理脚本,用于提取"uint16"类型的二进制数据文件,并一次以6400块的形式进行各种处理.该代码最初是用Matlab编写的,但由于分析代码是用 Python编写的,我们 ...
- c++怎么可以在二进制文件中读取带string的数据_文件处理 | csv文件读写
欢迎关注公众号 学习资料不会少 文件处理 在我们做自动化测试的过程中,常常会将数据文件存放在csv或者Excel文件里边.这一章节内容将给大家介绍,如何使用python进行csv和Excel文件的处理 ...
- c语言中读取内存的文件,c++从内存中读取文件内容,内容写到内存 实现文件的内存共享代码实例...
使用c++代码进行内存共享操作,内存共享可以通过key value的形式来保存内存,后面可以使用key值来直接读取内存,效率会很高/ 函数说明: shmget(key_t key, size_t si ...
- c语言结构体在内存中的存储,C语言结构体在内存中的存储情况探究------内存对齐...
条件(先看一下各个基本类型都占几个字节): voidsize_(){ printf("char类型:%d", sizeof(char)); printf("int类型:% ...
- MATLAB中批量从txt文件中读取指定行的数据保存为txt文件
经常遇到,我们想要读取的数据,不是从头开始读取的,我们往往要求从固定的行开始读取,MATLAB代码如下: function readData() %从指定行开始读取数据 readFilePath='C ...
最新文章
- GNU parted的指令說明[转]
- WebBrowser组件和MSHTML
- Caffe + CUDA8.0 + CuDNNv5.1 + OpenCV3.1 + Ubuntu14.04 配置参考文献 ---- Wang Xiao Anhui University CVP
- [转]敏捷开发之Scrum扫盲,及敏捷开发中XP与SCRUM的区别
- 04_SSM整合ActiveMQ支持多种类型消息
- 【转载】Elasticsearch客户端API使用Demo
- 使用Keil5构建GD32450i-EVAL工程
- sublime 如何使用less_Sublime Text3 使用教程
- android tablet gps antenna,A Novel Tri-band GPS/WLAN Antenna for Tablet with Full Metal Housing
- [Python] 网络爬虫和正则表达式学习总结
- Spring Data Jpa使用@Query时 报错Validation failed for query for method public abstract
- 实验4-1-2 求奇数和 (15 分)
- Selenium2用最简xpath查找元素
- 交通灯c语言单片机程序,基于51单片机的一个简单交通灯程序
- 【资源】机器学习 周志华
- 工业机器人导轨 百度文库_工业机器人复习资料
- php微信公众号报修系统,微信公众号报修系统使用流程
- java实现腾讯云直播
- angular监听输入框值的变化_angular 实时监听input框value值的变化触发函数
- 写给大学时期自己的寄语