How to get YUV422 Format from AMD GPU

PENG TONG 90 Reputation points
2026-06-22T11:15:50.89+00:00

HRESULT Direct3DDevice::VideoProcessInit(UINT width, UINT height)

{

Logger::Write(LogLevel::LOG_INFO, L"VideoProcessInit");

HRESULT hr;

hr = Device->QueryInterface(IID_PPV_ARGS(&VideoDevice));

if(FAILED(hr))

{

    Logger::Write(LogLevel::LOG_INFO, L"Failed to get ID3D11VideoDevice");

    return hr;

}

else

{

    Logger::Write(LogLevel::LOG_INFO, L"Pass to get ID3D11VideoDevice");

}

hr = DeviceContext->QueryInterface(IID_PPV_ARGS(&VideoContext));

if (FAILED(hr))

{

    Logger::Write(LogLevel::LOG_INFO, L"Failed to get ID3D11VideoContext");

    return hr;

}

else

{

    Logger::Write(LogLevel::LOG_INFO, L"Pass to get ID3D11VideoContext");

}

D3D11_VIDEO_PROCESSOR_CONTENT_DESC contentDesc = {};

contentDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;

contentDesc.InputWidth = width;

contentDesc.InputHeight = height;

contentDesc.OutputWidth = width;

contentDesc.OutputHeight = height;

contentDesc.Usage = D3D11_VIDEO_USAGE_OPTIMAL_QUALITY;

hr = VideoDevice->CreateVideoProcessorEnumerator(&contentDesc, &Enumerator);

if(FAILED(hr))

{

    Logger::Write(LogLevel::LOG_INFO, L"Failed to create video processor enumerator");

    return hr;

}

else

{

    Logger::Write(LogLevel::LOG_INFO, L"Pass to create video processor enumerator");

}

hr = VideoDevice->CreateVideoProcessor(Enumerator.Get(), 0, &VideoProcessor);

if(FAILED(hr))

{

    Logger::Write(LogLevel::LOG_INFO, L"Failed to create video processor");

    return hr;

}

else

{

    Logger::Write(LogLevel::LOG_INFO, L"Pass to create video processor");

}

D3D11_TEXTURE2D_DESC outputDesc = {};

outputDesc.Width = width;

outputDesc.Height = height;

outputDesc.MipLevels = 1;

outputDesc.ArraySize = 1;

outputDesc.Format = DXGI_FORMAT_YUY2;

outputDesc.SampleDesc.Count = 1;

outputDesc.SampleDesc.Quality = 0;

outputDesc.Usage = D3D11_USAGE_DEFAULT;

outputDesc.BindFlags = D3D11_BIND_RENDER_TARGET;

outputDesc.CPUAccessFlags = 0;

outputDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;

hr = Device->CreateTexture2D(&outputDesc, nullptr, &OutputTexture);

if(FAILED(hr))

{

    Logger::Write(LogLevel::LOG_INFO, L"Failed to create YUY2 output texture");

    return hr;

}

else

{

    Logger::Write(LogLevel::LOG_INFO, L"Pass to create YUY2 output texture");

}

D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputViewDesc = {};

outputViewDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;

outputViewDesc.Texture2D.MipSlice = 0;

hr = VideoDevice->CreateVideoProcessorOutputView(OutputTexture.Get(), Enumerator.Get(), &outputViewDesc, &OutputView);

if(FAILED(hr))

{

    Logger::Write(LogLevel::LOG_INFO, L"Failed to create video processor output view");

    return hr;

}

else

{

    Logger::Write(LogLevel::LOG_INFO, L"Pass to create video processor output view");

}

D3D11_VIDEO_PROCESSOR_COLOR_SPACE srcColorSpace = {};

srcColorSpace.Usage = 0;

srcColorSpace.RGB_Range = 0;

srcColorSpace.YCbCr_Matrix = 0;

srcColorSpace.YCbCr_xvYCC = 0;

D3D11_VIDEO_PROCESSOR_COLOR_SPACE dstColorSpace = {};

dstColorSpace.Usage = 0;

dstColorSpace.RGB_Range = 0;

dstColorSpace.YCbCr_Matrix = 1;

dstColorSpace.YCbCr_xvYCC = 0;

dstColorSpace.Nominal_Range = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255; // TV范围

VideoContext->VideoProcessorSetStreamColorSpace(VideoProcessor.Get(), 0, &srcColorSpace);

VideoContext->VideoProcessorSetOutputColorSpace(VideoProcessor.Get(), &dstColorSpace);

RECT destRect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height) };

RECT srcRect = destRect;

VideoContext->VideoProcessorSetOutputTargetRect(VideoProcessor.Get(), TRUE, &destRect);

VideoContext->VideoProcessorSetStreamDestRect(VideoProcessor.Get(), 0, TRUE, &destRect);

VideoContext->VideoProcessorSetStreamSourceRect(VideoProcessor.Get(), 0, TRUE, &srcRect);

D3D11_VIDEO_COLOR backgroundColor = {};

backgroundColor.RGBA.A = 1.0f;

backgroundColor.RGBA.R = 0.0f;

backgroundColor.RGBA.G = 0.0f;

backgroundColor.RGBA.B = 0.0f;

VideoContext->VideoProcessorSetOutputBackgroundColor(VideoProcessor.Get(), TRUE, &backgroundColor);

return S_OK;

}

HRESULT Direct3DDevice::RebuildVideoProcessorIfNeeded(UINT width, UINT height)

{

if (width == 0 || height == 0) return E_INVALIDARG;

{

    std::lock_guard<std::mutex> lock(VideoProcMutex);

    if (IsVideoProcessorValid && CurrentWidth == width && CurrentHeight == height)

        return S_OK;

    Logger::Write(LogLevel::LOG_INFO, L"IsVideoProcessorValid is true");

    // Release old resources

    VideoProcessor.Reset();

    OutputView.Reset();

    OutputTexture.Reset();

    Enumerator.Reset();

    // Reinitialize video processor with new size

    HRESULT hr = VideoProcessInit(width, height);

    if(SUCCEEDED(hr))

    {

        CurrentWidth = width;

        CurrentHeight = height;

        IsVideoProcessorValid = true;

        Logger::Write(LogLevel::LOG_INFO, L"VideoProcessInit is pass");

    }

    else

    {

        IsVideoProcessorValid = false;

        Logger::Write(LogLevel::LOG_ERROR, L"Failed to rebuild video processor for " +

            Logger::number2wstring(width) + L"x" + Logger::number2wstring(height) + L"    " +Logger::hex2wstring(hr));

    }

    return hr;

}

}

Using the above code,I can obtain YUV422 format frames on the Intel integrated graphics platform. For AMD independent graphics cards, it is failed for Device->CreateTexture2D(&outputDesc, nullptr, &OutputTexture). I set outputDesc.BindFlags = 0, It is failed for VideoDevice->CreateVideoProcessorOutputView(OutputTexture.Get(), Enumerator.Get(), &outputViewDesc, &OutputView);

Windows development | Windows Driver Kit (WDK)
0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.