百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

VPF:适用于 Python 的开源视频处理框架,加速视频任务、提高 GPU 利用率

ccwgpt 2024-09-20 13:23 28 浏览 0 评论

雷锋网 AI 开发者按:近日,NVIDIA 开源了适用于 Python 的视频处理框架「VideoProcessingFramework(VPF)」。该框架为开发人员提供了一个简单但功能强大的 Python 工具,可用于硬件加速的视频编码、解码和处理类等任务。

同时,由于 Python 绑定下的 C ++代码,它使开发者可以在数十行代码中实现较高的 GPU 利用率。解码后的视频帧以 NumPy 数组或 CUDA 设备指针的形式公开,以简化交互过程及其扩展功能。

目前,VPF 并未对 NVIDIA Video Codec SDK 附加任何限制,开发者可充分利用 NVIDIA 专业级 GPU 的功能。

Python 中的硬件加速视频处理框架 VPF

VPF 是基于 CMake 的开源跨平台框架,它依赖于 FFmpeg 库来进行(de)muxing 和 pybind11 项目从而构建 Python 绑定。它包含了一组开源的 C ++库和 Python 绑定,可与其封闭源代码 Codec SDK 进行交互。

该框架的主要功能是简化从 Python 开发 GPU 加速视频编码/解码的过程,可为视频处理任务(例如解码,编码,代码转换以及 GPU 加速的色彩空间和像素格式转换)提供完整的硬件加速。

尽管 Python 不是性能最高的语言,但它易于使用;在 NVIDIA 发布此视频处理框架之后,它相当于在现有 Video Codec SDK C ++ 堆栈周围的 Python wrapper,将用于在 Kepler 及更高版本上基于 GPU 的视频编码/解码。这使得 VPF 在利用基于 GPU 的高性能视频加速的同时,也获得了易于阅读/编写的代码。

NVIDIA Video Codec SDK 使用效果示意图

同时值得注意的是,VPF 还利用 NVIDIA Video Codec SDK(一套全面的 API,包括用于 Windows 和 Linux 上硬件加速视频编码和解码的高性能工具,示例和文档)来提高灵活性和性能,并为开发人员提供 Python 固有的易用性。目前,该代码在 GitHub 上已开源。

Github 地址:

https://github.com/NVIDIA/VideoProcessingFramework

代码示例及结果

在官网博客宣布 VPF 时,开发者也提供了一个简短的 Python 代码示例,该示例使用 PyNvCodec 模块显示 Python 中的视频转码:

import PyNvCodec as nvc


gpuID = 0

encFile = "big_buck_bunny_1080p_h264.mov"

xcodeFile = open("big_buck_bunny_1080p.h264", "wb")


nvDec = nvc.PyNvDecoder(encFile, gpuID)

nvEnc = nvc.PyNvEncoder({'preset': 'hq', 'codec': 'h264', 's': '1920x1080'}, gpuID)


while True:

rawSurface = nvDec.DecodeSingleSurface

# Decoder will return zero surface if input file is over;

if not (rawSurface.GetCudaDevicePtr):

break

encFrame = nvEnc.EncodeSingleSurface(rawSurface)

if(encFrame.size):

frameByteArray = bytearray(encFrame)

xcodeFile.write(frameByteArray)


# Encoder is asynchronous, so we need to flush it

encFrames = nvEnc.Flush

for encFrame in encFrames:

encByteArray = bytearray(encFrame)

xcodeFile.write(encByteArray)

尽管这一示例的设计简单,但 VPF 仍具有良好的性能。上面显示的代码转换示例足以使 RTX 5000 GPU 上的 Nvenc 单元饱和,如下所示:

Big Buck Bunny 序列包含 14315 帧,可以在 32 秒内进行转码,而无需使用任何先进的技术(例如生产者-消费者模式),解码器和编码器将在单独的线程中启动共享解码器队列,从而可以在约 447fps 的速度下进行转码。由于所有转码均在 GPU 上完成,因此没有明显的 CPU 负载。

VPF 使用类说明

VPF 中包含了多个类,其核心部分是 PyNvDecoder 和 PyNvEncoder 类,它们是与 NVIDIA Video Codec SDK 的 Python 绑定。

PyNvDecoder 和 PyNvEncoder 类支持 NV12 像素格式,所有转换均通过 GPU 加速,并在 VRAM 内存中完成,以提高性能。其中——

PyNvDecoder 类有五个主要方法:

  • DecodeSingleSurface从输入视频解码单帧,返回带有解码像素的 Surface。下次用户调用此方法时,先前返回的 Surface 可能会被重用。如果未解码帧,则解码后的 Surface 的 GetCudaDevicePtr 方法将返回零;

  • DecodeSingleFram从输入视频解码单帧,返回带有解码像素的 NumPy 数组。下次用户调用此方法时,将返回另一个 NumPy 数组实例。如果未解码帧,它将返回空的 NumPy 数组。此操作将设备复制到主机内存;

  • Width返回解码的帧宽度;

  • Height返回解码的帧高度;

  • PixelFormat返回解码的帧像素格式。

用户使用 DecodeSingleSurface 和 DecodeSingleFrame 时,不会破坏解码器的内部状态。解码器类支持 H.264 和 H.265 编解码器。

PyNvEncoder 类有六个方法:

  • EncodeSingleSurface以原始像素获取 NV12 Surface,对其进行编码,然后将基本视频比特流作为 NumPy 数组返回。编码器是异步的,因此此方法可能会在前几次调用时返回空数组(取决于编码器设置),这不是编码错误;

  • EncodeSingleFrame以原始像素获取 NumPy 数组,对其进行编码,然后将基本视频比特流作为 NumPy 数组返回。编码器是异步的,因此此方法可能在前几次调用时返回空数组(取决于编码器设置);

  • Flush冲洗编码器。除非编码器队列中的所有原始帧都已编码,否则它不会返回,并返回带有基本流字节的 NumPy 数组的列表;

  • Width返回编码的帧宽度;

  • Height返回编码的帧高度;

  • PixelFormat返回编码的帧像素格式。

如果用户使用 EncodeSingleSurface 和 EncodeSingleFrame,则不会破坏编码器的内部状态。此外,PyNvEncoder 可以获取任意分辨率的输入帧,并在实际编码之前即时在 GPU 上调整其大小。

编码器类支持 H.264 和 H.265 编解码器,并且具有较低的延迟,因此在编码会话结束时,应调用 Flush 刷新编码器帧队列。

HardwareSurface 类包含一个包装器 CUdeviceptr:

  • GetCudaDevicePtr将 CUdeviceptr 返回到 CUDA 内存对象。

对于主机和设备之间的内存传输,有两个名为 PyFrameUploader 和 PySurfaceDownloader 的类:

  • PyFrameUploader 用于将 NumPy 数组上传到 GPU;

  • UploadSingleFrame 将一个 numpy 数组上传到 GPU,再将句柄返回到上传的 Surface。下次用户调用此方法时,先前返回的 Surface 可能会被重用。

PySurfaceDownloader 类用于从 GPU 下载 Surface,它只包含一种方法:

  • DownloadSingleSurface将 GPU 端 Surface 下载到 CPU 端 numpy 数组中。下次用户调用此方法时,将返回另一个 numpy 数组实例。

PySurfaceConverter 类用于 GPU 加速的色彩空间和像素格式转换。以下是受支持的转化列表:

  • YUV420 至 NV12

  • NV12 到 YUV420

  • NV12 转 RGB

PySurfaceConverter 类包含一种方法:

  • Execute 在 GPU 上执行转换,将句柄以输出格式返回给 Surface。下次用户调用此方法时,先前返回的 Surface 可能会被重用。

而 VPF 运行的主要数据类型有两种:

  • 用于 CPU 端数据的 NumPy 数组;

  • 用户透明 Surface 类,表示 GPU 端数据;

由于 GPU 端内存对象分配很复杂,并且会严重影响性能,因此所有归还 Surface,并在下次调用时重用先前返回的 VPF 类方法。

与此不同的是,VPF 类方法每次被调用时都会返回新的 NumPy 数组实例。移动构造函数可避免内存复制的运行成本。

其它开源视频处理框架

一、RxFFmpeg

RxFFmpeg 是基于 ( FFmpeg 4.0 + X264 + mp3lame + fdk-aac ) 编译的适用于 Android 平台的音视频编辑、视频剪辑的快速处理框架。

包含:视频拼接,转码,压缩,裁剪,片头片尾,分离音视频,变速,添加静态贴纸和 gif 动态贴纸,添加字幕,添加滤镜,添加背景音乐,加速减速视频,倒放音视频,音频裁剪,变声,混音,图片合成视频,视频解码图片等主流特色功能。

RxFFmpeg 开源地址:

https://github.com/microshow/RxFFmpeg

二、VidGear

VidGear 是一个围绕 OpenCV 视频 I/O 模块的轻量级 python 包装器,它使用多线程 Gears(又名 API)构建,每个都有独特的开拓性功能。

这些 API 提供了易于使用,高度可扩展的多线程包装器,这些包装器围绕着许多底层的最新 python 库,例如 OpenCV,FFmpeg,picamera,pafy,pyzmq 和 python-mss ?,可以在各种设备和平台上实现高速视频帧读取功能 。它也是 imutils 库视频模块的重新实现,修复了所有主要错误,并附带了直接网络流支持。

VidGear 开源地址:

https://pypi.org/project/vidgear/

VPF 博客地址:

https://devblogs.nvidia.com/vpf-hardware-accelerated-video-processing-framework-in-python/

雷锋网 AI 开发者 雷锋网

相关推荐

十分钟让你学会LNMP架构负载均衡(impala负载均衡)

业务架构、应用架构、数据架构和技术架构一、几个基本概念1、pv值pv值(pageviews):页面的浏览量概念:一个网站的所有页面,在一天内,被浏览的总次数。(大型网站通常是上千万的级别)2、u...

AGV仓储机器人调度系统架构(agv物流机器人)

系统架构层次划分采用分层模块化设计,分为以下五层:1.1用户接口层功能:提供人机交互界面(Web/桌面端),支持任务下发、实时监控、数据可视化和报警管理。模块:任务管理面板:接收订单(如拣货、...

远程热部署在美团的落地实践(远程热点是什么意思)

Sonic是美团内部研发设计的一款用于热部署的IDEA插件,本文其实现原理及落地的一些技术细节。在阅读本文之前,建议大家先熟悉一下Spring源码、SpringMVC源码、SpringBoot...

springboot搭建xxl-job(分布式任务调度系统)

一、部署xxl-job服务端下载xxl-job源码:https://gitee.com/xuxueli0323/xxl-job二、导入项目、创建xxl_job数据库、修改配置文件为自己的数据库三、启动...

大模型:使用vLLM和Ray分布式部署推理应用

一、vLLM:面向大模型的高效推理框架1.核心特点专为推理优化:专注于大模型(如GPT-3、LLaMA)的高吞吐量、低延迟推理。关键技术:PagedAttention:类似操作系统内存分页管理,将K...

国产开源之光【分布式工作流调度系统】:DolphinScheduler

DolphinScheduler是一个开源的分布式工作流调度系统,旨在帮助用户以可靠、高效和可扩展的方式管理和调度大规模的数据处理工作流。它支持以图形化方式定义和管理工作流,提供了丰富的调度功能和监控...

简单可靠高效的分布式任务队列系统

#记录我的2024#大家好,又见面了,我是GitHub精选君!背景介绍在系统访问量逐渐增大,高并发、分布式系统成为了企业技术架构升级的必由之路。在这样的背景下,异步任务队列扮演着至关重要的角色,...

虚拟服务器之间如何分布式运行?(虚拟服务器部署)

  在云计算和虚拟化技术快速发展的今天,传统“单机单任务”的服务器架构早已难以满足现代业务对高并发、高可用、弹性伸缩和容错容灾的严苛要求。分布式系统应运而生,并成为支撑各类互联网平台、企业信息系统和A...

一文掌握 XXL-Job 的 6 大核心组件

XXL-Job是一个分布式任务调度平台,其核心组件主要包括以下部分,各组件相互协作实现高效的任务调度与管理:1.调度注册中心(RegistryCenter)作用:负责管理调度器(Schedule...

京东大佬问我,SpringBoot中如何做延迟队列?单机与分布式如何做?

京东大佬问我,SpringBoot中如何做延迟队列?单机如何做?分布式如何做呢?并给出案例与代码分析。嗯,用户问的是在SpringBoot中如何实现延迟队列,单机和分布式环境下分别怎么做。这个问题其实...

企业级项目组件选型(一)分布式任务调度平台

官网地址:https://www.xuxueli.com/xxl-job/能力介绍架构图安全性为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯;调度中心和执...

python多进程的分布式任务调度应用场景及示例

多进程的分布式任务调度可以应用于以下场景:分布式爬虫:importmultiprocessingimportrequestsdefcrawl(url):response=re...

SpringBoot整合ElasticJob实现分布式任务调度

介绍ElasticJob是面向互联网生态和海量任务的分布式调度解决方案,由两个相互独立的子项目ElasticJob-Lite和ElasticJob-Cloud组成。它通过弹性调度、资源管控、...

分布式可视化 DAG 任务调度系统 Taier 的整体流程分析

Taier作为袋鼠云的开源项目之一,是一个分布式可视化的DAG任务调度系统。旨在降低ETL开发成本,提高大数据平台稳定性,让大数据开发人员可以在Taier直接进行业务逻辑的开发,而不用关...

SpringBoot任务调度:@Scheduled与TaskExecutor全面解析

一、任务调度基础概念1.1什么是任务调度任务调度是指按照预定的时间计划或特定条件自动执行任务的过程。在现代应用开发中,任务调度扮演着至关重要的角色,它使得开发者能够自动化处理周期性任务、定时任务和异...

取消回复欢迎 发表评论: