gpt4 book ai didi

python - 使用 ffmpeg+CUDA 将 np.uin8 数组编码为视频

转载 作者:行者123 更新时间:2023-12-04 22:54:14 25 4
gpt4 key购买 nike

我试图利用我的 Nvidia GPU 的视频编码功能,而不是 CPU,将 numpy 数组流保存到 .mp4 或 .avi 文件。
有了这个,我打算:

  • 从我的 CPU 中释放工作,这样他们就可以同时做其他事情
  • 潜在地,加速编码

  • 为此,我创建了 a sample repository实现了这个功能。使用 CUDA 的 ffmpeg 调用如下所示:
    ffmpeg -y -f rawvideo -pix_fmt rgb24 -vsync 0 -extra_hw_frames 2 -s 2000x2000 -r 45 -i - -an -c:v h264_nvenc output.mp4
    如您所见,ffmpeg 从标准输入接收数据。此标准输入由 ffmpeg_gpu_benchmark.py 提供。脚本。
    但是,即使运行 CUDA 标志 -c:v h264_nvenc ,我观察到ffmpeg和python仍然占用了大量的CPU时间。为什么会这样?
    为了完整起见,这里是相关代码
    def run_v2(camera, proc, args, pb, data=None):
    try:
    if data is None:
    frame = read_frame(camera=camera, color=args.color, height=args.height, width=args.width)
    data = frame

    write_to_ffmpeg(proc, data)
    if pb: pb.update(1)
    if args.preview:
    cv2.imshow("frame", cv2.resize(frame, (300, 300)))
    if cv2.waitKey(1) == ord("q"):
    raise QuitException
    return 0
    except (KeyboardInterrupt, QuitException):
    stop_camera(camera)
    return 1
    在哪里 procsubprocess.Popen是这样创建的
    proc = subprocess.Popen(
    cmd,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    shell=False
    )

    write_to_ffmpeg只是运行这个
    # data is an np.array with dtype np.uint8
    proc.stdin.write(data)
    即使我设置 frame 也是如此是使用 np.random.randint 创建的恒定随机帧当程序启动时。因此,这不是由于帧获取引起的延迟。
    PS我这样做是因为不幸的是 the CUDA based VideoWriter class from OpenCV is only supported on Windows and not Linux

    最佳答案

    在执行您的代码示例时,我可以确定两个问题:

  • frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)具有较高的 CPU 利用率。
  • 相机模拟的帧率不是45fps。

  • 由于我没有Basler Camera,所以我的答案只针对模拟相机。
    正如 Kesh 评论的那样,您可以为相机视频解码应用硬件加速(如果视频被编码)。

    为了避免 OpenCV 颜色转换,我们可以预先创建 RGB 帧,而不是将每个帧从灰度转换为 RGB。
    替换: frame = np.random.randint(0, 256, (height, width, 1), dtype=np.uint8)与: frame = np.random.randint(0, 256, (height, width, 3), dtype=np.uint8)并更换
    if color:
    frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)

    和:
    if not color:
    frame = frame[:, :, 0]
    在我的机器中,它将 CPU 利用率从 55% 降低到大约 30%。
    我还尝试使用我的 following post 中的代码创建 NV12 帧格式(预先),而不是 RGB。 ,但几乎没有影响。

    另一个问题是代码没有模拟 45fps 输入源。
    默认的 FFmpeg 行为是尽可能快地对帧进行编码。
    因为没有真正的相机,所以没有什么可以将输入帧率限制为 45fps。
    对于模拟 45fps 输入帧率,添加 -re争论:
    command = f"ffmpeg -y -re ...

    The FFmpeg's "-re" flag means to "Read input at native frame rate. Mainly used to simulate a grab device." i.e. if you wanted to stream a video file, then you would want to use this, otherwise it might stream it too fast (it attempts to stream at line speed by default).


    添加 -re将 CPU 使用率降低到 20% 左右。

    添加后 -re ,使用 NV12(输入)格式,而不是 RGB,将 CPU 使用率降低到 9% 左右。
    为了模拟随机 NV12 帧,我们可以创建高度*1.5 行的帧:
    frame = np.random.randint(0, 256, (height*3//2, width), dtype=np.uint8)

    关于python - 使用 ffmpeg+CUDA 将 np.uin8 数组编码为视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71226669/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com