春山眉黛~xvid命令行参数学习

时间:2022-07-11 14:33:38

xvid.h

程序版本信息

很多XviD结构体都包含一个version成员,用于指定所采用的XviD的版本。正确的初始化方法是:先将结构体全部清空为0,然后再设置version成员。如下所示:
memset(&struct,0,sizeof(struct));
struct.version = XVID_VERSION;
与XviD版本有关的宏定义为:
#define XVID_MAKE_VERSION(a,b,c) ((((a)&0xff)<<16) | (((b)&0xff)<<8) | ((c)&0xff))
#define XVID_VERSION_MAJOR(a) ((char)(((a)>>16) & 0xff))
#define XVID_VERSION_MINOR(a) ((char)(((a)>> 8) & 0xff))
#define XVID_VERSION_PATCH(a) ((char)(((a)>> 0) & 0xff))
#define XVID_MAKE_API(a,b) ((((a)&0xff)<<16) | (((b)&0xff)<<0))
#define XVID_API_MAJOR(a) (((a)>>16) & 0xff)
#define XVID_API_MINOR(a) (((a)>> 0) & 0xff)
#define XVID_VERSION XVID_MAKE_VERSION(1,1,2)
#define XVID_API XVID_MAKE_API(4, 1)
XviD中存在两个版本,一个是XviD库本身的版本,即XVID_VERSION;另一个是
XviD应用编程接口(API)简介(v0.1) - 2 -
XviD的API接口的版本,即XVID_API。XVID_VERSION定义为一个24位的无符号整数;XVID_API定义为一个16位的无符号整数。
XVID_MAKE_VERSION(a,b,c)宏的作用是生成XVID_VERSION,其中a、b、c分别是XviD版本号中的$major、$minor和$patch。
XVID_VERSION_MAJOR(a) 用于从XVID_VERSION中抽取出$major;XVID_VERSION_MINOR(a)用于从XVID_VERSION中抽取 出$minor;XVID_VERSION_PATCH(a)用于从XVID_VERSION中抽取出$patch。

程序中的错误码

所有XviD函数都以返回小于0的值表明出现了错误。定义的错误码如下:
#define XVID_ERR_FAIL -1
#define XVID_ERR_MEMORY -2
#define XVID_ERR_FORMAT -3
#define XVID_ERR_VERSION -4
#define XVID_ERR_END -5
XVID_ERR_FAIL 表示一般性错误;XVID_ERR_MEMORY表示内存分配错误;XVID_ERR_FORMAT表示文件格式错误;XVID_ERR_VERSION 表明程序中使用了不再被支持的结构体版本;XVID_ERR_END是编码器独有的错误码,表示已经到达流末尾。

程序中的色彩空间

XviD中定义的色场空间如下:
#define XVID_CSP_PLANAR (1<< 0)
#define XVID_CSP_USER XVID_CSP_PLANAR
#define XVID_CSP_I420 (1<< 1)
#define XVID_CSP_YV12 (1<< 2)
#define XVID_CSP_YUY2 (1<< 3)
#define XVID_CSP_UYVY (1<< 4)
#define XVID_CSP_YVYU (1<< 5)
#define XVID_CSP_BGRA (1<< 6)
#define XVID_CSP_ABGR (1<< 7)
#define XVID_CSP_RGBA (1<< 8)
#define XVID_CSP_ARGB (1<<15)
#define XVID_CSP_BGR (1<< 9)
#define XVID_CSP_RGB555 (1<<10)
#define XVID_CSP_RGB565 (1<<11)

#define XVID_CSP_SLICE (1<<12)
#define XVID_CSP_INTERNAL (1<<13)
#define XVID_CSP_NULL (1<<14)
#define XVID_CSP_VFLIP (1<<31)
尽管XviD定义的色场空间比较多,但实际上常用的只有XVID_CSP_I420、XVID_CSP_YV12、XVID_CSP_BGR、XVID_CSP_RGB555、XVID_CSP_RGB565这样几种。
作 者个人的观点:XVID_CSP_PLANAR、XVID_CSP_USER、XVID_CSP_I420、XVID_CSP_YV12都属于 YUV4:2:0色场空间,采用YUV平面格式存放;XVID_CSP_YUY2、XVID_CSP_UYVY、XVID_CSP_YVYU都属于 YUV4:2:2色场空间,采用YUV紧缩格式存放。XviD似乎没有提供对YUV4:4:4和YUV4:1:1色场空间的支持——也可能是MPEG-4 标准不支持。无论如何,常用的YUV色场空间是YUV4:2:0。


xvid.c

程序默认的参数设置、

#define MAX_ZONES   64
#define MAX_ENC_INSTANCES 4
#define MAX_XDIM 4096
#define MAX_YDIM 4096
#define DEFAULT_QUANT 400
#define DEFAULT_BITRATE 700000 /* bitrate expressed in bps, not kbps */
#define DEFAULT_INTERLACING 1  /* 1:BFF, 2:TFF */
#define DEFAULT_SSIM 2
#define DEFAULT_PROGRESS 10    /* show progress every 10 frames by default */

可指定的参数

  if (strcmp("-asm", argv[i]) == 0) {    

use_assembler = 1;
} else if (strcmp("-noasm", argv[i]) == 0) {
use_assembler = 0;  //是否使用汇编优化
} 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]);   //视频的w宽和h高
} else if (strcmp("-csp",argv[i]) == 0 && i < argc - 1) {
i++;
if (strcmp(argv[i],"i420") == 0){
ARG_COLORSPACE = XVID_CSP_I420;
} else if(strcmp(argv[i],"yv12") == 0){
ARG_COLORSPACE = XVID_CSP_YV12;
} else {
printf("Invalid colorspace\n");
return 0;
}
} else if (strcmp("-bitrate", argv[i]) == 0) {
if (i < argc - 1)
ARG_BITRATE = atoi(argv[i+1]);
if (ARG_BITRATE) {
i++;
if (ARG_BITRATE <= 20000)
/* if given parameter is <= 20000, assume it means kbps */
ARG_BITRATE *= 1000;
}
else
ARG_BITRATE = DEFAULT_BITRATE;
} else if (strcmp("-size", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_TARGETSIZE = atoi(argv[i]);
        } else if (strcmp("-cq", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_CQ = atof(argv[i])*100;
} else if (strcmp("-single", argv[i]) == 0) {
ARG_SINGLE = 1;
ARG_PASS1 = NULL;
ARG_PASS2 = NULL;
} else if (strcmp("-pass1", argv[i]) == 0) {
ARG_SINGLE = 0;
if ((i < argc - 1) && (*argv[i+1] != '-')) {
i++;
ARG_PASS1 = argv[i];
} else {
ARG_PASS1 = "xvid.stats";
}
} else if (strcmp("-full1pass", argv[i]) == 0) {
ARG_FULL1PASS = 1;
} else if (strcmp("-pass2", argv[i]) == 0) {
ARG_SINGLE = 0;
if ((i < argc - 1) && (*argv[i+1] != '-')) {
i++;
ARG_PASS2 = argv[i];
} else {
ARG_PASS2 = "xvid.stats";
}
} else if (strcmp("-max_bframes", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_MAXBFRAMES = atoi(argv[i]);
} else if (strcmp("-par", argv[i]) == 0 && i < argc - 1) {
i++;
if (sscanf(argv[i], "%d:%d", &(ARG_PARWIDTH), &(ARG_PARHEIGHT))!=2)
ARG_PAR = atoi(argv[i]);
else {
int div;
ARG_PAR = 0;
div = gcd(ARG_PARWIDTH, ARG_PARHEIGHT);
ARG_PARWIDTH /= div;
ARG_PARHEIGHT /= div;
}
} else if (strcmp("-nopacked", argv[i]) == 0) {
ARG_PACKED = 0;
} else if (strcmp("-packed", argv[i]) == 0) {
ARG_PACKED = 2;
} else if (strcmp("-nochromame", argv[i]) == 0) {
ARG_CHROMAME = 0;
} else if (strcmp("-chromame", argv[i]) == 0) {
ARG_CHROMAME = 1;
} else if (strcmp("-threads", argv[i]) == 0 && i < argc -1) {
i++;
ARG_THREADS = atoi(argv[i]);
} else if (strcmp("-slices", argv[i]) == 0 && i < argc -1) {
i++;
ARG_SLICES = atoi(argv[i]);
} else if (strcmp("-bquant_ratio", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_BQRATIO = atoi(argv[i]);
} else if (strcmp("-bquant_offset", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_BQOFFSET = atoi(argv[i]);


} else if (strcmp("-zones", argv[i]) == 0 && i < argc -1) {
char c;
char *frameoptions, *rem;
int startframe;
char options[40];

i++;


do {
rem = strrchr(argv[i], '/');
if (rem==NULL)
rem=argv[i];
else {
*rem = '\0';
rem++;
}
if (sscanf(rem, "%d,%c,%s", &startframe, &c, options)<3) {
fprintf(stderr, "Zone error, bad parameters %s\n", rem);
continue;
}
if (NUM_ZONES >= MAX_ZONES) {
fprintf(stderr, "warning: too many zones; zone ignored\n");
continue;
}
memset(&ZONES[NUM_ZONES], 0, sizeof(zone_t));


ZONES[NUM_ZONES].frame = startframe;
ZONES[NUM_ZONES].modifier = (int)(atof(options)*100);
if (toupper(c)=='Q')
ZONES[NUM_ZONES].mode = XVID_ZONE_QUANT;
else if (toupper(c)=='W')
ZONES[NUM_ZONES].mode = XVID_ZONE_WEIGHT;
else {
fprintf(stderr, "Bad zone type %c\n", c);
continue;
}


if ((frameoptions=strchr(options, ','))!=NULL) {
int readchar=0, count;
frameoptions++;
while (readchar<(int)strlen(frameoptions)) {
if (sscanf(frameoptions+readchar, "%d%n", &(ZONES[NUM_ZONES].bvop_threshold), &count)==1) {
readchar += count;
}
else {
if (toupper(frameoptions[readchar])=='K')
ZONES[NUM_ZONES].type = XVID_TYPE_IVOP;
else if (toupper(frameoptions[readchar])=='G')
ZONES[NUM_ZONES].greyscale = 1;
else if (toupper(frameoptions[readchar])=='O')
ZONES[NUM_ZONES].chroma_opt = 1;
else if (toupper(frameoptions[readchar])=='C')
ZONES[NUM_ZONES].cartoon_mode = 1;
else {
fprintf(stderr, "Error in zone %s option %c\n", rem, frameoptions[readchar]);
break;
}
readchar++;
}
}
}
NUM_ZONES++;
} while (rem != argv[i]);




} else if ((strcmp("-zq", argv[i]) == 0 || strcmp("-zw", argv[i]) == 0) && i < argc - 2) {


            if (NUM_ZONES >= MAX_ZONES) {
                fprintf(stderr,"warning: too many zones; zone ignored\n");
                continue;
            }
memset(&ZONES[NUM_ZONES], 0, sizeof(zone_t));
if (strcmp("-zq", argv[i])== 0) {
ZONES[NUM_ZONES].mode = XVID_ZONE_QUANT;
}
else {
ZONES[NUM_ZONES].mode = XVID_ZONE_WEIGHT;
}
ZONES[NUM_ZONES].modifier = (int)(atof(argv[i+2])*100);
i++;
            ZONES[NUM_ZONES].frame = atoi(argv[i]);
i++;
ZONES[NUM_ZONES].type = XVID_TYPE_AUTO;
ZONES[NUM_ZONES].greyscale = 0;
ZONES[NUM_ZONES].chroma_opt = 0;
ZONES[NUM_ZONES].bvop_threshold = 0;
ZONES[NUM_ZONES].cartoon_mode = 0;


            NUM_ZONES++;
} else if (strcmp("-quality", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QUALITY = atoi(argv[i]);
} else if (strcmp("-start", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_STARTFRAMENR = atoi(argv[i]);
} else if (strcmp("-vhqmode", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_VHQMODE = atoi(argv[i]);
} else if (strcmp("-metric", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QMETRIC = atoi(argv[i]);
} else if (strcmp("-framerate", argv[i]) == 0 && i < argc - 1) {
int exponent;
i++;
ARG_FRAMERATE = (float) atof(argv[i]);
exponent = (int) strcspn(argv[i], ".");
if (exponent<(int)strlen(argv[i]))
exponent=(int)pow(10.0, (int)(strlen(argv[i])-1-exponent));
else
exponent=1;
ARG_DWRATE = (int)(atof(argv[i])*exponent);
ARG_DWSCALE = exponent;
exponent = gcd(ARG_DWRATE, ARG_DWSCALE);
ARG_DWRATE /= exponent;
ARG_DWSCALE /= exponent;
} else if (strcmp("-max_key_interval", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_MAXKEYINTERVAL = atoi(argv[i]);
} else if (strcmp("-i", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_INPUTFILE = argv[i];
} else if (strcmp("-stats", argv[i]) == 0) {
ARG_STATS = 1;
} else if (strcmp("-nostats", argv[i]) == 0) {
ARG_STATS = 0;
} else if (strcmp("-ssim", argv[i]) == 0) {
ARG_SSIM = DEFAULT_SSIM;
if ((i < argc - 1) && (*argv[i+1] != '-')) {
i++;
ARG_SSIM = atoi(argv[i]);
}
} else if (strcmp("-psnrhvsm", argv[i]) == 0) {
ARG_PSNRHVSM = 1;
} else if (strcmp("-nopsnrhvsm", argv[i]) == 0) {
ARG_PSNRHVSM = 0;
} else if (strcmp("-ssim_file", argv[i]) == 0 && i < argc -1) {
i++;
ARG_SSIM_PATH = argv[i];
} else if (strcmp("-timecode", argv[i]) == 0 && i < argc -1) {
i++;
ARG_TIMECODEFILE = argv[i];
} else if (strcmp("-dump", argv[i]) == 0) {
ARG_DUMP = 1;
} else if (strcmp("-masking", argv[i]) == 0 && i < argc -1) {
i++;
ARG_LUMIMASKING = atoi(argv[i]);
} else if (strcmp("-type", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_INPUTTYPE = atoi(argv[i]);
} else if (strcmp("-frames", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_MAXFRAMENR = atoi(argv[i]);
} else if (strcmp("-drop", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_FRAMEDROP = atoi(argv[i]);
} else if (strcmp("-imin", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QUANTS[0] = atoi(argv[i]);
} else if (strcmp("-imax", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QUANTS[1] = atoi(argv[i]);
} else if (strcmp("-pmin", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QUANTS[2] = atoi(argv[i]);
} else if (strcmp("-pmax", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QUANTS[3] = atoi(argv[i]);
} else if (strcmp("-bmin", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QUANTS[4] = atoi(argv[i]);
} else if (strcmp("-bmax", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QUANTS[5] = atoi(argv[i]);
} else if (strcmp("-qtype", argv[i]) == 0 && i < argc - 1) {
i++;
ARG_QTYPE = atoi(argv[i]);
} else if (strcmp("-qmatrix", argv[i]) == 0 && i < argc - 1) {
FILE *fp = fopen(argv[++i], "rb");
if (fp == NULL) {
fprintf(stderr, "Error opening input file %s\n", argv[i]);
return (-1);
}
fseek(fp, 0, SEEK_END);
if (ftell(fp) != 128) {
fprintf(stderr, "Unexpected size of input file %s\n", argv[i]);
return (-1);
}


fseek(fp, 0, SEEK_SET);
fread(qmatrix_intra, 1, 64, fp);
fread(qmatrix_inter, 1, 64, fp);


ARG_QMATRIX = 1;
ARG_QTYPE = 1;
} else if (strcmp("-save", argv[i]) == 0) {
ARG_SAVEMPEGSTREAM = 1;
ARG_SAVEINDIVIDUAL = 1;
} else if (strcmp("-debug", argv[i]) == 0 && i < argc -1) {
i++;
            if (!(sscanf(argv[i],"0x%x", &(ARG_DEBUG)))) 
sscanf(argv[i],"%d", &(ARG_DEBUG));
} else if (strcmp("-o", argv[i]) == 0 && i < argc - 1) {
ARG_SAVEMPEGSTREAM = 1;
i++;
ARG_OUTPUTFILE = argv[i];
} else if (strcmp("-avi", argv[i]) == 0 && i < argc - 1) {
#ifdef XVID_AVI_OUTPUT
ARG_SAVEMPEGSTREAM = 1;
i++;
ARG_AVIOUTPUTFILE = argv[i];
#else
fprintf( stderr, "Not compiled with AVI output support.\n");
return(-1);
#endif
} else if (strcmp("-mkv", argv[i]) == 0 && i < argc - 1) {
#ifdef XVID_MKV_OUTPUT
ARG_SAVEMPEGSTREAM = 1;
i++;
ARG_MKVOUTPUTFILE = argv[i];
#else
fprintf(stderr, "Not compiled with MKV output support.\n");
return(-1);
#endif
} else if (strcmp("-vop_debug", argv[i]) == 0) {
ARG_VOPDEBUG = 1;
} else if (strcmp("-novop_debug", argv[i]) == 0) {
ARG_VOPDEBUG = 0;
} else if (strcmp("-trellis", argv[i]) == 0) {
ARG_TRELLIS = 1;
} else if (strcmp("-notrellis", argv[i]) == 0) {
ARG_TRELLIS = 0;
} else if (strcmp("-bvhq", argv[i]) == 0) {
ARG_BVHQ = 1;
} else if (strcmp("-nobvhq", argv[i]) == 0) {
ARG_BVHQ = 0;
} else if (strcmp("-qpel", argv[i]) == 0) {
ARG_QPEL = 1;
} else if (strcmp("-noqpel", argv[i]) == 0) {
ARG_QPEL = 0;
} else if (strcmp("-turbo", argv[i]) == 0) {
ARG_TURBO = 1;
} else if (strcmp("-noturbo", argv[i]) == 0) {
ARG_TURBO = 0;
} else if (strcmp("-gmc", argv[i]) == 0) {
ARG_GMC = 1;
} else if (strcmp("-nogmc", argv[i]) == 0) {
ARG_GMC = 0;
} else if (strcmp("-interlaced", argv[i]) == 0) {
if ((i < argc - 1) && (*argv[i+1] != '-')) {
i++;
ARG_INTERLACING = atoi(argv[i]);
} else {
ARG_INTERLACING = DEFAULT_INTERLACING;
}
} else if (strcmp("-noclosed_gop", argv[i]) == 0) {
ARG_CLOSED_GOP = 0;
} else if (strcmp("-closed_gop", argv[i]) == 0) {
ARG_CLOSED_GOP = 2;
} else if (strcmp("-vbvsize", argv[i]) == 0 && i < argc -1) {
i++;
ARG_VBVSIZE = atoi(argv[i]);
} else if (strcmp("-vbvmax", argv[i]) == 0 && i < argc -1) {
i++;
ARG_VBVMAXRATE = atoi(argv[i]);
} else if (strcmp("-vbvpeak", argv[i]) == 0 && i < argc -1) {
i++;
ARG_VBVPEAKRATE = atoi(argv[i]);
} else if (strcmp("-reaction", argv[i]) == 0 && i < argc -1) {
i++;
ARG_REACTION = atoi(argv[i]);
} else if (strcmp("-averaging", argv[i]) == 0 && i < argc -1) {
i++;
ARG_AVERAGING = atoi(argv[i]);
} else if (strcmp("-smoother", argv[i]) == 0 && i < argc -1) {
i++;
ARG_SMOOTHER = atoi(argv[i]);
} else if (strcmp("-kboost", argv[i]) == 0 && i < argc -1) {
i++;
ARG_KBOOST = atoi(argv[i]);
} else if (strcmp("-kthresh", argv[i]) == 0 && i < argc -1) {
i++;
ARG_KTHRESH = atoi(argv[i]);
} else if (strcmp("-chigh", argv[i]) == 0 && i < argc -1) {
i++;
ARG_CHIGH = atoi(argv[i]);
} else if (strcmp("-clow", argv[i]) == 0 && i < argc -1) {
i++;
ARG_CLOW = atoi(argv[i]);
} else if (strcmp("-ostrength", argv[i]) == 0 && i < argc -1) {
i++;
ARG_OVERSTRENGTH = atoi(argv[i]);
} else if (strcmp("-oimprove", argv[i]) == 0 && i < argc -1) {
i++;
ARG_OVERIMPROVE = atoi(argv[i]);
} else if (strcmp("-odegrade", argv[i]) == 0 && i < argc -1) {
i++;
ARG_OVERDEGRADE = atoi(argv[i]);
} else if (strcmp("-overhead", argv[i]) == 0 && i < argc -1) {
i++;
ARG_OVERHEAD = atoi(argv[i]);
} else if (strcmp("-kreduction", argv[i]) == 0 && i < argc -1) {
i++;
ARG_KREDUCTION = atoi(argv[i]);
        } else if (strcmp("-progress", argv[i]) == 0) {
if (i < argc - 1)
/* in kbps */
ARG_PROGRESS = atoi(argv[i+1]);
if (ARG_PROGRESS > 0)
i++;
else
ARG_PROGRESS = DEFAULT_PROGRESS;
} else if (strcmp("-help", argv[i]) == 0) {
    if (i < argc - 1 && strcmp("zones", argv[i+1]) == 0) {
fprintf(stderr, "Zones options\n\
NB: You can define up to %d zones using the -zones option as described below.\n\
\n\
 -zones start,mode,value[,options][/start,mode,value[,options]]...\n\
\n\
 Parameters of a zone use the comma (,) as a delimiter. Multiple zones are\n\
 separated by a slash (/). The end of each zone is defined by either the start\n\
 of the following zone or the last frame of the input file.\n\
\n\
 start     : start frame of the zone\n\
 mode      : weight zone = w, quantizer zone = q\n\
 value     : depending on mode either the zone's weight or quantizer\n\
 options   : enable certain encoder features for the zone. Each feature is\n\
             represented by a single letter. An integer number stands for\n\
             b-frame sensitivity. To enable multiple features at the same time\n\
             combine the appropriate symbols without any delimiting characters.\n\
             K = begin with keyframe\n\
             O = enable chroma optimizer\n\
             G = greyscale encoding\n\
             C = cartoon mode\n\
       integer = b-frame sensitivity\n\
\n\
 Example:\n\
  to create a first zone starting at frame 0 with weight 1.0, all options\n\
  enabled and b-frame sensitivity -5, and a second zone starting at frame 1000\n\
  with constant quant 4 and no options enabled you would use the -zones option\n\
  like this:\n\
\n\
  -zones 0,w,1.0,-5KOGC/1000,q,4\n\n", MAX_ZONES);
} else
usage();
return (0);
} else {
usage();
exit(-1);
}


}