(FFmpeg)VP9 Vaapi从给定的官方ffmpeg示例编码为.mp4或.webm容器 [英] (FFmpeg) VP9 Vaapi encoding to a .mp4 or .webm container from given official ffmpeg example
问题描述
我正在尝试实施vp9硬件加速编码过程.我遵循了ffmpeg官方github的示例(此处-> vaapi_encode.c ).
I'm trying to implement vp9 hardware acceleration encoding process. I followed ffmpeg offical github's example (Here -> vaapi_encode.c).
但是给定的示例仅将.yuv文件保存为.h264文件,我想将框架保存到.mp4或.webm容器.并具有控制质量等的能力.
But given example only save a .yuv file to .h264 file, I would like to save the frames to either .mp4 or .webm container. And having the ability to control the quality, and etc.
我不是从文件中读取帧,而是从实时供稿中收集帧.当从实时Feed获得完整的5秒钟帧时,请使用vp9_vaapi将这些帧编码为5秒钟的.mp4文件.
I'm not reading frames from a file, I'm collecting frames from a live feed. When having full 5 secs of frames from the live feed, encode those frames using vp9_vaapi to a 5 secs .mp4 file.
我能够将所有5秒钟的帧从实时供稿中保存到.mp4或.webm文件中,但无法正确播放(更精确的说:保持加载状态,然后打开).
I'm able to save all the 5 secs frames from my live feed to a .mp4 or .webm file, but they couldn't be played correctly (more precisely: keep loading, and I open).
官方网站示例的结果:
cpu编码的vp9 .mp4文件结果:
The cpu encoded vp9 .mp4 file result:
结果
推荐答案
您将需要直接使用FFmpeg,您可以选择在其中添加 vp9_raw_reorder 比特流过滤器如果在vp9_vaapi
编码器中启用了B帧,则在同一命令行中.
You will need to use FFmpeg directly, where you may optionally add the vp9_superframe and the vp9_raw_reorder bitstream filters in the same command line if you enable B-frames in the vp9_vaapi
encoder.
示例:
ffmpeg -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -re -i http://server:port -vf 'format=nv12|vaapi,hwupload' -c:v vp9_vaapi -global_quality 50 -bf 1 -bsf:v vp9_raw_reorder,vp9_superframe -f segment -segment_time 5 -segment_format_options movflags=+faststart output%03d.mp4
根据需要调整输入和输出路径/URL.
Adjust your input and output paths/urls as needed.
此命令的作用:
It will create 5 second long mp4 segments, via the segment muxer.
See the usage of the movflags=+faststart
, and how it has been passed as a format option to the underlying mp4 muxer via -segment_format_options
flag above.
段的长度可能不完全是5秒长,因为每个段开始(切入)(带有关键帧).
The segment lengths may not be exactly 5 seconds long, as each segment begins (gets cut on) (with) a keyframe.
但是,我不建议在该编码器中启用B帧,因为这些位流过滤器还有其他不良影响,例如触发这样的错误.这在生产环境中是不希望的.这就是下面的脚本未启用该选项的原因,而我们直接在编码器选项中定义了设置速率控制模式.
However, I'd not recommend enabling B-frames in that encoder, as these bitstream filters have other undesired effects, such as mucking around with the encoder's rate control and triggering bugs like this one. This is not desirable in a production environment. This is why the scripts below do not have that option enabled, and instead, we define a set rate control mode directly in the encoder options.
如果您需要利用VAAPI进行1:N编码,请使用以下代码段:
If you need to take advantage of 1:N encoding with VAAPI, use these snippets:
- 如果需要去隔行,请调用
deinterlace_vaapi
过滤器:
- If you need to deinterlace, call up the
deinterlace_vaapi
filter:
ffmpeg -re -loglevel debug -threads 4 \
-init_hw_device vaapi=va:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_device va -filter_hw_device va -hwaccel_output_format vaapi \
-i 'http://server:port' \
-filter_complex "[0:v]format=nv12|vaapi,hwupload,deinterlace_vaapi,split=3[n0][n1][n2]; \
[n0]scale_vaapi=1152:648[v0]; \
[n1]scale_vaapi=848:480[v1];
[n2]scale_vaapi=640:360[v2]" \
-b:v:0 2250k -maxrate:v:0 2250k -bufsize:v:0 360k -c:v:0 vp9_vaapi -g:v:0 50 -r:v:0 25 -rc_mode:v:0 2 \
-b:v:1 1750k -maxrate:v:1 1750k -bufsize:v:1 280k -c:v:1 vp9_vaapi -g:v:1 50 -r:v:1 25 -rc_mode:v:1 2 \
-b:v:2 1000k -maxrate:v:2 1000k -bufsize:v:2 160k -c:v:2 vp9_vaapi -g:v:2 50 -r:v:2 25 -rc_mode:v:2 2 \
-c:a aac -b:a 128k -ar 48000 -ac 2 \
-flags -global_header -f tee -use_fifo 1 \
-map "[v0]" -map "[v1]" -map "[v2]" -map 0:a \
"[select=\'v:0,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path0/output%03d.mp4| \
[select=\'v:1,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path1/output%03d.mp4| \
[select=\'v:2,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path2/output%03d.mp4"
- 不进行隔行扫描:
ffmpeg -re -loglevel debug -threads 4 \
-init_hw_device vaapi=va:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_device va -filter_hw_device va -hwaccel_output_format vaapi \
-i 'http://server:port' \
-filter_complex "[0:v]format=nv12|vaapi,hwupload,split=3[n0][n1][n2]; \
[n0]scale_vaapi=1152:648[v0]; \
[n1]scale_vaapi=848:480[v1];
[n2]scale_vaapi=640:360[v2]" \
-b:v:0 2250k -maxrate:v:0 2250k -bufsize:v:0 2250k -c:v:0 vp9_vaapi -g:v:0 50 -r:v:0 25 -rc_mode:v:0 2 \
-b:v:1 1750k -maxrate:v:1 1750k -bufsize:v:1 1750k -c:v:1 vp9_vaapi -g:v:1 50 -r:v:1 25 -rc_mode:v:1 2 \
-b:v:2 1000k -maxrate:v:2 1000k -bufsize:v:2 1000k -c:v:2 vp9_vaapi -g:v:2 50 -r:v:2 25 -rc_mode:v:2 2 \
-c:a aac -b:a 128k -ar 48000 -ac 2 \
-flags -global_header -f tee -use_fifo 1 \
-map "[v0]" -map "[v1]" -map "[v2]" -map 0:a \
"[select=\'v:0,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path0/output%03d.mp4| \
[select=\'v:1,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path1/output%03d.mp4| \
[select=\'v:2,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path2/output%03d.mp4"
注意:如果您使用QuickSync路径,请注意,如果系统上的Media SDK库支持MFE(多帧编码模式),则默认情况下将启用MFE(多帧编码模式).
Note: If you use the QuickSync path, note that MFE (Multi-Frame encoding mode) will be enabled by default if the Media SDK library on your system supports it.
用于导出以上代码段的公式:
最佳bufsize:v =目标比特率(-b:v值)
Optimal bufsize:v = target bitrate (-b:v value)
将GOP大小设置为:2 * fps(GOP间隔设置为2秒).
Set GOP size as: 2 * fps (GOP interval set to 2 seconds).
我们通过-threads:v
限制了视频编码器的线程数,以防止VBV溢出.
We limit the thread counts for the video encoder(s) via -threads:v
to prevent VBV overflows.
使用的分辨率阶梯:16:9中的640p,480p和360p,请参见
Resolution ladder used: 640p, 480p and 360p in 16:9, see this link. Adjust this as needed.
根据需要替换上面的变量($output_path{0-2}
,输入等).
Substitute the variables above ($output_path{0-2}
, the input, etc) as needed.
测试并报告.
当前观察结果:
在我的系统上,我可以使用 Apple建议的用于HLS的HEVC编码的分辨率和比特率作为基准.有关系统负载等信息,请参见下图.
On my system, I'm able to encode up to 5 streams at real-time with VP9 using Apple's recommended resolutions and bit-rates for HEVC encoding for HLS as a benchmark. See the picture below on system load, etc.
平台详细信息:
我在Coffee-lake系统上,为此工作流使用i965
驱动程序:
I'm on a Coffee-lake system, using the i965
driver for this workflow:
libva info: VA-API version 1.5.0
libva info: va_getDriverName() returns 0
libva info: User requested driver 'i965'
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_1_5
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.5 (libva 2.4.0.pre1)
vainfo: Driver version: Intel i965 driver for Intel(R) Coffee Lake - 2.4.0.pre1 (2.3.0-11-g881e67a)
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointEncSliceLP
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointEncSliceLP
VAProfileH264MultiviewHigh : VAEntrypointVLD
VAProfileH264MultiviewHigh : VAEntrypointEncSlice
VAProfileH264StereoHigh : VAEntrypointVLD
VAProfileH264StereoHigh : VAEntrypointEncSlice
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileNone : VAEntrypointVideoProc
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileVP8Version0_3 : VAEntrypointVLD
VAProfileVP8Version0_3 : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileHEVCMain10 : VAEntrypointVLD
VAProfileHEVCMain10 : VAEntrypointEncSlice
VAProfileVP9Profile0 : VAEntrypointVLD
VAProfileVP9Profile0 : VAEntrypointEncSlice
VAProfileVP9Profile2 : VAEntrypointVLD
我的ffmpeg版本信息:
My ffmpeg build info:
ffmpeg -buildconf
ffmpeg version N-93308-g1144d5c96d Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-27ubuntu1~18.04)
configuration: --pkg-config-flags=--static --prefix=/home/brainiarc7/bin --bindir=/home/brainiarc7/bin --extra-cflags=-I/home/brainiarc7/bin/include --extra-ldflags=-L/home/brainiarc7/bin/lib --enable-cuda-nvcc --enable-cuvid --enable-libnpp --extra-cflags=-I/usr/local/cuda/include/ --extra-ldflags=-L/usr/local/cuda/lib64/ --enable-nvenc --extra-cflags=-I/opt/intel/mediasdk/include --extra-ldflags=-L/opt/intel/mediasdk/lib --extra-ldflags=-L/opt/intel/mediasdk/plugins --enable-libmfx --enable-libass --enable-vaapi --disable-debug --enable-libvorbis --enable-libvpx --enable-libdrm --enable-opencl --enable-gpl --cpu=native --enable-opengl --enable-libfdk-aac --enable-libx265 --enable-openssl --extra-libs='-lpthread -lm' --enable-nonfree
libavutil 56. 26.100 / 56. 26.100
libavcodec 58. 47.103 / 58. 47.103
libavformat 58. 26.101 / 58. 26.101
libavdevice 58. 6.101 / 58. 6.101
libavfilter 7. 48.100 / 7. 48.100
libswscale 5. 4.100 / 5. 4.100
libswresample 3. 4.100 / 3. 4.100
libpostproc 55. 4.100 / 55. 4.100
configuration:
--pkg-config-flags=--static
--prefix=/home/brainiarc7/bin
--bindir=/home/brainiarc7/bin
--extra-cflags=-I/home/brainiarc7/bin/include
--extra-ldflags=-L/home/brainiarc7/bin/lib
--enable-cuda-nvcc
--enable-cuvid
--enable-libnpp
--extra-cflags=-I/usr/local/cuda/include/
--extra-ldflags=-L/usr/local/cuda/lib64/
--enable-nvenc
--extra-cflags=-I/opt/intel/mediasdk/include
--extra-ldflags=-L/opt/intel/mediasdk/lib
--extra-ldflags=-L/opt/intel/mediasdk/plugins
--enable-libmfx
--enable-libass
--enable-vaapi
--disable-debug
--enable-libvorbis
--enable-libvpx
--enable-libdrm
--enable-opencl
--enable-gpl
--cpu=native
--enable-opengl
--enable-libfdk-aac
--enable-libx265
--enable-openssl
--extra-libs='-lpthread -lm'
--enable-nonfree
从inxi输出:
inxi -F
System: Host: cavaliere Kernel: 5.0.0 x86_64 bits: 64 Desktop: Gnome 3.28.3 Distro: Ubuntu 18.04.2 LTS
Machine: Device: laptop System: ASUSTeK product: Zephyrus M GM501GS v: 1.0 serial: N/A
Mobo: ASUSTeK model: GM501GS v: 1.0 serial: N/A
UEFI: American Megatrends v: GM501GS.308 date: 10/01/2018
Battery BAT0: charge: 49.3 Wh 100.0% condition: 49.3/55.0 Wh (90%)
CPU: 6 core Intel Core i7-8750H (-MT-MCP-) cache: 9216 KB
clock speeds: max: 4100 MHz 1: 2594 MHz 2: 3197 MHz 3: 3633 MHz 4: 3514 MHz 5: 3582 MHz 6: 3338 MHz
7: 3655 MHz 8: 3684 MHz 9: 1793 MHz 10: 3651 MHz 11: 3710 MHz 12: 3662 MHz
Graphics: Card-1: Intel Device 3e9b
Card-2: NVIDIA GP104M [GeForce GTX 1070 Mobile]
Display Server: x11 (X.Org 1.19.6 ) drivers: modesetting,nvidia (unloaded: fbdev,vesa,nouveau)
Resolution: 1920x1080@144.03hz
OpenGL: renderer: GeForce GTX 1070/PCIe/SSE2 version: 4.6.0 NVIDIA 418.43
Audio: Card-1 Intel Cannon Lake PCH cAVS driver: snd_hda_intel Sound: ALSA v: k5.0.0
Card-2 NVIDIA GP104 High Definition Audio Controller driver: snd_hda_intel
Card-3 Kingston driver: USB Audio
Network: Card: Intel Wireless-AC 9560 [Jefferson Peak] driver: iwlwifi
IF: wlo1 state: up mac: (redacted)
Drives: HDD Total Size: 3050.6GB (94.5% used)
ID-1: /dev/nvme0n1 model: Samsung_SSD_960_EVO_1TB size: 1000.2GB
ID-2: /dev/sda model: Crucial_CT2050MX size: 2050.4GB
Partition: ID-1: / size: 246G used: 217G (94%) fs: ext4 dev: /dev/nvme0n1p5
ID-2: swap-1 size: 8.59GB used: 0.00GB (0%) fs: swap dev: /dev/nvme0n1p6
RAID: No RAID devices: /proc/mdstat, md_mod kernel module present
Sensors: System Temperatures: cpu: 64.0C mobo: N/A gpu: 61C
Fan Speeds (in rpm): cpu: N/A
Info: Processes: 412 Uptime: 3:32 Memory: 4411.3/32015.5MB Client: Shell (bash) inxi: 2.3.56
为什么要包含最后一位:
我正在运行最新的Linux内核,版本5.0. 这同样适用于Ubuntu 18.04LTS上的图形驱动程序堆栈. FFmpeg的构建如下所示,此处,因为此笔记本电脑同时具有通过Optimus启用的NVIDIA + Intel GPU.这样,我可以根据需要利用VAAPI,QuickSync和NVENC hwaccels. 您的里程可能会有所不同,即使我们的硬件相同.
I'm running the latest Linux kernel to date, version 5.0. The same also applies to the graphics driver stack, on Ubuntu 18.04LTS. FFmpeg was built as shown here as this laptop has both NVIDIA+ Intel GPU enabled via Optimus. That way, I can tap into VAAPI, QuickSync and NVENC hwaccels as needed. Your mileage may vary even if our hardware is identical.
参考文献:
- 请参阅编码器选项,包括支持的速率控制方法:
ffmpeg -h encoder=vp9_vaapi
- 请参阅deinterlace_vaapi过滤器使用选项:
ffmpeg -h filter=deinterlace_vaapi
例如,如果要从去隔行器输出场速率而不是帧速率,则可以将rate=field
选项传递给它:
For instance, if you want field-rate output rather than frame-rate output from the deinterlacer, you could pass the rate=field
option to it instead:
-vf=vaapi_deinterlace=rate=field
例如,此功能与支持 MBAFF的编码器绑定在一起.其他功能,例如FFmpeg中基于NVENC的功能,尚未实现(自撰写本文时).
This feature, for instance, is tied to encoders that support MBAFF. Others, such as the NVENC-based ones in FFmpeg, do not have this implemented (as of the time of writing).
使用FFmpeg的提示:
与上面显示的示例一样,尽可能推断出内置文档. 通过了解滤波器链接和编码器初始化的工作方式,不支持的功能等以及对性能的影响,它们可以发现可能避免的潜在陷阱.
Where possible, infer to the built-in docs, as with the examples shown above. They can uncover potential pitfalls that you may be able to avoid by understanding how filter chaining and encoder initialization works, unsupported features, etc, and the impact on performance.
例如,您会看到在上面的片段中,我们仅调用去隔行器一次,然后通过split
过滤器将其输出拆分为单独的缩放器.这样做是为了降低如果我们多次调用去隔行扫描器而产生的开销,那会很浪费.
For example, you'll see that in the snippets above, we call up the deinterlacer only once, then split its' output via the split
filter to separate scalers. This is done to lower the overhead that would be incurred had we called up the deinterlacer more than once, and it would've been wasteful.
这篇关于(FFmpeg)VP9 Vaapi从给定的官方ffmpeg示例编码为.mp4或.webm容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!