Искаженное изображение захвата экрана DXGI

Мало того, что фпс падает с 60 до 20-21, так еще и изображение выглядит таким искаженным. Второе изображение, как это должно выглядеть

Как это выглядит Как это должно выглядеть

if (captureVideo == 1) {
    pNewTexture = NULL;

    // Use the IDXGISwapChain::GetBuffer API to retrieve a swap chain surface ( use the uuid  ID3D11Texture2D for the result type ).
    pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &pSurface ) ); 

    /* The swap chain buffers are not mapable, so I need to copy it to a staging resource. */

    pSurface->GetDesc( &description ); //Use ID3D11Texture2D::GetDesc to retrieve the surface description

    // Patch it with a D3D11_USAGE_STAGING usage and a cpu access flag of D3D11_CPU_ACCESS_READ
    description.BindFlags = 0;
    description.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    description.Usage = D3D11_USAGE_STAGING;

    // Create a temporary surface ID3D11Device::CreateTexture2D
    HRESULT hr = pDevice->CreateTexture2D( &description, NULL, &pNewTexture );
    if( pNewTexture )
    {
        // Copy to the staging surface ID3D11DeviceContext::CopyResource
        pContext->CopyResource( pNewTexture, pSurface );
        // Now I have a ID3D11Texture2D with the content of your swap chain buffer that allow you to use the ID3D11DeviceContext::Map API to read it on the CPU
        D3D11_MAPPED_SUBRESOURCE resource;
        pContext->Map( pNewTexture, D3D11CalcSubresource( 0, 0, 0), D3D11_MAP_READ, 0, &resource );

        const int pitch = w << 2;
        const unsigned char* source = static_cast< const unsigned char* >( resource.pData );
        unsigned char* dest = static_cast< unsigned char* >(m_lpBits);
        for( int i = 0; i < h; ++i )
        {
            memcpy( dest, source, w * 4 );
            source += pitch;
            dest += pitch;
        }

        AppendNewFrame(w, h, m_lpBits,24);

        pContext->Unmap( pNewTexture, 0);
        pNewTexture->Release();
    }
}

person Josh    schedule 24.06.2018    source источник
comment
Вы должны проверить результат вызова GetBuffer, а также других вызовов здесь. Обратите внимание, что следует проверять результат CreateTexture2D, а не значение указателя. Вы также, похоже, не выпускаете pSurface после того, как закончили его использовать.   -  person user7860670    schedule 25.06.2018
comment
Я думаю, что есть несколько проблем с кодом, однако наиболее значительный эффект дает число 24 в строке AppendNewFrame. И вы не показываете этот код...   -  person Roman R.    schedule 25.06.2018
comment
Функция AppendNewFrame работает, проверено несколько раз. Она просто создает видеофайл mp4 и добавляет кадр, если бы это было не так, я бы не получил ни одного видеофайла, чтобы показать вам результат. все та же проблема...   -  person Josh    schedule 25.06.2018
comment
Согласен с Романом Р. - Я также считаю, что эта проблема больше связана с подачей, вывод, который вы даете, - это раздача, я подозреваю, что вам следует сначала посмотреть здесь. На заметку: я бы также посоветовал вам изменить порядок рендеринга так, чтобы вы не рендерили напрямую в буфер SwapChain, а вместо этого использовали текстуру и ресурс разрешения (или копировали, если это не msaa). Причина в том, что вы можете сделать снимок экрана частью потока конвейера рендеринга, а не прикреплять его. это также означает, что вы можете повторно использовать код для других резервных буферов, которые вы, возможно, захотите захватить.   -  person ErnieDingo    schedule 25.06.2018
comment
Привет, я не думаю, что это как-то связано с полем, потому что если я удалю цикл и просто напрямую сделаю AppendNewFrame(w, h, resource.pData,24); Я получаю то же самое. Кажется, что pData, который я получаю, виноват, если я изменяю шаг, я просто изменяю то, как показывает этот pData, поэтому проблема возникла раньше, вероятно, в CreateTexture2D?   -  person Josh    schedule 25.06.2018
comment
Я предполагаю, что AppendNewFrame на самом деле этот или аналогичный, и тогда это действительно проблемная линия. Ваша текстура 32-битная, и это создаст искажение, подобное тому, которое представлено на изображениях вопроса. Затем я вижу, что шаг угадывается, скорее всего, правильно, но в любом случае это делает код опасным/неточным. Шаг берется из переменной D3D11_MAPPED_SUBRESOURCE. Однако изначальная проблема заключается не в поле.   -  person Roman R.    schedule 25.06.2018
comment
Это была проблема, спасибо. Но теперь возникла другая проблема, мои значения красного и синего синего, кажется, поменялись местами, и изображение перевернуто. Есть ли способ лучше/быстрее исправить это, кроме очевидных петель для замены байты?   -  person Josh    schedule 25.06.2018
comment
Это должно быть точно проблема RGB против BGR. Вам нужно упростить обмен байтами с помощью графического процессора или сделать это самостоятельно. С кодом, который вы уже показали, я думаю, что ваша ручная замена байтов проста и приемлема.   -  person Roman R.    schedule 25.06.2018
comment
Удалось переключить R на B , но когда я переворачиваю изображение по горизонтали, я теряю много кадров в секунду. Как мне заставить графический процессор поменять их местами?   -  person Josh    schedule 25.06.2018
comment
@Josh: Здесь вы должны задавать по одному вопросу за раз. Я предлагаю вам создать новую и предоставить новое описание для новой проблемы, поскольку вы, кажется, исправили уже несколько.   -  person Roman R.    schedule 26.06.2018


Ответы (1)


Фрагмент кода, хотя и неполный, показывает несколько потенциальных проблем:

  1. Число 24 в строке AppendNewFrame говорит о том, что вы пытаетесь обрабатывать данные как 24-битный RGB, а ваши данные — 32-битный RGB. Такое жестокое обращение соответствует артефактам, представленным на прикрепленных изображениях;
  2. Шаг/шаг принимается по умолчанию, в то время как у вас есть эффективно используемый в структуре D3D11_MAPPED_SUBRESOURCE, и вы должны использовать его.
person Roman R.    schedule 26.06.2018
comment
См. модуль ScreenGrab в наборе инструментов DirectX для получения дополнительной информации. полное решение. - person Chuck Walbourn; 27.07.2018