📄 dxc.c
字号:
//多线程成功实例#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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -