如何利用GPU加速ffmpeg滤镜的处理速度?
How to use GPU to accelerate the processing speed of ffmpeg filter?
根据 NVIDIA 的开发者网站,您可以使用 GPU 加速 ffmpeg 过滤器的渲染。
Create high-performance end-to-end hardware-accelerated video
processing, 1:N encoding and 1:N transcoding pipeline using built-in > filters in FFmpeg
Ability to add your own custom high-performance CUDA filters using
the shared CUDA context implementation in FFmpeg
我现在遇到的问题是如何使用GPU加速多个ffmpeg滤镜处理?
例如:
ffmpeg -loop 1 -i dog.jpg -filter_complex "scale=iw*4:-1,zoompan=z='zoom+0.002':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':s=720x960" -pix_fmt yuv420p -vcodec libx264 -preset ultrafast -y -r:v 25 -t 5 -crf 28 dog.mp4
您将需要使用它们的扩展来编译您自己的 ffmpeg 版本 - 请参阅 https://developer.nvidia.com/ffmpeg 了解说明,因为标准二进制文件不包含这些功能。
可能的解决方案。未经测试,所以让我知道任何错误...
ffmpeg -loglevel debug -hwaccel NVENC -loop 1 -i dog.jpg -filter_complex "scale=iw*4:-1,zoompan=z='zoom+0.002':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':s=720x960" -pix_fmt yuv420p -vcodec h264_nvenc -preset ultrafast -y -r:v 25 -t 5 -crf 28 dog.mp4
你在哪里...
通过-hwaccel NVENC
初始化NVIDIA编码。
将编解码器设置为-vcodec h264_nvenc
。
说到FFmpeg的硬件加速,按类型你可以期待以下实现:
1. Hardware-accelerated 编码器: 对于 NVIDIA,通过 h264_nvenc 和 hevc_nvenc 包装器支持和实施 NVENC。请参阅 this 关于如何调整它们的答案,以及您可能 运行 进入的任何限制,具体取决于您所使用的硬件代数。
2。 Hardware-accelerated 过滤器: FFmpeg 中提供执行 scaling 和 post-processing(去隔行等)等任务的过滤器,一些实现是 hardware-accelerated。对于 NVIDIA,以下过滤器可以利用 hardware-acceleration:
(一)。 scale_cuda: This is a scaling filter analogous to the generic scale filter, implemented in CUDA. It's dependency is the ffnvcodec 项目,headers 还需要启用 NVENC-based 编码器。当 ffnvcodec headers 存在时,依赖于它的相应过滤器(scale_cuda 和 yadif_cuda)将自动启用。在生产中,弃用此过滤器以支持 scale_npp
可能是明智的,因为它的选项集非常有限。
(b)。 scale_npp: This is a scaling filter implemented in NVIDIA's Performance Primitives. It's primary dependency is the CUDA SDK,当从源代码构建 FFmpeg 时,必须在编译时通过将 --enable-libnpp
、--enable-cuda-nvcc
和 --enable-nonfree
标志传递给 ./configure
来显式启用它。尽可能使用此过滤器代替 scale_cuda
。
(c)。 yadif_cuda:这是一个去隔行器,在 CUDA 中实现。如上所述,它的依赖项是 headers.
的 ffnvcodec 包
(d)。 所有 OpenCL-based 过滤器: 主线 NVIDIA driver 和 CUDA SDK 支持的所有 NVENC-capable GPU 实现了 OpenCL 支持。我以这个澄清开始本节,因为风中有消息称 NVIDIA 将 deprecating mobile Kepler GPUs in their mainline driver,将其降级为旧版支持状态。因此,如果您在这样的平台上,请考虑这一点。
要启用这些过滤器,请在构建时将 --enable-opencl
传递给 FFmpeg 的 ./configure
脚本。请注意,这需要 OpenCL headers 出现在您的系统上,并且您的包管理器可以安全地满足您使用的任何 Linux 发行版。在其他操作系统上,您的情况可能会有所不同。
要查看所有 OpenCL-based 个过滤器,运行:
ffmpeg -h filters | grep opencl
一些值得注意的示例是 unsharp_opencl
、avgblur_opencl
等。有关更多选项,请参阅 this wiki 部分。
(e)。所有 Vulkan-based 个过滤器:
如果 FFmpeg 构建时支持 Vulkan back-end,新的过滤器将可用,可以通过以下方式列出:
ffmpeg -filters | grep vulkan
这些过滤器主要有利于 VAAPI 和 AMD 的 AMF 互操作性,其中共享 HWContext 可用于大幅加速缩放等功能。AMD 的用例尤其允许您执行 hardware-accelerated使用 Vulkan 缩放,这对于 AMF 编码器的 real-time 吞吐量至关重要,因为 FFmpeg 中 AMF 的当前实现缺少缩放过滤器。这可能会在未来改变为 Khronos finishes up on Vulkan extensions for video encoding.
一个Vulkan-based scale filter with FFmpeg 运行ning 在 NVIDIA GPU 上的 NVDEC H/W 加速与 NVENC 编码的示例如下所示:
ffmpeg -threads 1 -loglevel info -nostdin -y \
-fflags +genpts-fastseek \
-init_hw_device cuda=cuda:0 -filter_hw_device cuda \
-hwaccel nvdec -hwaccel_output_format cuda -extra_hw_frames 3 \
-reinit_filter 1 -vsync 1 -async 1 -filter_threads 2 -filter_complex_threads 2 \
-i input.mp4 -filter_complex \
"[0:v]hwupload=derive_device=vulkan,split=2[s0][s1]; \
[s0]scale_vulkan=w=1920:h=1080:scaler=0,hwupload=derive_device=cuda[v0]; \
[s1]scale_vulkan=w=1280:h=720:scaler=0,hwupload=derive_device=cuda[v1]" \
-map "[v0]" -b:v:0 5800k -minrate:v:0 5800k -maxrate:v:0 5800k -bufsize:v:0 5800k -c:v:0 h264_nvenc -r:v:0 ntsc \
-profile:v:0 high -preset:v:0 llhp -rc:v:0 cbr_ld_hq -g:v:0 60 -gpu:v:0 0 -strict_gop:v:0 1 -bf:v:0 0 \
-map "[v1]" -b:v:1 4000k -minrate:v:1 4000k -maxrate:v:1 4000k -bufsize:v:1 4000k -c:v:1 h264_nvenc -r:v:1 ntsc \
-profile:v:1 high -preset:v:1 llhp -rc:v:1 cbr_ld_hq -g:v:1 60 -gpu:v:1 0 -strict_gop:v:1 1 -bf:v:1 0 \
-map 0:a -c:a libfdk_aac -ac 2 -ar 48000 -b:a 128k \
-flags +global_header+cgop \
-max_muxing_queue_size 9000000 -f tee \
"[select=\'v:0,a\':f=mp4]'hq.mp4'| \
[select=\'v:1,a\':f=mp4]'med.mp4'"
查看上面的代码片段如何利用 hwupload 过滤器的设备派生功能将 Vulkan H/W 上下文插入到复杂的过滤器链中。
有关 OpenCL 和 Vulkan-based 过滤器性能的说明: 请考虑过滤器链(例如 hwupload
和hwdownload
可能会引入您的管道,因为在系统内存和加速器之间上传和上传纹理会影响性能,格式转换操作(通过 format
过滤器)也会影响性能,其中 needed/required .
在这种情况下,利用 hwmap
filter, and deriving contexts where applicable. For instance, VAAPI has a mechanism that allows for OpenCL device derivation and reverse mapping via hwmap
, if the cl_intel_va_api_media_sharing
OpenCL extension is present. This is typically provided by the Beignet ICD, and is absent in others, such as the newer Neo OpenCL driver.
可能会有所帮助
3. Hardware-accelerated 解码器(及其关联的包装器): 根据您的输入源和 NVIDIA GPU 的功能,您还可以利用基于 CUVID 或 NVDEC 的硬件加速。这些方法的不同之处在于它们在加速器上处理纹理的方式 in-flight,并且在使用它们时评估其他因素(例如 VRAM 利用率)是明智的。
通常,如果需要,您可以利用 CUVID-based hwaccel 进行去隔行等操作。通过以下方式查看它们的用法:
ffmpeg -h decoder=h264_cuvid
ffmpeg -h decoder=hevc_cuvid
ffmpeg -h decoder=mpeg2_cuvid
但是,请注意处理 MBAFF encoded content with these decoders, where double deinterlacing is required, is not advisable as NVIDIA has not yet implemented MBAFF support in the backend. Take a look at this thread 以获取更多信息。
最后: 评估硬件加速卸载(过滤、编码和解码)在何时何地提供优势或可接受的 trade-off(在质量方面)是明智的,功能支持和可靠性)在生产部署之前在您的管道中。这是一种 vendor-neutral 方法,用于决定卸载管道的哪些部分以及何时卸载,这同样适用于 NVIDIA 的解决方案。
有关详细信息,请参阅 hardware acceleration entry in FFmpeg's wiki。
警告:务必将解码器的线程数降低到 1。这些 hwaccel,尤其是 cuvid(和 nvdec 包装器)不实现线程支持。事实上,如果线程数超过 32,他们会 throw warnings 攻击你。se 解码器、线程数明确假定表面数。
在输入之前将-threads 1
传递给ffmpeg 。线程的参数位置很重要。在这种情况下,它将解码器的线程数设置为 1。输入后,它将 FFmpeg 的编码器和多路复用器(如果支持线程)使用的线程数设置为配置值。
另请注意使用 NVDEC 时直接传递给 FFmpeg 的新参数 -extra_hw_frames 3
的用法。这样做是为了确保分配给解码器和编码器实例的表面池足够,通常是其他过滤器被链接在一起的情况,例如使用 yadif_cuda
、scale_npp
等进行去隔行扫描。参见 this ticket了解更多信息。
根据上述注释演示 hardware-accelerated 过滤、编码和解码使用的示例:
1.用NVENC演示1:N编码的使用:
做出以下假设:test-bed 只有一个 NVENC-capable GPU,一个简单的 GTX 1070。因此,我被限制为同时进行两个 NVENC 会话,并且采用考虑到下面的片段。
请注意,需要使用多个 NVENC-capable GPU 的情况需要适当修改命令行。
我的示例文件在 ~/Desktop/src
我将使用如下所示的示例文件:
ffprobe -i deint-testfile.mkv -show_format -hide_banner -show_streams
Input #0, matroska,webm, from 'deint-testfile.mkv':
Metadata:
encoder : libebml v1.3.3 + libmatroska v1.4.4
creation_time : 2016-03-02T23:20:05.000000Z
Duration: 00:04:56.97, start: 0.066000, bitrate: 31036 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 59.94 fps, 59.94 tbr, 1k tbn, 59.94 tbc (default)
Metadata:
BPS : 29131349
BPS-eng : 29131349
DURATION : 00:04:56.896000000
DURATION-eng : 00:04:56.896000000
NUMBER_OF_FRAMES: 17598
NUMBER_OF_FRAMES-eng: 17598
NUMBER_OF_BYTES : 1081122637
NUMBER_OF_BYTES-eng: 1081122637
_STATISTICS_WRITING_APP: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_APP-eng: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_DATE_UTC: 2016-03-02 23:20:05
_STATISTICS_WRITING_DATE_UTC-eng: 2016-03-02 23:20:05
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:1: Audio: dts (DTS-HD MA), 48000 Hz, stereo, s32p (24 bit) (default)
Metadata:
BPS : 1907258
BPS-eng : 1907258
DURATION : 00:04:56.896000000
DURATION-eng : 00:04:56.896000000
NUMBER_OF_FRAMES: 27834
NUMBER_OF_FRAMES-eng: 27834
NUMBER_OF_BYTES : 70782196
NUMBER_OF_BYTES-eng: 70782196
_STATISTICS_WRITING_APP: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_APP-eng: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_DATE_UTC: 2016-03-02 23:20:05
_STATISTICS_WRITING_DATE_UTC-eng: 2016-03-02 23:20:05
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=High
codec_type=video
codec_time_base=317/38002
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
width=1920
height=1080
coded_width=1920
coded_height=1088
has_b_frames=1
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p
level=41
color_range=tv
color_space=bt709
color_transfer=bt709
color_primaries=bt709
chroma_location=left
field_order=tt
timecode=N/A
refs=1
is_avc=true
nal_length_size=4
id=N/A
r_frame_rate=19001/317
avg_frame_rate=19001/317
time_base=1/1000
start_pts=66
start_time=0.066000
duration_ts=N/A
duration=N/A
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:BPS=29131349
TAG:BPS-eng=29131349
TAG:DURATION=00:04:56.896000000
TAG:DURATION-eng=00:04:56.896000000
TAG:NUMBER_OF_FRAMES=17598
TAG:NUMBER_OF_FRAMES-eng=17598
TAG:NUMBER_OF_BYTES=1081122637
TAG:NUMBER_OF_BYTES-eng=1081122637
TAG:_STATISTICS_WRITING_APP=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_APP-eng=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_DATE_UTC=2016-03-02 23:20:05
TAG:_STATISTICS_WRITING_DATE_UTC-eng=2016-03-02 23:20:05
TAG:_STATISTICS_TAGS=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
TAG:_STATISTICS_TAGS-eng=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
[/STREAM]
[STREAM]
index=1
codec_name=dts
codec_long_name=DCA (DTS Coherent Acoustics)
profile=DTS-HD MA
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
sample_fmt=s32p
sample_rate=48000
channels=2
channel_layout=stereo
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/1000
start_pts=76
start_time=0.076000
duration_ts=N/A
duration=N/A
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=24
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:BPS=1907258
TAG:BPS-eng=1907258
TAG:DURATION=00:04:56.896000000
TAG:DURATION-eng=00:04:56.896000000
TAG:NUMBER_OF_FRAMES=27834
TAG:NUMBER_OF_FRAMES-eng=27834
TAG:NUMBER_OF_BYTES=70782196
TAG:NUMBER_OF_BYTES-eng=70782196
TAG:_STATISTICS_WRITING_APP=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_APP-eng=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_DATE_UTC=2016-03-02 23:20:05
TAG:_STATISTICS_WRITING_DATE_UTC-eng=2016-03-02 23:20:05
TAG:_STATISTICS_TAGS=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
TAG:_STATISTICS_TAGS-eng=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
[/STREAM]
[FORMAT]
filename=deint-testfile.mkv
nb_streams=2
nb_programs=0
format_name=matroska,webm
format_long_name=Matroska / WebM
start_time=0.066000
duration=296.972000
size=1152134036
bit_rate=31036839
probe_score=100
TAG:encoder=libebml v1.3.3 + libmatroska v1.4.4
TAG:creation_time=2016-03-02T23:20:05.000000Z
[/FORMAT]
有了这些信息,我们可以知道输入文件是去隔行的,编码为 59.94 FPS。
在下面的示例中,我将使用封闭的 GOP 以相同的帧速率为目标,假设关键帧距离固定为 2 秒(由 -g 120
设置,其中 -r=60
)。
我可以 运行 如图所示的编码器示例,演示两个用例:
- 使用 cuvid-based 解码器 (h264_cuvid) 作为反交错器(注意输入格式是 H.264/AVC,因此,我们使用正确的解码器):
ffmpeg -threads 1 -fflags +genpts -y -c:v h264_cuvid -surfaces 8 -deint 2 -drop_second_field 1 -hwaccel_output_format cuda -extra_hw_frames 3 \
-i 'deint-testfile.mkv' -filter_complex \
"[0:v:0]split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=super[c]; \
[b]scale_npp=w=640:h=360:interp_algo=super[d]" \
-bsf:a aac_adtstoasc -c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 -async 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 400k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 59.94 -g:v:0 120 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 280k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 59.94 -g:v:1 120 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header+cgop \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks1.flv""
2。将 nvdec hwaccel 与 yadif_cuda 去隔行器配对使用:
ffmpeg -threads 1 -fflags +genpts -y -hwaccel nvdec -hwaccel_output_format cuda -extra_hw_frames 3 \
-i 'deint-testfile.mkv' -filter_complex \
"[0:v:0]yadif_cuda=0:-1:1,split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=super[c]; \
[b]scale_npp=w=640:h=360:interp_algo=super[d]" \
-c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 -async 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 400k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 59.94 -g:v:0 120 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 280k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 59.94 -g:v:1 120 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header+cgop \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks1.flv""
您可以在 yadif_cuda
去隔行器之前使用额外的过滤器,hwupload_cuda
在不需要硬件加速解码的情况下。
当你调用 hwupload_cuda
过滤器时,它会自动创建一个设备类型 cuda,将所有 in-flight 纹理转换为 cuda 格式并将它们上传到共享的 CUDA 硬件上下文,后者从中过滤 yadif_cuda
可以操作。
但是,如果您传递 -hwaccel_output_format cuda
选项,则可以跳过这个额外的 hwupload_cuda
过滤器。这是最大吞吐量的首选方法。
为 yadif_cuda
过滤器指定的选项是:
(一)。设置去隔行模式为每帧发送一帧。
(b)。将假定的图片类型奇偶校验设置为自动。
(c)。仅去隔行标记为去隔行的帧。
您可以通过 运行ning 确认:
ffmpeg -h filter=yadif_cuda
您还可以尝试 double de-interlacing(其中 de-interlacer 每场发送一帧,而不是每帧发送一帧),方法是应用下面的去隔行器选项。(请参阅传入的过滤器选项 yadif_cuda=1:-1:1
):
ffmpeg -fflags +genpts -y -hwaccel nvdec -hwaccel_output_format cuda \
-threads 1 -extra_hw_frames 3 \
-i 'deint-testfile.mkv' -filter_complex \
"[0:v:0]yadif_cuda=1:-1:1,split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=lanczos[c]; \
[b]scale_npp=w=640:h=360:interp_algo=lanczos[d]" \
-af "aresample=async=1000:min_hard_comp=0.100000" -c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 400k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 59.94 -g:v:0 120 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 280k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 59.94 -g:v:1 120 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks1.flv""
但是,请谨慎使用此选项,因为它可能会在某些特定的帧速率下失败。在我的测试中,使用 29.970 FPS 的 NTSC 隔行扫描内容导致在尝试双反隔行扫描时失败。
您的里程可能会有所不同。
3.演示如何将 OpenCL 过滤器与 NVIDIA GPU 结合使用:
我们将在本例中使用的过滤器是 tonemap_opencl
,具有以下使用选项:
ffmpeg -h filter=tonemap_opencl
Filter tonemap_opencl
perform HDR to SDR conversion with tonemapping
Inputs:
#0: default (video)
Outputs:
#0: default (video)
tonemap_opencl AVOptions:
tonemap <int> ..FV..... tonemap algorithm selection (from 0 to 6) (default none)
none ..FV.....
linear ..FV.....
gamma ..FV.....
clip ..FV.....
reinhard ..FV.....
hable ..FV.....
mobius ..FV.....
transfer <int> ..FV..... set transfer characteristic (from -1 to INT_MAX) (default bt709)
bt709 ..FV.....
bt2020 ..FV.....
t <int> ..FV..... set transfer characteristic (from -1 to INT_MAX) (default bt709)
bt709 ..FV.....
bt2020 ..FV.....
matrix <int> ..FV..... set colorspace matrix (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
m <int> ..FV..... set colorspace matrix (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
primaries <int> ..FV..... set color primaries (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
p <int> ..FV..... set color primaries (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
range <int> ..FV..... set color range (from -1 to INT_MAX) (default -1)
tv ..FV.....
pc ..FV.....
limited ..FV.....
full ..FV.....
r <int> ..FV..... set color range (from -1 to INT_MAX) (default -1)
tv ..FV.....
pc ..FV.....
limited ..FV.....
full ..FV.....
format <pix_fmt> ..FV..... output pixel format (default none)
peak <double> ..FV..... signal peak override (from 0 to DBL_MAX) (default 0)
param <double> ..FV..... tonemap parameter (from DBL_MIN to DBL_MAX) (default nan)
desat <double> ..FV..... desaturation parameter (from 0 to DBL_MAX) (default 0.5)
threshold <double> ..FV..... scene detection threshold (from 0 to DBL_MAX) (default 0.2)
正在使用的示例文件嵌入了 HDR 元数据,并且使用 NVENC 编码器,将被编码为一对应用了 tone-mapping 的输出。
使用的示例文件来自 this URL.
来自 ffprobe:
ffprobe -i lgnyhdrdemo.ts -show_streams -hide_banner -show_format
[mpegts @ 0x55f34f8bbf80] start time for stream 1 is not set in estimate_timings_from_pts
[mpegts @ 0x55f34f8bbf80] Could not find codec parameters for stream 1 (Audio: aac ([15][0][0][0] / 0x000F), 0 channels): unspecified sample format
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from 'lgnyhdrdemo.ts':
Duration: 00:01:12.24, start: 0.999989, bitrate: 52032 kb/s
Program 1
Stream #0:0[0x101]: Video: hevc (Main 10) ([36][0][0][0] / 0x0024), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x2160 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 25 tbc
Stream #0:1[0x102](und): Audio: aac ([15][0][0][0] / 0x000F), 0 channels
[STREAM]
index=0
codec_name=hevc
codec_long_name=H.265 / HEVC (High Efficiency Video Coding)
profile=Main 10
codec_type=video
codec_time_base=1/25
codec_tag_string=[36][0][0][0]
codec_tag=0x0024
width=3840
height=2160
coded_width=3840
coded_height=2160
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p10le
level=150
color_range=tv
color_space=bt2020nc
color_transfer=smpte2084
color_primaries=bt2020
chroma_location=unspecified
field_order=unknown
timecode=N/A
refs=1
id=0x101
r_frame_rate=25/1
avg_frame_rate=25/1
time_base=1/90000
start_pts=89999
start_time=0.999989
duration_ts=6501600
duration=72.240000
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
[/STREAM]
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=unknown
codec_type=audio
codec_time_base=1/0
codec_tag_string=[15][0][0][0]
codec_tag=0x000f
sample_fmt=unknown
sample_rate=0
channels=0
channel_layout=unknown
bits_per_sample=0
id=0x102
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/90000
start_pts=89999
start_time=0.999989
duration_ts=6501600
duration=72.240000
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:language=und
[/STREAM]
[FORMAT]
filename=lgnyhdrdemo.ts
nb_streams=2
nb_programs=1
format_name=mpegts
format_long_name=MPEG-TS (MPEG-2 Transport Stream)
start_time=0.999989
duration=72.240000
size=469857120
bit_rate=52032903
probe_score=50
[/FORMAT]
现在让我们将 tonemap_opencl
过滤器应用于上一个命令,切换到新的输入文件,并对命令计时:
time ffmpeg -fflags +genpts -y -hwaccel nvdec -init_hw_device opencl=ocl -filter_hw_device ocl \
-threads 1 -extra_hw_frames 3 \
-i 'lgnyhdrdemo.ts' -filter_complex \
"[0:v:0]hwupload,tonemap_opencl=t=bt2020:tonemap=hable:desat=0:format=nv12,hwupload_cuda,split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=lanczos[c]; \
[b]scale_npp=w=640:h=360:interp_algo=lanczos[d]" \
-af "aresample=async=1000:min_hard_comp=0.100000" -c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 480k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 25 -g:v:0 50 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 672k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 25 -g:v:1 50 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/tonemapped0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/tonemapped1.flv""
根据 FFmpeg,这花费了:
frame= 1806 fps= 37 q=2.0 Lq=2.0 size=N/A time=00:01:12.20 bitrate=N/A speed=1.49x
video:84533kB audio:1068kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[aac @ 0x562e85cc9b00] Qavg: 4252.148
real 0m48.894s
user 0m45.710s
sys 0m17.049s
有关 tone-mapping 的更多信息,请参阅 this 优秀 write-up。
根据 NVIDIA 的开发者网站,您可以使用 GPU 加速 ffmpeg 过滤器的渲染。
Create high-performance end-to-end hardware-accelerated video processing, 1:N encoding and 1:N transcoding pipeline using built-in > filters in FFmpeg
Ability to add your own custom high-performance CUDA filters using the shared CUDA context implementation in FFmpeg
我现在遇到的问题是如何使用GPU加速多个ffmpeg滤镜处理?
例如:
ffmpeg -loop 1 -i dog.jpg -filter_complex "scale=iw*4:-1,zoompan=z='zoom+0.002':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':s=720x960" -pix_fmt yuv420p -vcodec libx264 -preset ultrafast -y -r:v 25 -t 5 -crf 28 dog.mp4
您将需要使用它们的扩展来编译您自己的 ffmpeg 版本 - 请参阅 https://developer.nvidia.com/ffmpeg 了解说明,因为标准二进制文件不包含这些功能。
可能的解决方案。未经测试,所以让我知道任何错误...
ffmpeg -loglevel debug -hwaccel NVENC -loop 1 -i dog.jpg -filter_complex "scale=iw*4:-1,zoompan=z='zoom+0.002':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':s=720x960" -pix_fmt yuv420p -vcodec h264_nvenc -preset ultrafast -y -r:v 25 -t 5 -crf 28 dog.mp4
你在哪里...
通过
-hwaccel NVENC
初始化NVIDIA编码。将编解码器设置为
-vcodec h264_nvenc
。
说到FFmpeg的硬件加速,按类型你可以期待以下实现:
1. Hardware-accelerated 编码器: 对于 NVIDIA,通过 h264_nvenc 和 hevc_nvenc 包装器支持和实施 NVENC。请参阅 this 关于如何调整它们的答案,以及您可能 运行 进入的任何限制,具体取决于您所使用的硬件代数。
2。 Hardware-accelerated 过滤器: FFmpeg 中提供执行 scaling 和 post-processing(去隔行等)等任务的过滤器,一些实现是 hardware-accelerated。对于 NVIDIA,以下过滤器可以利用 hardware-acceleration:
(一)。 scale_cuda: This is a scaling filter analogous to the generic scale filter, implemented in CUDA. It's dependency is the ffnvcodec 项目,headers 还需要启用 NVENC-based 编码器。当 ffnvcodec headers 存在时,依赖于它的相应过滤器(scale_cuda 和 yadif_cuda)将自动启用。在生产中,弃用此过滤器以支持 scale_npp
可能是明智的,因为它的选项集非常有限。
(b)。 scale_npp: This is a scaling filter implemented in NVIDIA's Performance Primitives. It's primary dependency is the CUDA SDK,当从源代码构建 FFmpeg 时,必须在编译时通过将 --enable-libnpp
、--enable-cuda-nvcc
和 --enable-nonfree
标志传递给 ./configure
来显式启用它。尽可能使用此过滤器代替 scale_cuda
。
(c)。 yadif_cuda:这是一个去隔行器,在 CUDA 中实现。如上所述,它的依赖项是 headers.
的 ffnvcodec 包(d)。 所有 OpenCL-based 过滤器: 主线 NVIDIA driver 和 CUDA SDK 支持的所有 NVENC-capable GPU 实现了 OpenCL 支持。我以这个澄清开始本节,因为风中有消息称 NVIDIA 将 deprecating mobile Kepler GPUs in their mainline driver,将其降级为旧版支持状态。因此,如果您在这样的平台上,请考虑这一点。
要启用这些过滤器,请在构建时将 --enable-opencl
传递给 FFmpeg 的 ./configure
脚本。请注意,这需要 OpenCL headers 出现在您的系统上,并且您的包管理器可以安全地满足您使用的任何 Linux 发行版。在其他操作系统上,您的情况可能会有所不同。
要查看所有 OpenCL-based 个过滤器,运行:
ffmpeg -h filters | grep opencl
一些值得注意的示例是 unsharp_opencl
、avgblur_opencl
等。有关更多选项,请参阅 this wiki 部分。
(e)。所有 Vulkan-based 个过滤器:
如果 FFmpeg 构建时支持 Vulkan back-end,新的过滤器将可用,可以通过以下方式列出:
ffmpeg -filters | grep vulkan
这些过滤器主要有利于 VAAPI 和 AMD 的 AMF 互操作性,其中共享 HWContext 可用于大幅加速缩放等功能。AMD 的用例尤其允许您执行 hardware-accelerated使用 Vulkan 缩放,这对于 AMF 编码器的 real-time 吞吐量至关重要,因为 FFmpeg 中 AMF 的当前实现缺少缩放过滤器。这可能会在未来改变为 Khronos finishes up on Vulkan extensions for video encoding.
一个Vulkan-based scale filter with FFmpeg 运行ning 在 NVIDIA GPU 上的 NVDEC H/W 加速与 NVENC 编码的示例如下所示:
ffmpeg -threads 1 -loglevel info -nostdin -y \
-fflags +genpts-fastseek \
-init_hw_device cuda=cuda:0 -filter_hw_device cuda \
-hwaccel nvdec -hwaccel_output_format cuda -extra_hw_frames 3 \
-reinit_filter 1 -vsync 1 -async 1 -filter_threads 2 -filter_complex_threads 2 \
-i input.mp4 -filter_complex \
"[0:v]hwupload=derive_device=vulkan,split=2[s0][s1]; \
[s0]scale_vulkan=w=1920:h=1080:scaler=0,hwupload=derive_device=cuda[v0]; \
[s1]scale_vulkan=w=1280:h=720:scaler=0,hwupload=derive_device=cuda[v1]" \
-map "[v0]" -b:v:0 5800k -minrate:v:0 5800k -maxrate:v:0 5800k -bufsize:v:0 5800k -c:v:0 h264_nvenc -r:v:0 ntsc \
-profile:v:0 high -preset:v:0 llhp -rc:v:0 cbr_ld_hq -g:v:0 60 -gpu:v:0 0 -strict_gop:v:0 1 -bf:v:0 0 \
-map "[v1]" -b:v:1 4000k -minrate:v:1 4000k -maxrate:v:1 4000k -bufsize:v:1 4000k -c:v:1 h264_nvenc -r:v:1 ntsc \
-profile:v:1 high -preset:v:1 llhp -rc:v:1 cbr_ld_hq -g:v:1 60 -gpu:v:1 0 -strict_gop:v:1 1 -bf:v:1 0 \
-map 0:a -c:a libfdk_aac -ac 2 -ar 48000 -b:a 128k \
-flags +global_header+cgop \
-max_muxing_queue_size 9000000 -f tee \
"[select=\'v:0,a\':f=mp4]'hq.mp4'| \
[select=\'v:1,a\':f=mp4]'med.mp4'"
查看上面的代码片段如何利用 hwupload 过滤器的设备派生功能将 Vulkan H/W 上下文插入到复杂的过滤器链中。
有关 OpenCL 和 Vulkan-based 过滤器性能的说明: 请考虑过滤器链(例如 hwupload
和hwdownload
可能会引入您的管道,因为在系统内存和加速器之间上传和上传纹理会影响性能,格式转换操作(通过 format
过滤器)也会影响性能,其中 needed/required .
在这种情况下,利用 hwmap
filter, and deriving contexts where applicable. For instance, VAAPI has a mechanism that allows for OpenCL device derivation and reverse mapping via hwmap
, if the cl_intel_va_api_media_sharing
OpenCL extension is present. This is typically provided by the Beignet ICD, and is absent in others, such as the newer Neo OpenCL driver.
3. Hardware-accelerated 解码器(及其关联的包装器): 根据您的输入源和 NVIDIA GPU 的功能,您还可以利用基于 CUVID 或 NVDEC 的硬件加速。这些方法的不同之处在于它们在加速器上处理纹理的方式 in-flight,并且在使用它们时评估其他因素(例如 VRAM 利用率)是明智的。 通常,如果需要,您可以利用 CUVID-based hwaccel 进行去隔行等操作。通过以下方式查看它们的用法:
ffmpeg -h decoder=h264_cuvid
ffmpeg -h decoder=hevc_cuvid
ffmpeg -h decoder=mpeg2_cuvid
但是,请注意处理 MBAFF encoded content with these decoders, where double deinterlacing is required, is not advisable as NVIDIA has not yet implemented MBAFF support in the backend. Take a look at this thread 以获取更多信息。
最后: 评估硬件加速卸载(过滤、编码和解码)在何时何地提供优势或可接受的 trade-off(在质量方面)是明智的,功能支持和可靠性)在生产部署之前在您的管道中。这是一种 vendor-neutral 方法,用于决定卸载管道的哪些部分以及何时卸载,这同样适用于 NVIDIA 的解决方案。
有关详细信息,请参阅 hardware acceleration entry in FFmpeg's wiki。
警告:务必将解码器的线程数降低到 1。这些 hwaccel,尤其是 cuvid(和 nvdec 包装器)不实现线程支持。事实上,如果线程数超过 32,他们会 throw warnings 攻击你。se 解码器、线程数明确假定表面数。
在输入之前将-threads 1
传递给ffmpeg 。线程的参数位置很重要。在这种情况下,它将解码器的线程数设置为 1。输入后,它将 FFmpeg 的编码器和多路复用器(如果支持线程)使用的线程数设置为配置值。
另请注意使用 NVDEC 时直接传递给 FFmpeg 的新参数 -extra_hw_frames 3
的用法。这样做是为了确保分配给解码器和编码器实例的表面池足够,通常是其他过滤器被链接在一起的情况,例如使用 yadif_cuda
、scale_npp
等进行去隔行扫描。参见 this ticket了解更多信息。
根据上述注释演示 hardware-accelerated 过滤、编码和解码使用的示例:
1.用NVENC演示1:N编码的使用:
做出以下假设:test-bed 只有一个 NVENC-capable GPU,一个简单的 GTX 1070。因此,我被限制为同时进行两个 NVENC 会话,并且采用考虑到下面的片段。 请注意,需要使用多个 NVENC-capable GPU 的情况需要适当修改命令行。
我的示例文件在 ~/Desktop/src
我将使用如下所示的示例文件:
ffprobe -i deint-testfile.mkv -show_format -hide_banner -show_streams
Input #0, matroska,webm, from 'deint-testfile.mkv':
Metadata:
encoder : libebml v1.3.3 + libmatroska v1.4.4
creation_time : 2016-03-02T23:20:05.000000Z
Duration: 00:04:56.97, start: 0.066000, bitrate: 31036 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 59.94 fps, 59.94 tbr, 1k tbn, 59.94 tbc (default)
Metadata:
BPS : 29131349
BPS-eng : 29131349
DURATION : 00:04:56.896000000
DURATION-eng : 00:04:56.896000000
NUMBER_OF_FRAMES: 17598
NUMBER_OF_FRAMES-eng: 17598
NUMBER_OF_BYTES : 1081122637
NUMBER_OF_BYTES-eng: 1081122637
_STATISTICS_WRITING_APP: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_APP-eng: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_DATE_UTC: 2016-03-02 23:20:05
_STATISTICS_WRITING_DATE_UTC-eng: 2016-03-02 23:20:05
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:1: Audio: dts (DTS-HD MA), 48000 Hz, stereo, s32p (24 bit) (default)
Metadata:
BPS : 1907258
BPS-eng : 1907258
DURATION : 00:04:56.896000000
DURATION-eng : 00:04:56.896000000
NUMBER_OF_FRAMES: 27834
NUMBER_OF_FRAMES-eng: 27834
NUMBER_OF_BYTES : 70782196
NUMBER_OF_BYTES-eng: 70782196
_STATISTICS_WRITING_APP: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_APP-eng: mkvmerge v8.9.0 ('Father Daughter') 64bit
_STATISTICS_WRITING_DATE_UTC: 2016-03-02 23:20:05
_STATISTICS_WRITING_DATE_UTC-eng: 2016-03-02 23:20:05
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=High
codec_type=video
codec_time_base=317/38002
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
width=1920
height=1080
coded_width=1920
coded_height=1088
has_b_frames=1
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p
level=41
color_range=tv
color_space=bt709
color_transfer=bt709
color_primaries=bt709
chroma_location=left
field_order=tt
timecode=N/A
refs=1
is_avc=true
nal_length_size=4
id=N/A
r_frame_rate=19001/317
avg_frame_rate=19001/317
time_base=1/1000
start_pts=66
start_time=0.066000
duration_ts=N/A
duration=N/A
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:BPS=29131349
TAG:BPS-eng=29131349
TAG:DURATION=00:04:56.896000000
TAG:DURATION-eng=00:04:56.896000000
TAG:NUMBER_OF_FRAMES=17598
TAG:NUMBER_OF_FRAMES-eng=17598
TAG:NUMBER_OF_BYTES=1081122637
TAG:NUMBER_OF_BYTES-eng=1081122637
TAG:_STATISTICS_WRITING_APP=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_APP-eng=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_DATE_UTC=2016-03-02 23:20:05
TAG:_STATISTICS_WRITING_DATE_UTC-eng=2016-03-02 23:20:05
TAG:_STATISTICS_TAGS=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
TAG:_STATISTICS_TAGS-eng=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
[/STREAM]
[STREAM]
index=1
codec_name=dts
codec_long_name=DCA (DTS Coherent Acoustics)
profile=DTS-HD MA
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
sample_fmt=s32p
sample_rate=48000
channels=2
channel_layout=stereo
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/1000
start_pts=76
start_time=0.076000
duration_ts=N/A
duration=N/A
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=24
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:BPS=1907258
TAG:BPS-eng=1907258
TAG:DURATION=00:04:56.896000000
TAG:DURATION-eng=00:04:56.896000000
TAG:NUMBER_OF_FRAMES=27834
TAG:NUMBER_OF_FRAMES-eng=27834
TAG:NUMBER_OF_BYTES=70782196
TAG:NUMBER_OF_BYTES-eng=70782196
TAG:_STATISTICS_WRITING_APP=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_APP-eng=mkvmerge v8.9.0 ('Father Daughter') 64bit
TAG:_STATISTICS_WRITING_DATE_UTC=2016-03-02 23:20:05
TAG:_STATISTICS_WRITING_DATE_UTC-eng=2016-03-02 23:20:05
TAG:_STATISTICS_TAGS=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
TAG:_STATISTICS_TAGS-eng=BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
[/STREAM]
[FORMAT]
filename=deint-testfile.mkv
nb_streams=2
nb_programs=0
format_name=matroska,webm
format_long_name=Matroska / WebM
start_time=0.066000
duration=296.972000
size=1152134036
bit_rate=31036839
probe_score=100
TAG:encoder=libebml v1.3.3 + libmatroska v1.4.4
TAG:creation_time=2016-03-02T23:20:05.000000Z
[/FORMAT]
有了这些信息,我们可以知道输入文件是去隔行的,编码为 59.94 FPS。
在下面的示例中,我将使用封闭的 GOP 以相同的帧速率为目标,假设关键帧距离固定为 2 秒(由 -g 120
设置,其中 -r=60
)。
我可以 运行 如图所示的编码器示例,演示两个用例:
- 使用 cuvid-based 解码器 (h264_cuvid) 作为反交错器(注意输入格式是 H.264/AVC,因此,我们使用正确的解码器):
ffmpeg -threads 1 -fflags +genpts -y -c:v h264_cuvid -surfaces 8 -deint 2 -drop_second_field 1 -hwaccel_output_format cuda -extra_hw_frames 3 \
-i 'deint-testfile.mkv' -filter_complex \
"[0:v:0]split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=super[c]; \
[b]scale_npp=w=640:h=360:interp_algo=super[d]" \
-bsf:a aac_adtstoasc -c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 -async 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 400k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 59.94 -g:v:0 120 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 280k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 59.94 -g:v:1 120 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header+cgop \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks1.flv""
2。将 nvdec hwaccel 与 yadif_cuda 去隔行器配对使用:
ffmpeg -threads 1 -fflags +genpts -y -hwaccel nvdec -hwaccel_output_format cuda -extra_hw_frames 3 \
-i 'deint-testfile.mkv' -filter_complex \
"[0:v:0]yadif_cuda=0:-1:1,split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=super[c]; \
[b]scale_npp=w=640:h=360:interp_algo=super[d]" \
-c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 -async 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 400k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 59.94 -g:v:0 120 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 280k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 59.94 -g:v:1 120 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header+cgop \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks1.flv""
您可以在 yadif_cuda
去隔行器之前使用额外的过滤器,hwupload_cuda
在不需要硬件加速解码的情况下。
当你调用 hwupload_cuda
过滤器时,它会自动创建一个设备类型 cuda,将所有 in-flight 纹理转换为 cuda 格式并将它们上传到共享的 CUDA 硬件上下文,后者从中过滤 yadif_cuda
可以操作。
但是,如果您传递 -hwaccel_output_format cuda
选项,则可以跳过这个额外的 hwupload_cuda
过滤器。这是最大吞吐量的首选方法。
为 yadif_cuda
过滤器指定的选项是:
(一)。设置去隔行模式为每帧发送一帧。
(b)。将假定的图片类型奇偶校验设置为自动。
(c)。仅去隔行标记为去隔行的帧。
您可以通过 运行ning 确认:
ffmpeg -h filter=yadif_cuda
您还可以尝试 double de-interlacing(其中 de-interlacer 每场发送一帧,而不是每帧发送一帧),方法是应用下面的去隔行器选项。(请参阅传入的过滤器选项 yadif_cuda=1:-1:1
):
ffmpeg -fflags +genpts -y -hwaccel nvdec -hwaccel_output_format cuda \
-threads 1 -extra_hw_frames 3 \
-i 'deint-testfile.mkv' -filter_complex \
"[0:v:0]yadif_cuda=1:-1:1,split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=lanczos[c]; \
[b]scale_npp=w=640:h=360:interp_algo=lanczos[d]" \
-af "aresample=async=1000:min_hard_comp=0.100000" -c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 400k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 59.94 -g:v:0 120 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 280k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 59.94 -g:v:1 120 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/cheeks1.flv""
但是,请谨慎使用此选项,因为它可能会在某些特定的帧速率下失败。在我的测试中,使用 29.970 FPS 的 NTSC 隔行扫描内容导致在尝试双反隔行扫描时失败。 您的里程可能会有所不同。
3.演示如何将 OpenCL 过滤器与 NVIDIA GPU 结合使用:
我们将在本例中使用的过滤器是 tonemap_opencl
,具有以下使用选项:
ffmpeg -h filter=tonemap_opencl
Filter tonemap_opencl
perform HDR to SDR conversion with tonemapping
Inputs:
#0: default (video)
Outputs:
#0: default (video)
tonemap_opencl AVOptions:
tonemap <int> ..FV..... tonemap algorithm selection (from 0 to 6) (default none)
none ..FV.....
linear ..FV.....
gamma ..FV.....
clip ..FV.....
reinhard ..FV.....
hable ..FV.....
mobius ..FV.....
transfer <int> ..FV..... set transfer characteristic (from -1 to INT_MAX) (default bt709)
bt709 ..FV.....
bt2020 ..FV.....
t <int> ..FV..... set transfer characteristic (from -1 to INT_MAX) (default bt709)
bt709 ..FV.....
bt2020 ..FV.....
matrix <int> ..FV..... set colorspace matrix (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
m <int> ..FV..... set colorspace matrix (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
primaries <int> ..FV..... set color primaries (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
p <int> ..FV..... set color primaries (from -1 to INT_MAX) (default -1)
bt709 ..FV.....
bt2020 ..FV.....
range <int> ..FV..... set color range (from -1 to INT_MAX) (default -1)
tv ..FV.....
pc ..FV.....
limited ..FV.....
full ..FV.....
r <int> ..FV..... set color range (from -1 to INT_MAX) (default -1)
tv ..FV.....
pc ..FV.....
limited ..FV.....
full ..FV.....
format <pix_fmt> ..FV..... output pixel format (default none)
peak <double> ..FV..... signal peak override (from 0 to DBL_MAX) (default 0)
param <double> ..FV..... tonemap parameter (from DBL_MIN to DBL_MAX) (default nan)
desat <double> ..FV..... desaturation parameter (from 0 to DBL_MAX) (default 0.5)
threshold <double> ..FV..... scene detection threshold (from 0 to DBL_MAX) (default 0.2)
正在使用的示例文件嵌入了 HDR 元数据,并且使用 NVENC 编码器,将被编码为一对应用了 tone-mapping 的输出。 使用的示例文件来自 this URL.
来自 ffprobe:
ffprobe -i lgnyhdrdemo.ts -show_streams -hide_banner -show_format
[mpegts @ 0x55f34f8bbf80] start time for stream 1 is not set in estimate_timings_from_pts
[mpegts @ 0x55f34f8bbf80] Could not find codec parameters for stream 1 (Audio: aac ([15][0][0][0] / 0x000F), 0 channels): unspecified sample format
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from 'lgnyhdrdemo.ts':
Duration: 00:01:12.24, start: 0.999989, bitrate: 52032 kb/s
Program 1
Stream #0:0[0x101]: Video: hevc (Main 10) ([36][0][0][0] / 0x0024), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x2160 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 25 tbc
Stream #0:1[0x102](und): Audio: aac ([15][0][0][0] / 0x000F), 0 channels
[STREAM]
index=0
codec_name=hevc
codec_long_name=H.265 / HEVC (High Efficiency Video Coding)
profile=Main 10
codec_type=video
codec_time_base=1/25
codec_tag_string=[36][0][0][0]
codec_tag=0x0024
width=3840
height=2160
coded_width=3840
coded_height=2160
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p10le
level=150
color_range=tv
color_space=bt2020nc
color_transfer=smpte2084
color_primaries=bt2020
chroma_location=unspecified
field_order=unknown
timecode=N/A
refs=1
id=0x101
r_frame_rate=25/1
avg_frame_rate=25/1
time_base=1/90000
start_pts=89999
start_time=0.999989
duration_ts=6501600
duration=72.240000
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
[/STREAM]
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=unknown
codec_type=audio
codec_time_base=1/0
codec_tag_string=[15][0][0][0]
codec_tag=0x000f
sample_fmt=unknown
sample_rate=0
channels=0
channel_layout=unknown
bits_per_sample=0
id=0x102
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/90000
start_pts=89999
start_time=0.999989
duration_ts=6501600
duration=72.240000
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:language=und
[/STREAM]
[FORMAT]
filename=lgnyhdrdemo.ts
nb_streams=2
nb_programs=1
format_name=mpegts
format_long_name=MPEG-TS (MPEG-2 Transport Stream)
start_time=0.999989
duration=72.240000
size=469857120
bit_rate=52032903
probe_score=50
[/FORMAT]
现在让我们将 tonemap_opencl
过滤器应用于上一个命令,切换到新的输入文件,并对命令计时:
time ffmpeg -fflags +genpts -y -hwaccel nvdec -init_hw_device opencl=ocl -filter_hw_device ocl \
-threads 1 -extra_hw_frames 3 \
-i 'lgnyhdrdemo.ts' -filter_complex \
"[0:v:0]hwupload,tonemap_opencl=t=bt2020:tonemap=hable:desat=0:format=nv12,hwupload_cuda,split=2[a][b]; \
[a]scale_npp=w=1280:h=720:interp_algo=lanczos[c]; \
[b]scale_npp=w=640:h=360:interp_algo=lanczos[d]" \
-af "aresample=async=1000:min_hard_comp=0.100000" -c:a aac -ac 2 -ar 48000 -b:a 128k -vsync 1 \
-b:v:0 6000k -minrate:v:0 6000k -maxrate:v:0 6000k -bufsize:v:0 480k -c:v:0 h264_nvenc \
-profile:v:0 high -rc:v:0 cbr_ld_hq -level:v:0 4.2 -r:v:0 25 -g:v:0 50 -bf:v:0 3 -strict_gop:v:0 1 \
-b:v:1 4200k -minrate:v:1 4200k -maxrate:v:1 4200k -bufsize:v:1 672k -c:v:1 h264_nvenc \
-profile:v:1 high -rc:v:1 cbr_ld_hq -level:v:1 4.2 -r:v:1 25 -g:v:1 50 -bf:v:1 3 -strict_gop:v:1 1 \
-flags +global_header \
-map "[c]" -map "[d]" -map a:0 \
-f tee \
"[select=\'v:0,a\':f=flv]"/home/brainiarc7/Desktop/src/tonemapped0.flv"| \
[select=\'v:1,a\':f=flv]"/home/brainiarc7/Desktop/src/tonemapped1.flv""
根据 FFmpeg,这花费了:
frame= 1806 fps= 37 q=2.0 Lq=2.0 size=N/A time=00:01:12.20 bitrate=N/A speed=1.49x
video:84533kB audio:1068kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[aac @ 0x562e85cc9b00] Qavg: 4252.148
real 0m48.894s
user 0m45.710s
sys 0m17.049s
有关 tone-mapping 的更多信息,请参阅 this 优秀 write-up。