←手機掃碼閱讀
火星人
@ 2014-03-26 ,
C/S 架構 程序很大以部分修改自SPCAVIEW 加入了XVID編解碼和JRTP傳輸 需要安裝相應的庫 另外攝像頭用的中星微電子的 所以 驅動最好裝那個萬能驅動 在一個國外網站上下的 忘記是什麼了 好像叫SPCAXX
只要你裝對了東西 這程序保證能用。
文件server.cpp中的程序代碼
#include
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "jrtplib3/rtpsession.h" #include "jrtplib3/rtppacket.h" #include "jrtplib3/rtpudpv4transmitter.h" #include "jrtplib3/rtpipv4address.h" #include "jrtplib3/rtpsessionparams.h" #include "jrtplib3/rtperrors.h" #include #include "cxvid.h" #include "tcp.h" #define OUTFRMNUMB 4 static int XDIM=320,YDIM=240; uint8_t localip[] = { 202, 194, 26, 67 }; #define Packetfixlength 7000 #define frameheadfixlength 50 RTPTime delay (0.0001); int status; int nread; RTPSession session; RTPSessionParams sessionparams; RTPUDPv4TransmissionParams transparams; int sendpacket (unsigned char *framepointer, int framelength); struct frame_t{ char header[5]; int nbframe; double seqtimes; int deltatimes; int w; int h; int size; int format; unsigned short bright; unsigned short contrast; unsigned short colors; unsigned short exposure; unsigned char wakeup; int acknowledge; } __attribute__ ((packed)); struct vdIn { int fd; char *videodevice ; struct video_mmap vmmap; struct video_capability videocap; int mmapsize; struct video_mbuf videombuf; struct video_picture videopict; struct video_window videowin; struct video_channel videochan; int cameratype ; char *cameraname; char bridge[9]; int palette; // available palette int channel ; int grabMethod ; unsigned char *pFramebuffer; unsigned char *ptframe[4]; int framelock[4]; pthread_mutex_t grabmutex; int framesizeIn ; volatile int frame_cour; int bppIn; int hdrwidth; int hdrheight; int formatIn; int signalquit; }; struct vdIn videoIn; int init_v4l (struct vdIn *vd); static int SetVideoPict (struct vdIn *vd); static int GetVideoPict (struct vdIn *vd); int close_v4l (struct vdIn *vd); int init_videoIn (struct vdIn *vd, char *device, int width, int height,int format ,int grabmethod); int v4lGrab (struct vdIn *vd ); void *grab (void *); void *service (void *ir); void sigchld_handler(int s); int main () { char *videodevice = "/dev/video0"; int err; int grabmethod = 1; int width = 320; int height = 240; int i; int serv_sock,new_sock; pthread_t w1; pthread_t server_th; int sin_size; unsigned short serverport = 7070; struct sockaddr_in their_addr; struct sigaction sa; sessionparams.SetOwnTimestampUnit (1 / 90000); sessionparams.SetAcceptOwnPackets (true); sessionparams.SetMaximumPacketSize (10000); transparams.SetPortbase (8000); status = session.Create (sessionparams, &transparams); if (status < 0) { exit (-1); } RTPIPv4Address addr (localip, 7000); status = session.AddDestination (addr); if (status < 0) { exit (-1); } memset (&videoIn, 0, sizeof (struct vdIn)); if (init_videoIn (&videoIn, videodevice, width, height, VIDEO_PALETTE_YUV420P,grabmethod) != 0) printf (" damned encore rate !!\n"); if((err= pthread_create (&w1, NULL,grab, NULL)) != 0){ printf("thread grabbing error %d \n",err); close_v4l (&videoIn); exit(1); } serv_sock = open_sock(serverport); signal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; syslog(LOG_ERR," server Listening on Port %d\n",serverport); printf("Waiting .... for connection. CTrl_c to stop !!!! \n"); while (videoIn.signalquit) { sin_size = sizeof(struct sockaddr_in); if ((new_sock = accept(serv_sock, (struct sockaddr *)&their_addr, (size_t *)&sin_size)) == -1) { continue; } syslog(LOG_ERR,"Got connection from %s\n",inet_ntoa(their_addr.sin_addr)); printf("Got connection from %s\n",inet_ntoa(their_addr.sin_addr)); pthread_create(&server_th, NULL, service, &new_sock); } pthread_join (w1, NULL); close(serv_sock); close_v4l (&videoIn); } void *grab (void*) { int err = 0; for (;;) { err = v4lGrab(&videoIn); if (!videoIn.signalquit || (err < 0)){ printf("GRABBER going out !!!!! \n"); break; } } } void *service (void *ir) { int *id = (int*) ir; int frameout = 1; struct frame_t *headerframe; int ret; int sock; int framecount=0; int retsize=0; int ack = 0; unsigned char x = 0; unsigned char y = 0; int err; unsigned char wakeup = 0; unsigned char cmd = 0; unsigned short bright; unsigned short contrast; sock = *id; for (;;) { ack =1; redo: while ((frameout == videoIn.frame_cour) && videoIn.signalquit) usleep(1000); if (videoIn.signalquit){ videoIn.framelock[frameout]++; headerframe = (struct frame_t *) videoIn.ptframe[frameout]; headerframe->acknowledge = ack; headerframe->bright = bright; headerframe->contrast = contrast; headerframe->wakeup = wakeup; if(headerframe->size == 0){ // frame corrupt get another one videoIn.framelock[frameout]--; frameout = (frameout+1)% OUTFRMNUMB; goto redo; } ret=sendpacket((unsigned char *)headerframe,sizeof(struct frame_t)); printf("\n sock send out"); if(!wakeup) { printf("\nthe packat is %d",headerframe->size); ret=sendpacket((unsigned char*)(videoIn.ptframe[frameout]+sizeof(struct frame_t)),headerframe->size); } videoIn.framelock[frameout]--; frameout = (frameout+1)% OUTFRMNUMB; } else { printf("reader %d going out \n",*id); break; } } close_sock(sock); pthread_exit(NULL); } void sigchld_handler(int s) { videoIn.signalquit = 0; } int init_videoIn (struct vdIn *vd, char *device, int width, int height, int format, int grabmethod) { int err = -1; int i; if (vd == NULL || device == NULL) return -1; if (width == 0 || height == 0) return -1; if(grabmethod < 0 || grabmethod > 1) grabmethod = 1; //read by default; // check format vd->videodevice = NULL; vd->cameraname = NULL; vd->videodevice = NULL; vd->videodevice = (char *) realloc (vd->videodevice, 16); vd->cameraname = (char *) realloc (vd->cameraname, 32); snprintf (vd->videodevice, 12, "%s", device); printf("video %s \n",vd->videodevice); memset (vd->cameraname, 0, sizeof (vd->cameraname)); memset(vd->bridge, 0, sizeof(vd->bridge)); vd->signalquit = 1; vd->hdrwidth = width; vd->hdrheight = height; /* compute the max frame size */ vd->formatIn = format; vd->bppIn = (8 * 3) >> 1; vd->grabMethod = grabmethod; //mmap or read vd->pFramebuffer = NULL; /* init and check all setting */ err = init_v4l (vd); /* allocate the 4 frames output buffer */ for (i = 0; i < OUTFRMNUMB; i++) { vd->ptframe = NULL; vd->ptframe = (unsigned char *) realloc (vd->ptframe, sizeof(struct frame_t) + (size_t) vd->framesizeIn ); vd->framelock = 0; } vd->frame_cour = 0; pthread_mutex_init (&vd->grabmutex, NULL); return err; } static int GetVideoPict (struct vdIn *vd) { if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0) exit(1); printf ("VIDIOCGPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d" "depth=%d palette=%d\n", vd->videopict.brightness, vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast, vd->videopict.whiteness, vd->videopict.depth, vd->videopict.palette); return 0; } int init_v4l (struct vdIn *vd) { int f; int erreur = 0; int err; if ((vd->fd = open (vd->videodevice, O_RDWR)) == -1) exit(1); if (ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap)) == -1) exit(1); printf ("Camera found: %s \n", vd->videocap.name); snprintf (vd->cameraname, 32, "%s", vd->videocap.name); erreur = GetVideoPict (vd); if (ioctl (vd->fd, VIDIOCGCHAN, &vd->videochan) == -1) { printf ("Hmm did not support Video_channel\n"); vd->cameratype = UNOW; } else { if (vd->videochan.name){ printf ("Bridge found: %s \n", vd->videochan.name); snprintf (vd->bridge, 9, "%s", vd->videochan.name); } else { vd->cameratype = UNOW; } } printf ("StreamId: %d Camera\n", vd->cameratype); printf (" Format asked %d check %d\n",vd->formatIn, err); vd->videopict.palette = vd->formatIn; vd->videopict.depth = (8 * 3) >> 1; vd->bppIn = (8 * 3) >> 1; vd->framesizeIn = (vd->hdrwidth * vd->hdrheight * vd->bppIn) >> 3; erreur = SetVideoPict (vd); erreur = GetVideoPict (vd); if (vd->formatIn != vd->videopict.palette || vd->bppIn != vd->videopict.depth) exit(1); if (erreur < 0) exit(1); printf (" grabbing method default MMAP asked \n"); // MMAP VIDEO acquisition memset (&(vd->videombuf), 0, sizeof (vd->videombuf)); if (ioctl (vd->fd, VIDIOCGMBUF, &(vd->videombuf)) < 0) { perror (" init VIDIOCGMBUF FAILED\n"); } printf ("VIDIOCGMBUF size %d frames %d offets[0]=%d offsets[1]=%d\n", vd->videombuf.size, vd->videombuf.frames, vd->videombuf.offsets[0], vd->videombuf.offsets[1]); vd->pFramebuffer = (unsigned char *) mmap (0, vd->videombuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, vd->fd, 0); vd->mmapsize = vd->videombuf.size; vd->vmmap.height = vd->hdrheight; vd->vmmap.width = vd->hdrwidth; vd->vmmap.format = vd->formatIn; for (f = 0; f < vd->videombuf.frames; f++) { vd->vmmap.frame = f; if (ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) { perror ("cmcapture"); } } vd->vmmap.frame = 0; vd->frame_cour = 0; return erreur; } int v4lGrab (struct vdIn *vd ) { static int frame = 0; int len; int status; int count = 0; int size; int erreur = 0; int m4vsize = 0; int qualite = 1024; struct frame_t *headerframe; double timecourant =0; double temps = 0; /******XVID****/ unsigned char *mp4_buffer = NULL; unsigned char *in_buffer = NULL; int key; int stats_type; int stats_quant; int stats_length; int sse[3]; int enc_result; int input_num; /******************/ vd->vmmap.height = vd->hdrheight; vd->vmmap.width = vd->hdrwidth; vd->vmmap.format = vd->formatIn; if (ioctl (vd->fd, VIDIOCSYNC,&vd->vmmap.frame) < 0) { perror ("cvsync err\n"); erreur = -1; } /* Is there someone using the frame */ while((vd->framelock[vd->frame_cour] != 0) && vd->signalquit) usleep(1000); pthread_mutex_lock (&vd->grabmutex); /********************************XVID******************************************/ in_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM, YDIM)); if (!in_buffer) {printf("in_buffer err!"); goto free_all_memory;} mp4_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM, YDIM) * 2); if (mp4_buffer==NULL) { fprintf(stderr,"malloc error"); goto free_all_memory; } enc_result = enc_init(1); if (enc_result) { fprintf(stderr, "Encore INIT problem, return value %d\n", enc_result); goto release_all; } memcpy(in_buffer,vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame],IMAGE_SIZE(XDIM, YDIM)); printf("the framesize is %d",IMAGE_SIZE(XDIM, YDIM)); m4vsize=enc_main((uint8_t *)in_buffer, mp4_buffer,&key, &stats_type,&stats_quant, &stats_length, sse); printf("the m4vsize is %d!!!!\n\n",m4vsize); memcpy(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),mp4_buffer,m4vsize); /****************************************************************************/ headerframe=(struct frame_t*)vd->ptframe[vd->frame_cour]; snprintf(headerframe->header,5,"%s","SPCA"); headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant); headerframe->w = vd->hdrwidth; headerframe->h = vd->hdrheight; headerframe->size = (( m4vsize < 0)?0:m4vsize); headerframe->format = vd->formatIn; headerframe->nbframe = frame++; pthread_mutex_unlock (&vd->grabmutex); /************************************/ if ((ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) < 0) { perror ("cmcapture"); printf (">>cmcapture err %d\n", status); erreur = -1; } vd->vmmap.frame = (vd->vmmap.frame + 1) % vd->videombuf.frames; vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB; //printf("frame nb %d\n",vd->vmmap.frame); release_all: if (enc_handle) { enc_result = enc_stop(); if (enc_result) fprintf(stderr, "Encore RELEASE problem return value %d\n", enc_result); } free_all_memory: printf("free the mem"); free(mp4_buffer); free(in_buffer); return erreur; } static int SetVideoPict (struct vdIn *vd) { if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0) exit(1); printf ("VIDIOCSPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d" "depth=%d palette=%d\n", vd->videopict.brightness, vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast, vd->videopict.whiteness, vd->videopict.depth, vd->videopict.palette); return 0; } int close_v4l (struct vdIn *vd) { int i; printf ("unmapping frame buffer\n"); munmap (vd->pFramebuffer, vd->mmapsize); printf ("close video_device\n"); close (vd->fd); if (vd->videodevice) { free (vd->videodevice); vd->videodevice = NULL; } if (vd->cameraname) { free (vd->cameraname); vd->cameraname = NULL; } for (i = 0; i < OUTFRMNUMB; i++) { if (vd->ptframe) { free (vd->ptframe); vd->ptframe = NULL; vd->framelock = 0; printf ("freeing output buffer %d\n",i); } } pthread_mutex_destroy (&vd->grabmutex); } int sendpacket ( unsigned char *framepointer, int framelength) { bool done = false; while (!done) { if (framelength > Packetfixlength) { framelength -= Packetfixlength; nread = Packetfixlength; } else { nread = framelength; framelength = 0; } if (nread!=frameheadfixlength&&framelength==0) {status = session.SendPacket(framepointer, nread,26,1,1000);} else {status = session.SendPacket(framepointer, nread,26,0,1000);} if (status < 0) { exit (-1); } RTPTime::Wait (delay); framepointer += Packetfixlength; printf("%d",nread); if (framelength == 0) return (10); } } 文件cxvid.h中的程序代碼 #define FRAMERATE_INCR 1001 #define SMALL_EPS (1e-10) #define IMAGE_SIZE(x,y) ((x)*(y)*3/2) #define UNOW 1 #define WIDTH 352 #define HEIGHT 288 #define BPPIN 8 void *enc_handle = NULL; int enc_init(int use_assembler); int enc_main(unsigned char *image, unsigned char *bitstream, int *key, int *stats_type, int *stats_quant, int *stats_length, int stats[3]); int enc_stop(); 文件cxvid.c文件的程序代碼 #include #include #include #include #include "xvid.h" #define FRAMERATE_INCR 1001 #define SMALL_EPS (1e-10) #define IMAGE_SIZE(x,y) ((x)*(y)*3/2) #define UNOW 1 #define WIDTH 352 #define HEIGHT 288 #define BPPIN 8 static float ARG_FRAMERATE = 25.00f; static int ARG_QUALITY = 4; static int ARG_MAXKEYINTERVAL = 250; static int use_assembler = 0; static void *enc_handle = NULL; static const int motion_presets[] = { /* quality 0 */ 0, /* quality 1 */ XVID_ME_ADVANCEDDIAMOND16, /* quality 2 */ XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16, /* quality 3 */ XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8, /* quality 4 */ XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP, /* quality 5 */ XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP, /* quality 6 */ XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 | XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP, }; static const int vop_presets[] = { /* quality 0 */ 0, /* quality 1 */ 0, /* quality 2 */ XVID_VOP_HALFPEL, /* quality 3 */ XVID_VOP_HALFPEL | XVID_VOP_INTER4V, /* quality 4 */ XVID_VOP_HALFPEL | XVID_VOP_INTER4V, /* quality 5 */ XVID_VOP_HALFPEL | XVID_VOP_INTER4V | XVID_VOP_TRELLISQUANT, /* quality 6 */ XVID_VOP_HALFPEL | XVID_VOP_INTER4V | XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED, }; static int XDIM=320,YDIM=240; int enc_init(int use_assembler) { int xerr; xvid_plugin_single_t single; xvid_plugin_2pass1_t rc2pass1; xvid_plugin_2pass2_t rc2pass2; xvid_enc_plugin_t plugins[7]; xvid_gbl_init_t xvid_gbl_init; xvid_enc_create_t xvid_enc_create; /*------------------------------------------------------------------------ * XviD core initialization *----------------------------------------------------------------------*/ /* Set version -- version checking will done by xvidcore */ memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init)); xvid_gbl_init.version = XVID_VERSION; xvid_gbl_init.debug = 0; /* Do we have to enable ASM optimizations ? */ if (use_assembler) { xvid_gbl_init.cpu_flags = 0; } /* Initialize XviD core -- Should be done once per __process__ */ xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL); /*------------------------------------------------------------------------ * XviD encoder initialization *----------------------------------------------------------------------*/ /* Version again */ memset(&xvid_enc_create, 0, sizeof(xvid_enc_create)); xvid_enc_create.version = XVID_VERSION; /* Width and Height of input frames */ xvid_enc_create.width = XDIM; xvid_enc_create.height = YDIM; xvid_enc_create.profile = XVID_PROFILE_S_L3; /* init plugins */ xvid_enc_create.zones = NULL; xvid_enc_create.num_zones = 0; xvid_enc_create.plugins = NULL; xvid_enc_create.num_plugins = 0; /* No fancy thread tests */ xvid_enc_create.num_threads = 0; /* Frame rate - Do some quick float fps = fincr/fbase hack */ if ((ARG_FRAMERATE - (int) ARG_FRAMERATE) < SMALL_EPS) { xvid_enc_create.fincr = 1; xvid_enc_create.fbase = (int) ARG_FRAMERATE; } else { xvid_enc_create.fincr = FRAMERATE_INCR; xvid_enc_create.fbase = (int) (FRAMERATE_INCR * ARG_FRAMERATE); } /* Maximum key frame interval */ if (ARG_MAXKEYINTERVAL > 0) { xvid_enc_create.max_key_interval = ARG_MAXKEYINTERVAL; }else { xvid_enc_create.max_key_interval = (int) ARG_FRAMERATE *10; } /* Bframes settings */ xvid_enc_create.max_bframes = 0; xvid_enc_create.bquant_ratio = 150; xvid_enc_create.bquant_offset = 100; /* Dropping ratio frame -- we don't need that */ xvid_enc_create.frame_drop_ratio = 0; /* Global encoder options */ xvid_enc_create.global = 0; /* I use a small value here, since will not encode whole movies, but short clips */ xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); /* Retrieve the encoder instance from the structure */ enc_handle = xvid_enc_create.handle; return (xerr); } int enc_main(unsigned char *image, unsigned char *bitstream, int *key, int *stats_type, int *stats_quant, int *stats_length, int sse[3]) { int ret; xvid_enc_frame_t xvid_enc_frame; xvid_enc_stats_t xvid_enc_stats; /* Version for the frame and the stats */ memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame)); xvid_enc_frame.version = XVID_VERSION; memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats)); xvid_enc_stats.version = XVID_VERSION; /* Bind output buffer */ xvid_enc_frame.bitstream = bitstream; xvid_enc_frame.length = -1; /* Initialize input image fields */ if (image) { xvid_enc_frame.input.plane[0] = image; xvid_enc_frame.input.csp = XVID_CSP_I420; xvid_enc_frame.input.stride[0] = XDIM; } else { xvid_enc_frame.input.csp = XVID_CSP_NULL; } /* Set up core's general features */ xvid_enc_frame.vol_flags = 0; /* Set up core's general features */ xvid_enc_frame.vop_flags = vop_presets[ARG_QUALITY]; /* Frame type -- let core decide for us */ xvid_enc_frame.type = XVID_TYPE_AUTO; /* Force the right quantizer -- It is internally managed by RC plugins */ xvid_enc_frame.quant = 3; /* Set up motion estimation flags */ xvid_enc_frame.motion = motion_presets[ARG_QUALITY]; /* We don't use special matrices */ xvid_enc_frame.quant_intra_matrix = NULL; xvid_enc_frame.quant_inter_matrix = NULL; /* Encode the frame */ ret = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xvid_enc_frame, &xvid_enc_stats); *key = (xvid_enc_frame.out_flags & XVID_KEYFRAME); *stats_type = xvid_enc_stats.type; *stats_quant = xvid_enc_stats.quant; *stats_length = xvid_enc_stats.length; sse[0] = xvid_enc_stats.sse_y; sse[1] = xvid_enc_stats.sse_u; sse[2] = xvid_enc_stats.sse_v; return (ret); } int enc_stop() { int xerr; /* Destroy the encoder instance */ xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL); return (xerr); } 文件tcp.h中的程序代碼 static void initaddr (struct sockaddr_in *servadrr,char *address,int port); int open_sock (int port); void close_sock (int sockhandle); 文件tcp.c中的程序代碼 #include #include #include #include #include #include #include #include #include #include #define MAXCONNECT 5 static void initaddr (struct sockaddr_in *servadrr,char *address,int port) { int adrsize = 0; if(address){ adrsize = strlen(address); if(adrsize < 7 || adrsize > 15) exit(1); servadrr->sin_addr.s_addr = inet_addr(address); } else { servadrr->sin_addr.s_addr = INADDR_ANY; } servadrr->sin_family = AF_INET; servadrr->sin_port = htons (port); memset (&(servadrr->sin_zero), '\0', 8); } int open_sock (int port) { struct sockaddr_in servadr; int server_handle; int O_on = 1; /* Create a new socket */ if ((server_handle = socket (AF_INET, SOCK_STREAM, 0)) == -1) exit(1); if (setsockopt (server_handle, SOL_SOCKET, SO_REUSEADDR, &O_on, sizeof (int)) == -1) exit(1); /* Now set the server address struct and bind socket to the port*/ initaddr (&servadr,NULL, port); if (bind (server_handle, (struct sockaddr *) &servadr, sizeof (struct sockaddr)) == -1) exit(1); /* Listen on the socket */ if (listen (server_handle, MAXCONNECT) == -1) exit(1); return server_handle; } void close_sock (int sockhandle) { close (sockhandle); } 客戶端程序 MAKEFILE文件 ############################## # Client Makefile ############################## INSTALLROOT=$(PWD) CC=gcc CPP=g++ INSTALL=install APP_BINARY=client BIN=/usr/local/bin SERVFLAGS= -O2 -DLINUX $(WARNINGS) MATH_LIB=-lm SDL_ILD=-I/usr/include/SDL SDL_LIB=-L/usr/liub -lSDL SERVLIBS= $(MATH_LIB) -lpthread JRTPLIBS=-I/usr/local/include/jrtplib3 -I/usr/local/include/jthread -L/usr/local/lib -ljthread -ljrtp -lxvidcore #WARNINGS = -Wall \ # -Wundef -Wpointer-arith -Wbad-function-cast \ # -Wcast-align -Wwrite-strings -Wstrict-prototypes \ # -Wmissing-prototypes -Wmissing-declarations \ # -Wnested-externs -Winline -Wcast-qual -W \ # -Wno-unused # -Wunused CFLAGS =-O2 -DLINUX $(SDLFLAGS) $(WARNINGS) CPPFLAGS = $(CFLAGS) SHCFLAGS= -O2 -ffast-math -fforce-addr -fstrict-aliasing -fomit-frame-pointer #CLIBFLAGS= -O9 -falign-functions=4 -march=athlon #LIB_ENCODE = libjpgenc.a #LIB_ENCODE_OBJECTS = encoder.o huffman.o marker.o quant.o OBJECTS=tcp.o dxvid.o client.c # Makefile commands: #libjpgenc: $(LIB_ENCODE_OBJECTS) # ld -r $(LIB_ENCODE_OBJECTS) -o $(LIB_ENCODE) all: client clean: @echo "Cleaning up directory." rm -f *.a *.o $(APP_BINARY) server *~ log errlog # Applications: client: $(OBJECTS) $(CPP) $(CFLAGS) $(OBJECTS) $(X11_LIB) $(XPM_LIB)\ $(SDL_LIB) \ $(SDL_ILD) \ $(MATH_LIB) \ $(JRTPLIBS)\ $(SERVLIBS)\ -o $(APP_BINARY) chmod 755 $(APP_BINARY) tcp.o : tcp.c tcp.h $(CC) $(SHCFLAGS) -c -o $@ $< cxvid.o: dxvid.c dxvid.h $(CC) $(SHCFLAGS) -c -o $@ $< install: client $(INSTALL) -s -m 755 -g root -o root client $(BIN) 文件client.c程序源碼 #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tcp.h" #include "rtpsession.h" #include "rtppacket.h" #include "rtpudpv4transmitter.h" #include "rtpipv4address.h" #include "rtpsessionparams.h" #include "rtperrors.h" #include "rtpsourcedata.h" #include #include #include #include #include "dxvid.h" #define BUFFER_SIZE (2*1024*1024) SDL_Overlay *overlay; SDL_Rect rect; int SHXDIM =320;//display size int SHYDIM =240; SDL_Surface *screen; char receivebuffer[1000000]; char *receivepointer = receivebuffer; bool visiflag = false; int receivepayloadlength = 0; int headreceiveflag=0; RTPUDPv4TransmissionParams transparams; RTPSessionParams sessparams; void checkerror (int rtperr) { if (rtperr < 0) { std::cout << "ERROR: " << RTPGetErrorString (rtperr) << std::endl; exit (-1); } } class MyRTPSession:public RTPSession { protected: void OnPollThreadStep (); int ProcessRTPPacket (const RTPSourceData & srcdat, const RTPPacket & rtppack); }; MyRTPSession sess; void MyRTPSession::OnPollThreadStep () { BeginDataAccess (); // check incoming packets if (GotoFirstSourceWithData ()) { do { RTPPacket *pack; RTPSourceData *srcdat; srcdat = GetCurrentSourceInfo (); while ((pack = GetNextPacket ()) != NULL&&visiflag==false) { ProcessRTPPacket (*srcdat, *pack); delete pack; } } while (GotoNextSourceWithData ()); } if (visiflag==false) printf(" \n %d",receivepayloadlength); EndDataAccess (); } int MyRTPSession::ProcessRTPPacket (const RTPSourceData & srcdat, const RTPPacket & rtppack) { int i; char * payloadpointer = (char *)rtppack.GetPayloadData (); // You can inspect the packet and the source's info here std::cout << "Got packet " << rtppack. GetExtendedSequenceNumber () << " from SSRC " << srcdat. GetSSRC () << std::endl; bool packermarker = rtppack.HasMarker (); if (headreceiveflag==0) { if(rtppack.GetPayloadLength ()==50) headreceiveflag=1; else {printf("error"); return (-1);} } if (!packermarker) { memcpy(receivepointer,payloadpointer,rtppack.GetPayloadLength ()); //for (i = 0; i < rtppack.GetPayloadLength (); i++) //*(receivepointer++) = *(payloadpointer++); receivepointer+=rtppack.GetPayloadLength (); receivepayloadlength += rtppack.GetPayloadLength (); visiflag = false; } else {memcpy(receivepointer,payloadpointer,rtppack.GetPayloadLength ()); // for (i = 0; i < rtppack.GetPayloadLength (); i++) //*(receivepointer++) = *(payloadpointer++); receivepointer+=rtppack.GetPayloadLength (); receivepayloadlength += rtppack.GetPayloadLength (); visiflag = true;headreceiveflag=0; } } struct frame_t{ char header[5]; int nbframe; double seqtimes; int deltatimes; int w; int h; int size; int format; unsigned short bright; unsigned short contrast; unsigned short colors; unsigned short exposure; unsigned char wakeup; int acknowledge; } __attribute__ ((packed)); int readm4v(int sock, unsigned char **buf,struct frame_t *headerframe,int statOn); int Client (char *Ip, short port,int owidth, int oheight, int statOn); static int videoOk = 0; void init_SDL(); int main(int argc, char *argv[]) { int statOn = 0; int owidth = 0; int oheight = 0; int i; uint16_t portbase, destport; uint32_t destip; std::string ipstr; int status; sessparams.SetOwnTimestampUnit (1.0/90000); /*********************************/ char *AdIpPort; char AdIp[]= "000.000.000.000"; unsigned short ports = 0; /*********************************/ std::cout << "Enter local portbase:" << std::endl; std::cin >> portbase; std::cout << std::endl; transparams.SetPortbase (portbase); status = sess.Create (sessparams, &transparams); checkerror (status); for (i = 1; i < argc; i++) { /* skip bad arguments */ if (argv == NULL || *argv == 0 || *argv != '-') { continue; } if (strcmp (argv, "-w") == 0) { if (i + 1 >= argc) { printf ("No parameter specified with -w, aborting.\n"); exit (1); } AdIpPort = strdup (argv[i + 1]); if(reportip(AdIpPort,AdIp,&ports) < 0) printf("error in port convertion \n"); printf ("using Server %s Port %d \n",AdIp,ports); } } Client(AdIp,ports,owidth,oheight, statOn); } int Client (char *Ip, short port,int owidth, int oheight, int statOn) { struct frame_t *headerframe; //struct client_t *messcallback; unsigned char *buf = NULL; int width,height; int jpegsize; int sock_client; int run = 1; int quit =1; int keypressed =0; int bpp = 3; struct tm *tdate; time_t curdate; char titre[21]; size_t outbytes; SDL_Event event; int fps = 25; FILE *out; int used_bytes; int status; unsigned char *out_buffer=NULL; xvid_dec_stats_t xvid_dec_stats; int bufframenum; unsigned char *mp4_buffer; unsigned char *mp4_ptr; int useful_bytes; useful_bytes=0; int i; int fpsdelay; uint32_t lastftick; int paused=0; int resized=0; int y; uint8_t *outy,*outu,*outv,*op[3]; mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE); if (!mp4_buffer) goto free_all_memory; out_buffer = (unsigned char *)malloc(XDIM*YDIM*3/2); if (!out_buffer) goto free_all_memory; init_SDL(); sock_client = open_clientsock(Ip,port); headerframe=(struct frame_t*)malloc(sizeof(struct frame_t)); status = dec_init(1, 0); if (status) { fprintf(stderr, "Decore INIT problem, return value %d\n", status); goto release_all; } /* set the start frame */ i=0; fpsdelay=1000/fps; lastftick=SDL_GetTicks(); do { if((useful_bytes = readm4v(sock_client,&buf,headerframe,statOn)) < 0){ printf(" No size !!! exit fatal \n"); goto error;} mp4_ptr=buf; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_VIDEORESIZE: screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE); rect.w=event.resize.w; rect.h=event.resize.h; if (paused) { resized=1; } break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_SPACE) { paused=!paused; break; } if (event.key.keysym.sym != SDLK_ESCAPE) { goto release_all; } case SDL_QUIT: goto release_all; } } if ((!paused)||(resized)) { if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized)) { lastftick=SDL_GetTicks(); /* This loop is needed to handle VOL/NVOP reading */ do{ /* Decode frame */ used_bytes = dec_main(mp4_ptr, out_buffer, useful_bytes, &xvid_dec_stats); printf ("the usedbytes is %d\n",used_bytes); if(xvid_dec_stats.type==XVID_TYPE_VOL && (xvid_dec_stats.data.vol.width != XDIM ||xvid_dec_stats.data.vol.height != YDIM)) {printf("panduan\n"); //reallocate bigger out frame free(out_buffer); XDIM = xvid_dec_stats.data.vol.width; YDIM = xvid_dec_stats.data.vol.height; out_buffer = (unsigned char *) malloc(XDIM*YDIM*3/2); if (!out_buffer) goto free_all_memory; //reallocate bigger yuv overlay SDL_FreeYUVOverlay(overlay); overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen); if (!overlay) { fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError()); exit(4); } } if(used_bytes > 0) { mp4_ptr += used_bytes; useful_bytes -= used_bytes; } }while (xvid_dec_stats.type <= 0 && useful_bytes > 0); SDL_LockSurface(screen); SDL_LockYUVOverlay(overlay); outy = out_buffer; outu = out_buffer+XDIM*YDIM; outv = out_buffer+XDIM*YDIM*5/4; for(y=0;yh && yh;y++) { op[0]=overlay->pixels[0]+overlay->pitches[0]*y; op[1]=overlay->pixels[1]+overlay->pitches[1]*(y/2); op[2]=overlay->pixels[2]+overlay->pitches[2]*(y/2); memcpy(op[0],outy+y*XDIM,XDIM); if(y%2 == 0) { memcpy(op[1],outu+XDIM/2*y/2,XDIM/2); memcpy(op[2],outv+XDIM/2*y/2,XDIM/2); } } SDL_UnlockYUVOverlay(overlay); SDL_UnlockSurface(screen); SDL_DisplayYUVOverlay(overlay, &rect); if (resized) resized = 0; } } SDL_Delay(10); } while (1 ); useful_bytes = 0; /* Empty buffer */ release_all: if (dec_handle) { status = dec_stop(); if (status) fprintf(stderr, "decore RELEASE problem return value %d\n", status); } error: close_sock(sock_client); free(buf); free(headerframe); SDL_Quit (); free_all_memory: free(out_buffer); free(mp4_buffer); return 0; } int readm4v(int sock, unsigned char **buf,struct frame_t *headerframe,int statOn) { int byteread,bytewrite; while (1){ if (visiflag==true ) break; usleep(10); } memcpy(headerframe,receivebuffer,sizeof(struct frame_t)); if(statOn) printf (" key %s nb %d width %d height %d times %dms size %d \n",headerframe->header, headerframe->nbframe,headerframe->w,headerframe->h,headerframe->deltatimes,headerframe->size); if(headerframe->size && !headerframe->wakeup){ //if(headerframe->size){ *buf=(unsigned char*) realloc(*buf,headerframe->size); memcpy(*buf,receivebuffer+sizeof(struct frame_t),headerframe->size); /*if((byteread = read_sock(sock,*buf,headerframe->size)) < 0){ printf("Seem server is gone !! try later \n"); goto error;} */} //printf("buf read %d \n",byteread); if(headerframe->acknowledge) usleep(5000); printf("h"); receivepayloadlength = 0; receivepointer = receivebuffer; visiflag=false; return ((headerframe->wakeup)?0:(headerframe->size)); //return (headerframe->size); error: return -1; } void init_SDL() { if (SDL_Init (SDL_INIT_VIDEO) < 0) { videoOk=0; fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit (1); } videoOk=1; atexit (SDL_Quit); screen = SDL_SetVideoMode (320, 240, 0, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_ANYFORMAT | SDL_RESIZABLE); if (screen == NULL) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(2); } if (0 == screen->flags & SDL_HWSURFACE) { fprintf(stderr,"Can't get hardware surface\n"); exit(3); } SDL_WM_SetCaption ("SDL MultiMedia Application", NULL); overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen); if (!overlay) { fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError()); exit(4); } //show the overlay status printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes, overlay->hw_overlay?"hardware":"software", overlay->format==SDL_YV12_OVERLAY?"YV12": overlay->format==SDL_IYUV_OVERLAY?"IYUV": overlay->format==SDL_YUY2_OVERLAY?"YUY2": overlay->format==SDL_UYVY_OVERLAY?"UYVY": overlay->format==SDL_YVYU_OVERLAY?"YVYU": "Unknown"); rect.x=0; rect.y=0; rect.w=SHXDIM; rect.h=SHYDIM; } 文件dxvid.h程序源碼 #define CSP XVID_CSP_I420 #define BPP 1 int *dec_handle=NULL; int XDIM=352; int YDIM=288; int dec_init(int use_assembler, int debug_level); int dec_main(unsigned char *istream, unsigned char *ostream, int istream_size, xvid_dec_stats_t *xvid_dec_stats); int dec_stop(); 文件dxvid.c程序源碼 #include #include #include #include #include #include #include #include #include "dxvid.h" int dec_main(unsigned char *istream, unsigned char *ostream, int istream_size, xvid_dec_stats_t *xvid_dec_stats) { int ret; xvid_dec_frame_t xvid_dec_frame; /* Reset all structures */ memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t)); memset(xvid_dec_stats, 0, sizeof(xvid_dec_stats_t)); /* Set version */ xvid_dec_frame.version = XVID_VERSION; xvid_dec_stats->version = XVID_VERSION; /* No general flags to set */ xvid_dec_frame.general = 0; /* Input stream */ xvid_dec_frame.bitstream = istream; xvid_dec_frame.length = istream_size; /* Output frame structure */ xvid_dec_frame.output.plane[0] = ostream; xvid_dec_frame.output.stride[0] = XDIM*BPP; xvid_dec_frame.output.csp = CSP; ret = xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats); return(ret); } /* close decoder to release resources */ int dec_stop() { int ret; ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL); return(ret); } /***************************************************************************** * Routines for decoding: init decoder, use, and stop decoder ****************************************************************************/ /* init decoder before first run */ int dec_init(int use_assembler, int debug_level) { int ret; xvid_gbl_init_t xvid_gbl_init; xvid_dec_create_t xvid_dec_create; /* Reset the structure with zeros */ memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t)); memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t)); /*------------------------------------------------------------------------ * XviD core initialization *----------------------------------------------------------------------*/ /* Version */ xvid_gbl_init.version = XVID_VERSION; /* Assembly setting */ if(use_assembler) xvid_gbl_init.cpu_flags = 0; else xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; xvid_gbl_init.debug = debug_level; xvid_global(NULL, 0, &xvid_gbl_init, NULL); /*------------------------------------------------------------------------ * XviD encoder initialization *----------------------------------------------------------------------*/ /* Version */ xvid_dec_create.version = XVID_VERSION; /* * Image dimensions -- set to 0, xvidcore will resize when ever it is * needed */ xvid_dec_create.width = 0; xvid_dec_create.height = 0; ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL); dec_handle = (int *)xvid_dec_create.handle; return(ret); } 文件tcp.h程序源碼 #include #include #include void close_sock (int sockhandle); int reportip( char *src, char *ip, unsigned short *port); static void initaddr (struct sockaddr_in *servadrr,char *address,int port); int open_clientsock(char * address, int port); 文件tcp.c程序源碼 #include #include #include #include #include #include #include #include "tcp.h" int open_clientsock(char * address, int port) { struct sockaddr_in servadr; int client_handle; /* Create a new socket */ if ((client_handle = socket (AF_INET, SOCK_STREAM, 0)) == -1) exit(1); /* Now set the server address struct and connect client socket to the port*/ initaddr (&servadr,address,port); if (connect(client_handle,(struct sockaddr *) &servadr, sizeof (struct sockaddr)) == -1) exit(1); return client_handle; } static void initaddr (struct sockaddr_in *servadrr,char *address,int port) { int adrsize = 0; if(address){ adrsize = strlen(address); if(adrsize < 7 || adrsize > 15) exit(1); servadrr->sin_addr.s_addr = inet_addr(address); } else { servadrr->sin_addr.s_addr = INADDR_ANY; } servadrr->sin_family = AF_INET; servadrr->sin_port = htons (port); memset (&(servadrr->sin_zero), '\0', 8); } int reportip( char *src, char *ip, unsigned short *port) { int j,k,done,ipdone,nbpt=0; char *AdIpPort= src; char *AdIp = ip; char Ports[] = "65536"; j=0;k=0;done=0;ipdone=0; while(j < 22){ switch (AdIpPort[j]){ case '\0': done =1; break; case '.': nbpt++; if(nbpt > 3){ printf("error fatal \n"); return -1; } break; case ':': k = 0; ipdone = 1; AdIp[j++] ='\0'; break; default: break; } if (ipdone) Ports[k++]=AdIpPort[j++]; else AdIp[k++]=AdIpPort[j++]; if(done) break; } *port = (unsigned short) atoi (Ports); //printf ("Ip %s Port %s \n",AdIp,Ports); if(*port < 1024) { printf("ERROR Set default port to 7070 \n"); *port = 7070; } return 0; } void close_sock (int sockhandle) { close (sockhandle); }
[火星人
]
上大學時做的Linux上視頻傳輸的程序 已經有659 次圍觀
本文地址: http://coctec.com/docs/linux/show-post-187974.html