📄 vidcat.c
字号:
int main ()
{
// int width = DEF_WIDTH, height = DEF_HEIGHT, size, dev = -1, c;
int width = 160, height = 120, size, dev = -1, c;
// char *image, *device = VIDEO_DEV, *file = NULL;
char *image, *device ="/dev/v4l/video0", *file = NULL;
int max_try = 5; /* we try 5 seconds/times to open the device */
//int quality = QUAL_DEFAULT; /* default jpeg quality setting */
int input = INPUT_DEFAULT; /* this means take over current device settings*/
int norm = NORM_DEFAULT;
int loop =1 ;
int binary = 0;
pthread_t th_udp;
int palette = VIDEO_PALETTE_RGB24;
//int palette = VIDEO_PALETTE_YUV420;
int num = 0;
int nBitmapInfoSize;
char bmpinfo[54];
int loopnumber=0;
long tmpframe=0;
char buf[1024];
struct video_mbuf vid_buf;
struct video_mmap vid_mmap;
char *map, *convmap;
int len;
int bytes = 3;
int frame=0;
long error;
long sended;
int ret2;
long BmpDataLen=width*height*3;
BITMAPINFO* pbmpinfo = NULL;
BITMAPINFOHEADER* pInfoHead;
sint bfType;
BITMAPFILEHEADER bmfHeader;
int nFileHeadSize;
// FILE *bmpfile;
// char filename[10]="bmp.bmp";
int sockfd,new_fd,new_fd2;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size;
ret2=pthread_create(&th_udp,NULL,(void *)ctlthread,NULL);
if(ret2!=0)
{
printf("create pthread error!\n");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
printf("socket error\n");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
printf("bind error\n");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
printf("listen error\n");
exit(1);
}
while(1)
{
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size))==-1)
{
printf("accept error\n");
continue;
}else{break;}
}
nBitmapInfoSize = sizeof(BITMAPINFOHEADER);
//pbmpinfo =(BITMAPINFO *)();
pbmpinfo=(BITMAPINFO *)malloc(sizeof(BITMAPINFO));
memset((void *)pbmpinfo,0,nBitmapInfoSize);
pInfoHead = (BITMAPINFOHEADER *)pbmpinfo;
memset((void *)pInfoHead,0,sizeof(BITMAPINFOHEADER));
pInfoHead->biSize = sizeof(BITMAPINFOHEADER);
pInfoHead->biBitCount = 24;
pInfoHead->biPlanes = 1;
pInfoHead->biSizeImage = width*height*3;
pInfoHead->biCompression = 0;
pInfoHead->biWidth = width;
pInfoHead->biHeight = height;
pInfoHead->biXPelsPerMeter = 0;//3780;
pInfoHead->biYPelsPerMeter = 0;//3780;
//BYTE* pBits = NULL;
nFileHeadSize = sizeof(BITMAPFILEHEADER);
memset((void *)&bmfHeader,0,sizeof(BITMAPFILEHEADER));
bfType = 19778;//'BM' ((WORD) ('M' << 8) | 'B');
bmfHeader.bfSize = nFileHeadSize + nBitmapInfoSize + BmpDataLen+2;
bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + nBitmapInfoSize+2;
memset(bmpinfo,0,54);
memcpy(bmpinfo,&bfType,sizeof(sint));
memcpy(bmpinfo+2,&bmfHeader,nFileHeadSize);
memcpy(bmpinfo+14,pbmpinfo,nBitmapInfoSize);
if(!fork())
{
if(send(new_fd,bmpinfo,54,0)==-1)
{
printf("send info error\n");
close(new_fd);
exit(0);
}
}
memset(bmpinfo,0,54);
close(new_fd);
while(waitpid(-1,NULL,WNOHANG)>0);
printf("send bmpinfo successfull\n");
while(1)
{
sin_size=sizeof(struct sockaddr_in);
if((new_fd2=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size))==-1)
{
printf("accept2 error\n");
continue;
}else
{
break;
}
}
// close(sockfd);
again:
/* open the video4linux device */
while (max_try) {
dev = open (device, O_RDWR);
if (dev == -1) {
if (!--max_try) {
fprintf (stderr, "Can't open device %s\n", device);
return (1);
}
sleep (1);
} else { break; }
}
if (!num) {
/* if we loop we have to do this only once. so
* check frame number and execute only for the
* frame number "0".
*/
if (v4l_set_input (dev, input, norm) == -1) {
return (1);
}
if (v4l_check_size (dev, &width, &height) == -1) {
return (1);
}
/*if (v4l_check_palette (dev, &palette) == -1) {
return (1);
}*/
}
if (palette == VIDEO_PALETTE_GREY)
bytes = 1; /* bytes per pixel */
if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {
/* to do a normal read()
*/
printf("vidiocgmbuf error \n");
return (1);
}
// printf("vid_buf.frames=%d\n",vid_buf.frames);
map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED,dev,0);
if ((unsigned char *)-1 == (unsigned char *)map) {
perror ("mmap()");
return (NULL);
}
vid_mmap.format = palette;
vid_mmap.width = width;
vid_mmap.height = height;
vid_mmap.frame = frame;
if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
perror ("VIDIOCMCAPTURE");
fprintf (stderr, "args: width=%d height=%d palette=%d\n",
vid_mmap.width, vid_mmap.height, vid_mmap.format);
munmap (map, vid_buf.size);
return (NULL);
}
while(1)
{
if(ioctl (dev, VIDIOCSYNC, &vid_mmap.frame) == -1) {
perror ("VIDIOCSYNC");
munmap (map, vid_buf.size);
close(dev);
if(sockfd)
close(sockfd);
if(new_fd2)
close(new_fd2);
return (NULL);
}
//usleep(10000);
memset(buf,0,1024);
buf[0]=170;
buf[1]=170;
buf[2]=170;
buf[3]=170;
buf[4]=170;
buf[5]=170;
buf[6]=170;
buf[7]=170;
if((sended=send(new_fd2,buf,1024,0))==-1)
{
perror("perr");
printf("send bmp data error\n");
tcpflag=1;
close(new_fd2);
break;
exit(0);
}
while(1)
{
memset(buf,0,1024);
memcpy(buf,map+vid_buf.offsets[frame]+tmpframe,1024);
tmpframe+=1024;
if((sended=send(new_fd2,buf,1024,0))==-1)
{
perror("perr");
printf("send bmp data error\n");
close(new_fd2);
tcpflag=1;
break;
exit(0);
}
if(tmpframe==(BmpDataLen-BmpDataLen%1024))
{ if(tmpframe==BmpDataLen)
{tmpframe=0;
break; }
memset(buf,0,1024);
memcpy(buf,map+vid_buf.offsets[frame]+tmpframe,(BmpDataLen%1024));
memset(buf+BmpDataLen%1024,0,(1024-BmpDataLen%1024));
if((sended=send(new_fd2,buf,1024,0))==-1)
{
perror("perr");
printf("send bmp data error\n");
close(new_fd2);
tcpflag=1;
break;
exit(0);
}
tmpframe=0;
break;
}
if(tcpflag==1)
{break;}
}
frame=(frame+1)%2;
vid_mmap.frame = frame;
//usleep(100000);
if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
perror ("VIDIOCMCAPTURE");
fprintf (stderr, "args: width=%d height=%d palette=%d\n",
vid_mmap.width, vid_mmap.height, vid_mmap.format);
munmap (map, vid_buf.size);
if(dev)
close(dev);
if(sockfd)
close(sockfd);
if(new_fd2)
close(new_fd2);
return (NULL);
}
}
if (vid_buf.size) {
munmap (map, size);
close (dev);
} else if (map) {
free (map);
}
if(dev!=-1)
{close(dev);}
if (loop) {
goto again;
} else {
if(new_fd2)
close(new_fd2);
while(waitpid(-1,NULL,WNOHANG)>0);
if(sockfd)
close(sockfd);
return (0);
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -