更新记录(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. GNU parted的指令說明[转]
  2. WebBrowser组件和MSHTML
  3. Caffe + CUDA8.0 + CuDNNv5.1 + OpenCV3.1 + Ubuntu14.04 配置参考文献 ---- Wang Xiao Anhui University CVP
  4. [转]敏捷开发之Scrum扫盲,及敏捷开发中XP与SCRUM的区别
  5. 04_SSM整合ActiveMQ支持多种类型消息
  6. 【转载】Elasticsearch客户端API使用Demo
  7. 使用Keil5构建GD32450i-EVAL工程
  8. sublime 如何使用less_Sublime Text3 使用教程
  9. android tablet gps antenna,A Novel Tri-band GPS/WLAN Antenna for Tablet with Full Metal Housing
  10. [Python] 网络爬虫和正则表达式学习总结
  11. Spring Data Jpa使用@Query时 报错Validation failed for query for method public abstract
  12. 实验4-1-2 求奇数和 (15 分)
  13. Selenium2用最简xpath查找元素
  14. 交通灯c语言单片机程序,基于51单片机的一个简单交通灯程序
  15. 【资源】机器学习 周志华
  16. 工业机器人导轨 百度文库_工业机器人复习资料
  17. php微信公众号报修系统,微信公众号报修系统使用流程
  18. java实现腾讯云直播
  19. angular监听输入框值的变化_angular 实时监听input框value值的变化触发函数
  20. 写给大学时期自己的寄语

热门文章

  1. HDU2082 找单词【母函数】
  2. HDU3348 coins【贪心】
  3. UVA495 Fibonacci Freeze【大数+万进制】
  4. CCF NOI1044 最近元素
  5. I00038 自守数(Automorphic number)
  6. 马尔科夫随机过程的理解
  7. 机器学习实践指南(四)—— 算法的细节
  8. Matlab Tricks(二)—— 空参空返回值的函数
  9. WinEdt LaTex(二)—— 空心中括号
  10. jdbc连oracle dns报错,近期处理的oracle问题汇总