ret=pthread_create(&cam_id,NULL,cam_work,NULL); //启动摄像头采集线程
void *cam_work(void *arg)
{
struct sockaddr_in img_peer;
socklen_t len=sizeof(struct sockaddr_in);
struct v4l2_buffer buf_temp;
int on=1,dst_fd,ret,count,jpg_len;
char temp[64];
if(cam_flag<1) return;
memset(&buf_temp,0,sizeof(buf_temp));
buf_temp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf_temp.memory = V4L2_MEMORY_MMAP;
//开启视频
if(ioctl(camfd,VIDIOC_STREAMON,&on)<0)
{
perror("camera stream");
return;
}
while(1)
{
//开始监听imgsock
imgcfd=accept(img_fd,(struct sockaddr *)&img_peer,&len);
strcpy(server_info.net.img_socket,"connected");
while(imgcfd)
{
if(ioctl(camfd,VIDIOC_DQBUF,&buf_temp)<0)
{
perror("DQBUF");
cam_flag=0;
exit(-1);
}
//测试将图像写入文件
//dst_fd=open("./test.bmp",O_RDWR|O_CREAT|O_TRUNC,0777);
//write(dst_fd,img[buf.index],buf.length);
//close(dst_fd);
//dst_fd=open("./test2.bmp",O_RDWR|O_CREAT|O_TRUNC,0777);
//count =0;
//while(count
//初始化相机
int init_camera(void)
{
int ret=0,i;
printf("Init camera %s...",server_info.cdev_cam);
camfd=open(server_info.cdev_cam,O_RDWR);
if(camfd<0)
{
printf("Open error...Ignore\n");
cam_flag=0;
return 1;
}
printf("...ok\n");
//查询驱动信息
ioctl(camfd,VIDIOC_QUERYCAP,&cap);
printf("DriverName:%s\n",cap.driver);
printf("Card Name:%s \n",cap.card);
printf("Bus info:%s\n",cap.bus_info);
printf("DriverVersion:%u.%u.%u\n",\
(cap.version>>16)&0Xff,\
(cap.version>>8)&0Xff,\
cap.version & 0xff);
//显示当前支持的数据格式Mjpeg yuyv
fmtdesc.index=0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while(ioctl(camfd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
printf("Support:%d %s\n",fmtdesc.index++,fmtdesc.description);
//显示支持的解析度
for(i=0;;i++)
{
fmtsize.index=i;
fmtsize.pixel_format = fmtdesc.pixelformat;
if(ioctl(camfd,VIDIOC_ENUM_FRAMESIZES,&fmtsize)<0)
break;
switch(fmtsize.type)
{
case V4L2_FRMSIZE_TYPE_DISCRETE:
printf("Width = %d Height = %d\n",\
fmtsize.discrete.width,fmtsize.discrete.height);
break;
}
}//end for
//设置摄像头工作参数
memset(&fmt,0,sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = server_info.cam.width;
fmt.fmt.pix.height = server_info.cam.height;
//fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
//fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
if(ioctl(camfd,VIDIOC_S_FMT,&fmt)<0)
{
perr("camera set format")
return -1;
}
//申请1个缓冲区
req.count=1;
req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory=V4L2_MEMORY_MMAP;
if(ioctl(camfd,VIDIOC_REQBUFS,&req)<0)
{
perr("camera request buff")
return -1;
}
memset(&buf,0,sizeof(buf));
for(i=0;i<1;i++)
{
buf.index = i;
buf.type =V4L2_BUF_TYPE_VIDEO_CAPTURE;
//获得缓冲区首地址放入img[]里
if(ioctl(camfd,VIDIOC_QUERYBUF,&buf)==0)
{
printf("buffer %d offset=%d len=%d\n",i,buf.m.offset,buf.length);
img[i]=(char*) mmap(NULL,buf.length,PROT_READ,MAP_SHARED,\
camfd,buf.m.offset);
if(img[i]==MAP_FAILED)
{
perr("mmap failed");
return -1;
}
//加入缓冲区采集队列
if(ioctl(camfd,VIDIOC_QBUF,&buf)<0)
{
perr("qbuf")
return -1;
}
}//end if
}//end for
cam_flag=1;
}