linux下多线程网络编程,实现arm9视频采集和网络发送jpeg数据,使用udp协议,自己写的,搞了好几天!linux下的多线程比较复杂易出错。
linux network under the multi-threaded programming, video capture and realize ARM9 send jpeg data network, using udp protocol, wrote it myself, engaged in for several days! linux under the more complicated multi-threaded, error-prone.
-
-
- #include <strings.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <stdarg.h>
- #include <linux/types.h>
- #include <linux/videodev.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <sys/types.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/file.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <time.h>
- #include <string.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <sys/times.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <sys/param.h>
- #include <ctype.h>
- #include <sys/utsname.h>
-
- #define BUFSIZE 6
- #define DATA 32*1024
- #define PORT 5000
- #define RTP_HDR_SZ 12
- #define VIDEO_PALETTE_JPEG 21
-
- unsigned char buf[BUFSIZE+2][DATA];
- int head,tail;
-
- sem_t writen;
- sem_t readn;
-
- struct ARG{int sockfd;
- int sin_size;
- struct sockaddr_in client;
- };
-
- struct FDG{
- int video_fd;
- };
-
- typedef unsigned char u_int8;
- typedef unsigned short u_int16;
-
- int get_jpegsize (unsigned char *buf, int insize);
- double tdbl(struct timeval *a);
- pthread_mutex_t buffer_mutex=PTHREAD_MUTEX_INITIALIZER;
-
- static void *producer(void *fdg)
- {
- struct FDG *vd;
- int video_fd;
-
- if(sizeof(fdg)!=sizeof(struct FDG))
- {
- perror("producer arg error");
- exit(1);
- }
- else
- {
- vd=(struct FDG *)fdg;
- video_fd=vd->video_fd;
- free(fdg);
- fdg=NULL;
- }
-
-
- for( ; ; )
- {
- sem_wait(&writen);
- pthread_mutex_lock(&buffer_mutex);
-
- read(video_fd, buf[head], DATA);
- head=(head+1) % BUFSIZE;
-
- pthread_mutex_unlock(&buffer_mutex);
- sem_post(&readn);
-
- }
- }
-
-
- static void *consumer(void *arg)
- {
- int sockfd;
- int sin_size;
- int jpegsize;
- struct sockaddr_in client;
- struct ARG *info;
-
- typedef struct {
- unsigned int version:2;
- unsigned int p:1;
- unsigned int x:1;
- unsigned int cc:4;
- unsigned int m:1;
- unsigned int pt:7;
- unsigned int seq:16;
- unsigned int ts;
- unsigned int ssrc;
- } rtp_hdr_t;
-
- struct timeval start;
-
- rtp_hdr_t rtphdr;
- u_int8 *jpeg_data;
- u_int8 *packet_buf;
- unsigned int ts;
- unsigned int ssrc;
- u_int8 *ptr;
- u_int8 frame,bframe;
- int bytes_left ;
- int data_len,packetsize;
-
- info=( struct ARG *)arg;
- if(info->sockfd<0)
- {
- perror("error error");
- exit(1);
- }
-
- if(info->sin_size!=16)
- {
- perror("err error");
- exit(1);
- }
- sockfd=info->sockfd;
- sin_size=info->sin_size;
- memcpy(&client,&info->client,sizeof(info->client));
- free(arg);
- arg=NULL;
-
- packetsize=RTP_HDR_SZ+2050;
- packet_buf = (u_int8 *)calloc(packetsize, sizeof(u_int8));
- jpeg_data= (u_int8 *) malloc(DATA);
-
- for(;;)
- {
- frame=0;
- gettimeofday(&start, 0);
- ts = (unsigned int)(tdbl(&start)*1000);
- ssrc = 125;
-
-
- rtphdr.version = 2;
- rtphdr.p = 0;
- rtphdr.x = 0;
- rtphdr.cc = 0;
- rtphdr.m = 0;
- rtphdr.pt = 40;
- rtphdr.seq = 1;
- rtphdr.ts = htonl(ts);
- rtphdr.ssrc = htonl(ssrc);
-
- sem_wait(&readn);
-
- pthread_mutex_lock(&buffer_mutex);
-
- jpegsize=get_jpegsize(buf[tail],DATA);
-
- if(jpegsize!=-1)
- {
- memcpy(jpeg_data,buf[tail],jpegsize);
- }
-
- tail=(tail+1) % BUFSIZE;
-
- pthread_mutex_unlock(&buffer_mutex);
-
- sem_post(&writen);
-
- bytes_left = jpegsize;
-
- while (bytes_left > 0)
- {
- ptr = packet_buf + RTP_HDR_SZ;
-
- bframe=frame;
-
- data_len = packetsize - (ptr - packet_buf)-2;
-
- if (data_len >= bytes_left)
- {
- data_len = bytes_left;
- rtphdr.m = 1;
- bframe=255;
- data_len=jpegsize%2048;
- }
-
- *ptr=bframe; ptr++;
- *ptr=frame; ptr++;
-
- rtphdr.seq = htons(rtphdr.seq);
- memcpy(packet_buf, &rtphdr, RTP_HDR_SZ);
- memcpy(ptr, jpeg_data + frame*2048, data_len);
-
- if(sendto(sockfd,packet_buf,(ptr - packet_buf) + data_len,
- 0,(struct sockaddr *)&client,sin_size)<0)
- {
- perror(" sendto error");
- }
-
- frame++;
- bytes_left -= 2048;
- rtphdr.seq = ntohs(rtphdr.seq);
- rtphdr.seq++;
- }
-
- sleep(0.0001);
- }
- free(packet_buf);
- free(jpeg_data);
- pthread_exit(NULL);
- }
-
-
- int main()
- {
- clock_t oldtick,newtick;
- float time1 ;
- static int vf=0;
- int i;
- clock_t totalold,totalnew;
- int video_fd;
- struct video_capability grab_cap;
-
- int width = 320;
- int height = 240;
-
-
- struct video_picture grab_pic;
- struct video_mmap grab_map;
- struct video_mbuf grab_buf;
-
-
- int sockfd;
- int sin_size;
- struct sockaddr_in client;
- struct sockaddr_in server;
- char msg[100];
- struct ARG *arg;
- struct FDG *fdg;
- pthread_t p_tid;
- pthread_t c_tid;
- head=0;
- tail=0;
- for(i=0; i<BUFSIZE+2; i++)
- {
- bzero(buf[i],DATA);
-
- }
- sem_init(&writen,0,BUFSIZE);
- sem_init(&readn,0,0);
-
-
- loop:
- totalold = clock();
- video_fd = open("/dev/video0", O_RDWR);
- if (video_fd == -1)
- {
-
- fprintf(stderr, "can not open video0");
- exit(1);
- }
- oldtick = clock();
- if ((ioctl(video_fd, VIDIOCGCAP, &grab_cap)) < 0)
- {
- fprintf(stderr, "ioctl VIDEOCGCAP failed.");
- exit(1);
- }
- newtick = clock();
- time1 = (double)(newtick - oldtick)/ CLOCKS_PER_SEC;
- printf("\n%f second is take to ioctl VIDEOCGCAP \n",time1);
-
- printf("The VideoCap Name: %s\n", grab_cap.name);
- printf("The hannels: %d\n", grab_cap.channels);
- printf("The Audios: %d\n", grab_cap.audios);
- printf("The maxwidth: %d, maxheight: %d, minwidth %d, minheight: %d\n",
- grab_cap.maxwidth, grab_cap.maxheight,
- grab_cap.minwidth, grab_cap.minheight);
-
- oldtick = clock();
-
- if ((ioctl(video_fd, VIDIOCGPICT, &grab_pic)) < 0)
- {
- fprintf(stderr, "ioctl VIDIOCGPICT failed.");
- exit(1);
- }
- newtick = clock();
- time1 = (double)(newtick - oldtick)/ CLOCKS_PER_SEC;
- printf("\n%f second is take to ioctl VIDIOCGPICT \n",time1);
-
- printf("The brightness: %d\nThe hue: %d\nThe colour: %d\n
- The contrast:%d\nThe whiteness: %d\nThe depth: %d\nThe palette: %d\n",
- grab_pic.brightness, grab_pic.hue, grab_pic.colour, grab_pic.contrast,
- grab_pic.whiteness, grab_pic.depth, grab_pic.palette);
-
- oldtick = clock();
-
- if ((ioctl(video_fd, VIDIOCGMBUF, &grab_buf)) < 0)
- {
- fprintf(stderr, "ioctl VIDIOCGMBUF, failed.");
- exit(1);
- }
- newtick = clock();
- time1 = (double)(newtick - oldtick)/ CLOCKS_PER_SEC;
- printf("\n%f second is take to ioctl VIDIOCGMBUF \n",time1);
-
- printf("The mapping size:%d\nThe mapping frames:%d\nThe mapping offset %d\n",
- grab_buf.size, grab_buf.frames, grab_buf.offsets);
- printf("The mapping size: %d nihao\n",grab_buf.size);
- grab_map.width = width;
- grab_map.height = height;
- grab_map.format = VIDEO_PALETTE_JPEG;
- grab_map.frame = 0;
- if(vf==0)
- {
- vf=vf+1;
- close(video_fd);
- goto loop;
- }
-
-
- fdg=(struct FDG *)malloc(sizeof(struct FDG));
- if(fdg==NULL)
- {
- perror("fdg malloc error");
- exit(1);
- }
- else {fdg->video_fd=video_fd;}
-
- if(pthread_create(&p_tid, NULL, producer, (void *)fdg))
- {
- perror("pthrea p_tid1 error!");
- exit(1);
- }
-
-
-
-
-
- if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
- {
- perror("creat socket error");
- exit(1);
- }
-
- bzero(&server,sizeof(server));
- server.sin_family=AF_INET;
- server.sin_port=htons(PORT);
- server.sin_addr.s_addr=htonl(INADDR_ANY);
- if(bind(sockfd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1){
- perror("bind error");
- exit(1);}
-
- sin_size=sizeof(struct sockaddr_in);
-
- while(1)
- {
-
- if((recvfrom(sockfd,msg,100,0,(struct sockaddr *)&client,&sin_size))<0)
- {
- perror("recv error");
- exit(1);
- }
-
- arg=(struct ARG *)malloc(sizeof(struct ARG));
- if(arg==NULL)
- {
- perror("ARG malloc error");
- exit(1);
- }
- else {
- arg->sockfd=sockfd;
- arg->sin_size=sin_size;
- memcpy((void *)&arg->client,&client,sizeof(client));
- }
-
-
- if(pthread_create(&c_tid,NULL,consumer,(void *)arg))
- {
- perror("pthread c_tid error!");
- exit(1);
- }
-
-
-
-
- }
-
- pthread_join(p_tid,NULL);
-
- pthread_join(c_tid,NULL);
- close(video_fd);
- close(sockfd);
- return 0;
-
- }
-
-
- int get_jpegsize (unsigned char *buf, int insize)
- {
- int i,flg=0,fc=0,fd=0,nd=0,k;
-
- if((buf[0]==0xFF) && (buf[1]==0xD8)&& (buf[2]==0xFF) && (buf[3]==0xDB))
- {
- for ( k= 0 ; k< 590; k++)
- {
- if(buf[k]== 0x0D)nd++;
-
- if ((buf[k]== 0xFF) && (buf[k+1] == 0xC4))
- {
- flg++;
- fc=k+1;
- }
- if ((buf[k]== 0xFF) && (buf[k+1] == 0xDA))
- {
- fd=k+1;
- flg++;
- break;
- }
-
- }
-
- if((flg==2)&&(fc==137)&&(fd==576)&&(nd<=5))
- {
-
- for ( i= 1024*2 ; i< insize; i++)
- {
- if ((buf[i] == 0xFF) && (buf[i+1] == 0xD9)) return i+2;
- }
-
- }
- }
- return -1;
- }
-
-
-
- double tdbl(struct timeval *a)
- {
- return a->tv_sec + a->tv_usec/1e6;
- }
(sun) |