FFmpeg指定x265编码器线程数

转载请注明出处:https://cyc.wiki/index.php/2018/07/17/ffmpeg-x265-threads/


FFmpeg的-threads参数

FFmpeg调用编码器时,一般使用-threads参数对编码器使用的线程数进行设置。
比如:

ffmpeg -s 1920x1080 -framerate 25 -i input.yuv -c:v libx264 -threads 4 -y output.h264

对于x264编码器,这个参数的意义是明确的,既是编码器占用的线程数,也是编码器并行处理的帧数。

但对于x265编码器,这个参数的意义是否还具有同样的意义?
比如:

ffmpeg -s 1920x1080 -framerate 25 -i input.yuv -c:v libx265 -threads 4 -y output.hevc

这个答案存在分歧,虽然不清楚FFmpeg作者的用意,但确实会对一般使用者产生误导,所以在这里阐明。

FFmpeg中libx265.c的线程参数透传

FFmpeg中封装了调用x265编码器的libx265编码器模块,代码位于libavcodec/libx265.c,其中

    ctx->params->frameNumThreads = avctx->thread_count;
    ctx->params->fpsNum          = avctx->time_base.den;
    ctx->params->fpsDenom        = avctx->time_base.num * avctx->ticks_per_frame;
    ctx->params->sourceWidth     = avctx->width;
    ctx->params->sourceHeight    = avctx->height;

第一行就是FFmpeg传递threads参数的语句。FFmpeg编码器选项中的-threads会赋值给avctx->thread_count,从代码中可以看到,这个值被设置给了x265paramsframeNumThreads成员。
这个参数成员等效于x265命令行参数中的--frame-threads,官方文档给出的含义是:


--frame-threads, -F <integer>

Number of concurrently encoded frames. Using a single frame thread gives a slight improvement in compression, since the entire reference frames are always available for motion compensation, but it has severe performance implications. Default is an autodetected count based on the number of CPU cores and whether WPP is enabled or not.

Over-allocation of frame threads will not improve performance, it will generally just increase memory use.

Values: any value between 0 and 16. Default is 0, auto-detect


这意味着该参数代表了x265编码时并行处理的帧数。
那这是不是就代表了x265使用的线程数呢?并不是。HEVC标准在制定时就引入了帧内的WPP(Wavefront Parallel Processing,波前并行处理)机制,使得编码一帧时,所有CTU行可以在满足一定约束条件时并行处理。在x265中有--[no-]wpp命令行参数对WPP的开关进行控制。
当WPP开启时,每一帧都会有多个线程在并行处理,所以整个x265编码器的线程数就会大于--frame-threads所设定的值。

因此FFmpeg在对x265编码器进行调用时,-threads设置的不是x265编码器占有的线程数。

FFmpeg指定x265编码器线程数

那么正确的指定x265编码器线程数的方法是什么呢?答案是:

ffmpeg -s 1920x1080 -framerate 25 -i input.yuv -c:v libx265 -x265-params pools=4 -y output.hevc

这里用到的是x265编码器的--pools命令行参数,它的含义是:


--pools <string>, --numa-pools <string>

Comma seperated list of threads per NUMA node. If “none”, then no worker pools are created and only frame parallelism is possible. If NULL or “” (default) x265 will use all available threads on each NUMA node:


这个参数涉及到NUMA节点的分配,这里就不展开写了。总之,单个整数就代表了x265编码器线程池的大小,也就是x265编码器所占有的线程数。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google photo

You are commenting using your Google account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s