这里请注意,在编译ffmpeg时,不要使用--disable-devices选项。

使用

--enable-encoder=rawvideo
 --enable-decoder=rawvideo

启用rawvideo codec。

代码如下:

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <libavformat/avformat.h>
  5. #include <libavcodec/avcodec.h>
  6. #include <libavdevice/avdevice.h>
  7. #include <libswscale/swscale.h>
  8. #include <windows.h>
  9. #include <time.h>
  10. #define MAX_INPUT_DEVICE_NUM 10
  11. #ifdef _WIN32
  12. int strcasecmp(const char *s1, const char *s2)
  13. {
  14. while ((*s1 != '\0')
  15. && (tolower(*(unsigned char *) s1) ==
  16. tolower(*(unsigned char *) s2)))
  17. {
  18. s1++;
  19. s2++;
  20. }
  21. return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
  22. }
  23. int strncasecmp(const char *s1, const char *s2, unsigned int n)
  24. {
  25. if (n == 0)
  26. return 0;
  27. while ((n-- != 0)
  28. && (tolower(*(unsigned char *) s1) ==
  29. tolower(*(unsigned char *) s2))) {
  30. if (n == 0 || *s1 == '\0' || *s2 == '\0')
  31. return 0;
  32. s1++;
  33. s2++;
  34. }
  35. return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
  36. }
  37. #endif
  38. void save_bmp(unsigned char * data,int data_size,int w,int h,FILE * out)
  39. {
  40. // 位图文件头
  41. BITMAPFILEHEADER bmpheader;
  42. BITMAPINFO bmpinfo;
  43. int bit = 24;
  44. bmpheader.bfType = ('M' <<8)|'B';
  45. bmpheader.bfReserved1 = 0;
  46. bmpheader.bfReserved2 = 0;
  47. bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  48. bmpheader.bfSize = bmpheader.bfOffBits + w*h*bit/8;
  49. bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  50. bmpinfo.bmiHeader.biWidth = w;
  51. bmpinfo.bmiHeader.biHeight = 0-h;
  52. bmpinfo.bmiHeader.biPlanes = 1;
  53. bmpinfo.bmiHeader.biBitCount = bit;
  54. bmpinfo.bmiHeader.biCompression = BI_RGB;
  55. bmpinfo.bmiHeader.biSizeImage = 0;
  56. bmpinfo.bmiHeader.biXPelsPerMeter = 100;
  57. bmpinfo.bmiHeader.biYPelsPerMeter = 100;
  58. bmpinfo.bmiHeader.biClrUsed = 0;
  59. bmpinfo.bmiHeader.biClrImportant = 0;
  60. fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,out);
  61. fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,out);
  62. fwrite(data,data_size,1,out);
  63. }
  64. int CaptureFromLocalCamera()
  65. {
  66. AVFormatContext *ic = NULL;
  67. AVFormatParameters in_fmt_para={0};
  68. AVPacket packet;
  69. char buffer[MAX_PATH]={0};
  70. int width = 0,height = 0;
  71. int ret,video_stream = -1,i=0;
  72. //查找输入(vfwcap)格式
  73. AVInputFormat *in_fmt = av_find_input_format ("vfwcap");
  74. if (in_fmt == NULL)
  75. {
  76. printf("not support input device vfwcap.\n");
  77. return -1;
  78. }
  79. memset (&in_fmt_para, 0, sizeof(in_fmt_para));
  80. //指定需要采集图像的高度
  81. in_fmt_para.height = height;
  82. //指定需要采集图像的宽度
  83. in_fmt_para.width  = width;
  84. //设置帧率
  85. av_parse_video_frame_rate(&in_fmt_para.time_base,"20");
  86. //打开摄像头设备,从"0"到MAX_INPUT_DEVICE_NUM依次尝试打开
  87. for( i=0 ; i < MAX_INPUT_DEVICE_NUM + 1; i++ )
  88. {
  89. sprintf(buffer,"%d",i);
  90. ret = av_open_input_file ( &ic, buffer, in_fmt,sizeof(in_fmt_para),&in_fmt_para);
  91. if ( ret == 0 && ic)
  92. {
  93. break;
  94. }
  95. }
  96. //open success?
  97. if(!ic || ret != 0)
  98. {
  99. if(ic)
  100. av_close_input_file(ic);
  101. printf("can not open input file.\n");
  102. return -2;
  103. }
  104. printf("input device no. is %d\n",i);
  105. //find the video stream
  106. for(i=0;i<ic ->nb_streams;i++)
  107. {
  108. if ( CODEC_TYPE_VIDEO == ic ->streams[i] ->codec ->codec_type )
  109. {
  110. video_stream = i;
  111. break;
  112. }
  113. }
  114. if(video_stream < 0)
  115. {
  116. av_close_input_file(ic);
  117. printf("can not find a video stream.\n");
  118. return -3;
  119. }
  120. //获取视频时间宽度和高度
  121. width  = ic ->streams[video_stream] ->codec ->width;
  122. height = ic ->streams[video_stream] ->codec ->height;
  123. printf("video size: %dx%d\n",width,height);
  124. //从摄像头获取图像数据
  125. if( 0 == av_read_frame(ic,&packet))
  126. {
  127. //find the decode codec
  128. AVCodec * decodec =  avcodec_find_decoder(ic ->streams[video_stream] ->codec ->codec_id);
  129. if(decodec)
  130. {
  131. //open the decode codec
  132. if( 0 == avcodec_open(ic ->streams[video_stream] ->codec,decodec) )
  133. {
  134. int got_picture = 0;
  135. AVFrame * frame = avcodec_alloc_frame();
  136. avcodec_decode_video2(ic ->streams[video_stream] ->codec,frame,&got_picture,&packet);
  137. //decode success
  138. if(got_picture)
  139. {
  140. uint8_t * buffer = NULL;
  141. size_t buffer_size = 0;
  142. struct SwsContext *pSwsCtx=NULL;
  143. AVFrame * rgb_frame = avcodec_alloc_frame();
  144. buffer_size = avpicture_get_size(PIX_FMT_BGR24,width,height);
  145. buffer = (uint8_t *)av_malloc(buffer_size);
  146. avpicture_fill((AVPicture*)rgb_frame,(uint8_t *)buffer,PIX_FMT_BGR24,width,height);
  147. //get swscale ctx
  148. pSwsCtx = sws_getContext(
  149. ic ->streams[video_stream] ->codec ->width,
  150. ic ->streams[video_stream] ->codec ->height,
  151. ic ->streams[video_stream] ->codec ->pix_fmt,
  152. width,
  153. height,
  154. PIX_FMT_BGR24,
  155. SWS_BILINEAR,
  156. NULL,
  157. NULL,
  158. NULL);
  159. if(pSwsCtx)
  160. {
  161. FILE *fp = NULL;
  162. SYSTEMTIME dt={0};
  163. //图像格式转换
  164. sws_scale(
  165. pSwsCtx,
  166. frame ->data,
  167. frame ->linesize,
  168. 0,
  169. ic ->streams[video_stream] ->codec ->height,
  170. rgb_frame ->data,
  171. rgb_frame ->linesize);
  172. //create the image file name
  173. GetLocalTime(&dt);
  174. srand(0);
  175. sprintf(buffer,"imgs/%04d_%02d_%02d %02d_%02d_%02d %02d.bmp",dt.wYear,dt.wMonth,dt.wDay,dt.wHour,dt.wMinute,dt.wSecond,rand()%30);
  176. //
  177. CreateDirectoryA("imgs",NULL);
  178. //open file
  179. fp = fopen(buffer, "wb");
  180. if(fp)
  181. {
  182. save_bmp(rgb_frame ->data[0],rgb_frame ->linesize[0]*height,width,height,fp);
  183. fclose(fp);
  184. }
  185. //free sws ctx
  186. sws_freeContext(pSwsCtx);
  187. }
  188. //free buffer
  189. av_free(rgb_frame);
  190. av_free(buffer);
  191. }
  192. //free buffer
  193. av_free(frame);
  194. //close the decode codec
  195. avcodec_close(ic ->streams[video_stream] ->codec);
  196. }
  197. }
  198. }
  199. //close the input device
  200. av_close_input_file(ic);
  201. return 0;
  202. }
  203. int main()
  204. {
  205. //avcodec_init();
  206. avcodec_register_all();
  207. avdevice_register_all();
  208. CaptureFromLocalCamera();
  209. return 0;
  210. }

ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片的更多相关文章

  1. [转载] ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片

    这里请注意,在编译ffmpeg时,不要使用--disable-devices选项. 使用 --enable-encoder=rawvideo --enable-decoder=rawvideo 启用r ...

  2. JavaCV 采集摄像头和麦克风数据推送到流媒体服务器

    越来越觉得放弃JavaCV FFmpeg native API,直接使用JavaCV二次封装的API开发是很明智的选择,使用JavaCV二次封装的API开发避免了各种内存操作不当引起的crash. 上 ...

  3. wireshark在windows下无法抓取localhost数据包

    在调试SSL时要抓包,通过tcpview和minisniffer等工具明明看到tcp连接已经建立并开始收发数据了,但wireshark却总是无法抓到相应的数据包. 今天早上,HQ的高工告诉我“wire ...

  4. 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码

    ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...

  5. [转]RGB数据保存为BMP图片

    转自:http://blog.csdn.net/yixianfeng41/article/details/52591585 一.BMP文件由文件头.位图信息头.颜色信息和图形数据四部分组成. 1.BM ...

  6. ffmpeg windows下编译ffmpeg

    windows下编译ffmpeg 今天由于工作需求需重新编译ffmpeg,百度,goole了一大堆,看眼花缭乱的,但几乎都是三种方案,大部分都是直接转发,一字不漏,错误的缺文件的还是照转,可是问题都大 ...

  7. linux 下使用opengl的glut库显示和旋转BMP图片

    效果图: 这里显示的图和原图有明显的色差,目前猜测是opengl渲染时的颜色表顺序跟BMP文件里的颜色表顺序相反导致. BMP里应该是BGRBGRBRG... ,而opengl渲染时应该是按照RGBR ...

  8. 在windows下,将mysql离线数据文件导入本地mysql数据库

    1. 查看mysql路径 SELECT @@basedir AS basePath FROM DUAL 其实mysql5.6 的数据文件在 C:\ProgramData\MySQL\MySQL Ser ...

  9. FFmpeg Windows下安装与测试

    FFmpeg 简介 FFmpeg的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward",FFmpeg是一套可以用来记录.转换数字音频.视 ...

随机推荐

  1. 【转】欧拉回路&特殊图下的哈密顿回路题集

    转自:http://blog.csdn.net/shahdza/article/details/7779385 欧拉回路[HDU]1878 欧拉回路 判断3018 Ant Trip 一笔画问题1116 ...

  2. [转载]Windows 7 IIS (HTTP Error 500.21 - Internal Server Error)解决

    今天在测试网站的时候,在浏览器中输入http://localhost/时,发生如下错误: HTTP Error 500.21 - Internal Server Error Handler " ...

  3. python参考手册--第1章python简介

    1.if __name__ == '__main__': 直接运行myModel.py时,当前模块的名字是main:import myModel然后运行的时候当前模块的名字是myModel. 2.ev ...

  4. C# 中使用JSON - DataContractJsonSerializer

    C#中使用JSON不需要使用第三方库,使用.NET Framwork3.5自带的System.Runtime.Serialization.Json即可很好的完成JSON的解析. 关于JSON的入门介绍 ...

  5. poj 1797 Heavy Transportation(最短路变种2,连通图的最小边)

    题目 改动见下,请自行画图理解 具体细节也请看下面的代码: 这个花了300多ms #define _CRT_SECURE_NO_WARNINGS #include<string.h> #i ...

  6. Android开发--Activity生命周期回顾理解

    Activity和Servlet一样,都用了回调机制.我们通过类比servlet来学习Activity.当一个servlet开发出来之后,该servlet运行于Web服务器中.服务器何时创建servl ...

  7. HDU 1452 Happy 2004(因子和的积性函数)

    题目链接 题意 : 给你一个X,让你求出2004的X次方的所有因子之和,然后对29取余. 思路 : 原来这就是积性函数,点这里这里这里,这里讲得很详细. 在非数论的领域,积性函数指所有对于任何a,b都 ...

  8. hdu 4282 A very hard mathematic problem

    由于k的范围是0-2^31,而且x,y,z都是正整数,由题易知道2<=z<31,1<=x<y;所以直接枚举就好了!!! #include<iostream> #in ...

  9. ASP.NET 免费开源控件

    AspNetPager分页控件(当前版本:7.5.1) AspNetPager分页控件是应用于ASP.NET WebForm网站或应用程序中的自定义分页控件,支持默认的回发(Postback)分页和U ...

  10. [转] 软件定义网络(SDN) 的应运而生

    原文见51CTO:http://network.51cto.com/art/201103/251425.htm 2012的故事 2012年的某天,你跟往常一样起床,打开电脑,却发现无法登录到邮箱.无法 ...