Nvidia NVDEC - копирование декодированного кадра в текстуру D3D11 NV12

Я пытаюсь скопировать декодированный буфер NV12 NVDEC непосредственно в текстуру NV12 d3d11. Пока не повезло. Что мне удалось сделать, так это двойное копирование с использованием 2 текстур d3d11 (яркость + цветность), 2 cuGraphicsMapResources, 2 cuGraphicsSubResourceGetMappedArray, 2 CUDA_MEMCPY2D и пиксельного шейдера для объединения всех.... нет возможности выполнить одноразовое копирование, и пока нет ответа с форума Nvidia.

Я обнаружил, что этот старый вопрос сталкивается с очень похожей проблемой, и там тоже нет решения.

2 ответа

Не уверен, как это можно сделать с NVidia/Cuda, поскольку я не знаком. Но вот как мне удалось сделать это с помощью Direct3D (D3D11va), который может помочь вам перевести его в вашу ситуацию:

  1. (Устройство NV12 NDEC).CopySubresourceRegion(текстура src NV12 NVDEC, srcSubresourceArrayIndex, общая текстура dst NV12)

(Получить общий дескриптор для недавно созданной общей текстуры NV12)

  1. (Ваше устройство).OpenSharedResource(общий дескриптор NV12)

(Подготовьте VideoProcessorInputView, VideoProcessorOutputView и Streams)

  1. (Ваше устройство).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;
}
Другие вопросы по тегам