XVID基本参数解析

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的量化可以有三种方式:常量化,用户自己设定量化矩阵,调用默认的量化矩阵


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自己整理的openresty安装步骤

这几天一直在研究对webapi的限流和名单的问题&#xff0c;于是看了开涛博客的方案&#xff0c;于是就用到了openresty&#xff0c;一个把Nginx和lua集成的东西。 下面就是整理的安装方案&#xff08;简单使用基本可以这么安装&#xff09; 下载openresty&#xff08;centos上下…

京东入职一周感悟:4个匹配和4个观点

入职一周啦&#xff0c;随便写点。一、京东之缘1、我和京东之间的4点匹配Ⅰ技术2008年9月到2016年9月&#xff0c;一直坚持自学技术。京东&#xff0c;是一家商业化的互联网公司&#xff0c;有技术积淀&#xff0c;有发挥空间。作为技术人员&#xff0c;职业匹配。Ⅱ读书大学的…

C#赋值运算符及解析

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 赋值运算符对运算符右边的操作式求值&#xff0c;并用该值设置运算符左边的变量操作式。赋值运算符主要有简单赋值及复合赋值运算符&#xff1b;可以放在赋值运算符左边的对象类型是变量…

mysql 案例 ~ pt修复工具的使用

简介:今天咱们来聊聊PT修复工具pt-table-sync 注意事项&#xff1a; 1 表要有主键或者唯一键 2 针对每一个chunk加的是for update锁 3 修复过程中不能容忍从库延迟 如果从库延迟太多&#xff0c;pt-table-sync会长期持有对chunk的for update锁&#xff0c;然后等待从库的…

mpeg2,mpeg4,h264编码标准的异同

1、宏块匹配像素精度&#xff1a; MPEG2中&#xff0c;运动估计的精度是1/2的像素&#xff0c;通过线性插值实现&#xff08;可能有简单修正&#xff09;&#xff1b; H264和MPEG4 都可以支持1/4像素的精度 2、参考帧的数量&#xff1a;MPEG2&#xff0c;MPEG4的P帧只能有一帧…

四十岁学编程(一)

有时想想&#xff0c;人生还真的是曲折&#xff0c;人到中年了&#xff0c;我才开始学编程。 这一学&#xff0c;就是三年多&#xff0c;我居然坚持了下来。 更没想到的是&#xff0c;三年后的我居然有勇气投简历求职前端&#xff0c;虽然面试前战战兢兢。 很多时候&#xff0c…

01_SQlite数据库简介

转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/7023014.html

GNU Make 使用手册(中译版)

翻译&#xff1a;于凤昌译者注&#xff1a;本人在阅读Linux源代码过程中发现如果要全面了解Linux的结构、理解Linux的编程总体设计及思想必须首先全部读通Linux源代码中各级的Makefile文件。目前&#xff0c;在网上虽然有一些著作&#xff0c;但都不能全面的解释Linux源代码中各…

基础10 多进程、协程(multiprocessing、greenlet、gevent、gevent.monkey、select、selector)...

1.多进程实现方式&#xff08;类似于多线程&#xff09; 1 import multiprocessing2 import time,threading3 4 def thread_run():#定义一个线程函数5 print("我是子线程%s" %threading.get_ident()) #threading.get_ident()函数获取当前线程的id6 def run(name…

C#比较运算符及解析

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 比较运算符得出的结果是逻辑型&#xff08;bool&#xff09;&#xff0c;即 True 或 False 。 比较运算符又称关系运算符&#xff0c;我们可以把它理解为一种判断&#xff0c;判断的结果…

开发人员MySQL调优-理论篇

2019独角兽企业重金招聘Python工程师标准>>> 修改字符集 查看字符集 show variables like character% show variables like %char% 上面的两个命令都可以&#xff0c;我一般使用的下面的&#xff0c;会出来如下几个字符集设定的选项&#xff1a; character_set_clie…

Java基础之反射机制

Java反射机制 反射机制是什么 反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属性&#xff1b;这种动态获取的信息以及动态调用对象的方法的功能称为ja…

C#逻辑运算符及解析

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 逻辑运算符用于连接一个或多个条件&#xff0c;判断这些条件是否成立。 &#xff23;&#xff03;的逻辑运算符可以分为两类&#xff1a; “&#xff06;” “&#xff5c;” “&…

通过ProGet搭建一个内部的Nuget服务器

.NET Core项目完全使用Nuget 管理组件之间的依赖关系&#xff0c;Nuget已经成为.NET 生态系统中不可或缺的一个组件&#xff0c;从项目角度&#xff0c;将项目中各种组件的引用统统交给NuGet&#xff0c;添加组件/删除组件/以及更新组件即可一键完成&#xff0c;大大提升工作效…

unity官方教程-TANKS(一)

unity官方教程TANKS&#xff0c;难度系数中阶。跟着官方教程学习Unity&#xff0c;通过本教程你可以学会使用Unity开发游戏的基本流程。 一、环境 Unity 版本 > 5.2Asset Store 里面搜索 Tanks!Tutorial ,下载导入 二、项目设置 为了便于开发&#xff0c;很多时候我们选用的…

Play框架的用户验证。

最近刚刚参与一个基于Play框架的管理平台的升级工作&#xff0c;其中涉及到了用户的验证工作。第一次接触play框架&#xff0c;直接看已有代码&#xff0c;有点晕。因此&#xff0c;自己实现了一个简单的用户验证功能。 首先&#xff0c;新建一个User类&#xff0c;包含两个属性…

C#条件运算符if-else的简化格式

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 条件运算符&#xff08;&#xff1f;&#xff1a;&#xff09;是&#xff49;&#xff46;……&#xff45;&#xff4c;&#xff53;&#xff45;的简化形式 其使用格式为&#xff1a…

码率控制方式选择

同码率下的图像质量或同图像质量下的码率。 AVCodecContext /** * the average bitrate * - encoding: Set by user; unused for constant quantizer encoding. * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the strea…

Fortran执行语句中的“双冒号” ::

双冒号“::”&#xff0c;通常出现于Fortran在变量声明中&#xff0c;但是在特殊情况下&#xff0c;也会出现于数组中。例如&#xff1a; ... real,target,dimension(10):: a real,pointer,dimension(:):: pa,pb integer:: n3 ... pa > a(n::1) pb > a(n:10:1) ... 咋一看…

VS配置本地IIS以域名访问

1.IIS下配置自己的网站&#xff0c;添加主机名 2.修改hosts文件&#xff08;C://Windows/System32/drivers/etc&#xff09; 3.VS中配置项目Web服务器&#xff08;选择外部主机&#xff09; 转载于:https://www.cnblogs.com/zuimeideshi520/p/7028544.html