Nvidia NVDEC - копирование декодированного кадра в текстуру D3D11 NV12
Я пытаюсь скопировать декодированный буфер NV12 NVDEC непосредственно в текстуру NV12 d3d11. Пока не повезло. Что мне удалось сделать, так это двойное копирование с использованием 2 текстур d3d11 (яркость + цветность), 2 cuGraphicsMapResources, 2 cuGraphicsSubResourceGetMappedArray, 2 CUDA_MEMCPY2D и пиксельного шейдера для объединения всех.... нет возможности выполнить одноразовое копирование, и пока нет ответа с форума Nvidia.
Я обнаружил, что этот старый вопрос сталкивается с очень похожей проблемой, и там тоже нет решения.
2 ответа
Не уверен, как это можно сделать с NVidia/Cuda, поскольку я не знаком. Но вот как мне удалось сделать это с помощью Direct3D (D3D11va), который может помочь вам перевести его в вашу ситуацию:
- (Устройство NV12 NDEC).CopySubresourceRegion(текстура src NV12 NVDEC, srcSubresourceArrayIndex, общая текстура dst NV12)
(Получить общий дескриптор для недавно созданной общей текстуры NV12)
- (Ваше устройство).OpenSharedResource(общий дескриптор NV12)
(Подготовьте VideoProcessorInputView, VideoProcessorOutputView и Streams)
- (Ваше устройство).VideoProcessorBlt(общий дескриптор src NV12, dst - ваша текстура рендеринга RGBA/BGRA)
Это процесс ускорения видео, и он происходит только в вашем графическом процессоре (без использования ЦП / ОЗУ). Вы также должны убедиться, что адаптер графического процессора поддерживает это.
Возможно, вам понадобится что-то подобное. Этот фрагмент кода взят из проекта FFmpeg (с открытым исходным кодом),libavutil/hwcontext_cude.c
файл:
for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) {
CUDA_MEMCPY2D cpy = {
.srcMemoryType = CU_MEMORYTYPE_HOST,
.dstMemoryType = CU_MEMORYTYPE_DEVICE,
.srcHost = src->data[i],
.dstDevice = (CUdeviceptr)dst->data[i],
.srcPitch = src->linesize[i],
.dstPitch = dst->linesize[i],
.WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]),
.Height = src->height >> (i ? priv->shift_height : 0),
};
ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream));
if (ret < 0)
goto exit;
}