Кодирование рабочего стола ID3D11Texture2D API дублирования кадров с помощью NvPipe - PullRequest
1 голос
/ 30 мая 2019

Я пытаюсь захватывать кадры рабочего стола, используя Desktop Duplication API, и кодировать их сразу с помощью NvPipe, не обращаясь к процессору с пикселями.

Есть ли способ использовать данные ID3D11Texture2D в качестве входных данных для NvPipe или какой-нибудь другой эффективный способ сделать это? Я работаю над решением для виртуальной реальности, для которого требуется как можно более низкая задержка, поэтому даже сэкономленные 1 мс имеют большое значение.

Редактировать: После следующих рекомендаций @Soonts я получил этот код, который, похоже, не работает:

    cudaArray *array;
    m_DeviceContext->CopySubresourceRegion(CopyBuffer, 0, 0, 0, 0, m_SharedSurf, 0, Box);
    cudaError_t err = cudaGraphicsD3D11RegisterResource(&_cudaResource, CopyBuffer, cudaGraphicsRegisterFlagsNone);
    err = cudaGraphicsResourceSetMapFlags(_cudaResource, cudaGraphicsMapFlagsReadOnly);
    cudaStream_t cuda_stream;
    cudaStreamCreate(&cuda_stream);
    err = cudaGraphicsMapResources(1, &_cudaResource, cuda_stream);
    err = cudaGraphicsSubResourceGetMappedArray(&array, _cudaResource, 0, 0);
    uint64_t compressedSize = NvPipe_Encode(encoder, array, dataPitch, buffer.data(), buffer.size(), width, height, false);

NvPipe_Encode приводит к нарушению доступа к памяти и ничего не делает. Я не знаю, на каком этапе я ошибаюсь, так как я не могу найти какую-либо документацию о каких-либо функциях или переменных / структурах в Интернете, и размещение наблюдений за переменными не показывает никакой ценной информации, кроме их адреса в памяти.

1 Ответ

1 голос
/ 30 мая 2019

Я не пробовал, но я думаю, что это можно сделать с помощью взаимодействия CUDA.

Позвоните cudaGraphicsD3D11RegisterResource, чтобы зарегистрировать текстуру для взаимодействия CUDA. Не уверен, что вы можете зарегистрировать принадлежащую DWM текстуру, которую вы получаете от DD. Если это невозможно, создайте еще один (в пуле по умолчанию), зарегистрируйте его и обновите каждый кадр с помощью ID3D11DeviceContext :: CopyResource.

Позвоните cudaGraphicsResourceSetMapFlags, чтобы указать, что вы хотите доступ только для чтения со стороны взаимодействия CUDA.

Позвоните cudaGraphicsMapResources, чтобы позволить CUDA получить доступ к текстуре.

Звоните cudaGraphicsSubResourceGetMappedArray. Теперь у вас есть указатель устройства с данными фрейма, которые вы можете передать NvPipe.

P.S. Другой вариант - использование медиа-основы вместо NvPipe. Будет работать на всех графических процессорах, а не только на nVidia, на большинстве систем MF также использует аппаратные кодеры. Я не уверен насчет задержки, никогда не использовал MF для чего-то слишком чувствительного к нему и никогда не использовал NvPipe вообще, понятия не имею, как они сравниваются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...