(FFmpeg)VP9 Vaapi从给定的官方ffmpeg示例编码为.mp4或.webm容器 [英] (FFmpeg) VP9 Vaapi encoding to a .mp4 or .webm container from given official ffmpeg example

查看:218
本文介绍了(FFmpeg)VP9 Vaapi从给定的官方ffmpeg示例编码为.mp4或.webm容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施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.

此命令的作用:

它将通过 segment muxer创建5秒长的mp4段一个>. 请参见movflags=+faststart的用法,以及如何通过上面的-segment_format_options标志将其作为格式选项传递给基础mp4多路复用器.

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:

  1. 如果需要去隔行,请调用deinterlace_vaapi过滤器:
  1. 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"

  1. 不进行隔行扫描:

    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.

参考文献:

  1. 请参阅编码器选项,包括支持的速率控制方法:

ffmpeg -h encoder=vp9_vaapi

  1. 请参阅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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆