ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片

来源:互联网 发布:软件著作权源代码格式 编辑:程序博客网 时间:2024/04/28 00:59

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <libavformat/avformat.h>#include <libavcodec/avcodec.h>#include <libavdevice/avdevice.h>#include <libswscale/swscale.h>#include <windows.h>#include <time.h>#define MAX_INPUT_DEVICE_NUM 10#ifdef _WIN32int strcasecmp(const char *s1, const char *s2){while ((*s1 != '\0')&& (tolower(*(unsigned char *) s1) ==tolower(*(unsigned char *) s2))) {s1++;s2++;}return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);}int strncasecmp(const char *s1, const char *s2, unsigned int n){if (n == 0)return 0;while ((n-- != 0)&& (tolower(*(unsigned char *) s1) ==tolower(*(unsigned char *) s2))) {if (n == 0 || *s1 == '\0' || *s2 == '\0')return 0;s1++;s2++;}return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);}#endifvoid save_bmp(unsigned char * data,int data_size,int w,int h,FILE * out){// 位图文件头BITMAPFILEHEADER bmpheader; BITMAPINFO bmpinfo; int bit = 24;bmpheader.bfType = ('M' <<8)|'B'; bmpheader.bfReserved1 = 0; bmpheader.bfReserved2 = 0; bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bmpheader.bfSize = bmpheader.bfOffBits + w*h*bit/8;bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpinfo.bmiHeader.biWidth = w; bmpinfo.bmiHeader.biHeight = 0-h; bmpinfo.bmiHeader.biPlanes = 1; bmpinfo.bmiHeader.biBitCount = bit; bmpinfo.bmiHeader.biCompression = BI_RGB; bmpinfo.bmiHeader.biSizeImage = 0; bmpinfo.bmiHeader.biXPelsPerMeter = 100; bmpinfo.bmiHeader.biYPelsPerMeter = 100; bmpinfo.bmiHeader.biClrUsed = 0; bmpinfo.bmiHeader.biClrImportant = 0;fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,out); fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,out);fwrite(data,data_size,1,out);}int CaptureFromLocalCamera(){AVFormatContext *ic = NULL;AVFormatParameters in_fmt_para={0};AVPacket packet;char buffer[MAX_PATH]={0};int width = 0,height = 0;int ret,video_stream = -1,i=0;//查找输入(vfwcap)格式AVInputFormat *in_fmt = av_find_input_format ("vfwcap"); if (in_fmt == NULL) {printf("not support input device vfwcap.\n");return -1;}memset (&in_fmt_para, 0, sizeof(in_fmt_para));//指定需要采集图像的高度in_fmt_para.height = height;//指定需要采集图像的宽度in_fmt_para.width  = width;//设置帧率av_parse_video_frame_rate(&in_fmt_para.time_base,"20");//打开摄像头设备,从"0"到MAX_INPUT_DEVICE_NUM依次尝试打开for( i=0 ; i < MAX_INPUT_DEVICE_NUM + 1; i++ ){sprintf(buffer,"%d",i);ret = av_open_input_file ( &ic, buffer, in_fmt,sizeof(in_fmt_para),&in_fmt_para);if ( ret == 0 && ic){break;}}//open success?if(!ic || ret != 0){if(ic)av_close_input_file(ic);printf("can not open input file.\n");return -2;}printf("input device no. is %d\n",i);//find the video streamfor(i=0;i<ic ->nb_streams;i++){if ( CODEC_TYPE_VIDEO == ic ->streams[i] ->codec ->codec_type ){video_stream = i;break;}}if(video_stream < 0){av_close_input_file(ic);printf("can not find a video stream.\n");return -3;}//获取视频时间宽度和高度width  = ic ->streams[video_stream] ->codec ->width;height = ic ->streams[video_stream] ->codec ->height;printf("video size: %dx%d\n",width,height);//从摄像头获取图像数据if( 0 == av_read_frame(ic,&packet)){//find the decode codecAVCodec * decodec =  avcodec_find_decoder(ic ->streams[video_stream] ->codec ->codec_id);if(decodec){//open the decode codecif( 0 == avcodec_open(ic ->streams[video_stream] ->codec,decodec) ){int got_picture = 0;AVFrame * frame = avcodec_alloc_frame();avcodec_decode_video2(ic ->streams[video_stream] ->codec,frame,&got_picture,&packet);//decode successif(got_picture){uint8_t * buffer = NULL;size_t buffer_size = 0;struct SwsContext *pSwsCtx=NULL;AVFrame * rgb_frame = avcodec_alloc_frame();buffer_size = avpicture_get_size(PIX_FMT_BGR24,width,height);buffer = (uint8_t *)av_malloc(buffer_size);avpicture_fill((AVPicture*)rgb_frame,(uint8_t *)buffer,PIX_FMT_BGR24,width,height);//get swscale ctxpSwsCtx = sws_getContext(ic ->streams[video_stream] ->codec ->width,ic ->streams[video_stream] ->codec ->height,ic ->streams[video_stream] ->codec ->pix_fmt,width,height,PIX_FMT_BGR24,SWS_BILINEAR,NULL,NULL,NULL);if(pSwsCtx){FILE *fp = NULL;SYSTEMTIME dt={0};//图像格式转换sws_scale(pSwsCtx,frame ->data,frame ->linesize,0,ic ->streams[video_stream] ->codec ->height,rgb_frame ->data,rgb_frame ->linesize);//create the image file nameGetLocalTime(&dt);srand(0);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);//CreateDirectoryA("imgs",NULL);//open filefp = fopen(buffer, "wb");if(fp){save_bmp(rgb_frame ->data[0],rgb_frame ->linesize[0]*height,width,height,fp);fclose(fp);}//free sws ctxsws_freeContext(pSwsCtx);}//free bufferav_free(rgb_frame);av_free(buffer);}//free bufferav_free(frame);//close the decode codecavcodec_close(ic ->streams[video_stream] ->codec);}}}//close the input deviceav_close_input_file(ic);return 0;}int main(){//avcodec_init();    avcodec_register_all();avdevice_register_all();CaptureFromLocalCamera();return 0;}

0 0
原创粉丝点击