问题标签 [nvenc]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
2221 浏览

opengl - nvEncRegisterResource() 失败并显示 -23

在尝试使用 NVEnc 将 OpenGL 帧流式传输为 H264 时,我遇到了障碍。我已经在这个特定问题上待了将近 8 个小时,但没有任何进展。

问题是对 的调用nvEncRegisterResource(),它总是以代码 -23 失败(枚举值 NV_ENC_ERR_RESOURCE_REGISTER_FAILED,记录为“未能注册资源” - 感谢 NVidia)。

我正在尝试遵循奥斯陆大学本文档中概述的程序(第 54 页,“OpenGL 互操作”),因此我知道这应该可行,但不幸的是,该文档本身并未提供代码.

这个想法相当简单:

  1. 将OpenGL帧缓冲对象产生的纹理映射到CUDA中;
  2. 将纹理复制到(先前分配的)CUDA 缓冲区中;
  3. 将该缓冲区映射为 NVEnc 输入资源
  4. 使用该输入资源作为编码源

正如我所说,问题是步骤(3)。以下是相关的代码片段(为简洁起见,我省略了错误处理。)

这应该分配设备上的 CUDA 内存(“投球”品种,虽然我也尝试过非投球,但结果没有任何变化。)

这是砖墙。无论我尝试什么,都nvEncRegisterResource()失败了。

我应该注意,我宁愿认为(尽管我可能错了)我已经完成了所有必需的初始化。下面是创建和激活 CUDA 上下文的代码:

.. 然后创建编码会话:

最后,初始化编码器的代码:

以上所有初始化都报告成功。

我非常感谢任何能让我克服这个障碍的人。


编辑:这是重现问题的完整代码。与原始代码唯一可观察到的区别是cuPopContext()这里返回一个错误(可以忽略) - 可能我的原始程序创建了这样一个上下文作为使用 OpenGL 的副作用。否则,代码的行为与原始代码完全相同。我已经使用 Visual Studio 2013 构建了代码。您必须链接以下库文件(如果不在 C: 上,则调整路径):C:\Program Files (x86)\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\Win32\cuda.lib

您还必须确保C:\Program Files (x86)\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include\(或类似的)在包含路径中。

新编辑:修改代码以仅使用 CUDA 驱动程序接口,而不是与运行时 API 混合。仍然是相同的错误代码。

0 投票
1 回答
6335 浏览

video - How to stream H.264 video over UDP using the NVidia NVEnc hardware encoder?

This is going to be a self-answered question, because it has driven me nuts over the course of a full week and I wish to spare fellow programmers the frustration I went through.

The situation is this: you wish to use NVidia's NVEnc hardware encoder (available on Kepler and Maxwell cards, i.e. GT(x) 7xx and GT(x) 9xx, respectively) to stream the output of your graphics application via UDP. This is not a trivial path to take, but it can be very efficient as it circumvents the need to "download" frames from video memory to system memory until after the encoding stage, because NVEnc has the ability to access video memory directly.

I had already managed to make this work insofar as to generate a .h264 file by simply writing NVEnc's output buffers to it, frame after frame. VLC had no trouble playing such a file, except that the timing was off (I didn't try to fix this, as I only needed that file for debugging purposes).

The problem came when I tried to stream the encoded frames via UDP: neither VLC nor MPlayer were able to render the video. It turned out there were two reasons for that, which I'll explain in my answer.

0 投票
1 回答
2743 浏览

ffmpeg - ffmpeg nvenc GPU 内存使用情况

我在 Ubuntu的NVIDIA QUADRO K4200上对视频进行转码( ffmpeg 版本为 2.7.1,NVENC SDK 5.0.1)。一个流的 GPU 内存使用量为 100 MB。请查看 nvidia-smi 命令的输出: 在此处输入图像描述

但是,当我在另一台具有NVIDIA GTX 980 TIffmpeg 版本为 3.0 ,NVENC SDK 5.0.1)的计算机上使用相同的 ffmpeg 参数运行相同的转码过程时,一个流的 GPU 内存使用量为 170 MB。请看下面的截图: 在此处输入图像描述

为什么内存使用量如此不同?我可以像在 QUADRO K4000 上那样将 GTX 980 TI 上的 GPU 内存使用量减少到 100MB 吗?

0 投票
1 回答
866 浏览

opengl - 内存屏障无法在计算阶段和 CUDA 的数据访问之间同步

我有以下管道:

  1. 渲染到自定义 FBO 的纹理附件。
  2. 将该纹理附件绑定为图像。
  3. 运行计算着色器,使用 imageLoad/Store 从上面的图像中采样。
  4. 将结果写入 SSBO 或图像。
  5. 将 SSBO(或图像)映射为 CUDA CUgraphicsResource并使用 CUDA 处理来自该缓冲区的数据。

现在,问题在于在第 4 阶段和第 5 阶段之间同步数据。这是我尝试过的同步解决方案。

glFlush - 并不能真正起作用,因为它不能保证所有命令执行的完整性。

glFinish - 这个工作。但不建议这样做,因为它会完成所有提交给驱动程序的命令。

ARB_sync 这里据说不推荐,因为它严重影响性能。

glMemoryBarrier这个很有趣。但这根本行不通。

以下是代码示例:

并且还尝试过:

代码执行如下:

此外,我尝试在启动计算之前从上下文中解除绑定 FBO 和纹理,我什至尝试glMemoryBarrier在它们之间启动一个计算,然后将目标图像从第一次计算启动获取到 CUDA。仍然没有同步。(嗯,这是有道理的,因为两个计算也彼此不同步)

在计算着色器阶段之后。不同步!只有当我替换为glFinish, 或任何其他完全停止管道的操作时。比如glMapBuffer(),例如。

那么我应该只使用glFinish(),还是我在这里遗漏了什么?为什么 glMemoryBarrier() 在 CUDA 接管控制之前不同步计算着色器工作?

更新

我想稍微重构一下这个问题,因为原来的问题已经很老了。尽管如此,即使使用最新的 CUDA 和视频编解码器 SDK (NVENC),问题仍然存在。所以,我不在乎为什么glMemoryBarrier不同步。我想知道的是:

  1. 如果可以将 OpenGL 计算着色器执行完成与 CUDA 对该共享资源的使用同步,而不会停止整个渲染管道,在我的情况下是 OpenGL 图像。

  2. 如果答案是“是”,那该怎么做?

0 投票
2 回答
3969 浏览

windows - 带有 NVENC 的 FFmpeg 硬件加速产生半绿输出视频

使用此处找到的 FFmpeg 构建:https ://github.com/illuspas/ffmpeg-hw-win32

./configure --prefix=/home/aliang/FFmpeg/x86_64 --enable-small --disable-debug --disable-doc --arch=x86_64 --cc='ccache x86_64-w64-mingw32-gcc' - -cross-prefix=x86_64-w64-mingw32- --enable-cross-compile --target-os=mingw32 --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-libspeex --enable -libx264 --enable-libx265 --enable-libmfx --enable-nvenc --enable-libopenh264 --enable-libkvazaar --enable-gpl --enable-nonfree

我在 MacBook Pro 上运行 Windows。我还尝试了更新的版本并获得了相同的输出。

输入视频来自sample-videos.com

我正在运行的 ffmpeg 命令是:

sample-out-nvenc.mp4 通过 ffplay 或 vlc 看起来像这样:

在此处输入图像描述

当我使用 jpeg2 抓取一个框架时,颜色看起来很正常,但高度被压扁了。

在此处输入图像描述

输出的 ffprobe 结果 (sample-out-nvenc.mp4):

最后是 nvenc 编码命令的输出:

0 投票
1 回答
2496 浏览

ffmpeg - 使用 NVENC 编解码器以 60 fps 的 FFmpeg 抓取桌面

我在使用带有 NVENC 编解码器的最新 Windows 编译 FFmpeg 以 60FPS 录制我的桌面时遇到问题。元数据说文件是 60 fps,但是当我播放它时,我可以清楚地看到它不是60 FPS。

我使用的命令行如下:

我尝试使用实时缓冲区、使用另一个 DirectShow 设备、更改配置文件或强制比特率,但视频似乎总是在 30fps。

使用 NVIDIA 的 ShadowPlay 录制屏幕效果很好,所以我知道这在我的机器上是可行的。

使用 FFprobe 检查 ShadowPlay 的输出文件,我可以看到:

流 #0:0(und):视频:h264(高)(avc1 / 0x31637661)、yuv420p(tv、smpte170m/smpte170m/bt470m)、1920x1080 [SAR 1:1 DAR 16:9]、4573 kb/s、59.38 fps、240 tbr、60k tbn、120 tbc(默认)

但是,如果我强制我的输出具有相同的比特率和配置文件,我会得到:

流 #0:0(und):视频:h264(高)(avc1 / 0x31637661)、yuv420p、1920x1080 [SAR 1:1 DAR 16:9]、5519 kb/s、60 fps、60 tbr、15360 tbn、120待定(默认)

我可以看到tbr并且tbn不同,所以我知道我的输出是复制帧。

为了测试,我所有的录音都在背景上有这个 60 帧速率的测试页面,我可以清楚地看到差异。

我知道 ShadowPlay 可能比使用相同编解码器的 FFmpeg 做的更多。我知道 OBS 可以很容易地做到这一点,但我想了解我做错了什么。也许这是一些 FFmpeg 限制?

完整的控制台输出

使用 -v 跟踪命令:

0 投票
1 回答
423 浏览

c++ - 带有 HVEC 的 Nvidia NvEnc 导致除以零

我正在尝试使用 Nvidias NvEnc API 构建硬件编码器。此 API 使用两种编解码器来编码任何给定数据:H264 和 HEVC。因此,首先必须选择两个代码之一,然后配置编码会话或使用 varios 预设之一。我正在按照Nvidias NvEnc Programming Guide中的描述进行操作。

在使用 HVEC 编解码器时,我有以下导致问题的代码:

所以事情又来了:我正在使用 H264 GUID,一切都通过了。如果我使用 HEVC,我会得到一个 div by Zero... 我没有从 api 调用中得到一些错误代码,只是一个简单的 div by zero 错误。所以我的问题是:HEVC 是否需要我使用预设不提供的更多信息?如果是这样,什么样的信息?

非常感谢!

编辑:解决了。编程指南没有说明必须设置这些字段,但NV_ENC_INITIALIZE_PARAMSframeRateNumframeRateDen组成,导致 div 为零......不知道为什么在使用 H264 时不会发生这种情况。有人可能会关闭这个..

0 投票
1 回答
742 浏览

c++ - NVencs 输出比特流不可读

我有一个与 Nvidias NVenc API 相关的问题。我想使用 API 来编码一些 OpenGL 图形。我的问题是,API 在整个程序中都没有报告错误,一切似乎都很好。但是生成的输出是不可读的,例如 VLC。如果我尝试播放生成的文件,VLC 会闪烁黑屏约 0.5 秒,然后结束播放。Video 的长度为 0,Vid 的大小似乎也很小。分辨率为1280*720,5秒录制大小仅为700kb。这是现实的吗?

申请流程如下:

  1. 渲染到辅助帧缓冲区
  2. 将帧缓冲区下载到两个 PBO 之一 (glReadPixels())
  3. 映射前一帧的 PBO,以获得 Cuda 可以理解的指针。
  4. 调用一个简单的 CudaKernel 将 OpenGLs RGBA 转换为 ARGB,NVenc 根据(p.18) 应该可以理解。内核读取 PBO 的内容并将转换后的内容写入一个 CudaArray(使用 cudaMalloc 创建),该 CudaArray 使用 NVenc 注册为 InputResource。
  5. 转换后的 Array 的内容被编码。完成事件加上相应的输出比特流缓冲区排队。
  6. 辅助线程侦听排队的输出事件,如果发出一个事件信号,则输出比特流被映射并写入硬盘。

NVenc-Encoder的初始化:

CudaResource的注册

编码

非常感谢每一个小提示,在哪里看。我已经没有想法可能出了什么问题。

非常感谢!

0 投票
1 回答
647 浏览

nvenc - 如何找出 nvenc 中最不忙的 GPU?

我正在我的 C 项目中使用 nvenc lib 支持多个 GPU。我想找到最不忙的 gpu 并将其用于下一个编码器会话。有没有 API 可以做到这一点?

谢谢。

0 投票
1 回答
925 浏览

codec - NVENC SDK 示例

我正在尝试运行能够提供硬件加速视频编码的 NVENC 编码器 SDK 示例。

我正在尝试nvencoder使用我在这里找到的数据集运行示例:http: //www.sunrayimage.com/download/image_examples/yuv420/tulips_yuv420_inter_planar_qcif.yuv

我使用以下命令行运行它:

生成的结果文件不能真正由任何媒体播放器播放。VLC 会加载它,但不会产生我期望的任何图像。

查看帮助消息,它说:

我想知道是否需要做其他事情来确保这个文件是可播放的,或者我没有正确使用这个例子?也许比特流文件不是有效的 H.264 编码文件?