H265视频硬解

硬解,使用非CPU进行编码,如显卡GPU、专用的DSP、FPGA、ASIC芯片等。目前的主流GPU加速平台:INTEL、AMD、NVIDIA。

一、软编码和硬编码比较

软编码:实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。

硬编码:性能高,低码率下通常质量低于软编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。

二、目前主流的GPU平台开发框架

CUVID:NVIDIA的封闭编程框架,通过框架可以调用GPU计算资源,N卡专用。

AMD APP:AMD为自己的GPU提出的一套通用并行编程框架,标准开放,通过在CPU、GPU同时支持OpenCL框架,进行计算力融合。

OpenCL:开放计算语言,为异构平台编写程序的该框架,异构平台可包含CPU、GPU以及其他计算处理器,目标是使相同的运算能支持不同平台硬件加速。

Inel QuickSync:集成于Intel显卡中的专用视频编解码模块,核显专用。

CUDA只能够在NVIDIA的GPU硬件上运行。但是,OpenCL的目标是面向任何一种并行处理器,OpenCL是第一种真正的开放自由版权编程标准,适用于异构系统上的通用计算。而异构平台可由CPU、GPU、DSP、FPGA或其他类型的处理器搭建。

DXVA:DXVA是DirectX Video Acceleration的简称,中文译为视频硬件加速。DXVA是微软公司专门定制的视频加速规范,它共有两个版本,分别是DXVA 1.0和DXVA 2.0,几乎所有的显卡都具备硬件加速能力。

三、流程区别

硬解软编: read(ffmpeg) -》 decoder(NVIDIA) -》 | Queue -》 encoder(ffmpeg)

软解软编: read(ffmpeg) -》 decoder(ffmpeg) -》encoder(ffmpeg)

解码与编码之间维护一个队列,队列长度定为20(因为解码速度快于编码速度,数据被覆盖,丢帧)

四、NVIDIA CUVID,Intel QuickSync和DXVA2,其中DXVA2又分为DXVA2 (copy-back)和DXVA2 (native),那么这几种解码方式有什么区别?

NVIDIA CUVID是NVIDIA专用硬体解码介面,可以开启硬体去交错处理。

Intel QuickSync:Intel內显专用硬体解码介面,CPU使用率比其余硬解模式稍高5~10%左右,可以开启硬体去交错处理。

DXVA2 (copy-back):为微软开发的硬体加速介面,AMD,NVIDIA,Intel显示卡均可使用,会將解码完成的资讯回传给记忆体,由于多个回传动作,故效能会比native略差,不过优势为可以在解码器与渲染器中间添加滤镜。

DXVA2 (native):为微软开发的硬体加速介面,同样AMD,NVIDIA,Intel显示卡均可使用,会將解码完成的资讯將不会传给记忆体,直接渲染,故效能比copy-back佳,缺点为限制较多。

所以解码方式推荐:DXVA2 (native) > DXVA2 (copy-back) > NVIDIA CUVID 或 Intel QuickSync。

五、NVIDIA硬件编解码方案

1、使用 SDK 中的编解码接口

英伟达关于视频的编解码提供了两个相关的 SDK

NVENC --负责硬件编码

NVCUVID --负责硬件解码

NVENC是一个单独的 SDK,集成在最新的显卡驱动上面,安装最新的驱动之后可以找到相关的库文件。在 Ubuntu 14.04 中,可以在/usr/lib/nvidia-352/目录下面找到相关的库文件。

NVCUVID是CUDA的组件,包含在最新的CUDA Toolkit中。不过在显卡的类库中可以找到libnvcuvid.so这个库文件。在之前版本的显卡驱动中其他还包含一个称之为NVCUVENC的硬件编码器和NVCUVID相对应,不过目前这个组件已经被NVENC替代了。

2、使用编码器对于 OpenCL 和 SDK 的封装

这种方式是个人认为最理想的方式,FFMPEG 目前存在一个编码器nvenc是对于英伟达的NVENC的封装,通过使用它可以和 FFMPEG 无缝的整合起来。此外它也包含对于Intel QSV的封装。AMD 的相关接口目前没有找到相关的资料。

不过 FFMPEG 只存在NVENC的接口,不存在NVCUVID的封装。如果需要实现相关的解码器可能需要自己实现 FFMPEG 接口。

libx264有对于 OpenCL 的封装,不过我在 windows 中尝试这个功能的时候并没有成功。

另外还存在一个开源的格式转换器HandBrake,它包含对于Intel QuickSync的封装,以及使用OpenCL进行图象的拉伸处理和使用x264的opencl封装。这个项目缺点在于文档不是很丰富,研究起来有一定的难度。

要想在 FFMPEG 中使用nvenc编码器,你需要在编译选项中加入enable-nvenc选项(老版本,新版本是自动检测,显示提供disable-nvenc的选项)。

这个选项依赖于nvEncodeAPI.h头文件,这个头文件并没有包含在私有驱动中,你需要到NVIDIA VIDEO CODEC SDK中下载 SDK,解压后在Samples/common/inc目录下有这个头文件,把它拷贝到可以链接到的目录中去。之后编译就可以顺利的通过,得到包含nvenc编码器的库。

六、ffmpeg硬解码绘制视频,cpu依然占用高。

cpu占用高主要是因为av_hwframe_transfer_data(sw_frame, frame, 0)占用了cpu,不要用这个函数,应该用d3d+dxva2 或者cuda+opengl硬渲染。

OpenCL主要用于通用的并行计算,它基于预定义的数据结构和代码,可以让GPU处理各种通用的计算任务,例如视频处理、金融建模、科学计算和影像处理等,充分利用现代GPU的并行可扩展性。OpenCL可以在多个硬件平台上运行,包括CPU、GPU和FPGA,并且与OpenGL、Direct3D和其他API无关,因此可以与不同的图形API进行交互。

而OpenGL专注于计算机图形处理和渲染,它提供了一个强大的渲染管道,具有着广泛的支持和广泛的用途。在游戏和虚拟现实应用程序中,OpenGL被用作实时图形渲染的标准API。但是,OpenGL无法执行通用的计算任务,这要求我们使用其他API,例如OpenCL或CUDA。

七、常用命令

1、如何用ffmpeg命令列举支持的硬件解码器:

ffmpeg -hwaccels

2、ffmpeg硬解命令:

ffmpeg -i d:\input.mp4 -vcodec libx264  d:\output.mp4

ffmpeg 转码过程中输出的 frame ,fps,q,size, bitrate ,speed 的意义。

frame表示视频当前第几帧;fps表示一秒编码了多少个视频帧;q表示编码质量;size表示写入文件的数据大小;bitrate表示比特率(单位是 kbits/s 1000位/秒);time表示当前处理文件位置时长;speed表示编码速度(多少秒视频帧/多少秒ffmpeg处理时间)。

根据speed可以计算出ffmpeg耗时,一个视频文件ffmpeg处理完成时间为:视频时长秒/speed。

ffmpeg version 4.4-full_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 10.2.0 (Rev6, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libglslang --enable-vulkan --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mpeg, from 'd:\input.mp4':
  Duration: 03:37:39.62, start: 37915.032111, bitrate: 354 kb/s
  Stream #0:0[0x1e0]: Video: hevc (Main), yuvj420p(pc, bt709), 960x576, 50 fps, 25 tbr, 90k tbn, 50 tbc
  Stream #0:1[0x1c0]: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (hevc_cuvid) -> h264 (h264_nvenc))
Press [q] to stop, [?] for help
Output #0, mp4, to 'd:\ch01_202203302130002-hw3.mp4':
  Metadata:
    encoder         : Lavf58.76.100
  Stream #0:0: Video: h264 (Main) (avc1 / 0x31637661), nv12(pc, bt709, progressive), 960x576 [SAR 1:1 DAR 5:3], q=2-31, 4000 kb/s, 25 fps, 12800 tbn
    Metadata:
      encoder         : Lavc58.134.100 h264_nvenc
    Side data:
      cpb: bitrate max/min/avg: 0/0/4000000 buffer size: 8000000 vbv_delay: N/A
frame=200781 fps=728 q=9.0 size= 3945472kB time=02:13:51.12 bitrate=4024.5kbits/s dup=0 drop=5 speed=29.1x

3、显示英伟达显卡nvidia-smi命令

3.1显示GPU当前的状态:

nvidia-smi

参数详解:

**GPU:**本机中的GPU编号(有多块显卡的时候,从0开始编号)

**Fan:**风扇转速(0%-100%),N/A表示没有风扇,这个速度是计算机期望的风扇转速,实际情况下如果风扇堵转,可能打不到显示的转速。

**Name:**GPU类型,图上GPU的类型是:GeForce MX250/RTX 2080Ti

**Temp:**GPU的温度(GPU温度过高会导致GPU的频率下降)

**Perf:**GPU的性能状态,从P0(最大性能)到P12(最小性能)

**Persistence-M:**持续模式的状态,持续模式虽然耗能大,但是在新的GPU应用启动时花费的时间更少。

**Pwr:Usager/Cap:**能耗表示,Usage:用了多少,Cap总共多少

**Bus-Id:**GPU总线相关显示,domain:bus:device.function

**Disp.A:**Display Active ,表示GPU的显示是否初始化

**Memory-Usage:**显存使用率

**Volatile GPU-Util:**GPU使用率

**Uncorr. ECC:**关于ECC的东西,是否开启错误检查和纠正技术,0/disabled,1/enabled

**Compute M:**计算模式,0/DEFAULT,1/EXCLUSIVE_PROCESS,2/PROHIBITED

**Processes:**显示每个进程占用的显存使用率、进程号、占用的哪个GPU

**type:**进程类型。C 表示计算进程,G 表示图形进程,C+G 表示都有。

3.2隔几秒刷新一下显存状态:

nvidia-smi -l 秒数

3.3将监控结果写入文件,并且指定写入文件的监控字段:

nvidia-smi -l 1 --format=csv --filename=report.csv --query-gpu=timestamp,name,index,utilization.gpu,memory.total,memory.used,power.draw

参考资料:

https://tool.4xseo.com/a/169.html

https://www.cnblogs.com/huty/p/8517141.html

https://blog.csdn.net/qq_40594137/article/details/124959608

https://deepinout.com/opencl/opencl-tutorials/22_difference_between_opencl_and_opengl.html

相关推荐
简鹿办公7 小时前
如何提取某站 MV 视频中的音乐为 MP3 音频
音视频·简鹿视频格式转换器·视频提取mp3音频
yufengxinpian7 小时前
集成了高性能ARM Cortex-M0+处理器的一款SimpleLink 2.4 GHz无线模块-RF-BM-2340B1
单片机·嵌入式硬件·音视频·智能硬件
runing_an_min8 小时前
ffmpeg视频滤镜:替换部分帧-freezeframes
ffmpeg·音视频·freezeframes
runing_an_min11 小时前
ffmpeg视频滤镜:提取缩略图-framestep
ffmpeg·音视频·framestep
小曲曲11 小时前
接口上传视频和oss直传视频到阿里云组件
javascript·阿里云·音视频
安静读书14 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
佑华硬盘拷贝机14 小时前
音频档案批量拷贝:专业SD拷贝机解决方案
音视频
EasyNVR14 小时前
NVR管理平台EasyNVR多个NVR同时管理:全方位安防监控视频融合云平台方案
安全·音视频·监控·视频监控
xcLeigh21 小时前
HTML5超酷响应式视频背景动画特效(六种风格,附源码)
前端·音视频·html5
韩曙亮1 天前
【FFmpeg】FFmpeg 内存结构 ③ ( AVPacket 函数简介 | av_packet_ref 函数 | av_packet_clone 函数 )
ffmpeg·音视频·avpacket·av_packet_clone·av_packet_ref·ffmpeg内存结构