在嵌入式板子上插了一个usb摄像头(摄像头为索尼的,输入格式为mjpeg4),利用linux v4l2驱动抓取mpeg4图片,然后写入avi文件,在网上找了好几个开源库,找到两个库:
一个库在这里:
http://avifile.cvs.sourceforge.net/avifile/avifile-0.6/
但是这个库很久没有维护了,编译的时候还出了好多错,而且还是语法错误,各种问题比较多,而且比较庞大,暂时放弃,如果有兴趣的朋友可以继续研究,后面我会写一篇文章专门讲述编译过程。
另一个库是一个小巧的库,目前使用的就是这个库。(ps:我在网上搜到好几个站点介绍这个库的使用,都只是写了一半,然后把开源的源代码放在自己设定的下载站或者别的什么站点,下载时要扣除高额积分,这是一种无耻卑鄙下作的做法,用别人开源代码还藏着掖着,甚至为自己牟利。)
这个库的地址在这儿:
https://github.com/lanyou1900/avilib
下面是我使用的示例代码(其中v4l2-camera也是在网上找的代码修改的):
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "v4l2-camera.h"
/*We add this tag since here reference the c source file but the obj file in c++*/
extern "C"
{
#include "avilib.h"
}
using namespace v4l2;
int main()
{
V4l2Camera avobj;
//int fd = open("/dev/video0", O_RDONLY);
int numbers = avobj.get_number_of_cameras();
printf("The number of camera is:%d\n",numbers);
//printf("fd=%d\n",fd);
/*
if(fd>0)
{
close(fd);
}
*/
V4l2Capture parameter;
//int ret = avobj.InitDevice(¶meter,VideoFormat::MJPEG,"/dev/video0",30,1280,760);
int ret = avobj.InitDevice(¶meter,VideoFormat::MJPEG,"/dev/video0",25,320,240);
printf("init device,ret=%d\n",ret);
printf("fd=%d\n",parameter.fd);
printf("quality=%d\n",parameter.quality);
printf("brightness=%d\n",parameter.brightness);
avobj.StartDevice(parameter.fd);
int i = 1;
//avifile
char avifile[128] = {0};
char tmp[16] = {0};
snprintf(tmp,16,"%s","movie.avi");
strcat(avifile,"/home/");
strcat(avifile,tmp);
printf("the avi file name is:%s\n",avifile);
avi_t* avi_fd = NULL;
avi_fd = AVI_open_output_file(avifile);
if(avi_fd == NULL)
{
printf("Can not open the avifile.\n");
return 0;
}
printf("open the avifile.\n");
//AVI_set_video(avi_fd,1280,760,30,"MJPG");
AVI_set_video(avi_fd,320,240,25,"MJPG");
for(;;)
{
if(i==501)
{
break;
}
printf("begin to capture %d picture.\n",i);
ret = avobj.GetFrame(¶meter);
printf("get frame ret=%d\n",ret);
printf("parameter.v4l2Info.length=%d\n",parameter.v4l2Info.length);
char buffer[512];
memset(buffer,0,512*sizeof(char));
char data = 0;
/*
memset(parameter.v4l2Info.buffer,1,1);
memset((void*)(((char*)parameter.v4l2Info.buffer)+1),2,1);
memset((void*)(((char*)parameter.v4l2Info.buffer)+2),3,1);
memset((void*)(((char*)parameter.v4l2Info.buffer)+3),4,1);
memset((void*)(((char*)parameter.v4l2Info.buffer)+4),5,1);*/
for(int i=0;i<10;i++)
{
data = ((char*)parameter.v4l2Info.buffer)[i];
snprintf(buffer+2*i,3,"%02X",data);
}
printf("the buffer is:%s\n",buffer);
/*
char tmp[8] = {0};
snprintf(tmp,8,"%d.jpg",i);
char filename[128];
memset((void*)filename,0,128*sizeof(char));
strcat(filename,"/home/");
strcat(filename,tmp);
printf("the file name is:%s\n",filename);
FILE *fp = fopen(filename,"wb+");
if(fp == NULL)
{
printf("open file %s fail!\n",filename);
}
else
{
printf("begin to write image to file %s.................\n",filename);
fwrite(parameter.v4l2Info.buffer,parameter.v4l2Info.length,1,fp);
fclose(fp);
fp = NULL;
printf("end to write image to file %s\n",filename);
}
*/
printf("begin to write avi file.\n");
AVI_write_frame(avi_fd,(char*)parameter.v4l2Info.buffer,parameter.v4l2Info.length,0);
printf("end to write avi file.\n");
i++;
//sleep(1);
}
AVI_close(avi_fd);
return 0;
}
写成的avi文件用暴风播放器可以播放,其它播放器没有试过,抓的时候时间适当长一点。