XVID,X264等是MPEG4、H264标准的开源编码器,其中X264只有编码部分,解码部分需要FFMPEG完成;XVID有编解码部分,其中解码亦可以利用FFMPEG中的MPEG4完成解码。视频压缩算法的计算复杂度,都是比较高的。其中具有最大计算复杂度有三部分:宏块搜素运动补偿部分、码率控制部分、滤波算法部分;这三部分占据了算法复杂度的绝大部分资源。
XVID参数解释:
参数的设置集中在FFMPEG中的libxvidff.C中的 ff_xvid_encode_init()函数里面,主要是对编码上下文进行初始化赋值操作,此函数中的宏定义在XVID.H之中:
ff_xvid_encode_init(AVCodecContext *avctx)  {
    int xerr, i;
    int xvid_flags = avctx->flags;
    xvid_context_t *x = avctx->priv_data;
    uint16_t *intra, *inter;
    int fd;

xvid_plugin_single_t single;
    xvid_ff_pass1_t rc2pass1;
    xvid_plugin_2pass2_t rc2pass2;
    xvid_gbl_init_t xvid_gbl_init;
    xvid_enc_create_t xvid_enc_create;
    xvid_enc_plugin_t plugins[7];

/* Bring in VOP flags from ffmpeg command-line */
    x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ 半像素运动插值
    if( xvid_flags & CODEC_FLAG_4MV )
        x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */每个宏块分配四个运动矢量
    if( xvid_flags & CODEC_FLAG_TRELLIS_QUANT)
        x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */
    if( xvid_flags & CODEC_FLAG_AC_PRED )
        x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 * /高质量的AC预测
    if( xvid_flags & CODEC_FLAG_GRAY )
        x->vop_flags |= XVID_VOP_GREYSCALE;

/* Decide which ME quality setting to use */
    x->me_flags = 0;
    switch( avctx->me_method ) { //宏块搜索区域,搜索算法
       case ME_FULL:   /* Quality 6 */
           x->me_flags |=  XVID_ME_EXTSEARCH16/* extend PMV by more searches */
                       |   XVID_ME_EXTSEARCH8;/* use diamond/square for extended 8x8 search */

case ME_EPZS:   /* Quality 4 */
           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND8/* use advdiamond for XVID_ME_EXTSEARCH8 */
                       |   XVID_ME_HALFPELREFINE8
                       |   XVID_ME_CHROMA_PVOP/* also use chroma for P_VOP/S_VOP ME */
                       |   XVID_ME_CHROMA_BVOP;/* also use chroma for B_VOP ME */

case ME_LOG:    /* Quality 2 */
       case ME_PHODS:
       case ME_X1:
           x->me_flags |=  XVID_ME_ADVANCEDDIAMOND16/* use advdiamonds instead of diamonds as search pattern */
                       |   XVID_ME_HALFPELREFINE16;

case ME_ZERO:   /* Quality 0 */
       default:
           break;
    }

/* Decide how we should decide blocks */
    switch( avctx->mb_decision ) { //是否选择码率控制方式 avctx->mb_decision=1时,编码一帧时间迅速增加
       case 2:
           x->vop_flags |= XVID_VOP_MODEDECISION_RD;
           x->me_flags |=  XVID_ME_HALFPELREFINE8_RD
                       |   XVID_ME_QUARTERPELREFINE8_RD
                       |   XVID_ME_EXTSEARCH_RD
                       |   XVID_ME_CHECKPREDICTION_RD;
       case 1:
           if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) )
               x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD;
           x->me_flags |=  XVID_ME_HALFPELREFINE16_RD
                       |   XVID_ME_QUARTERPELREFINE16_RD;

default:
           break;
    }

/* Bring in VOL flags from ffmpeg command-line */
    x->vol_flags = 0;
    if( xvid_flags & CODEC_FLAG_GMC ) {
        x->vol_flags |= XVID_VOL_GMC;
        x->me_flags |= XVID_ME_GME_REFINE;
    }
    if( xvid_flags & CODEC_FLAG_QPEL ) { //是否允许1/4像素
        x->vol_flags |= XVID_VOL_QUARTERPEL;
        x->me_flags |= XVID_ME_QUARTERPELREFINE16;
        if( x->vop_flags & XVID_VOP_INTER4V )
            x->me_flags |= XVID_ME_QUARTERPELREFINE8;
    }

memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
    xvid_gbl_init.version = XVID_VERSION;
    xvid_gbl_init.debug = 0;

#ifdef ARCH_POWERPC
    /* XviD's PPC support is borked, use libavcodec to detect */
#if HAVE_ALTIVEC==1
    if( has_altivec() ) {
        xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC;
    } else
#endif
        xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
#else
    /* XviD can detect on x86 */
    xvid_gbl_init.cpu_flags = 0;
#endif

/* Initialize */
    xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);

/* Create the encoder reference */
    memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
    xvid_enc_create.version = XVID_VERSION;

/* Store the desired frame size */
    xvid_enc_create.width = x->xsize = avctx->width; //图像宽度
    xvid_enc_create.height = x->ysize = avctx->height; //图像高度

/* XviD can determine the proper profile to use */
     xvid_enc_create.profile = XVID_PROFILE_S_L3; //  编码设定档次和级别 //压缩级别,MPEG4-ASP最高压缩级别

/* We don't use zones or threads */
    xvid_enc_create.zones = NULL;
    xvid_enc_create.num_zones = 0;
    xvid_enc_create.num_threads = 0;

xvid_enc_create.plugins = plugins;
    xvid_enc_create.num_plugins = 0;

/* Initialize Buffers */
    x->twopassbuffer = NULL;
    x->old_twopassbuffer = NULL;
    x->twopassfile = NULL;

if( xvid_flags & CODEC_FLAG_PASS1 ) {
   
        }
        x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0;

plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
        xvid_enc_create.num_plugins++;
    } else if( xvid_flags & CODEC_FLAG_PASS2 ) {//第二次编码,需要第一次编码生成的文件才可以完成第二次编码,不适用实时编码
        memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
        rc2pass2.version = XVID_VERSION;
        rc2pass2.bitrate = avctx->bit_rate;

close(fd);
        rc2pass2.filename = x->twopassfile;
        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
        plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
        xvid_enc_create.num_plugins++;
    } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) {
        /* Single Pass Bitrate Control! */
        memset(&single, 0, sizeof(xvid_plugin_single_t));
        single.version = XVID_VERSION;
        single.bitrate = avctx->bit_rate;

plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
        plugins[xvid_enc_create.num_plugins].param = &single;
        xvid_enc_create.num_plugins++;
    }

/* Luminance Masking */
    if( 0.0 != avctx->lumi_masking ) {
        plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
        plugins[xvid_enc_create.num_plugins].param = NULL;
        xvid_enc_create.num_plugins++;
    }

/* Frame Rate and Key Frames */
    xvid_correct_framerate(avctx);
    xvid_enc_create.fincr = avctx->time_base.num;
    xvid_enc_create.fbase = avctx->time_base.den;
    if( avctx->gop_size > 0 )
        xvid_enc_create.max_key_interval = avctx->gop_size; //图像组的长度设定
    else
        xvid_enc_create.max_key_interval = 240; /* XviD's best default */

/* Quants */
    if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1; ///encodes[i]->codec.vcc->flags|=CODEC_FLAG_QSCALE; 选择常量化/ //质量控制=量化参数,1~31,数值越小质量越高
    else x->qscale = 0;

xvid_enc_create.min_quant[0] = avctx->qmin;
    xvid_enc_create.min_quant[1] = avctx->qmin;
    xvid_enc_create.min_quant[2] = avctx->qmin;
    xvid_enc_create.max_quant[0] = avctx->qmax;
    xvid_enc_create.max_quant[1] = avctx->qmax;
    xvid_enc_create.max_quant[2] = avctx->qmax;

/* Quant Matrices */
    x->intra_matrix = x->inter_matrix = NULL;
    if( avctx->mpeg_quant ) //允许MPEG量化 量化矩阵
       x->vol_flags |= XVID_VOL_MPEGQUANT;
    if( (avctx->intra_matrix || avctx->inter_matrix) ) { //可以自己设定量化矩阵avctx->intra_matrix,avctx->inter_matrix
       x->vol_flags |= XVID_VOL_MPEGQUANT;

if( avctx->intra_matrix ) {
           intra = avctx->intra_matrix;
           x->intra_matrix = av_malloc(sizeof(unsigned char) * 64);
       } else
           intra = NULL;
       if( avctx->inter_matrix ) {
           inter = avctx->inter_matrix;
           x->inter_matrix = av_malloc(sizeof(unsigned char) * 64);
       } else
           inter = NULL;

for( i = 0; i < 64; i++ ) {
           if( intra )
               x->intra_matrix[i] = (unsigned char)intra[i];
           if( inter )
               x->inter_matrix[i] = (unsigned char)inter[i];
       }
    }

/* Misc Settings */
    xvid_enc_create.frame_drop_ratio = 0; //丢帧率;0~100
    xvid_enc_create.global = 0;
    if( xvid_flags & CODEC_FLAG_CLOSED_GOP )
        xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;

/* Determines which codec mode we are operating in */
    avctx->extradata = NULL;
    avctx->extradata_size = 0;
    if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) {
        /* In this case, we are claiming to be MPEG4 */
        x->quicktime_format = 1;
        avctx->codec_id = CODEC_ID_MPEG4;
    } else {
        /* We are claiming to be XviD */
        x->quicktime_format = 0;
        if(!avctx->codec_tag)
            avctx->codec_tag = ff_get_fourcc("xvid");
    }

/* Bframes */
    xvid_enc_create.max_bframes = avctx->max_b_frames;
    xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset;
    xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor;
    if( avctx->max_b_frames > 0  && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED;

/* Create encoder context */
    xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); //建立编码上下文
    if( xerr ) {
        av_log(avctx, AV_LOG_ERROR, "XviD: Could not create encoder reference\n");
        return -1;
    }

x->encoder_handle = xvid_enc_create.handle;
    avctx->coded_frame = &x->encoded_picture;

return 0;
}

int ff_xvid_encode_frame(AVCodecContext *avctx,

unsigned char *frame, int buf_size, void *data) { 开始编码一帧

xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE,
        &xvid_enc_frame, &xvid_enc_stats); //开始编码一帧

XVID的量化可以有三种方式:常量化,用户自己设定量化矩阵,调用默认的量化矩阵

XVID基本参数解析相关推荐

  1. Go 学习笔记(45)— Go 标准库之 flag(命令行参数解析)

    1. 参数解析说明 import "flag" flag 包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个 set 集合.每条都有各自的状态参数. 使用 f ...

  2. google gflags的参数解析,便捷实用

    命令行参数解析,一直是我们后段开发人员需要经常使用的一个功能,用来从终端解析接口的输入 ,并做出对应的处理.这里为使用C++/python的开发人员推荐一个便捷的命令行解析接口集 gflags. 我们 ...

  3. 【Qt】通过QtCreator源码学习Qt(六):命令行参数解析实现

    参考下大神的命令行参数解析是如何是实现的 //使用const char []代替宏定义字符串,我以前都是用const QString,想想好傻 const char SETTINGS_OPTION[] ...

  4. url参数解析 url解析 ?解析成对象

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 正文: 代码: // url参数解析 function getUrlkey(url) {var params ...

  5. JS 把url的参数解析成对象

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 正文: 实现思路:请看log和打印结果 // url参数解析 function getUrlkey(url) ...

  6. python命令行参数解析OptionParser类用法实例

    python命令行参数解析OptionParser类用法实例 本文实例讲述了python命令行参数解析OptionParser类的用法,分享给大家供大家参考. 具体代码如下:     from opt ...

  7. 介绍Shell脚本的参数解析工具

    Argbash是一个代码生成器,它为你的脚本生成一个量身定制的解析库.与其他bash模块的通用代码不同,它生成你的脚本所需的最少代码. Argbash是一个代码生成器,它为你的脚本生成一个量身定制的解 ...

  8. 3gpp文件头文件解析_居于LLVM 的命令行参数解析

    在写命令行程序的时候经常需要解析各种命令行参数.打印help信息等,觉得非常的麻烦.今天介绍一种超级棒的命令参数解析的方法:居于LLVM 的命令行参数解析,有了它妈妈再也不用担心我不会解析命令行参数^ ...

  9. Python命令行参数解析模块------argparse

      首先,argparse 是python自带的命令行参数解析包,可以用来方便地读取命令行参数,当你的代码需要频繁地修改参数的时候,使用这个工具可以将参数和代码分离开来,让你的代码更简洁,适用范围更广 ...

最新文章

  1. struts2下的Action配置的各项默认值
  2. XSS-Game level 6
  3. 函数名的使用-闭包-迭代器
  4. 【Oracle】rollup函数
  5. 非IE内核浏览器支持activex插件
  6. PHP环境配置遇到的问题与解决
  7. 计算机控制试题库 百度文库,计算机控制技术练习题附答案_百度文库.doc
  8. 滤芯怎么换 石头机器人_拆开看个究竟,石头扫拖一体机器人T6到底如何?
  9. PerformanceTest
  10. 3G 模块驱动应用开发总结
  11. [阿毛]Ubuntu 16安装CH340串口驱动
  12. 只会增删改查的程序员出路在哪里?
  13. 判断手机是否处于静音、震动、正常模式
  14. 变焦光学系统工作原理及初始结构设计方法
  15. 什么是token及怎样生成token
  16. Visual Studio 中使用万能头文件 #include <bits/stdc++.h>
  17. Mysql组合索引使用和用法
  18. 龙芯1D处理器用户手册
  19. 物联网项目——具体分工
  20. 足不出户也能放风筝?OpenGL 一招搞定!

热门文章

  1. ConcurrentDictionary的ToDictionary
  2. jqGrid格式化日期
  3. 小波分析实验: 实验1 连续小波变换
  4. ListBox的一个郁闷小问题!
  5. spring-6、动态代理(cglib 与 JDK)
  6. mybatis比hibernate处理速度快的原因
  7. 用列表+for循环生成乘法口诀表
  8. 关于Unity中NGUI的Pivot和锚点
  9. C#最简单最完整的webservice实例
  10. (转)在ios android设备上使用 Protobuf (使用dll方式)