【FFMPEG】线程-FF_THREAD_FRAME 和 FF_THREAD_SLICE 区别

0 阅读2分钟

编解码器的 FF_THREAD_FRAME 和 FF_THREAD_SLICE 区别

AVCodecContext *input_codec_ctx = avcodec_alloc_context3(input_codec);
if (!input_codec_ctx) {
    std::cerr << "Could not allocate codec context" << std::endl;
    avformat_close_input(&input_format_ctx);
    return;
}
input_codec_ctx->thread_type = FF_THREAD_FRAME;
input_codec_ctx->thread_type = FF_THREAD_SLICE

FFmpeg 会默认使用 FF_THREAD_SLICE

1. FF_THREAD_FRAME(帧级多线程)

  • 并行化粒度:以为单位进行并行解码。

  • 工作原理

    • 将视频帧分成多个独立的帧,每个线程解码一帧。
    • 帧与帧之间是独立的,因此可以并行解码。
  • 优点

    • 适用于帧间依赖性较低的视频(如 I 帧较多的视频)。
    • 并行化效果好,解码速度快。
  • 缺点

    • 对于帧间依赖性较强的视频(如 B 帧和 P 帧较多的视频),可能会导致线程等待,降低并行效率。
    • 需要更多的内存来存储多帧数据。
  • 适用场景

    • 高分辨率视频(如 4K、8K)。
    • 帧间依赖性较低的视频(如 I 帧较多的视频)。

2. FF_THREAD_SLICE(切片级多线程)

  • 并行化粒度:以切片为单位进行并行解码。

  • 工作原理

    • 将一帧视频分成多个切片(Slice),每个线程解码一个切片。
    • 切片之间是独立的,因此可以并行解码。
  • 优点

    • 适用于帧内依赖性较低的视频(如切片之间独立性较强的视频)。
    • 内存占用较少,因为只需要存储一帧的数据。
  • 缺点

    • 对于帧内依赖性较强的视频(如切片之间有较多依赖的视频),可能会导致线程等待,降低并行效率。
    • 并行化效果不如帧级多线程。
  • 适用场景

    • 低分辨率视频(如 720p、1080p)。
    • 帧内依赖性较低的视频(如切片之间独立性较强的视频)。

3. 对比总结

特性FF_THREAD_FRAMEFF_THREAD_SLICE
并行化粒度帧级切片级
适用场景高分辨率、帧间依赖性较低的视频低分辨率、帧内依赖性较低的视频
内存占用较高(需要存储多帧数据)较低(只需要存储一帧数据)
并行效率高(帧间独立性较强时)中(切片间独立性较强时)
实现复杂度较高较低

4. 如何选择线程模型?

  • 如果你的视频是高分辨率(如 4K、8K)且帧间依赖性较低(如 I 帧较多),建议使用 FF_THREAD_FRAME
  • 如果你的视频是低分辨率(如 720p、1080p)且帧内依赖性较低(如切片之间独立性较强),建议使用 FF_THREAD_SLICE
  • 如果不确定,可以尝试两种模式,并根据实际性能进行选择。