翻译自VPF原作者论坛:python硬解码过程及VPF安装总结

引言

翻译自VPF原作者论坛:python硬解码过程及VPF安装总结

本篇是对VPF原作者在论坛上所发布内容的翻译,内容是关于VPF的方法以及原理介绍,其基本上涵盖了整个python硬解码的过程,通过它能对视频的编解码有一个很全面的认识,关于VPF的安装总结的全过程如下链接:

Video Processing Framework框架的编译过程,Video Processing Framework框架的启动全过程

VideoProcessingFramework介绍

从Kepler一代的NVIDIA GPU起,就开始支持加速的硬件视频编码,自Fermi一代以来的所有GPU,都借助NVIDIA Video Codec SDK支持硬件视频加速解码。

它表现出出色的性能和灵活性,与此同时,它需要C / C ++的知识。另一个选择是使用第三方库和应用程序,比如FFmpeg或GStreamer,它们再次需要内置C / C ++专业知识,并且要为每个用户自定义。

但是,硬件加速视频功能或许对更广泛的受众有帮助,VPF即视频处理框架,其目的是在运用Python处理视频时借助NVIDIA GPU的简单且强大的工具,VPF利用NVIDIA Video Codec SDK来提升灵活性与性能,还为开发人员提供Python所固有的易用性。

VPF是一组C ++库以及Python绑定,它能为视频处理任务提供完整的硬件加速,这些任务包括解码、编码、代码转换,还有GPU加速的色彩空间和像素格式转换,VPF是基于Apache 2许可发布的,基于CMake的开源跨平台软件。它依靠FFmpeg库进行解复用,依靠pybind11项目来构建Python绑定。

VPF把C ++视频处理类导出至PyNvCodec这个Python模块里。为阐述易用性,让我们从一个快速的代码片段着手,该代码片段展示了怎样在GPU上实现完全硬件加速的视频转码,且无需在主机与设备之间复制原始帧:

import PyNvCodec as nvc
gpuID = 0
encFile = “大野兔1080p H.264格式的影片文件”(这里是根据原英文推测的中文含义,因为原英文看起来像是一个视频文件名,具体含义需结合更多背景信息确定) 。
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()
    如果输入文件结束,解码器将返回零表面。
    if not (rawSurface.GetCudaDevicePtr()):
        break
    
    encFrame = nvEnc.EncodeSingleSurface(rawSurface)
    if(encFrame.size):
        frameByteArray = bytearray(encFrame)
         xcodeFile.write(frameByteArray)
编码器是异步的,所以我们需要刷新它。
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的核心部分包含PyNvDecoder类和PyNvEncoder类,这两个类是针对NVIDIA Video Codec SDK的Python绑定。VPF操作存在两种主要的数据类型:

GPU端内存对象的分配复杂,且会严重影响性能,所有归还Surface的情况,拥有它们的情况,以及Surface下次调用时重用先前返回的VPF类方法的情况,都存在。不同的是,VPF类方法每次被调用时都会返回新的NumPy数组实例。移动构造函数用于避免内存复制开销。

PyNvDecoder类支持仅NV12像素格式,PyNvEncoder类也支持仅NV12像素格式,这么做是为了简单起见。一组颜色空间和像素格式转换类支持其他像素格式。所有转换都是GPU加速的,且在VRAM内存中完成,目的是提高性能。

PyNvDecoder 该类有五个主要方法:

DecodeSingleSurface

从输入视频中解码单个帧,返回一个带有解码像素的Surface。下次用户调用这个方法时,之前返回的Surface有可能会被再次使用。要是没有解码帧,那么解码后的Surface的GetCudaDevicePtr方法将会返回零。

DecodeSingleFrame

从输入视频中解码出单帧,返回一个带有解码像素的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,Flush是一种将刷新编码器帧队列的方法。

以下是受支持的编码器参数的列表:

参数

类型

含义

profile

串

编码配置文件。

H264可能的值有,baseline,main,high 。

hevc的可能值:main。

lookahead

整数

前瞻的大小。

vbvinit

整数+单位

VBV初始延迟(以位为单位),可以以1,K,M为单位。

bitrate

整数+单位

平均比特率,可以以1,K,M为单位。

fps

整数

帧率。

preset

串

编码预设。

可能的值有:default,hp,hq,bd,ll,ll_hp,ll_hq,lossless,lossless_hp 。

constqp

整数

constqp速率控制模式的QP值。

qmin

整数

最小QP值。

qmax

整数

最大QP值。

cq

整数

VBR模式的目标恒定质量水平

可能的值:[0,51],0=auto。

initqp

整数

初始QP值。

temporalaq

(无值)启用临时AQ。

vbvbufsize

整数+单位

VBV缓冲区大小(以位为单位),可以1,K,M为单位。

bf

整数

连续B帧的数量。

rc

串

速率控制模式。

可能的值为:constqp,vbr,cbr,cbr_lowdelay_hq,cbr_hq,vbr_hq 。

aq

整数

启用空间AQ并设置其强度

可能的值:[0,15],0=auto。

maxbitrate

整数+单位

最大比特率,可以以1,K,M为单位。

gop

整数

GOP(图片组)的长度。

codec

串

视频编解码器。可能的值:h264,hevc。

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加速的色彩空间和像素格式转换,以下是受支持的转化列表:

PySurfaceConverter 有一种方法:

Execute

在GPU上进行转换操作,把句柄按照输出格式返回给Surface。当下次用户调用这个方法的时候,之前返回的Surface有可能会被再次使用。

总结

VPF为开发人员提供了一个简单且功能强大的Python工具,这个工具用于完全硬件加速的视频编码、解码以及处理类。因为有Python绑定下的C ++代码,所以能在数十行代码中实现较高的GPU利用率。解码后的视频帧以NumPy数组的形式公开,也以CUDA设备指针的形式公开,这样做是为了简化交互并扩展功能。VPF没有对NVIDIA Video Codec SDK设置任何约束,VPF准许您充分发挥NVIDIA专业级GPU的潜能。

原文链接:

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

31阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

26阅读

python教程大全集,python教程600集

2026年09月02日

26阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

22阅读