📄 xvid_encraw.c
字号:
} else {#ifdef XVID_AVI_INPUT if (strcmp(ARG_INPUTFILE+(strlen(ARG_INPUTFILE)-3), "avs")==0 || strcmp(ARG_INPUTFILE+(strlen(ARG_INPUTFILE)-3), "avi")==0 || ARG_INPUTTYPE==2) { AVISTREAMINFO avi_info; AVIFileInit(); if (AVIStreamOpenFromFile(&avi_stream, ARG_INPUTFILE, streamtypeVIDEO, 0, OF_READ, NULL) != AVIERR_OK) { fprintf(stderr, "Can't open stream from file '%s'!\n", ARG_INPUTFILE); AVIFileExit(); return (-1); } if(AVIStreamInfo(avi_stream, &avi_info, sizeof(AVISTREAMINFO)) != AVIERR_OK) { fprintf(stderr, "Can't get stream info from file '%s'!\n", ARG_INPUTFILE); AVIStreamRelease(avi_stream); AVIFileExit(); return (-1); } if (avi_info.fccHandler != MAKEFOURCC('Y', 'V', '1', '2')) { fprintf(stderr, "Unsupported input colorspace! Only YV12 is supported!\n"); AVIStreamRelease(avi_stream); AVIFileExit(); return (-1); } ARG_MAXFRAMENR = min(ARG_MAXFRAMENR, avi_info.dwLength); XDIM = avi_info.rcFrame.right - avi_info.rcFrame.left; YDIM = avi_info.rcFrame.bottom - avi_info.rcFrame.top; ARG_FRAMERATE = (float) avi_info.dwRate / (float) avi_info.dwScale; ARG_INPUTTYPE = 2; } else#endif { in_file = fopen(ARG_INPUTFILE, "rb"); if (in_file == NULL) { fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE); return (-1); } } } if (ARG_INPUTTYPE==1) {#ifndef READ_PNM if (read_pgmheader(in_file)) {#else if (read_pnmheader(in_file)) {#endif fprintf(stderr, "Wrong input format, I want YUV encapsulated in PGM\n"); return (-1); } } /* now we know the sizes, so allocate memory */ in_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM, YDIM)); if (!in_buffer) goto free_all_memory; /* this should really be enough memory ! */ mp4_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM, YDIM) * 2); if (!mp4_buffer) goto free_all_memory;/***************************************************************************** * XviD PART Start ****************************************************************************/ result = enc_init(use_assembler); if (result) { fprintf(stderr, "Encore INIT problem, return value %d\n", result); goto release_all; }/***************************************************************************** * Main loop ****************************************************************************/ if (ARG_SAVEMPEGSTREAM && ARG_OUTPUTFILE) { if ((out_file = fopen(ARG_OUTPUTFILE, "w+b")) == NULL) { fprintf(stderr, "Error opening output file %s\n", ARG_OUTPUTFILE); goto release_all; } } else { out_file = NULL; }/***************************************************************************** * Encoding loop ****************************************************************************/ totalsize = 0; result = 0; input_num = 0; /* input frame counter */ output_num = 0; /* output frame counter */ do { char *type; int sse[3]; if (input_num >= ARG_MAXFRAMENR) { result = 1; } if (!result) {#ifdef XVID_AVI_INPUT if (ARG_INPUTTYPE==2) { /* read avs/avi data (YUV-format) */ if(AVIStreamRead(avi_stream, input_num, 1, in_buffer, IMAGE_SIZE(XDIM, YDIM), NULL, NULL ) != AVIERR_OK) result = 1; } else#endif if (ARG_INPUTTYPE==1) { /* read PGM data (YUV-format) */#ifndef READ_PNM result = read_pgmdata(in_file, in_buffer);#else result = read_pnmdata(in_file, in_buffer);#endif } else { /* read raw data (YUV-format) */ result = read_yuvdata(in_file, in_buffer); } }/***************************************************************************** * Encode and decode this frame ****************************************************************************/ enctime = msecond(); m4v_size = enc_main(!result ? in_buffer : 0, mp4_buffer, &key, &stats_type, &stats_quant, &stats_length, sse); enctime = msecond() - enctime; /* Write the Frame statistics */ printf("%5d: key=%i, time= %6.0f, len= %7d", !result ? input_num : -1, key, (float) enctime, (int) m4v_size); if (stats_type > 0) { /* !XVID_TYPE_NOTHING */ switch (stats_type) { case XVID_TYPE_IVOP: type = "I"; break; case XVID_TYPE_PVOP: type = "P"; break; case XVID_TYPE_BVOP: type = "B"; break; case XVID_TYPE_SVOP: type = "S"; break; default: type = "U"; break; } printf(" | type=%s, quant= %2d, len= %7d", type, stats_quant, stats_length);#define SSE2PSNR(sse, width, height) ((!(sse))?0.0f : 48.131f - 10*(float)log10((float)(sse)/((float)((width)*(height))))) if (ARG_STATS) { printf(", psnr y = %2.2f, psnr u = %2.2f, psnr v = %2.2f", SSE2PSNR(sse[0], XDIM, YDIM), SSE2PSNR(sse[1], XDIM / 2, YDIM / 2), SSE2PSNR(sse[2], XDIM / 2, YDIM / 2)); totalPSNR[0] += SSE2PSNR(sse[0], XDIM, YDIM); totalPSNR[1] += SSE2PSNR(sse[1], XDIM/2, YDIM/2); totalPSNR[2] += SSE2PSNR(sse[2], XDIM/2, YDIM/2); } }#undef SSE2PSNR printf("\n"); if (m4v_size < 0) { break; } /* Update encoding time stats */ totalenctime += enctime; totalsize += m4v_size;/***************************************************************************** * Save stream to file ****************************************************************************/ if (m4v_size > 0 && ARG_SAVEMPEGSTREAM) { /* Save single files */ if (ARG_SAVEINDIVIDUAL) { FILE *out; sprintf(filename, "%sframe%05d.m4v", filepath, output_num); out = fopen(filename, "w+b"); fwrite(mp4_buffer, m4v_size, 1, out); fclose(out); output_num++; } /* Save ES stream */ if (ARG_OUTPUTFILE && out_file) fwrite(mp4_buffer, 1, m4v_size, out_file); } input_num++; /* Read the header if it's pgm stream */ if (!result && (ARG_INPUTTYPE==1))#ifndef READ_PNM result = read_pgmheader(in_file);#else result = read_pnmheader(in_file);#endif } while (1);/***************************************************************************** * Calculate totals and averages for output, print results ****************************************************************************/ printf("Tot: enctime(ms) =%7.2f, length(bytes) = %7d\n", totalenctime, (int) totalsize); if (input_num > 0) { totalsize /= input_num; totalenctime /= input_num; totalPSNR[0] /= input_num; totalPSNR[1] /= input_num; totalPSNR[2] /= input_num; } else { totalsize = -1; totalenctime = -1; } printf("Avg: enctime(ms) =%7.2f, fps =%7.2f, length(bytes) = %7d", totalenctime, 1000 / totalenctime, (int) totalsize); if (ARG_STATS) { printf(", psnr y = %2.2f, psnr u = %2.2f, psnr v = %2.2f", totalPSNR[0],totalPSNR[1],totalPSNR[2]); } printf("\n");/***************************************************************************** * XviD PART Stop ****************************************************************************/ release_all:#ifdef XVID_AVI_INPUT if (avi_stream) { AVIStreamRelease(avi_stream); AVIFileExit(); }#endif if (enc_handle) { result = enc_stop(); if (result) fprintf(stderr, "Encore RELEASE problem return value %d\n", result); } if (in_file) fclose(in_file); if (out_file) fclose(out_file); free_all_memory: free(out_buffer); free(mp4_buffer); free(in_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 doublemsecond(){#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.0 / CLOCKS_PER_SEC);#endif}/***************************************************************************** * Usage message *****************************************************************************/static voidusage(){ fprintf(stderr, "Usage : xvid_stat [OPTIONS]\n\n"); fprintf(stderr, "Input options:\n"); fprintf(stderr, " -i string : input filename (default=stdin)\n");#ifdef XVID_AVI_INPUT fprintf(stderr, " -type integer: input data type (yuv=0, pgm=1, avi/avs=2)\n");#else fprintf(stderr, " -type integer: input data type (yuv=0, pgm=1)\n");#endif fprintf(stderr, " -w integer: frame width ([1.2048])\n"); fprintf(stderr, " -h integer: frame height ([1.2048])\n"); fprintf(stderr, " -frames integer: number of frames to encode\n"); fprintf(stderr, "\n"); fprintf(stderr, "Output options:\n"); fprintf(stderr, " -dump : save decoder output\n"); fprintf(stderr, " -save : save an Elementary Stream file per frame\n"); fprintf(stderr, " -o string: save an Elementary Stream for the complete sequence\n"); fprintf(stderr, "\n"); fprintf(stderr, "BFrames options:\n"); fprintf(stderr, " -max_bframes integer: max bframes (default=0)\n"); fprintf(stderr, " -bquant_ratio integer: bframe quantizer ratio (default=150)\n"); fprintf(stderr, " -bquant_offset integer: bframe quantizer offset (default=100)\n"); fprintf(stderr, "\n"); fprintf(stderr, "Rate control options:\n"); fprintf(stderr, " -framerate float : target framerate (>0 | default=25.0)\n"); fprintf(stderr, " -bitrate integer : target bitrate\n"); fprintf(stderr, " -single : single pass mode\n"); fprintf(stderr, " -pass1 filename : twopass mode (first pass)\n"); fprintf(stderr, " -pass2 filename : twopass mode (2nd pass)\n"); fprintf(stderr, " -zq starting_frame float : bitrate zone; quant\n"); fprintf(stderr, " -zw starting_frame float : bitrate zone; weight\n"); fprintf(stderr, " -max_key_interval integer : maximum keyframe interval\n"); fprintf(stderr, "\n"); fprintf(stderr, "Other options\n"); fprintf(stderr, " -noasm : do not use assembly optmized code\n"); fprintf(stderr, " -turbo : use turbo presets for higher encoding speed\n"); fprintf(stderr, " -quality integer : quality ([0..%d])\n", ME_ELEMENTS - 1); fprintf(stderr, " -vhqmode integer : level of Rate-Distortion optimizations ([0..4]) (default=0)\n"); fprintf(stderr, " -bvhq : use Rate-Distortion optimizations for B-frames too\n"); fprintf(stderr, " -qpel : use quarter pixel ME\n"); fprintf(stderr, " -gmc : use global motion compensation\n"); fprintf(stderr, " -qtype integer : quantization type (H263:0, MPEG4:1) (default=0)\n"); fprintf(stderr, " -qmatrix filename: use custom MPEG4 quantization matrix\n"); fprintf(stderr, " -interlaced : use interlaced encoding (this is NOT a deinterlacer!)\n"); fprintf(stderr, " -packed : packed mode\n"); fprintf(stderr, " -closed_gop : closed GOP mode\n"); fprintf(stderr, " -grey : grey scale coding (chroma is discarded)\n"); fprintf(stderr, " -lumimasking : use lumimasking algorithm\n"); fprintf(stderr, " -stats : print stats about encoded frames\n"); fprintf(stderr, " -debug : activates xvidcore internal debugging output\n"); fprintf(stderr, " -vop_debug : print some info directly into encoded frames\n"); fprintf(stderr, " -help : prints this help message\n"); fprintf(stderr, "\n"); fprintf(stderr, "NB: You can define %d zones repeating the -z[qw] option as many times as needed.\n", MAX_ZONES); fprintf(stderr, "\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 * *****************************************************************************/#ifndef READ_PNMstatic intread_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 > 4096) || (ysize > 4096*3/2) || (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 intread_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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -