Проблема совместимости D3D11VA/CUDA с поверхностями NV12

Я пытаюсь построить конвейер транскодирования, в котором видео декодируется с использованием D3D11VA, затем переносится в CUDA, дополнительно модифицируется и / или анализируется с использованием ядра CUDA и, наконец, кодируется с использованием NVENC (с использованием взаимодействия CUDA-NVENC); Идея состоит в том, чтобы делать все на GPU без видеокадров, когда-либо загружающих основную память Что-то, что я смог сделать:

  • Работает декодирование D3D11VA (с использованием массива Texture2D с 20 поверхностями в формате NV12, привязанными к видеодекодеру); декодер дает мне индекс в этом массиве для каждого декодированного кадра
  • Я могу легко вывести данные в основную память, используя отдельную Texture2D того же размера и формата, что и для массива декодирования, но с D3D11_USAGE_STAGING а также D3D11_CPU_ACCESS_READ; как только декодер предоставил мне индекс для массива декодера, я просто делаю CopySubresourceRegion от фрагмента массива декодера до этой промежуточной текстуры, а затем сопоставить промежуточную текстуру и прочитать данные (я могу успешно прочитать данные для плоскостей Y и UV)
  • Я также могу зарегистрировать промежуточную текстуру в качестве ресурса CUDA (хотя в руководстве по CUDA NV12 не указан в качестве поддерживаемого формата пикселей); Я могу затем сопоставить этот ресурс, применить cudaGraphicsSubResourceGetMappedArray на ресурс и копировать данные с полученного cudaArray в неправильную память CUDA.

Итак, проблема в том, что я могу скопировать только плоскость Y из cudaArray, Я перепробовал все, что мог придумать, чтобы получить данные УФ текстуры как-то безрезультатно. Единственным "решением", которое сработало, было создание еще одной текстуры с 1,5-кратной высотой исходной текстуры в формате R8, создание двух шейдерных представлений в промежуточной текстуре и использование шейдера, который просто копирует данные из обоих представлений в эту вспомогательную текстуру; Затем я могу сопоставить эту текстуру с CUDA и скопировать все данные в память CUDA.

Мне действительно не нравится это решение - оно уродливое, раздутое и требует дополнительного бесполезного копирования данных. Есть ли другой способ добиться этого? Способ заставить CUDA видеть все данные в текстуре NV12, или в качестве альтернативы скопировать все данные из текстуры NV12 в одну текстуру R8 или пару текстур R8/R8 или R8/R8G8?

0 ответов

Другие вопросы по тегам