Проблема совместимости 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?