www.pudn.com > dxc.rar > dxc.c, change:2007-09-01,size:9806b


//多线程成功实例

#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);//进入互斥区
       // 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<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");//\u6253\u5f00\u6444\u50cf\u5934
   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\nThe 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;
}