📄 xvid_decraw.c
字号:
/***************************************************************************** * * XVID MPEG-4 VIDEO CODEC * - Console based decoding test application - * * Copyright(C) 2002-2003 Christoph Lampert * 2002-2003 Edouard Gomez <ed.gomez@free.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: xvid_decraw.c,v 1.1 2006/02/23 15:13:25 kevin-fu Exp $ * ****************************************************************************//***************************************************************************** * * Application notes : * * An MPEG-4 bitstream is read from an input file (or stdin) and decoded, * the speed for this is measured. * * The program is plain C and needs no libraries except for libxvidcore, * and maths-lib. * * Use ./xvid_decraw -help for a list of options * ****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#ifndef WIN32#include <sys/time.h>#else#include <time.h>#endif#include "xvid.h"/***************************************************************************** * Global vars in module and constants ****************************************************************************/#define USE_PNM 0#define USE_TGA 1static int XDIM = 0;static int YDIM = 0;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;#define MIN_USEFUL_BYTES 1/***************************************************************************** * Local prototypes ****************************************************************************/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";}/***************************************************************************** * Main program ****************************************************************************/int main(int argc, char *argv[]){ unsigned char *mp4_buffer = NULL; unsigned char *mp4_ptr = NULL; unsigned char *out_buffer = NULL; int useful_bytes; int chunk; xvid_dec_stats_t xvid_dec_stats; double totaldectime; long totalsize; int status; int use_assembler = 0; int debug_level = 0; char filename[256]; FILE *in_file; int filenr; int i; printf("xvid_decraw - raw mpeg4 bitstream decoder "); printf("written by Christoph Lampert 2002-2003\n\n");/***************************************************************************** * Command line parsing ****************************************************************************/ 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("-m", argv[i]) == 0) { ARG_SAVEMPEGSTREAM = 1; } 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 { usage(); exit(-1); } } #if defined(_MSC_VER) if (ARG_INPUTFILE==NULL) { fprintf(stderr, "Warning: MSVC build does not read EOF correctly from stdin. Use the -i switch.\n\n"); }#endif/***************************************************************************** * Values checking ****************************************************************************/ if ( ARG_INPUTFILE == NULL || strcmp(ARG_INPUTFILE, "stdin") == 0) { in_file = stdin; } else { 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 allocation ****************************************************************************/ /* Memory for encoded mp4 stream */ mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE); mp4_ptr = mp4_buffer; if (!mp4_buffer) goto free_all_memory; /***************************************************************************** * 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 */ useful_bytes = fread(mp4_buffer, 1, BUFFER_SIZE, in_file); totaldectime = 0; totalsize = 0; filenr = 0; mp4_ptr = mp4_buffer; chunk = 0; do { int used_bytes = 0; double dectime; /* * 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); } /* 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; /* Resize image buffer if needed */ if(xvid_dec_stats.type == XVID_TYPE_VOL) { /* Check if old buffer is smaller */ if(XDIM*YDIM < xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height) { /* Copy new witdh and new height from the vol structure */ XDIM = xvid_dec_stats.data.vol.width; YDIM = xvid_dec_stats.data.vol.height; /* Free old output buffer*/ if(out_buffer) free(out_buffer); /* Allocate the new buffer */ out_buffer = (unsigned char*)malloc(XDIM*YDIM*4); if(out_buffer == NULL) goto free_all_memory; fprintf(stderr, "Resized frame buffer to %dx%d\n", XDIM, YDIM); } /* Save individual mpeg4 stream if required */ if(ARG_SAVEMPEGSTREAM) { FILE *filehandle = NULL; sprintf(filename, "%svolhdr.m4v", filepath); filehandle = fopen(filename, "wb"); if(!filehandle) { fprintf(stderr, "Error writing vol header mpeg4 stream to file %s\n", filename); } else { fwrite(mp4_ptr, 1, used_bytes, filehandle); fclose(filehandle); } } } /* Update buffer pointers */ if(used_bytes > 0) { mp4_ptr += used_bytes; useful_bytes -= used_bytes; /* Total size */ totalsize += used_bytes; } if (display_buffer_bytes) { printf("Data chunk %d: %d bytes consumed, %d bytes in buffer\n", chunk++, used_bytes, useful_bytes); } } while (xvid_dec_stats.type <= 0 && useful_bytes > MIN_USEFUL_BYTES); /* 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; 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 individual mpeg4 stream if required */ if(ARG_SAVEMPEGSTREAM) { FILE *filehandle = NULL; sprintf(filename, "%sframe%05d.m4v", filepath, filenr); filehandle = fopen(filename, "wb"); if(!filehandle) { fprintf(stderr, "Error writing single mpeg4 stream to file %s\n", filename); } else { fwrite(mp4_ptr-used_bytes, 1, used_bytes, filehandle); fclose(filehandle); } } /* 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++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -