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
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #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); //进入互斥区
- // memset(buf[head], 's', 20);
- read(video_fd, buf[head], DATA);
- head=(head+1) % BUFSIZE;
- pthread_mutex_unlock(&buffer_mutex); //离开互斥区
- sem_post(&readn); //增加可读资源数
- // sleep(0.0001);
- }
- }
- 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; /* protocol version */
- unsigned int p:1; /* padding flag */
- unsigned int x:1; /* header extension flag */
- unsigned int cc:4; /* CSRC count */
- unsigned int m:1; /* marker bit */
- unsigned int pt:7; /* payload type */
- unsigned int seq:16; /* sequence number */
- unsigned int ts; /* timestamp */
- unsigned int ssrc; /* synchronization source */
- } 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 ; //jpeg数据总长度
- int data_len,packetsize; //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;
- /* Initialize RTP header*/
- 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
- {
- 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)
- {
- ///u6253/u5f00/u6444/u50cf/u5934
- 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);
- }
- // free(fdg);
- // fdg=NULL;
- //网络部分
- 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);
- }
- // free(arg);
- // arg=NULL;
- }
- pthread_join(p_tid,NULL);
- //pthread_join(p_tid2,NULL);
- pthread_join(c_tid,NULL);
- close(video_fd);
- close(sockfd);
- return 0;
- }
- //获得JPEG图片大小
- 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;
- }