一.LINUX DVR源码
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <errno.h> #include <fcntl.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <linux/videodev.h> #include "xvid.h" #define FRAMERATE_INCR 1001 #define SMALL_EPS (1e-10) #define VIDEO "/dev/video" #define INDEX 0 #define IOCTL(fd, req, addr ) / ((-1==ioctl(fd,req,addr))?(perror(#req),close(fd),exit(EXIT_FAILURE)):0) static float ARG_FRAMERATE = 25.00f; static int ARG_QUALITY = 4; static int ARG_MAXKEYINTERVAL = 250; static char * ARG_OUTPUTFILE= "out.m4u"; static FILE * fp = NULL; static int done = 0; 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=352,YDIM=288; static use_assembler = 0; static void *enc_handle = NULL; static int enc_init(int use_assembler); static int enc_main(unsigned char *image, unsigned char *bitstream, int *key, int *stats_type, int *stats_quant, int *stats_length, int stats[3]); static int enc_stop(); //signal act method defination static void clean(int signum) { done=1; } int main(int argc,char *argv[]) { //register SIGINT action method ,to save the m4u file signal(SIGINT,clean); int fd; struct v4l2_capability cap; struct v4l2_format format; struct v4l2_requestbuffers reqbuf; struct v4l2_buffer buffer; struct v4l2_input input; int index=0,i; for (i=1; i< argc; i++) { if (strcmp("-asm", argv[i]) == 0 ) { use_assembler = 1; }else if(strcmp("-f", argv[i]) == 0 && i < argc -1){ i++; ARG_OUTPUTFILE = argv[i]; }else if(strcmp("-i", argv[i]) == 0 && i < argc -1){ i++; index = atoi(argv[i]); } else if(strcmp("-w", argv[i]) == 0 && i < argc -1){ i++; XDIM = atoi(argv[i]); } else if(strcmp("-h", argv[i]) == 0 && i < argc -1){ i++; YDIM = atoi(argv[i]); } } //init capture card fd = open(VIDEO,O_RDWR); if(fd<0) { perror("Can't open /dev/video device"); exit(errno); } //if card can't support video capture and by means of steamio,exit IOCTL(fd, VIDIOC_QUERYCAP, &cap); if ( !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) &&!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf(stderr, "Couldn't use the card /n"); exit(3); } //query input and select the desired input IOCTL(fd, VIDIOC_G_INPUT, &index); input.index = index; IOCTL(fd, VIDIOC_ENUMINPUT, &input); printf ("Current input: Index %i,Name %s/n", index,input.name); for(i=0;;i++) { if(i!=index) { input.index = i; if(-1==ioctl(fd, VIDIOC_ENUMINPUT, &input)) break; else printf ("Other input: Index %i,Name %s/n",i,input.name); } } IOCTL(fd, VIDIOC_S_INPUT, &index); //get current video format,set the desired format format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; IOCTL(fd,VIDIOC_G_FMT,&format); format.fmt.pix.width = XDIM; format.fmt.pix.height = YDIM; format.fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420; format.fmt.pix.field = V4L2_FIELD_ANY;//V4L2_FIELD_INTERLACED IOCTL(fd,VIDIOC_S_FMT,&format); XDIM = format.fmt.pix.width; printf("Gotten width %d/n",XDIM); YDIM = format.fmt.pix.height; printf("Gotten height %d/n",YDIM); //let driver get the buffers reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; reqbuf.count = 4; IOCTL(fd,VIDIOC_REQBUFS,&reqbuf ); if (reqbuf.count < 4) { printf ("Not enough buffer memory for driver/n"); exit (5); } //mmap the driver's buffer to application address //create relative buffers struct to be used by mmap struct { void * start; size_t length; } buffers[reqbuf.count]; //mmap the driver's kernel buffer into application for (i=0;i<reqbuf.count;i++) { buffer.type = reqbuf.type; buffer.index =i ; //query the status of one buffer ,mmap the driver buffer IOCTL(fd,VIDIOC_QUERYBUF,&buffer); buffers[i].length = buffer.length; buffers[i].start = mmap (NULL,buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd,buffer.m.offset); if (buffers[i].start == MAP_FAILED) { close(fd); perror ("mmap"); exit(errno); } } //begin video capture IOCTL(fd,VIDIOC_STREAMON,&reqbuf.type); //enqueue all driver buffers for (i=0;i<reqbuf.count;i++) { buffer.type = reqbuf.type; buffer.index = i; IOCTL(fd,VIDIOC_QUERYBUF, &buffer); IOCTL(fd,VIDIOC_QBUF,&buffer); } //init xvid int result; result = enc_init(1); if(result!=0) { fprintf(stderr, "Encore INIT problem, return value %d/n", result); goto clean_all; } //get mem of mpg4 frame uint8_t *mp4_buffer = NULL; mp4_buffer = (unsigned char *) malloc(XDIM*YDIM); if (mp4_buffer==NULL) { fprintf(stderr,"malloc error"); goto clean_all; } int key; int stats_type; int stats_quant; int stats_length; int sse[3]; //create store mp4 file fp= fopen(ARG_OUTPUTFILE, "rb"); if (fp== NULL) { perror("Error opening output file."); exit(-1); } //main loop ,frame capture,compressed i = 0; int outbytes,m4v_size; while(!done) { //dequeue one frame buffer.type = reqbuf.type; buffer.index = i; IOCTL(fd, VIDIOC_QUERYBUF, &buffer); IOCTL(fd, VIDIOC_DQBUF, &buffer); /*debug info printf("current frame's unix time seconds :%d/n",buffer.timestamp.tv_sec); printf("current frame's unix time mcicoseconds :%d/n",buffer.timestamp.tv_usec); */ //compress a frame m4v_size = enc_main((uint8_t *)buffers[i].start, mp4_buffer+16, &key, &stats_type,&stats_quant, &stats_length, sse); //store into output file outbytes = fwrite(mp4_buffer, 1, m4v_size, fp); if(outbytes != m4v_size) { fprintf(stderr,"Error writing the m4u file/n"); exit(7); } //enqueue one frame buffer.type = reqbuf.type; buffer.index = i; IOCTL(fd, VIDIOC_QUERYBUF, &buffer ); IOCTL(fd, VIDIOC_QBUF, &buffer ); i++; if( i >= reqbuf.count ) i = 0; } clean_all: fclose(fp); enc_stop(); //stop capture IOCTL(fd, VIDIOC_STREAMOFF, &reqbuf.type ); //unmmap the apllication buffer for (i=0;i<reqbuf.count;i++) munmap (buffers[i].start,buffers[i].length); //release the dynamic mem close(fd); return 0; } int enc_init(int use_assembler) { int xerr; //xvid_plugin_cbr_t cbr; xvid_plugin_single_t single; xvid_plugin_2pass1_t rc2pass1; xvid_plugin_2pass2_t rc2pass2; //xvid_plugin_fixed_t rcfixed; 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); }

下面是基于SDL的跨平台MPEG4播放器源代码,支持硬件YUV加速
#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <SDL/SDL.h> #include "xvid.h" #define USE_PNM 1 #define USE_TGA 0 static int SHXDIM = 0;//display size static int SHYDIM = 0; static int XDIM = 352;//real size static int YDIM = 288; static int ARG_SAVEDECOUTPUT = 0; static int ARG_SAVEMPEGSTREAM = 0; static char *ARG_INPUTFILE = NULL; static int CSP = XVID_CSP_I420; static int BPP = 1; static int FORMAT = USE_PNM; static char filepath[256] = "./"; static void *dec_handle = NULL; #define BUFFER_SIZE (2*1024*1024) static const int display_buffer_bytes = 0; static SDL_Surface *screen; static SDL_Overlay *overlay; static SDL_Rect rect; static double msecond(); static int dec_init(int use_assembler, int debug_level); static int dec_main(unsigned char *istream, unsigned char *ostream, int istream_size, xvid_dec_stats_t *xvid_dec_stats); static int dec_stop(); static void usage(); static int write_image(char *prefix, unsigned char *image); static int write_pnm(char *filename, unsigned char *image); static int write_tga(char *filename, unsigned char *image); const char * type2str(int type) { if (type==XVID_TYPE_IVOP) return "I"; if (type==XVID_TYPE_PVOP) return "P"; if (type==XVID_TYPE_BVOP) return "B"; return "S"; } static void init_SDL() { if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf (stderr, "Couldn't initialize SDL: %s/n", SDL_GetError()); exit (1); } atexit (SDL_Quit); screen = SDL_SetVideoMode (SHXDIM, SHYDIM, 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; } int main(int argc, char *argv[]) { SDL_Event event; uint32_t lastftick; unsigned char *mp4_buffer = NULL; unsigned char *mp4_ptr = NULL; unsigned char *out_buffer = NULL; int useful_bytes; xvid_dec_stats_t xvid_dec_stats; double totaldectime; long totalsize; int status; int fps = 25; int fpsdelay; int paused=0; int resized=0; int use_assembler = 1; int debug_level = 0; char filename[256]; FILE *in_file; int filenr; int i; for (i=1; i< argc; i++) { if (strcmp("-asm", argv[i]) == 0 ) { use_assembler = 1; } else if (strcmp("-debug", argv[i]) == 0 && i < argc - 1 ) { i++; if (sscanf(argv[i], "0x%x", &debug_level) != 1) { debug_level = atoi(argv[i]); } } else if (strcmp("-d", argv[i]) == 0) { ARG_SAVEDECOUTPUT = 1; } else if (strcmp("-i", argv[i]) == 0 && i < argc - 1 ) { i++; ARG_INPUTFILE = argv[i]; } else if (strcmp("-c", argv[i]) == 0 && i < argc - 1 ) { i++; if (strcmp(argv[i], "rgb16") == 0) { CSP = XVID_CSP_RGB555; BPP = 2; } else if (strcmp(argv[i], "rgb24") == 0) { CSP = XVID_CSP_BGR; BPP = 3; } else if (strcmp(argv[i], "rgb32") == 0) { CSP = XVID_CSP_BGRA; BPP = 4; } else if (strcmp(argv[i], "yv12") == 0) { CSP = XVID_CSP_YV12; BPP = 1; } else { CSP = XVID_CSP_I420; BPP = 1; } } else if (strcmp("-f", argv[i]) == 0 && i < argc -1) { i++; if (strcmp(argv[i], "tga") == 0) { FORMAT = USE_TGA; } else { FORMAT = USE_PNM; } } else if (strcmp("-help", argv[i]) == 0) { usage(); return(0); } else if(strcmp("-w", argv[i]) == 0 && i < argc -1){ i++; SHXDIM = atoi(argv[i]); } else if(strcmp("-h", argv[i]) == 0 && i < argc -1){ i++; SHYDIM = atoi(argv[i]); } else if(strcmp("-fps", argv[i]) == 0 && i < argc -1){ i++; fps = atoi(argv[i]); } else { usage(); exit(-1); } } if (ARG_INPUTFILE==NULL) { fprintf(stderr, "Warning: MSVC build does not read EOF correctly from stdin. Use the -i switch./n/n"); } in_file = fopen(ARG_INPUTFILE, "rb"); if (in_file == NULL) { fprintf(stderr, "Error opening input file %s/n", ARG_INPUTFILE); return(-1); } /* PNM/PGM format can't handle 16/32 bit data */ if (BPP != 1 && BPP != 3 && FORMAT == USE_PNM) { FORMAT = USE_TGA; } /* Memory for encoded mp4 stream */ 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 *******************************************************************************/ init_SDL(); /***************************************************************************** * XviD PART Start ****************************************************************************/ status = dec_init(use_assembler, debug_level); if (status) { fprintf(stderr, "Decore INIT problem, return value %d/n", status); goto release_all; } /***************************************************************************** * Main loop ****************************************************************************/ /* Fill the buffer ,create 2M buffer*/ useful_bytes = fread(mp4_buffer, 1, BUFFER_SIZE, in_file); totaldectime = 0; totalsize = 0; filenr = 0; mp4_ptr = mp4_buffer; uint8_t *outy,*outu,*outv,*op[3]; int y; /* set the start frame */ i=0; fpsdelay=1000/fps; lastftick=SDL_GetTicks(); do { int used_bytes = 0; double dectime; 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 the buffer is half empty or there are no more bytes in it * then fill it. */ if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2) { int already_in_buffer = (mp4_buffer + BUFFER_SIZE - mp4_ptr); /* Move data if needed */ if (already_in_buffer > 0) memcpy(mp4_buffer, mp4_ptr, already_in_buffer); /* Update mp4_ptr */ mp4_ptr = mp4_buffer; /* read new data */ if(feof(in_file)) break; useful_bytes += fread(mp4_buffer + already_in_buffer, 1, BUFFER_SIZE - already_in_buffer, in_file); } if ((!paused)||(resized)) { if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized)) { lastftick=SDL_GetTicks(); /* This loop is needed to handle VOL/NVOP reading */ do{ /* Decode frame */ dectime = msecond(); used_bytes = dec_main(mp4_ptr, out_buffer, useful_bytes, &xvid_dec_stats); dectime = msecond() - dectime; if(xvid_dec_stats.type==XVID_TYPE_VOL && (xvid_dec_stats.data.vol.width != XDIM ||xvid_dec_stats.data.vol.height != YDIM)) { //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); } } /* Update buffer pointers */ if(used_bytes > 0) { mp4_ptr += used_bytes; useful_bytes -= used_bytes; /* Total size */ totalsize += used_bytes; } }while (xvid_dec_stats.type <= 0 && useful_bytes > 0); /* Check if there is a negative number of useful bytes left in buffer * This means we went too far */ if(useful_bytes < 0) break; /* Updated data - Count only usefull decode time */ totaldectime += dectime; //display the decoded frame SDL_LockSurface(screen); SDL_LockYUVOverlay(overlay); outy = out_buffer; outu = out_buffer+XDIM*YDIM; outv = out_buffer+XDIM*YDIM*5/4; for(y=0;y<screen->h && y<overlay->h;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); /* Save output frame if required */ if (ARG_SAVEDECOUTPUT) { sprintf(filename, "%sdec%05d", filepath, filenr); if(write_image(filename, out_buffer)) { fprintf(stderr, "Error writing decoded frame %s/n", filename); } } filenr++; if (resized) resized = 0; } } SDL_Delay(10); } while (useful_bytes>0 || !feof(in_file)); useful_bytes = 0; /* Empty buffer */ /***************************************************************************** * Flush decoder buffers ****************************************************************************/ do { /* Fake vars */ int used_bytes; double dectime; do { dectime = msecond(); used_bytes = dec_main(NULL, out_buffer, -1, &xvid_dec_stats); dectime = msecond() - dectime; } while(used_bytes>=0 && xvid_dec_stats.type <= 0); if (used_bytes < 0) { /* XVID_ERR_END */ break; } /* Updated data - Count only usefull decode time */ totaldectime += dectime; /* Prints some decoding stats */ if (!display_buffer_bytes) { printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d/n", filenr, type2str(xvid_dec_stats.type), dectime, used_bytes); } /* Save output frame if required */ if (ARG_SAVEDECOUTPUT) { sprintf(filename, "%sdec%05d", filepath, filenr); if(write_image(filename, out_buffer)) { fprintf(stderr, "Error writing decoded frame %s/n", filename); } } filenr++; }while(1); /***************************************************************************** * Calculate totals and averages for output, print results ****************************************************************************/ if (filenr>0) { totalsize /= filenr; totaldectime /= filenr; printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d/n", totaldectime, 1000/totaldectime, (int)totalsize); }else{ printf("Nothing was decoded!/n"); } /***************************************************************************** * XviD PART Stop ****************************************************************************/ release_all: SDL_FreeYUVOverlay(overlay); if (dec_handle) { status = dec_stop(); if (status) fprintf(stderr, "decore RELEASE problem return value %d/n", status); } free_all_memory: free(out_buffer); free(mp4_buffer); return 0; } /***************************************************************************** * Usage function ****************************************************************************/ static void usage() { fprintf(stderr, "Usage : xvid_decraw [OPTIONS]/n"); fprintf(stderr, "Options :/n"); fprintf(stderr, " -asm : use assembly optimizations (default=disabled)/n"); fprintf(stderr, " -i string : input filename (default=stdin)/n"); fprintf(stderr, " -d : save decoder output/n"); fprintf(stderr, " -f format : choose output file format (tga, pnm, pgm)/n"); fprintf(stderr, " -w width : init window width/n"); fprintf(stderr, " -h height : init window height/n"); fprintf(stderr, " -help : This help message/n"); fprintf(stderr, " (* means default)/n"); } /* return the current time in milli seconds */ static double msecond() { clock_t clk; clk = clock(); return(clk * 1000 / CLOCKS_PER_SEC); } static int write_image(char *prefix, unsigned char *image) { char filename[1024]; char *ext; int ret; if (FORMAT == USE_PNM && BPP == 1) { ext = "pgm"; } else if (FORMAT == USE_PNM && BPP == 3) { ext = "pnm"; } else if (FORMAT == USE_TGA) { ext = "tga"; } else { fprintf(stderr, "Bug: should not reach this path code -- please report to xvid-devel@xvid.org with command line options used"); exit(-1); } sprintf(filename, "%s.%s", prefix, ext); if (FORMAT == USE_PNM) { ret = write_pnm(filename, image); } else { ret = write_tga(filename, image); } return(ret); } static int write_tga(char *filename, unsigned char *image) { FILE * f; char hdr[18]; f = fopen(filename, "wb"); if ( f == NULL) { return -1; } hdr[0] = 0; /* ID length */ hdr[1] = 0; /* Color map type */ hdr[2] = (BPP>1)?2:3; /* Uncompressed true color (2) or greymap (3) */ hdr[3] = 0; /* Color map specification (not used) */ hdr[4] = 0; /* Color map specification (not used) */ hdr[5] = 0; /* Color map specification (not used) */ hdr[6] = 0; /* Color map specification (not used) */ hdr[7] = 0; /* Color map specification (not used) */ hdr[8] = 0; /* LSB X origin */ hdr[9] = 0; /* MSB X origin */ hdr[10] = 0; /* LSB Y origin */ hdr[11] = 0; /* MSB Y origin */ hdr[12] = (XDIM>>0)&0xff; /* LSB Width */ hdr[13] = (XDIM>>8)&0xff; /* MSB Width */ if (BPP > 1) { hdr[14] = (YDIM>>0)&0xff; /* LSB Height */ hdr[15] = (YDIM>>8)&0xff; /* MSB Height */ } else { hdr[14] = ((YDIM*3)>>1)&0xff; /* LSB Height */ hdr[15] = ((YDIM*3)>>9)&0xff; /* MSB Height */ } hdr[16] = BPP*8; hdr[17] = 0x00 | (1<<5) /* Up to down */ | (0<<4); /* Image descriptor */ /* Write header */ fwrite(hdr, 1, sizeof(hdr), f); /* write first plane */ fwrite(image, 1, XDIM*YDIM*BPP, f); /* Write Y and V planes for YUV formats */ if (BPP == 1) { int i; /* Write the two chrominance planes */ for (i=0; i<YDIM/2; i++) { fwrite(image+XDIM*YDIM + i*XDIM/2, 1, XDIM/2, f); fwrite(image+5*XDIM*YDIM/4 + i*XDIM/2, 1, XDIM/2, f); } } /* Close the file */ fclose(f); return(0); } static int write_pnm(char *filename, unsigned char *image) { FILE * f; f = fopen(filename, "wb"); if ( f == NULL) { return -1; } if (BPP == 1) { int i; fprintf(f, "P5/n#xvid/n%i %i/n255/n", XDIM, YDIM*3/2); fwrite(image, 1, XDIM*YDIM, f); for (i=0; i<YDIM/2;i++) { fwrite(image+XDIM*YDIM + i*XDIM/2, 1, XDIM/2, f); fwrite(image+5*XDIM*YDIM/4 + i*XDIM/2, 1, XDIM/2, f); } } else if (BPP == 3) { int i; fprintf(f, "P6/n#xvid/n%i %i/n255/n", XDIM, YDIM); for (i=0; i<XDIM*YDIM*3; i+=3) { fputc(image[i+2], f); fputc(image[i+1], f); fputc(image[i+0], f); } } fclose(f); return 0; } /***************************************************************************** * Routines for decoding: init decoder, use, and stop decoder ****************************************************************************/ /* init decoder before first run */ static 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 = xvid_dec_create.handle; return(ret); } /* decode one frame */ static 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 */ static int dec_stop() { int ret; ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL); return(ret); }

LINUX MPEG4 DVR源代码,还包括一个可以跨平台运行的MPEG4 播放器(需要XVID与SDL开发库包)相关推荐

  1. 一个简单的基于 DirectShow 的播放器 2(对话框类)

    上篇文章分析了一个封装DirectShow各种接口的封装类(CDXGraph):一个简单的基于 DirectShow 的播放器  1(封装类) 本文继续上篇文章,分析一下调用这个封装类(CDXGrap ...

  2. 一个简单的基于 DirectShow 的播放器 1(封装类)

    DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件. 注:该例子取自于<D ...

  3. 基于 Qt5 ( C++ ) 开发的一个小巧精美的本地音乐播放器

    LightMusicPlayer --南京大学2019秋季学期 "高级程序设计" 课程设计三 基于Qt5开发的一个小巧精美的本地音乐播放器 代码注释详细,适合作为一个用于入门的Qt ...

  4. 开源html5在线音乐网站,一个漂亮的开源HTML5音乐播放器——APlayer

    介绍 APlayer是一个简约且漂亮的html5音乐播放器,支持多种模式,包括播放列表模式.吸底模式 .迷你模式.MSE模式.HLS模式. Github https://github.com/diyg ...

  5. iOS一个模仿百度音乐盒的音乐播放器(带EQ均衡器)

    工作之余, 断断续续写了这么一个音乐播放器, eq实现各种音效, 指定位置播放, 快进快退, 锁屏耳机线控等等, 基本就是参考百度音乐盒的功能来实现的.(项目地址最后放出, 项目中的资源接口, 是抓百 ...

  6. 一个基于Directshow实现的音频播放器,支持歌词显示

    之前在VC知识库上下载了一个基于Directshow做的音乐播放器,带歌词显示功能,觉得挺酷的.我下载了代码,编译了工程之后,运行起来的界面效果如下: 这个播放器支持的功能有: 支持播放MP3/AAC ...

  7. 第六节:用audio标签打造一个属于自己的HTML5音乐播放器

    上一章节,我们刚刚讲了<video>标签,今晚,我们讲的是<audio>标签,这两个东东除了表示的内容不一样以外,其他的特性相似的地方真的太多了,属性和用法几乎一样,也就说,如 ...

  8. 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器...

    [索引页] [×××] 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器 作者:webabcd 介绍 Silverlight 2.0 ...

  9. 【游戏开发创新】手把手教你使用Unity制作一个高仿酷狗音乐播放器,滨崎步,旋律起,爷青回(声音可视化 | 频谱 | Audio)

    文章目录 一.前言 二.获取UI素材 三.使用UGUI制作界面 1.界面布局 2.账号圆形头像 3.搜索框 4.调节UI层 5.黑色按钮悬浮高亮效果 6.纯文字按钮 7.滚动列表自适应 8.歌名与视频 ...

  10. 用jq和bootstrap3 实现一个自定义网页版的音乐播放器

    用jq和bootstrap3 实现一个自定义网页版的音乐播放器 1.主要实现功能 1.1.点击播放与暂停,上一首和下一首: 注:用python返回所有歌曲的信息,加载完成默认选择第一首歌曲,通过传递歌 ...

最新文章

  1. 其他发行版本安装深度音乐播放器
  2. (0030) iOS 开发之跳转之转场动画
  3. UA MATH564 概率论VI 数理统计基础1
  4. 眼界大开 声临其境丨胡宜峰:视频深度伪造检测技术在内容安全领域的探索与实践
  5. 前端学习(2982):实现商品功能列表
  6. PHP建站环境搭建:汇总网上常见的1键安装包
  7. 熵权法 —— python
  8. android 根据滑动隐藏或显示导航 类似手机QQ好友个人信息
  9. zz在Ubuntu中通过源码安装编译安装软件(MySQL篇)
  10. 包装类(Wrapper)的使用
  11. C++17 Any类
  12. AllWinner T113 升级篇
  13. matlab串口实时画图,基于MATLABGUI界面的MCU串口实时绘图设计
  14. win10系统服务器不能创建对象,教你win10系统activex部件不能创建对象的解决教程...
  15. vue中使用粒子特效
  16. A64的原装风扇真让人头痛
  17. CSS单行文本溢出时显示省略号
  18. android图片按比例缩放,Android开发之imageView图片按比例缩放的实现方法
  19. linux计算字符串md5值,计算字符串md5的几个方法
  20. 用Python做一个猜数游戏(入门)

热门文章

  1. 利用dem生成横断面数据
  2. Ansys-结构动力学分析-有预应力琴弦横向振动模态分析学习收获
  3. 计算机软件税负率,软件产品增值税超税负退税实务问题
  4. lisp如何将度分秒转换为弧度_3 角 度分秒与弧度互相转换
  5. MTK 驱动部分双分区升级原理
  6. 助力疫情防控,无接触式Beacon蓝牙考勤打卡方案
  7. ABB机器人指令列表分类详解
  8. linux 向日葵教程,远程控制工具——Centos7上向日葵安装使用(转)
  9. 土建中级工程师考试用书电子版_真的!2020年湖南土建中级职称考试用书是没有指定的教材?...
  10. 《大明王朝》倒严的号角