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

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define MAX_INPUT_DEVICE_NUM 10

#ifdef _WIN32

intstrcasecmp(constchar*s1,constchar*s2)

{

while((*s1 !='\0')

&& (tolower(*(unsigned char*) s1) ==

tolower(*(unsigned char*) s2)))

{

s1++;

s2++;

}

returntolower(*(unsignedchar*) s1) - tolower(*(unsignedchar*) s2);

}

intstrncasecmp(constchar*s1,constchar*s2, unsignedintn)

{

if(n == 0)

return0;

while((n-- != 0)

&& (tolower(*(unsigned char*) s1) ==

tolower(*(unsigned char*) s2))) {

if(n == 0 || *s1 =='\0'|| *s2 =='\0')

return0;

s1++;

s2++;

}

returntolower(*(unsignedchar*) s1) - tolower(*(unsignedchar*) s2);

}

#endif

voidsave_bmp(unsignedchar* data,intdata_size,intw,inth,FILE* out)

{

// 位图文件头

BITMAPFILEHEADER bmpheader;

BITMAPINFO bmpinfo;

intbit = 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);

}

intCaptureFromLocalCamera()

{

AVFormatContext *ic = NULL;

AVFormatParameters in_fmt_para={0};

AVPacket packet;

charbuffer[MAX_PATH]={0};

intwidth = 0,height = 0;

intret,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 

{

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 stream

for(i=0;inb_streams;i++)

{

if( CODEC_TYPE_VIDEO == ic ->streams[i] ->codec ->codec_type )

{

video_stream = i;

break;

}

}

if(video_stream 

{

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 codec

AVCodec * decodec =  avcodec_find_decoder(ic ->streams[video_stream] ->codec ->codec_id);

if(decodec)

{

//open the decode codec

if( 0 == avcodec_open(ic ->streams[video_stream] ->codec,decodec) )

{

intgot_picture = 0;

AVFrame * frame = avcodec_alloc_frame();

avcodec_decode_video2(ic ->streams[video_stream] ->codec,frame,&got_picture,&packet);

//decode success

if(got_picture)

{

uint8_t * buffer = NULL;

size_tbuffer_size = 0;

structSwsContext *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 ctx

pSwsCtx = 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 name

GetLocalTime(&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 file

fp = fopen(buffer, "wb");

if(fp)

{

save_bmp(rgb_frame ->data[0],rgb_frame ->linesize[0]*height,width,height,fp);

fclose(fp);

}

//free sws ctx

sws_freeContext(pSwsCtx);

}

//free buffer

av_free(rgb_frame);

av_free(buffer);

}

//free buffer

av_free(frame);

//close the decode codec

avcodec_close(ic ->streams[video_stream] ->codec);

}

}

}

//close the input device

av_close_input_file(ic);

return0;

}

intmain()

{

//avcodec_init();

avcodec_register_all();

avdevice_register_all();

CaptureFromLocalCamera();

return0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值