FilterGraph是如何设置多线程的数量的?
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
ffmpeg 命令里面有两个参数可以设置滤镜的线程数量,如下:
filter_threads,设置简单滤镜规则的线程数量。filter_complex_threads,设置复杂滤镜规则的线程数量。
简单 与 复杂 只是 ffmpeg 命令行层面的功能,在 AVFilterGraph 内部,他们是不区分简单与复杂的,使用的都是 nb_threads 字段,如下:

当我们没有设置 AVFilterGraph::nb_threads 的时候,它就是 0,这时候在 avpriv_slicethread_create() 内部,会根据 cpu 核数来开启对应数量的线程,如下:

可以看到,开启的线程数量比 cpu 的核数多 1,也就是如果 cpu 是 8 核的,最后会有 9 个线程执行 overlay 滤波。
但是这不是说 他用 pthread_create() 创建了 9 个新的线程来执行 滤波函数,由于 FIlterGraph 是不设置 main_func() 函数的,所以他后面会把 nb_workers 减 1,所以实际只创建了 8 个新的线程,如下:

那我为什么说,最后 会有 9 个线程执行 overlay 滤波,是因为主线程也算一个线程,没有 main_func() 函数的时候,主线程会执行 滤波函数。如下:

那 nb_cpus + 1 的意义是什么呢?
你可以这样理解,如果有 main_func() 函数的时候,就会多创建一个新的线程。多出来的这个线程,其实就是给 main_func() 函数用的。
但这里并不是说,创建了 9 个 新线程,就从这 9 个新线程 选一个出来执行 main_func(),这 9 个新线程都是执行 滤波函数的。只是 主线程 从 执行滤波函数 变成了 执行 main_func() 函数。
如果没有设置 main_func() 函数,进程里面有 9 个线程,9个线程都执行 滤波函数。
如果设置了 main_func() 函数,进程里面有 10 个线程,9个线程在执行 滤波函数,剩下的一个线程执行 main_func() 函数。
nb_cpus + 1 实现的效果就是这样,确保有一个单独的线程运行 main_func(),
