Chinaunix首页 | 论坛 | 博客
  • 博客访问: 521803
  • 博文数量: 197
  • 博客积分: 2071
  • 博客等级: 上尉
  • 技术积分: 1307
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-02 09:49
个人简介

prothes 专注嵌入式的ARM linux

文章分类

全部博文(197)

文章存档

2014年(3)

2013年(16)

2012年(108)

2011年(70)

分类: C/C++

2011-09-06 13:19:50

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.

  1. //多线程成功实例  
  2.  
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include    
  10. #include   
  11. #include   
  12. #include   
  13. #include   
  14. #include   
  15. #include   
  16. #include   
  17. #include   
  18. #include   
  19. #include   
  20. #include   
  21. #include   
  22. #include    
  23. #include   
  24. #include   
  25. #include   
  26. #include   
  27. #include   
  28. #include   
  29. #include   
  30. #include   
  31.  
  32. #define BUFSIZE  6  
  33. #define DATA     32*1024  
  34. #define PORT     5000   
  35. #define RTP_HDR_SZ 12   
  36. #define VIDEO_PALETTE_JPEG 21   
  37.     
  38. unsigned  char  buf[BUFSIZE+2][DATA];   
  39. int  head,tail;   
  40.    
  41. sem_t writen;   
  42. sem_t readn;  
  43.  
  44. struct  ARG{ int  sockfd;  
  45.   int  sin_size;  
  46.   struct  sockaddr_in client;   
  47. };  
  48.    
  49. struct  FDG{   
  50. int  video_fd;   
  51. };  
  52.    
  53. typedef  unsigned  char   u_int8;   
  54. typedef  unsigned  short  u_int16;   
  55.  
  56. int  get_jpegsize (unsigned  char  *buf,  int  insize);  
  57. double  tdbl( struct  timeval *a);   
  58. pthread_mutex_t  buffer_mutex=PTHREAD_MUTEX_INITIALIZER;   
  59.    
  60. static   void  *producer( void  *fdg)   
  61. {  
  62.    struct  FDG *vd;   
  63.   int  video_fd;  
  64.    
  65.    if ( sizeof (fdg)!= sizeof ( struct  FDG))  
  66.   {  
  67.     perror( "producer arg error" );  
  68.     exit(1);  
  69.    }  
  70.    else    
  71.   {   
  72.   vd=( struct  FDG *)fdg;   
  73.   video_fd=vd->video_fd;   
  74.   free(fdg);  
  75.   fdg=NULL;  
  76.   }  
  77.  
  78.      
  79.    for ( ; ; )  
  80.   {   
  81.          sem_wait(&writen); //减少可读的资源数   
  82.          pthread_mutex_lock(&buffer_mutex); //进入互斥区  
  83.         // memset(buf[head], 's', 20);   
  84.          read(video_fd, buf[head], DATA);   
  85.          head=(head+1) % BUFSIZE;   
  86.           
  87.          pthread_mutex_unlock(&buffer_mutex); //离开互斥区   
  88.          sem_post(&readn); //增加可读资源数   
  89.          // sleep(0.0001);   
  90.   }  
  91. }  
  92.  
  93.    
  94. static   void  *consumer( void  *arg)   
  95. {   
  96.    int  sockfd;  
  97.    int  sin_size;  
  98.    int  jpegsize;  
  99.    struct  sockaddr_in client;  
  100.    struct  ARG *info;  
  101.     
  102.    typedef   struct  {   
  103.     unsigned  int  version:2; /* protocol version */    
  104.     unsigned  int  p:1;      /* padding flag */    
  105.     unsigned  int  x:1;      /* header extension flag */    
  106.     unsigned  int  cc:4;     /* CSRC count */    
  107.     unsigned  int  m:1;      /* marker bit */    
  108.     unsigned  int  pt:7;     /* payload type */    
  109.     unsigned  int  seq:16;   /* sequence number */    
  110.     unsigned  int  ts;       /* timestamp */    
  111.     unsigned  int  ssrc;     /* synchronization source */    
  112.   } rtp_hdr_t;  
  113.    
  114.    struct  timeval start;   
  115.     
  116.   rtp_hdr_t rtphdr;  
  117.   u_int8 *jpeg_data;   
  118.   u_int8 *packet_buf;  
  119.   unsigned  int   ts;  
  120.   unsigned  int  ssrc;  
  121.   u_int8 *ptr;  
  122.   u_int8 frame,bframe;  
  123.    int  bytes_left ; //jpeg数据总长度  
  124.    int  data_len,packetsize; //packetsize变量  
  125.    
  126.   info=(  struct  ARG *)arg;  
  127.    if (info->sockfd<0)  
  128.   {   
  129.     perror( "error error" );  
  130.     exit(1);  
  131.   }  
  132.     
  133.    if (info->sin_size!=16)  
  134.   {   
  135.     perror( "err error" );  
  136.     exit(1);  
  137.   }  
  138.   sockfd=info->sockfd;  
  139.   sin_size=info->sin_size;  
  140.   memcpy(&client,&info->client, sizeof (info->client));  
  141.   free(arg);   
  142.   arg=NULL;  
  143.     
  144.   packetsize=RTP_HDR_SZ+2050;  
  145.   packet_buf = (u_int8 *)calloc(packetsize,  sizeof (u_int8));  
  146.   jpeg_data= (u_int8 *) malloc(DATA);   
  147.    
  148.    for (;;)  
  149.   {  
  150.     frame=0;   
  151.     gettimeofday(&start, 0);  
  152.     ts = (unsigned  int )(tdbl(&start)*1000);  
  153.     ssrc = 125;  
  154.      /* Initialize RTP header*/  
  155.      
  156.     rtphdr.version = 2;  
  157.     rtphdr.p = 0;  
  158.     rtphdr.x = 0;  
  159.     rtphdr.cc = 0;  
  160.     rtphdr.m = 0;  
  161.     rtphdr.pt = 40;  
  162.     rtphdr.seq = 1;  
  163.     rtphdr.ts = htonl(ts);  
  164.     rtphdr.ssrc = htonl(ssrc);  
  165.    
  166.          sem_wait(&readn); //减少可读的资源数  
  167.             
  168.          pthread_mutex_lock(&buffer_mutex); //进入互斥区  
  169.            
  170.          jpegsize=get_jpegsize(buf[tail],DATA);  
  171.            
  172.           if (jpegsize!=-1)  
  173.           {   
  174.             memcpy(jpeg_data,buf[tail],jpegsize);   
  175.           }   
  176.           
  177.          tail=(tail+1) % BUFSIZE;  
  178.          
  179.          pthread_mutex_unlock(&buffer_mutex); //离开互斥区  
  180.           
  181.          sem_post(&writen); //增加可读资源数  
  182.     
  183.    bytes_left = jpegsize;         
  184.     
  185.    while  (bytes_left > 0)    
  186.   {  
  187.     ptr = packet_buf + RTP_HDR_SZ;  
  188.      
  189.     bframe=frame;  
  190.     
  191.     data_len = packetsize - (ptr - packet_buf)-2; //每一分片大小  
  192.  
  193.      if  (data_len >= bytes_left)    //当为最后一个分片时  
  194.     {  
  195.       data_len = bytes_left;  
  196.       rtphdr.m = 1;  
  197.       bframe=255;  
  198.       data_len=jpegsize%2048;  
  199.     }  
  200.       
  201.    *ptr=bframe;  ptr++;  
  202.    *ptr=frame;   ptr++;  
  203.      
  204.     rtphdr.seq = htons(rtphdr.seq);  
  205.     memcpy(packet_buf, &rtphdr, RTP_HDR_SZ);  
  206.     memcpy(ptr, jpeg_data + frame*2048, data_len);  
  207.      
  208.      if (sendto(sockfd,packet_buf,(ptr - packet_buf) + data_len,
  209. 0,( struct  sockaddr *)&client,sin_size)<0)  
  210.      {  
  211.        perror( " sendto error" );    
  212.      }  
  213.        
  214.     frame++;  
  215.     bytes_left -= 2048;  
  216.     rtphdr.seq = ntohs(rtphdr.seq);  
  217.     rtphdr.seq++;  
  218.   }  
  219.           
  220.        sleep(0.0001);       
  221.   }  
  222.   free(packet_buf);  
  223.   free(jpeg_data);  
  224.   pthread_exit(NULL);  
  225. }  
  226.  
  227.    
  228. int  main()   
  229. {   
  230.    clock_t  oldtick,newtick;  
  231.    float  time1 ;  
  232.    static   int  vf=0;  
  233.    int  i;  
  234.    clock_t  totalold,totalnew;  
  235.    int  video_fd;  
  236.    struct  video_capability grab_cap;  
  237.  
  238.    int  width = 320;  
  239.    int  height = 240;  
  240.  
  241.  
  242.    struct  video_picture grab_pic;  
  243.    struct  video_mmap grab_map;  
  244.    struct  video_mbuf grab_buf;  
  245.    
  246.    
  247.    int  sockfd;  
  248.    int  sin_size;  
  249.    struct  sockaddr_in client;   
  250.    struct  sockaddr_in server;  
  251.    char  msg[100];  
  252.    struct  ARG *arg;   
  253.    struct  FDG  *fdg;   
  254.   pthread_t p_tid;   
  255.   pthread_t c_tid;  
  256.   head=0;  
  257.   tail=0;  
  258.    for (i=0; i
  259.   {   
  260.     bzero(buf[i],DATA);  
  261.      
  262.    }  
  263.   sem_init(&writen,0,BUFSIZE);   
  264.   sem_init(&readn,0,0);   
  265.    
  266. //数据采集………………………………………………  
  267. loop:  
  268.  totalold = clock();  
  269.  video_fd = open( "/dev/video0" , O_RDWR);  
  270.   if  (video_fd == -1)   
  271.  {
  272. ///u6253/u5f00/u6444/u50cf/u5934
  273.    fprintf(stderr,  "can not open video0" );
  274.    exit(1);
  275.  }
  276.  oldtick = clock();
  277.   if  ((ioctl(video_fd, VIDIOCGCAP, &grab_cap)) < 0)
  278.  {
  279.    fprintf(stderr,  "ioctl VIDEOCGCAP failed." );
  280.    exit(1);
  281.  }
  282.  newtick = clock();
  283.  time1 = ( double )(newtick - oldtick)/ CLOCKS_PER_SEC;
  284.  printf( "/n%f second is take to ioctl VIDEOCGCAP /n" ,time1);
  285.  
  286. printf( "The VideoCap Name: %s/n" , grab_cap.name);
  287. printf( "The hannels: %d/n" , grab_cap.channels);
  288. printf( "The Audios: %d/n" , grab_cap.audios);
  289. printf( "The maxwidth: %d, maxheight: %d, minwidth %d, minheight: %d/n" ,
  290. grab_cap.maxwidth, grab_cap.maxheight,
  291. grab_cap.minwidth, grab_cap.minheight);  
  292.  
  293.  oldtick = clock();  
  294.  
  295. if  ((ioctl(video_fd, VIDIOCGPICT, &grab_pic)) < 0)   
  296. {  
  297.   fprintf(stderr,  "ioctl VIDIOCGPICT failed." );  
  298.   exit(1);  
  299. }  
  300.  newtick = clock();  
  301.  time1 = ( double )(newtick - oldtick)/ CLOCKS_PER_SEC;  
  302.  printf( "/n%f second is take to ioctl VIDIOCGPICT /n" ,time1);  
  303.  
  304. printf( "The brightness: %d/nThe hue: %d/nThe colour: %d/n
  305. The contrast:%d/nThe whiteness: %d/nThe depth: %d/nThe palette: %d/n" ,
  306. grab_pic.brightness, grab_pic.hue, grab_pic.colour, grab_pic.contrast,
  307. grab_pic.whiteness, grab_pic.depth, grab_pic.palette);  
  308.  
  309.  oldtick = clock();  
  310.  
  311. if  ((ioctl(video_fd, VIDIOCGMBUF, &grab_buf)) < 0)   
  312. {  
  313.   fprintf(stderr,  "ioctl VIDIOCGMBUF, failed." );  
  314.   exit(1);  
  315. }  
  316.  newtick = clock();  
  317.  time1 = ( double )(newtick - oldtick)/ CLOCKS_PER_SEC;  
  318.  printf( "/n%f second is take to ioctl VIDIOCGMBUF /n" ,time1);  
  319.  
  320. printf( "The mapping size:%d/nThe mapping frames:%d/nThe mapping offset %d/n" ,
  321. grab_buf.size, grab_buf.frames, grab_buf.offsets);  
  322. printf( "The mapping size: %d  nihao/n" ,grab_buf.size);  
  323. grab_map.width = width;  
  324. grab_map.height = height;  
  325. grab_map.format = VIDEO_PALETTE_JPEG;  
  326. grab_map.frame = 0;  
  327. if (vf==0)  
  328. {  
  329.   vf=vf+1;  
  330.   close(video_fd);  
  331.    goto  loop;  
  332. }  
  333.  
  334.    
  335. fdg=( struct  FDG *)malloc( sizeof ( struct  FDG));  
  336. if (fdg==NULL)  
  337. {   
  338.   perror( "fdg malloc error" );  
  339.   exit(1);  
  340.  }  
  341.   else   {fdg->video_fd=video_fd;}   
  342.    
  343. if (pthread_create(&p_tid, NULL, producer, ( void  *)fdg))  
  344. {  
  345.    perror( "pthrea p_tid1 error!" );  
  346.    exit(1);  
  347. }  
  348.    
  349.    // free(fdg);  
  350.    // fdg=NULL;  
  351.  
  352. //网络部分  
  353. if ((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)  
  354. {  
  355. perror( "creat socket error" );  
  356. exit(1);  
  357. }  
  358.  
  359. bzero(&server, sizeof (server));  
  360. server.sin_family=AF_INET;  
  361. server.sin_port=htons(PORT);  
  362. server.sin_addr.s_addr=htonl(INADDR_ANY);  
  363. if (bind(sockfd,( struct  sockaddr *)&server, sizeof ( struct  sockaddr))==-1){  
  364. perror( "bind error" );  
  365. exit(1);}  
  366.  
  367. sin_size= sizeof ( struct  sockaddr_in);  
  368.         
  369.    while (1)  
  370.   {  
  371.       
  372.      if ((recvfrom(sockfd,msg,100,0,( struct  sockaddr *)&client,&sin_size))<0)  
  373.     {  
  374.          perror( "recv error" );  
  375.           exit(1);  
  376.      }  
  377.        
  378.    arg=( struct  ARG *)malloc( sizeof ( struct  ARG));  
  379.    if (arg==NULL)  
  380.   {  
  381.     perror( "ARG malloc error" );  
  382.     exit(1);  
  383.    }  
  384.    else  {  
  385.          arg->sockfd=sockfd;  
  386.          arg->sin_size=sin_size;  
  387.          memcpy(( void  *)&arg->client,&client, sizeof (client));  
  388.         }  
  389.    
  390.      
  391.   if (pthread_create(&c_tid,NULL,consumer,( void  *)arg))  
  392.  {  
  393.   perror( "pthread c_tid error!" );  
  394.    exit(1);  
  395.  }  
  396.    
  397.   // free(arg);  
  398.    // arg=NULL;   
  399.     
  400.   }  
  401.      
  402. pthread_join(p_tid,NULL);  
  403. //pthread_join(p_tid2,NULL);   
  404. pthread_join(c_tid,NULL);   
  405. close(video_fd);  
  406. close(sockfd);  
  407. return  0;  
  408.  
  409. }   
  410.       
  411.     //获得JPEG图片大小  
  412. int  get_jpegsize (unsigned  char  *buf,  int  insize)  
  413. {  
  414.   int  i,flg=0,fc=0,fd=0,nd=0,k;   
  415.     
  416.    if ((buf[0]==0xFF) && (buf[1]==0xD8)&& (buf[2]==0xFF) && (buf[3]==0xDB))   
  417.   {      
  418.          for  ( k= 0 ; k< 590; k++)   
  419.         {   
  420.            if (buf[k]== 0x0D)nd++;  
  421.             
  422.            if  ((buf[k]== 0xFF) && (buf[k+1] == 0xC4))   
  423.           {  
  424.                flg++;  
  425.                fc=k+1;  
  426.            }  
  427.            if  ((buf[k]== 0xFF) && (buf[k+1] == 0xDA))   
  428.           {  
  429.                fd=k+1;  
  430.                flg++;  
  431.                 break ;  
  432.            }  
  433.                
  434.          }  
  435.        
  436.     if ((flg==2)&&(fc==137)&&(fd==576)&&(nd<=5))  
  437.    {  
  438.             
  439.       for  ( i= 1024*2 ; i< insize; i++)  
  440.       {  
  441.          if  ((buf[i] == 0xFF) && (buf[i+1] == 0xD9))  return  i+2;  
  442.       }   
  443.       
  444.    }   
  445.   }  
  446.   return  -1;  
  447. }  
  448.  
  449.  
  450.  
  451. double  tdbl( struct  timeval *a)  
  452. {  
  453.    return  a->tv_sec + a->tv_usec/1e6;  
  454. }

 

 

 

阅读(592) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~