linux视频采集软件,linux下视频采集服务器(UDP传输、多线程模式)

//多线程成功实例

#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 ***c; /* 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 ***c;

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);

***c = 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.***c = htonl(***c);

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)) 

{

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)) 

{

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)) 

{

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

{

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

{

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值