📄 xvid_encraw.c
字号:
} } else { out_file = NULL; }/***************************************************************************** * Encoding loop ****************************************************************************/ totalsize = 0; do { if (ARG_INPUTTYPE) status = read_pgmdata(in_file, in_buffer); /* read PGM data (YUV-format) */ else status = read_yuvdata(in_file, in_buffer); /* read raw data (YUV-format) */ if (status) { /* Couldn't read image, most likely end-of-file */ continue; }/***************************************************************************** * Read hints from file ****************************************************************************/ if(ARG_HINTMODE == HINT_MODE_SET) { fread(&hints_size, 1, sizeof(long), hints_file); hints_size = (!bigendian)?SWAP(hints_size):hints_size; fread(hints_buffer, 1, hints_size, hints_file); }/***************************************************************************** * Encode and decode this frame ****************************************************************************/ enctime = msecond(); status = enc_main(in_buffer, mp4_buffer, hints_buffer, &m4v_size, &frame_type, &hints_size); enctime = msecond() - enctime; totalenctime += enctime; totalsize += m4v_size; printf("Frame %5d: intra %1d, enctime=%6.1f ms, size=%6dbytes\n", (int)filenr, (int)frame_type, (float)enctime, (int)m4v_size);/***************************************************************************** * Save hints to file ****************************************************************************/ if(ARG_HINTMODE == HINT_MODE_GET) { hints_size = (!bigendian)?SWAP(hints_size):hints_size; fwrite(&hints_size, 1, sizeof(long), hints_file); hints_size = (!bigendian)?SWAP(hints_size):hints_size; fwrite(hints_buffer, 1, hints_size, hints_file); }/***************************************************************************** * Save stream to file ****************************************************************************/ if (ARG_SAVEMPEGSTREAM) { /* Save single files */ if (out_file == NULL) { sprintf(filename, "%sframe%05d.m4v", filepath, filenr); out_file = fopen(filename, "wb"); fwrite(mp4_buffer, m4v_size, 1, out_file); fclose(out_file); out_file = NULL; } else { /* Using mp4u container */ if (ARG_OUTPUTTYPE) { long size = m4v_size; size = (!bigendian)?SWAP(size):size; fwrite(&size, sizeof(size), 1, out_file); } /* Write mp4 data */ fwrite(mp4_buffer, m4v_size, 1, out_file); } } /* Read the header if it's pgm stream */ if (ARG_INPUTTYPE) status = read_pgmheader(in_file); filenr++; } while ( (!status) && (filenr<ARG_MAXFRAMENR) ); /***************************************************************************** * Calculate totals and averages for output, print results ****************************************************************************/ totalsize /= filenr; totalenctime /= filenr; printf("Avg: enctime %5.2f ms, %5.2f fps, filesize %7d bytes\n", totalenctime, 1000/totalenctime, (int)totalsize);/***************************************************************************** * XviD PART Stop ****************************************************************************/ release_all: if (enc_handle) { status = enc_stop(); if (status) fprintf(stderr, "Encore RELEASE problem return value %d\n", status); } if(in_file) fclose(in_file); if(out_file) fclose(out_file); if(hints_file) fclose(hints_file); free_all_memory: free(out_buffer); free(mp4_buffer); free(in_buffer); if(hints_buffer) free(hints_buffer); return 0;}/***************************************************************************** * "statistical" functions * * these are not needed for encoding or decoding, but for measuring * time and quality, there in nothing specific to XviD in these * *****************************************************************************//* Return time elapsed time in miliseconds since the program started */static double msecond(){ #ifndef WIN32 struct timeval tv; gettimeofday(&tv, 0); return tv.tv_sec*1.0e3 + tv.tv_usec * 1.0e-3;#else clock_t clk; clk = clock(); return clk * 1000 / CLOCKS_PER_SEC;#endif}/***************************************************************************** * Usage message *****************************************************************************/static void usage(){ fprintf(stderr, "Usage : xvid_encraw [OPTIONS]\n"); fprintf(stderr, "Options :\n"); fprintf(stderr, " -asm : use assembly code\n"); fprintf(stderr, " -w integer : frame width ([1.2048])\n"); fprintf(stderr, " -h integer : frame height ([1.2048])\n"); fprintf(stderr, " -b integer : target bitrate (>0 | default=900kbit)\n"); fprintf(stderr, " -f float : target framerate (>0)\n"); fprintf(stderr, " -i string : input filename (default=stdin)\n"); fprintf(stderr, " -t integer : input data type (yuv=0, pgm=1)\n"); fprintf(stderr, " -n integer : number of frames to encode\n"); fprintf(stderr, " -q integer : quality ([0..5])\n"); fprintf(stderr, " -m boolean : save mpeg4 raw stream (0 False*, !=0 True)\n"); fprintf(stderr, " -o string : output container filename (only usefull when -m 1 is used) :\n"); fprintf(stderr, " When this option is not used : one file per encoded frame\n"); fprintf(stderr, " When this option is used :\n"); fprintf(stderr, " + stream.m4v with -mt 0\n"); fprintf(stderr, " + stream.mp4u with -mt 1\n"); fprintf(stderr, " -mt integer : output type (m4v=0, mp4u=1)\n"); fprintf(stderr, " -mv integer : Use motion vector hints (no hints=0, get hints=1, set hints=2)\n"); fprintf(stderr, " -help : prints this help message\n"); fprintf(stderr, " -quant integer : fixed quantizer (disables -b setting)\n"); fprintf(stderr, " (* means default)\n");}/***************************************************************************** * Input and output functions * * the are small and simple routines to read and write PGM and YUV * image. It's just for convenience, again nothing specific to XviD * *****************************************************************************/static int read_pgmheader(FILE* handle){ int bytes,xsize,ysize,depth; char dummy[2]; bytes = fread(dummy,1,2,handle); if ( (bytes < 2) || (dummy[0] != 'P') || (dummy[1] != '5' )) return 1; fscanf(handle,"%d %d %d",&xsize,&ysize,&depth); if ( (xsize > 1440) || (ysize > 2880 ) || (depth != 255) ) { fprintf(stderr,"%d %d %d\n",xsize,ysize,depth); return 2; } if ( (XDIM==0) || (YDIM==0) ) { XDIM=xsize; YDIM=ysize*2/3; } return 0;}static int read_pgmdata(FILE* handle, unsigned char *image){ int i; char dummy; unsigned char *y = image; unsigned char *u = image + XDIM*YDIM; unsigned char *v = image + XDIM*YDIM + XDIM/2*YDIM/2; /* read Y component of picture */ fread(y, 1, XDIM*YDIM, handle); for (i=0;i<YDIM/2;i++) { /* read U */ fread(u, 1, XDIM/2, handle); /* read V */ fread(v, 1, XDIM/2, handle); /* Update pointers */ u += XDIM/2; v += XDIM/2; } /* I don't know why, but this seems needed */ fread(&dummy, 1, 1, handle); return 0;}static int read_yuvdata(FILE* handle, unsigned char *image){ if (fread(image, 1, IMAGE_SIZE(XDIM, YDIM), handle) != (unsigned int)IMAGE_SIZE(XDIM, YDIM)) return 1; else return 0;}/***************************************************************************** * Routines for encoding: init encoder, frame step, release encoder ****************************************************************************/#define FRAMERATE_INCR 1001/* Initialize encoder for first use, pass all needed parameters to the codec */static int enc_init(int use_assembler){ int xerr; XVID_INIT_PARAM xinit; XVID_ENC_PARAM xparam; if(use_assembler) {#ifdef ARCH_IA64 xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;#else xinit.cpu_flags = 0;#endif } else { xinit.cpu_flags = XVID_CPU_FORCE; } xvid_init(NULL, 0, &xinit, NULL); xparam.width = XDIM; xparam.height = YDIM; if ((ARG_FRAMERATE - (int)ARG_FRAMERATE) < SMALL_EPS) { xparam.fincr = 1; xparam.fbase = (int)ARG_FRAMERATE; } else { xparam.fincr = FRAMERATE_INCR; xparam.fbase = (int)(FRAMERATE_INCR * ARG_FRAMERATE); } xparam.rc_reaction_delay_factor = 16; xparam.rc_averaging_period = 100; xparam.rc_buffer = 10; xparam.rc_bitrate = ARG_BITRATE*1000; xparam.min_quantizer = ARG_MINQUANT; xparam.max_quantizer = ARG_MAXQUANT; xparam.max_key_interval = (int)ARG_FRAMERATE*10; /* I use a small value here, since will not encode whole movies, but short clips */ xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xparam, NULL); enc_handle=xparam.handle; return xerr;}static int enc_stop(){ int xerr; xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL); return xerr;}static int enc_main(unsigned char* image, unsigned char* bitstream, unsigned char* hints_buffer, long *streamlength, long *frametype, long *hints_size){ int xerr; XVID_ENC_FRAME xframe; XVID_ENC_STATS xstats; xframe.bitstream = bitstream; xframe.length = -1; /* this is written by the routine */ xframe.image = image; xframe.colorspace = XVID_CSP_YV12; /* defined in <xvid.h> */ xframe.intra = -1; /* let the codec decide between I-frame (1) and P-frame (0) */ xframe.quant = ARG_QUANTI; /* is quant != 0, use a fixed quant (and ignore bitrate) */ xframe.motion = motion_presets[ARG_QUALITY]; xframe.general = general_presets[ARG_QUALITY]; xframe.quant_intra_matrix = xframe.quant_inter_matrix = NULL; xframe.hint.hintstream = hints_buffer; if(ARG_HINTMODE == HINT_MODE_SET) { xframe.hint.hintlength = *hints_size; xframe.hint.rawhints = 0; xframe.general |= XVID_HINTEDME_SET; } if(ARG_HINTMODE == HINT_MODE_GET) { xframe.hint.rawhints = 0; xframe.general |= XVID_HINTEDME_GET; } xerr = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xframe, &xstats); if(ARG_HINTMODE == HINT_MODE_GET) *hints_size = xframe.hint.hintlength; /* * This is statictical data, e.g. for 2-pass. If you are not * interested in any of this, you can use NULL instead of &xstats */ *frametype = xframe.intra; *streamlength = xframe.length; return xerr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -