编码器的参数设置


ffmpeg书籍推荐: https://www.xianwaizhiyin.net/?p=51

//编码器参数设置
//sps/pps
enc_ctx->profile = FF_PROFILE_H264_HIGH_444;
enc_ctx->level = 50; //表示LEVEL是5.0
enc_ctx->width = 640;
enc_ctx->height = 480;
enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
enc_ctx->gop_size = 250;
enc_ctx->bit_rate = 600000;//600kbps
enc_ctx->time_base = (AVRational){
          
   1, 25};
enc_ctx->framerate = (AVRational){
          
   25, 1};//帧率
if(octx->oformat->flags & AVFMT_GLOBALHEADER)
{
          
   
	printf("set video GLOBAL_HEADER
");
	enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}//这octx是输出上下文,有些封装格式希望pps,sps和关键帧分离。设置AV_CODEC_FLAG_GLOBAL_HEADER
代表不会在每个关键帧前加入pps和sps了。会将pps和sps写入到extradata字节当中,当播放端解码器解码时,
从extradata中读取pps和sps然后加入到每个关键帧中。不同的封装格式要求不同,这个if代码块检测你设置的封装格式如"flv"是否需要设置分离。 
//解释一下pps和sps,它们对解码至关重要,如果找不到他们,那么解码就会
失败,因为它们存储的是编码器设置的参数,比如视频的heigth,width等,音频的采样率,通道数等。详见另一篇文章:[h264中的pps和sps](https://blog..net/weixin_43466192/article/details/121465618)

enc_ctx->keyint_min = 25;//option 由于gop过大,当运动变化过大时,允许自动多插入一个i帧,但两个i帧相差不能小于25帧;
enc_ctx->max_b_frames = 3;//option连续的B帧的数量,一般设置不超过三帧,这里设置三帧
enc_ctx->has_b_frames = 1;//option启动B帧
enc_ctx->refs = 3;//option参考帧的数量,解码器的缓冲区中可以存放的参考帧的数量。
option的选项如果不设置的话会使用默认值,会根据其他设置的值自动设置,这两个也是option选项。

两个预设值preset,tune 因为x264参数众多,且各个参数配合紧密,x264编码器专门提供了预设值,预设值的设置相当于模式的选择,设定一个预设值,代表着使用这个模式,那么这么模式会有默认的很多参数设置。后面再手动设置的参数会覆盖模式里对应的参数。因此这两个值要在其他值之前设置,除此之外tune要在preset后。 preset的值从高到低有:

ultrafast、superfast、veryfast、faster、fast、medium(默认值)、slow、slower、veryslow、placebo

注意:编码很考验cpu性能,提升编码速度能直接减少对cpu的消耗,同时还能显著减少延迟,但会牺牲画面质量。 tune的值有:

animation: 动画 grain: 需要保留大量的grain时用; stillimage: 静态图像编码时使用; psnr:为提高psnr做了优化的参数; ssim: 为提高ssim做了优化的参数; fastdecode: 可以快速解码的参数; zerolatency:零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码。能明显减少延时,但牺牲画面质量。

下面这个网站会有更详细的介绍以上参数,并给出x264未设置options参数时,默认是多少。

http://www.chaneru.com/Roku/HLS/X264_Settings.htm

下面这个网站会介绍这些参数在ffmpeg命令行中对应的名字是什么。

https://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping

附录: x264源码中base.c文件中

static int x264_param_apply_preset( x264_param_t *param, const char *preset )
{
          
   
    char *end;
    int i = strtol( preset, &end, 10 );
    if( *end == 0 && i >= 0 && i < sizeof(x264_preset_names)/sizeof(*x264_preset_names)-1 )
        preset = x264_preset_names[i];
 
    /*
     * 下面的这些参数设置会对编码质量和编码速度造成极大影响,因此,优化时首先考虑优化下面的参数
     */
 
    /* 极快(最快)
     */
    if( !strcasecmp( preset, "ultrafast" ) )
    {
          
   
        /* 参考帧数量设置为1
         */
        param->i_frame_reference = 1;
        /* 场景切换设置阈值
         */
        param->i_scenecut_threshold = 0;
        /* 不进行去方块滤波
         */
        param->b_deblocking_filter = 0;
        /* 不使用cabac
         */
        param->b_cabac = 0;
        /* 没有B帧
         */
        param->i_bframe = 0;
        /* 设置intra划分的partition,这里应该是不进行划分,只使用16x16
         */
        param->analyse.intra = 0;
        /* 设置inter划分的partition,这里应该是不进行划分,只使用16x16
         */
        param->analyse.inter = 0;
        /* 不使用8x8的的DCT变换
         */
        param->analyse.b_transform_8x8 = 0;
        /* 运动估计:DIA
         */
        param->analyse.i_me_method = X264_ME_DIA;
        /* 亚像素运动估计精度:0,表示只进行整像素运动估计
         */
        param->analyse.i_subpel_refine = 0;
        /* 关闭自适应量化
         */
        param->rc.i_aq_mode = 0;
        /* 禁止每个宏块的分区拥有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 不使用trellis优化
         */
        param->analyse.i_trellis = 0;
        /* 自适应B帧判断的概率(从-100到100)
         */
        param->i_bframe_adaptive = X264_B_ADAPT_NONE;
        /* 不使用mbtree
         */
        param->rc.b_mb_tree = 0;
        /* 权重预测中,P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
        /* 显式的B帧权重预测
         */
        param->analyse.b_weighted_bipred = 0;
        /* mbtree前向预测的帧的数量
         */
        param->rc.i_lookahead = 0;
    }
    /* 超级快
     */
    else if( !strcasecmp( preset, "superfast" ) )
    {
          
   
        /* inter划分:4x4和8x8
         */
        param->analyse.inter = X264_ANALYSE_I8x8|X264_ANALYSE_I4x4;
        /* 运动估计:DIA
         */
        param->analyse.i_me_method = X264_ME_DIA;
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 1;
        /* 参考帧数量:1
         */
        param->i_frame_reference = 1;
        /* 不允许每个宏块的分区有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 关闭trellis优化
         */
        param->analyse.i_trellis = 0;
        /* 关闭mbtree
         */
        param->rc.b_mb_tree = 0;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:0
         */
        param->rc.i_lookahead = 0;
    }
    /* 非常快
     */
    else if( !strcasecmp( preset, "veryfast" ) )
    {
          
   
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 2;
        /* 参考帧数量:1
         */
        param->i_frame_reference = 1;
        /* 不允许每个宏块的分区有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 关闭trellis优化
         */
        param->analyse.i_trellis = 0;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:10
         */
        param->rc.i_lookahead = 10;
    }
    /* 很快
     */
    else if( !strcasecmp( preset, "faster" ) )
    {
          
   
        /* 不允许每个宏块的分区有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 参考帧数量:2
         */
        param->i_frame_reference = 2;
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 4;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:20
         */
        param->rc.i_lookahead = 20;
    }
    /* 快
     */
    else if( !strcasecmp( preset, "fast" ) )
    {
          
   
        /* 参考帧数量:2
         */
        param->i_frame_reference = 2;
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 6;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:30
         */
        param->rc.i_lookahead = 30;
    }
    /* 正常:在速度与质量之间平衡
     */
    else if( !strcasecmp( preset, "medium" ) )
    {
          
   
        // 使用默认的参数
        /* Default is medium */
    }
    /* 慢
     */
    else if( !strcasecmp( preset, "slow" ) )
    {
          
   
        param->analyse.i_subpel_refine = 8;
        param->i_frame_reference = 5;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.i_trellis = 2;
        param->rc.i_lookahead = 50;
    }
    /* 很慢
     */
    else if( !strcasecmp( preset, "slower" ) )
    {
          
   
        param->analyse.i_me_method = X264_ME_UMH;
        param->analyse.i_subpel_refine = 9;
        param->i_frame_reference = 8;
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
        param->analyse.i_trellis = 2;
        param->rc.i_lookahead = 60;
    }
    /* 非常慢
     */
    else if( !strcasecmp( preset, "veryslow" ) )
    {
          
   
        param->analyse.i_me_method = X264_ME_UMH;
        param->analyse.i_subpel_refine = 10;
        param->analyse.i_me_range = 24;
        param->i_frame_reference = 16;
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
        param->analyse.i_trellis = 2;
        param->i_bframe = 8;
        param->rc.i_lookahead = 60;
    }
    /* 极慢
     */
    else if( !strcasecmp( preset, "placebo" ) )
    {
          
   
        param->analyse.i_me_method = X264_ME_TESA;
        param->analyse.i_subpel_refine = 11;
        param->analyse.i_me_range = 24;
        param->i_frame_reference = 16;
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
        param->analyse.b_fast_pskip = 0;
        param->analyse.i_trellis = 2;
        param->i_bframe = 16;
        param->rc.i_lookahead = 60;
    }
    else
    {
          
   
        x264_log( NULL, X264_LOG_ERROR, "invalid preset %s
", preset );
        return -1;
    }
    return 0;
}
static int x264_param_apply_preset( x264_param_t *param, const char *preset )
{
          
   
    char *end;
    int i = strtol( preset, &end, 10 );
    if( *end == 0 && i >= 0 && i < sizeof(x264_preset_names)/sizeof(*x264_preset_names)-1 )
        preset = x264_preset_names[i];
 
    /*
     * 下面的这些参数设置会对编码质量和编码速度造成极大影响,因此,优化时首先考虑优化下面的参数
     */
 
    /* 极快(最快)
     */
    if( !strcasecmp( preset, "ultrafast" ) )
    {
          
   
        /* 参考帧数量设置为1
         */
        param->i_frame_reference = 1;
        /* 场景切换设置阈值
         */
        param->i_scenecut_threshold = 0;
        /* 不进行去方块滤波
         */
        param->b_deblocking_filter = 0;
        /* 不使用cabac
         */
        param->b_cabac = 0;
        /* 没有B帧
         */
        param->i_bframe = 0;
        /* 设置intra划分的partition,这里应该是不进行划分,只使用16x16
         */
        param->analyse.intra = 0;
        /* 设置inter划分的partition,这里应该是不进行划分,只使用16x16
         */
        param->analyse.inter = 0;
        /* 不使用8x8的的DCT变换
         */
        param->analyse.b_transform_8x8 = 0;
        /* 运动估计:DIA
         */
        param->analyse.i_me_method = X264_ME_DIA;
        /* 亚像素运动估计精度:0,表示只进行整像素运动估计
         */
        param->analyse.i_subpel_refine = 0;
        /* 关闭自适应量化
         */
        param->rc.i_aq_mode = 0;
        /* 禁止每个宏块的分区拥有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 不使用trellis优化
         */
        param->analyse.i_trellis = 0;
        /* 自适应B帧判断的概率(从-100到100)
         */
        param->i_bframe_adaptive = X264_B_ADAPT_NONE;
        /* 不使用mbtree
         */
        param->rc.b_mb_tree = 0;
        /* 权重预测中,P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
        /* 显式的B帧权重预测
         */
        param->analyse.b_weighted_bipred = 0;
        /* mbtree前向预测的帧的数量
         */
        param->rc.i_lookahead = 0;
    }
    /* 超级快
     */
    else if( !strcasecmp( preset, "superfast" ) )
    {
          
   
        /* inter划分:4x4和8x8
         */
        param->analyse.inter = X264_ANALYSE_I8x8|X264_ANALYSE_I4x4;
        /* 运动估计:DIA
         */
        param->analyse.i_me_method = X264_ME_DIA;
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 1;
        /* 参考帧数量:1
         */
        param->i_frame_reference = 1;
        /* 不允许每个宏块的分区有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 关闭trellis优化
         */
        param->analyse.i_trellis = 0;
        /* 关闭mbtree
         */
        param->rc.b_mb_tree = 0;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:0
         */
        param->rc.i_lookahead = 0;
    }
    /* 非常快
     */
    else if( !strcasecmp( preset, "veryfast" ) )
    {
          
   
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 2;
        /* 参考帧数量:1
         */
        param->i_frame_reference = 1;
        /* 不允许每个宏块的分区有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 关闭trellis优化
         */
        param->analyse.i_trellis = 0;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:10
         */
        param->rc.i_lookahead = 10;
    }
    /* 很快
     */
    else if( !strcasecmp( preset, "faster" ) )
    {
          
   
        /* 不允许每个宏块的分区有自己的参考编号
         */
        param->analyse.b_mixed_references = 0;
        /* 参考帧数量:2
         */
        param->i_frame_reference = 2;
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 4;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:20
         */
        param->rc.i_lookahead = 20;
    }
    /* 快
     */
    else if( !strcasecmp( preset, "fast" ) )
    {
          
   
        /* 参考帧数量:2
         */
        param->i_frame_reference = 2;
        /* 亚像素运动估计精度
         */
        param->analyse.i_subpel_refine = 6;
        /* P帧的权值
         */
        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;
        /* mbtree向前预测的帧数:30
         */
        param->rc.i_lookahead = 30;
    }
    /* 正常:在速度与质量之间平衡
     */
    else if( !strcasecmp( preset, "medium" ) )
    {
          
   
        // 使用默认的参数
        /* Default is medium */
    }
    /* 慢
     */
    else if( !strcasecmp( preset, "slow" ) )
    {
          
   
        param->analyse.i_subpel_refine = 8;
        param->i_frame_reference = 5;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.i_trellis = 2;
        param->rc.i_lookahead = 50;
    }
    /* 很慢
     */
    else if( !strcasecmp( preset, "slower" ) )
    {
          
   
        param->analyse.i_me_method = X264_ME_UMH;
        param->analyse.i_subpel_refine = 9;
        param->i_frame_reference = 8;
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
        param->analyse.i_trellis = 2;
        param->rc.i_lookahead = 60;
    }
    /* 非常慢
     */
    else if( !strcasecmp( preset, "veryslow" ) )
    {
          
   
        param->analyse.i_me_method = X264_ME_UMH;
        param->analyse.i_subpel_refine = 10;
        param->analyse.i_me_range = 24;
        param->i_frame_reference = 16;
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
        param->analyse.i_trellis = 2;
        param->i_bframe = 8;
        param->rc.i_lookahead = 60;
    }
    /* 极慢
     */
    else if( !strcasecmp( preset, "placebo" ) )
    {
          
   
        param->analyse.i_me_method = X264_ME_TESA;
        param->analyse.i_subpel_refine = 11;
        param->analyse.i_me_range = 24;
        param->i_frame_reference = 16;
        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
        param->analyse.inter |= X264_ANALYSE_PSUB8x8;
        param->analyse.b_fast_pskip = 0;
        param->analyse.i_trellis = 2;
        param->i_bframe = 16;
        param->rc.i_lookahead = 60;
    }
    else
    {
          
   
        x264_log( NULL, X264_LOG_ERROR, "invalid preset %s
", preset );
        return -1;
    }
    return 0;
}

参考:https://blog..net/NB_vol_1/article/details/78363559?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163600570616780264056029%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163600570616780264056029&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-5-78363559.pc_search_result_cache&utm_term=preset%2Ctune&spm=1018.2226.3001.4187

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/290196.html

(0)
上一篇 2022年9月29日
下一篇 2022年9月29日

相关推荐

发表回复

登录后才能评论