标签: nvenc

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

我有以下管道:

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

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

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

glFinish - 这个有效.但不推荐使用它,因为它最终确定了提交给驱动程序的所有命令.

ARB_sync 这里有人说它不推荐使用,因为它会严重影响性能.

glMemoryBarrier这个很有意思.但它根本行不通.

以下是代码示例:

glMemoryBarrier(GL_ALL_BARRIER_BITS);
Run Code Online (Sandbox Code Playgroud)

并尝试过:

glTextureBarrierNV()
Run Code Online (Sandbox Code Playgroud)

代码执行如下:

 //rendered into the fbo...
  glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
  glBindImageTexture(imageUnit1, fboTex, 0, GL_FALSE, 0, GL_READ_ONLY,GL_RGBA8); 
  glBindImageTexture(imageUnit2, imageTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8));
  glDispatchCompute(16, 16, 1);

  glFinish(); // <-- must sync here,otherwise cuda buffer doesn't receive all the data

 //cuda maps the image to CUDA buffer here..
Run Code Online (Sandbox Code Playgroud)

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

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

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

UPDATE

我想稍微重构一下这个问题,因为原来的问题已经很久了.尽管如此,即使使用最新的CUDA和视频编解码器SDK(NVENC),问题仍然存在.所以,我不关心为什么glMemoryBarrier …

opengl cuda nvenc

7
推荐指数
1
解决办法
380
查看次数

使用NVidia GTX950M的FFMPEG hevc_nvenc"没有找到支持NVENC的设备"

在尝试这样的简单编码时,我收到错误"找不到NVENC功能的设备",甚至跳过音频以确保它不是音频问题:

ffmpeg.exe -i input.mp4 -c:v hevc_nvenc -an out.mp4
Run Code Online (Sandbox Code Playgroud)

我还尝试了更多细节,比如设置像素格式,预设,速率控制和格式.

在文档页面上:https: //trac.ffmpeg.org/wiki/HWAccelIntro 它说如果我们得到这个错误,我们应该检查像素格式.视频在这里有yuv420p,甚至指定格式会导致相同的错误.

我还检查了NVidia支持的卡,它说的是GeForce,但没有关于这些型号的详细信息:https: //developer.nvidia.com/video-encode-decode-gpu-support-matrix#Encoder

我尝试了h264_nvenc并且它工作正常,但问题是只有hevc_nvenc有没有人遇到过这个问题?

完整控制台输出:

[h264 @ 0000000002534560] Reinit context to 1280x544, pix_fmt: yuv420p
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isom
    creation_time   : 2014-05-23T13:04:15.000000Z
  Duration: 01:54:03.95, start: 0.000000, bitrate: 3193 kb/s
    Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), 1280x544 [SAR 1:1 DAR 40:17], 2750 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc …
Run Code Online (Sandbox Code Playgroud)

ffmpeg h.265 hevc nvenc

7
推荐指数
1
解决办法
7356
查看次数

如何使用NVidia NVEnc硬件编码器通过UDP传输H.264视频?

这将是一个自我回答的问题,因为它在整整一个星期的过程中让我疯狂,我希望让我的程序员免受我经历的挫折.

情况如下:您希望使用NVidia的NVEnc硬件编码器(分别在Kepler和Maxwell卡上提供,分别为GT(x)7xx和GT(x)9xx)来通过UDP流式传输图形应用程序的输出.这不是一条琐碎的道路,但它可以非常高效,因为它可以避免在编码阶段之前将帧从视频内存"下载"到系统内存,因为NVEnc能够直接访问视频内存.

我已经成功地完成了这项工作,只需要一帧又一帧地编写NVEnc的输出缓冲区来生成.h264 文件.VLC播放这样的文件没有问题,除了时间关闭(我没有尝试解决这个问题,因为我只需要该文件用于调试目的).

当我尝试通过UDP流式传输编码帧时出现问题:VLC和MPlayer都无法呈现视频.原来有两个原因,我将在答案中解释.

video nvidia video-encoding h.264 nvenc

6
推荐指数
1
解决办法
4918
查看次数

ffmpeg错误:在Windows中找不到libnpp

我正在尝试使用nvidia库在Windows中编译ffmpeg,以便使用MinGW/msys进行硬件加速.试图按照nvidias网站上的说明进行操作(部分:使用NVIDIA GPU开始使用FFmpeg/libav).配置为--enable-nonfree --disable-shared --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --extra-cflags = -Ilocal/include --extra-cflags = -I ../common/inc --extra-ldflags = -L ../ common/lib/x64 --prefix = ffmpeg但停在"ERROR:找不到libnpp".NVIDIA Video Codec SDK下载常用文件夹但没有npp libs或头文件.那有什么解决方案吗?感谢edvice.

windows cuda ffmpeg nvenc

6
推荐指数
2
解决办法
5802
查看次数

手动生成“空”h264 p帧

如果 p 帧不改变当前解码视频中的任何像素(即没有运动向量,什么都没有),我们就将其称为空帧。

我需要的是能够根据请求手动将空 p 帧插入到视频流中(需要以恒定的帧速率将帧发送到流客户端,但是流服务器上的帧源可以提供具有不同/较低帧速率的帧一)。

因此,我需要能够正确形成代表当前分辨率的空 p 帧的字节序列(我想知道还需要哪些其他参数?)

理想情况下,我更喜欢独立于编码器的解决方案,因为我使用两种不同的解决方案:通过 Nvidia Video SDK 的 nvenc 和通过 FFmpeg 的 x264。

我应该去哪里寻找?

ffmpeg video-streaming h.264 x264 nvenc

6
推荐指数
1
解决办法
1661
查看次数

在 nvidia docker 中使用 nvenc 运行 ffmpeg

使用 nvidia-docker 在 docker 容器内安装了Nvidia Video Codec SDK 8.2 + ffmpeg但当我运行此命令时

ffmpeg -f rawvideo -s:v 1920x1080 -r 30 -pix_fmt yuv420p -i HeavyHand_1080p.yuv -c:v h264_nvenc -preset slow -cq 10 -bf 2 -g 150 output.mp4
Run Code Online (Sandbox Code Playgroud)

我收到这个错误

无法加载 libnvidia-encode.so.1

nvenc 所需的最低 Nvidia 驱动程序为 390.25 或更高版本初始化输出流 0:0 时出错 - 打开输出流 #0:0 的编码器时出错 - 可能参数不正确,例如比特率、速率、宽度或高度

否则nvidia-smi显示此信息

在此输入图像描述

使用的GPU是GeForce 1050 Ticuda版本是9.0

ffmpeg nvidia docker nvenc nvidia-docker

5
推荐指数
2
解决办法
4815
查看次数

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)步.以下是相关的代码片段(为简洁起见,我省略了错误处理.)

// Round up width and height
priv->encWidth = (_resolution.w + 31) & ~31, priv->encHeight = (_resolution.h + 31) & ~31;

// Allocate CUDA "pitched" memory to match the input texture (YUV, one byte per component)
cuErr = cudaMallocPitch(&priv->cudaMemPtr, &priv->cudaMemPitch, 3 * priv->encWidth, priv->encHeight);
Run Code Online (Sandbox Code Playgroud)

这应该分配设备上的CUDA内存("倾斜"类型,尽管我也尝试过非音调,但结果没有任何改变.)

// Register the CUDA buffer as an input resource
NV_ENC_REGISTER_RESOURCE regResParams = { 0 };
regResParams.version = NV_ENC_REGISTER_RESOURCE_VER;
regResParams.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR; …
Run Code Online (Sandbox Code Playgroud)

opengl cuda nvidia video-streaming nvenc

3
推荐指数
1
解决办法
1591
查看次数

ffmpeg 3.2.0中如何在多个nvidia gpu中选择gpu?

我目前使用两个 nvidia p4 显卡。

在以前版本的 ffmpeg(3.2.0 之前)中,我可以使用选项“-gpu 0 或 1 等”来选择特定的 GPU 卡。

然而,在当前版本中,没有选择 GPU 卡的选项。

实际上,nvenc_h264.c 或 nvenc_hevc.c 中指定了“gpu”选项。

但在 nvenc.c 文件中,没有使用“gpu”选项的代码。

有什么办法可以选择特定的卡吗?

两张卡之间的负载均衡是如何实现的?

是在驱动级别完成的吗?

谢谢。

ffmpeg nvidia nvenc

3
推荐指数
1
解决办法
7020
查看次数

将 ffpmeg OpenCL 过滤器输出传递到 NVenc 而不需要 hwdownload?

我正在尝试使用 ffmpeg 对 UHD HDR 视频流进行色调映射(和调整大小)。以下命令:

ffmpeg -vsync 0 -hwaccel cuda -init_hw_device opencl=ocl -filter_hw_device ocl 
    -threads 1 -extra_hw_frames 3 -c:v hevc_cuvid -resize 1920x1080 -i "INPUT.hevc" 
    -vf "hwupload,
         tonemap_opencl=tonemap=mobius:param=0.01:desat=0:r=tv:p=bt709:t=bt709:m=bt709:format=nv12,
         hwdownload,format=nv12,hwupload_cuda" 
    -c:v hevc_nvenc -b:v 8M "OUTPUT.hevc"
Run Code Online (Sandbox Code Playgroud)

似乎有效(RTX 3080 上大约 200 FPS)。然而,我注意到它仍然使用一个 CPU 核心,并且 GPU 使用率据报告仅为 60-70%。当我只在没有任何滤镜的情况下调整大小时,我会在 100% GPU 使用率下获得大约 400FPS 的速度。

我怀疑最后的hwdownload,format=nv12,hwupload_cuda语句有问题,因为这增加了通过主内存的绕道。我尝试只使用hwupload_cuda而不使用hwdownload(就像这里建议的那样: https: //stackoverflow.com/a/55747785/929037在本答案末尾附近的过滤器示例中),但后来出现以下错误:

Impossible to convert between the formats supported by the filter 'Parsed_tonemap_opencl_1' and the filter 'auto_scaler_0'
Error reinitializing filters!
Failed to inject …
Run Code Online (Sandbox Code Playgroud)

video ffmpeg nvidia opencl nvenc

3
推荐指数
1
解决办法
2386
查看次数

如何在ffmpeg中指定nvenc使用的GPU

我使用的ffmpeg的可执行代码转换MPEGTS从h264码流与H265 nvenc和我有两个NVIDIA我的主板上安装图形卡:的GeForce GTX 690和Tesla K-10。ffmpeg中的nvenc是否有任何编解码器特定的参数,可以选择使用我想要的任何这些GPU进行编码?

parameters gpu ffmpeg nvidia nvenc

2
推荐指数
1
解决办法
7378
查看次数