Hardware gráfico da Intel H264 A chamada MFT ProcessInput falha após alimentar algumas amostras de entrada, o mesmo funciona bem com o hardware Nvidia MFT


9

Estou capturando a área de trabalho usando a API DesktopDuplication e convertendo as amostras de RGBA para NV12 na GPU e alimentando o mesmo no hardware MediaFoundation H264 MFT. Isso funciona bem com gráficos Nvidia e também com codificadores de software, mas falha quando apenas o hardware gráfico Intel MFT está disponível. O código funciona bem na mesma máquina gráfica Intel se eu recorrer ao Software MFT. Também assegurei que a codificação seja realmente feita em hardware nas máquinas gráficas da Nvidia.

Nos gráficos Intel, o MFT retorna MEError ( "Erro não especificado" ), que ocorre apenas após a alimentação da primeira amostra, e as chamadas subseqüentes a ProcessInput (quando o gerador de eventos aciona METransformNeedInput) retornam "O receptor atualmente não está aceitando mais informações" . É raro o MFT consumir mais algumas amostras antes de retornar esses erros. Esse comportamento é confuso. Estou alimentando uma amostra apenas quando o gerador de eventos aciona METransformNeedInput de forma assíncrona por IMFAsyncCallback e também verifico corretamente se METransformHaveOutput é acionado assim que uma amostra é alimentada. Isso realmente me deixa desconcertado quando a mesma lógica assíncrona funciona bem com os codificadores de hardware Nvidia MFT e Microsoft.

Há também uma pergunta não resolvida semelhante no próprio fórum da intel. Meu código é semelhante ao mencionado no segmento Intel, exceto pelo fato de eu também estar configurando o gerenciador de dispositivos d3d para o codificador, como abaixo.

E existem três outros threads de estouro de pilha que relatam um problema semelhante sem solução fornecida (o codificador MFTransform-> ProcessInput retorna E_FAIL & Como criar um exemplo de IMFS a partir da textura D11 para o codificador Intel MFT e o MFT assíncrono não está enviando o evento MFTransformHaveOutput (decodificador MJPEG de hardware da Intel) MFT) ). Eu tentei todas as opções possíveis sem melhorar isso.

O código do conversor de cores é obtido a partir de amostras da intel media sdk. Também enviei meu código completo aqui .

Método para definir o gerenciador do d3d:

void SetD3dManager() {

    HRESULT hr = S_OK;

    if (!deviceManager) {

        // Create device manager
        hr = MFCreateDXGIDeviceManager(&resetToken, &deviceManager);
    }

    if (SUCCEEDED(hr)) 
    {
        if (!pD3dDevice) {

            pD3dDevice = GetDeviceDirect3D(0);
        }
    }

    if (pD3dDevice) {

        // NOTE: Getting ready for multi-threaded operation
        const CComQIPtr<ID3D10Multithread> pMultithread = pD3dDevice;
        pMultithread->SetMultithreadProtected(TRUE);

        hr = deviceManager->ResetDevice(pD3dDevice, resetToken);
        CHECK_HR(_pTransform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, reinterpret_cast<ULONG_PTR>(deviceManager.p)), "Failed to set device manager.");
    }
    else {
        cout << "Failed to get d3d device";
    }
}

Getd3ddevice:

CComPtr<ID3D11Device> GetDeviceDirect3D(UINT idxVideoAdapter)
{
    // Create DXGI factory:
    CComPtr<IDXGIFactory1> dxgiFactory;
    DXGI_ADAPTER_DESC1 dxgiAdapterDesc;

    // Direct3D feature level codes and names:

    struct KeyValPair { int code; const char* name; };

    const KeyValPair d3dFLevelNames[] =
    {
        KeyValPair{ D3D_FEATURE_LEVEL_9_1, "Direct3D 9.1" },
        KeyValPair{ D3D_FEATURE_LEVEL_9_2, "Direct3D 9.2" },
        KeyValPair{ D3D_FEATURE_LEVEL_9_3, "Direct3D 9.3" },
        KeyValPair{ D3D_FEATURE_LEVEL_10_0, "Direct3D 10.0" },
        KeyValPair{ D3D_FEATURE_LEVEL_10_1, "Direct3D 10.1" },
        KeyValPair{ D3D_FEATURE_LEVEL_11_0, "Direct3D 11.0" },
        KeyValPair{ D3D_FEATURE_LEVEL_11_1, "Direct3D 11.1" },
    };

    // Feature levels for Direct3D support
    const D3D_FEATURE_LEVEL d3dFeatureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_9_3,
        D3D_FEATURE_LEVEL_9_2,
        D3D_FEATURE_LEVEL_9_1,
    };

    constexpr auto nFeatLevels = static_cast<UINT> ((sizeof d3dFeatureLevels) / sizeof(D3D_FEATURE_LEVEL));

    CComPtr<IDXGIAdapter1> dxgiAdapter;
    D3D_FEATURE_LEVEL featLevelCodeSuccess;
    CComPtr<ID3D11Device> d3dDx11Device;

    std::wstring_convert<std::codecvt_utf8<wchar_t>> transcoder;

    HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
    CHECK_HR(hr, "Failed to create DXGI factory");

    // Get a video adapter:
    dxgiFactory->EnumAdapters1(idxVideoAdapter, &dxgiAdapter);

    // Get video adapter description:
    dxgiAdapter->GetDesc1(&dxgiAdapterDesc);

    CHECK_HR(hr, "Failed to retrieve DXGI video adapter description");

    std::cout << "Selected DXGI video adapter is \'"
        << transcoder.to_bytes(dxgiAdapterDesc.Description) << '\'' << std::endl;

    // Create Direct3D device:
    hr = D3D11CreateDevice(
        dxgiAdapter,
        D3D_DRIVER_TYPE_UNKNOWN,
        nullptr,
        (0 * D3D11_CREATE_DEVICE_SINGLETHREADED) | D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
        d3dFeatureLevels,
        nFeatLevels,
        D3D11_SDK_VERSION,
        &d3dDx11Device,
        &featLevelCodeSuccess,
        nullptr
    );

    // Might have failed for lack of Direct3D 11.1 runtime:
    if (hr == E_INVALIDARG)
    {
        // Try again without Direct3D 11.1:
        hr = D3D11CreateDevice(
            dxgiAdapter,
            D3D_DRIVER_TYPE_UNKNOWN,
            nullptr,
            (0 * D3D11_CREATE_DEVICE_SINGLETHREADED) | D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
            d3dFeatureLevels + 1,
            nFeatLevels - 1,
            D3D11_SDK_VERSION,
            &d3dDx11Device,
            &featLevelCodeSuccess,
            nullptr
        );
    }

    // Get name of Direct3D feature level that succeeded upon device creation:
    std::cout << "Hardware device supports " << std::find_if(
        d3dFLevelNames,
        d3dFLevelNames + nFeatLevels,
        [featLevelCodeSuccess](const KeyValPair& entry)
        {
            return entry.code == featLevelCodeSuccess;
        }
    )->name << std::endl;

done:

    return d3dDx11Device;
}

Implementação de retorno de chamada assíncrona:

struct EncoderCallbacks : IMFAsyncCallback
{
    EncoderCallbacks(IMFTransform* encoder)
    {
        TickEvent = CreateEvent(0, FALSE, FALSE, 0);
        _pEncoder = encoder;
    }

    ~EncoderCallbacks()
    {
        eventGen = nullptr;
        CloseHandle(TickEvent);
    }

    bool Initialize() {

        _pEncoder->QueryInterface(IID_PPV_ARGS(&eventGen));

        if (eventGen) {

            eventGen->BeginGetEvent(this, 0);
            return true;
        }

        return false;
    }

    // dummy IUnknown impl
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; }
    virtual ULONG STDMETHODCALLTYPE AddRef(void) override { return 1; }
    virtual ULONG STDMETHODCALLTYPE Release(void) override { return 1; }

    virtual HRESULT STDMETHODCALLTYPE GetParameters(DWORD* pdwFlags, DWORD* pdwQueue) override
    {
        // we return immediately and don't do anything except signaling another thread
        *pdwFlags = MFASYNC_SIGNAL_CALLBACK;
        *pdwQueue = MFASYNC_CALLBACK_QUEUE_IO;
        return S_OK;
    }

    virtual HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult* pAsyncResult) override
    {
        IMFMediaEvent* event = 0;
        eventGen->EndGetEvent(pAsyncResult, &event);
        if (event)
        {
            MediaEventType type;
            event->GetType(&type);
            switch (type)
            {
            case METransformNeedInput: InterlockedIncrement(&NeedsInput); break;
            case METransformHaveOutput: InterlockedIncrement(&HasOutput); break;
            }
            event->Release();
            SetEvent(TickEvent);
        }

        eventGen->BeginGetEvent(this, 0);
        return S_OK;
    }

    CComQIPtr<IMFMediaEventGenerator> eventGen = nullptr;
    HANDLE TickEvent;
    IMFTransform* _pEncoder = nullptr;

    unsigned int NeedsInput = 0;
    unsigned int HasOutput = 0;
};

Gerar método de amostra:

bool GenerateSampleAsync() {

    DWORD processOutputStatus = 0;
    HRESULT mftProcessOutput = S_OK;
    bool frameSent = false;

    // Create sample
    CComPtr<IMFSample> currentVideoSample = nullptr;

    MFT_OUTPUT_STREAM_INFO StreamInfo;

    // wait for any callback to come in
    WaitForSingleObject(_pEventCallback->TickEvent, INFINITE);

    while (_pEventCallback->NeedsInput) {

        if (!currentVideoSample) {

            (pDesktopDuplication)->releaseBuffer();
            (pDesktopDuplication)->cleanUpCurrentFrameObjects();

            bool bTimeout = false;

            if (pDesktopDuplication->GetCurrentFrameAsVideoSample((void**)& currentVideoSample, waitTime, bTimeout, deviceRect, deviceRect.Width(), deviceRect.Height())) {

                prevVideoSample = currentVideoSample;
            }
            // Feed the previous sample to the encoder in case of no update in display
            else {
                currentVideoSample = prevVideoSample;
            }
        }

        if (currentVideoSample)
        {
            InterlockedDecrement(&_pEventCallback->NeedsInput);
            _frameCount++;

            CHECK_HR(currentVideoSample->SetSampleTime(mTimeStamp), "Error setting the video sample time.");
            CHECK_HR(currentVideoSample->SetSampleDuration(VIDEO_FRAME_DURATION), "Error getting video sample duration.");

            CHECK_HR(_pTransform->ProcessInput(inputStreamID, currentVideoSample, 0), "The resampler H264 ProcessInput call failed.");

            mTimeStamp += VIDEO_FRAME_DURATION;
        }
    }

    while (_pEventCallback->HasOutput) {

        CComPtr<IMFSample> mftOutSample = nullptr;
        CComPtr<IMFMediaBuffer> pOutMediaBuffer = nullptr;

        InterlockedDecrement(&_pEventCallback->HasOutput);

        CHECK_HR(_pTransform->GetOutputStreamInfo(outputStreamID, &StreamInfo), "Failed to get output stream info from H264 MFT.");

        CHECK_HR(MFCreateSample(&mftOutSample), "Failed to create MF sample.");
        CHECK_HR(MFCreateMemoryBuffer(StreamInfo.cbSize, &pOutMediaBuffer), "Failed to create memory buffer.");
        CHECK_HR(mftOutSample->AddBuffer(pOutMediaBuffer), "Failed to add sample to buffer.");

        MFT_OUTPUT_DATA_BUFFER _outputDataBuffer;
        memset(&_outputDataBuffer, 0, sizeof _outputDataBuffer);
        _outputDataBuffer.dwStreamID = outputStreamID;
        _outputDataBuffer.dwStatus = 0;
        _outputDataBuffer.pEvents = nullptr;
        _outputDataBuffer.pSample = mftOutSample;

        mftProcessOutput = _pTransform->ProcessOutput(0, 1, &_outputDataBuffer, &processOutputStatus);

        if (mftProcessOutput != MF_E_TRANSFORM_NEED_MORE_INPUT)
        {
            if (_outputDataBuffer.pSample) {

                CComPtr<IMFMediaBuffer> buf = NULL;
                DWORD bufLength;
                CHECK_HR(_outputDataBuffer.pSample->ConvertToContiguousBuffer(&buf), "ConvertToContiguousBuffer failed.");

                if (buf) {

                    CHECK_HR(buf->GetCurrentLength(&bufLength), "Get buffer length failed.");
                    BYTE* rawBuffer = NULL;

                    fFrameSize = bufLength;
                    fDurationInMicroseconds = 0;
                    gettimeofday(&fPresentationTime, NULL);

                    buf->Lock(&rawBuffer, NULL, NULL);
                    memmove(fTo, rawBuffer, fFrameSize > fMaxSize ? fMaxSize : fFrameSize);

                    bytesTransfered += bufLength;

                    FramedSource::afterGetting(this);

                    buf->Unlock();

                    frameSent = true;
                }
            }

            if (_outputDataBuffer.pEvents)
                _outputDataBuffer.pEvents->Release();
        }
        else if (MF_E_TRANSFORM_STREAM_CHANGE == mftProcessOutput) {

            // some encoders want to renegotiate the output format. 
            if (_outputDataBuffer.dwStatus & MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE)
            {
                CComPtr<IMFMediaType> pNewOutputMediaType = nullptr;
                HRESULT res = _pTransform->GetOutputAvailableType(outputStreamID, 1, &pNewOutputMediaType);

                res = _pTransform->SetOutputType(0, pNewOutputMediaType, 0);//setting the type again
                CHECK_HR(res, "Failed to set output type during stream change");
            }
        }
        else {
            HandleFailure();
        }
    }

    return frameSent;
}

Crie amostra de vídeo e conversão de cores:

bool GetCurrentFrameAsVideoSample(void **videoSample, int waitTime, bool &isTimeout, CRect &deviceRect, int surfaceWidth, int surfaceHeight)
{

FRAME_DATA currentFrameData;

m_LastErrorCode = m_DuplicationManager.GetFrame(&currentFrameData, waitTime, &isTimeout);

if (!isTimeout && SUCCEEDED(m_LastErrorCode)) {

    m_CurrentFrameTexture = currentFrameData.Frame;

    if (!pDstTexture) {

        D3D11_TEXTURE2D_DESC desc;
        ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));

        desc.Format = DXGI_FORMAT_NV12;
        desc.Width = surfaceWidth;
        desc.Height = surfaceHeight;
        desc.MipLevels = 1;
        desc.ArraySize = 1;
        desc.SampleDesc.Count = 1;
        desc.CPUAccessFlags = 0;
        desc.Usage = D3D11_USAGE_DEFAULT;
        desc.BindFlags = D3D11_BIND_RENDER_TARGET;

        m_LastErrorCode = m_Id3d11Device->CreateTexture2D(&desc, NULL, &pDstTexture);
    }

    if (m_CurrentFrameTexture && pDstTexture) {

        // Copy diff area texels to new temp texture
        //m_Id3d11DeviceContext->CopySubresourceRegion(pNewTexture, D3D11CalcSubresource(0, 0, 1), 0, 0, 0, m_CurrentFrameTexture, 0, NULL);

        HRESULT hr = pColorConv->Convert(m_CurrentFrameTexture, pDstTexture);

        if (SUCCEEDED(hr)) { 

            CComPtr<IMFMediaBuffer> pMediaBuffer = nullptr;

            MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), pDstTexture, 0, FALSE, (IMFMediaBuffer**)&pMediaBuffer);

            if (pMediaBuffer) {

                CComPtr<IMF2DBuffer> p2DBuffer = NULL;
                DWORD length = 0;
                (((IMFMediaBuffer*)pMediaBuffer))->QueryInterface(__uuidof(IMF2DBuffer), reinterpret_cast<void**>(&p2DBuffer));
                p2DBuffer->GetContiguousLength(&length);
                (((IMFMediaBuffer*)pMediaBuffer))->SetCurrentLength(length);

                //MFCreateVideoSampleFromSurface(NULL, (IMFSample**)videoSample);
                MFCreateSample((IMFSample * *)videoSample);

                if (videoSample) {

                    (*((IMFSample **)videoSample))->AddBuffer((((IMFMediaBuffer*)pMediaBuffer)));
                }

                return true;
            }
        }
    }
}

return false;
}

O driver gráfico da intel na máquina já está atualizado.

insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui

Somente o evento TransformNeedInput está sendo acionado o tempo todo, mas o codificador reclama que não pôde aceitar mais nenhuma entrada. O evento TransformHaveOutput nunca foi acionado.

insira a descrição da imagem aqui

Problemas semelhantes relatados nos fóruns intel & msdn: 1) https://software.intel.com/en-us/forums/intel-media-sdk/topic/607189 2) https://social.msdn.microsoft.com/ Forums / SECURITY / pt-BR / fe051dd5-b522-4e4b-9cbb-2c06a5450e40 / imfsinkwriter-validação de mérito falhou-para-mft-intel-quick-sync-video-h264-encoder-mft? Forum = mediafoundationdevelopment

Atualização: Eu tentei zombar apenas da fonte de entrada (criando programaticamente um exemplo de retângulo NV12 animado), deixando tudo intocado. Desta vez, o codificador intel não reclama nada, eu até tenho amostras de saída. Exceto o fato de que o vídeo de saída do codificador intel está distorcido, enquanto o codificador Nvidia funciona perfeitamente.

Além disso, ainda estou recebendo o erro ProcessInput da minha fonte NV12 original com o codificador intel. Não tenho problemas com os codificadores Nvidia MFT e software.

Saída da MFT de hardware Intel: (consulte a saída do codificador Nvidia) insira a descrição da imagem aqui

Saída do hardware da Nvidia MFT: insira a descrição da imagem aqui

Estatísticas de uso de gráficos da Nvidia: insira a descrição da imagem aqui

Estatísticas de uso de gráficos da Intel (não entendo por que o mecanismo GPU é exibido como decodificação de vídeo): insira a descrição da imagem aqui


Nenhum código relevante mostrado. É provável que algo dê errado exatamente ao receber "informações necessárias" e fornecê-las ProcessInput.
Roman R.

@RomanR. se for esse o caso, também pode ter falhado nos MFTs de software e Nvidia Hardware, não é? Não mostrei nenhum código relacionado à enumeração das configurações de MFT e de entrada e saída, pois será redundante, desnecessário e muito longo para um encadeamento, pois mencionei que segui exatamente o mesmo código fornecido no fórum da intel ( software.intel.com / pt-br / fóruns / intel-media-sdk / topic / 681571 ). Vou tentar atualizar esse segmento com os blocos de código necessários.
Ram

Não não é. As MFTs de hardware da AMD, Intel e NVIDIA implementam da mesma forma, mas ao mesmo tempo, comportamento ligeiramente diferente. Todos os três funcionam principalmente como MFTs assíncronas, então sua pergunta é uma indicação aparente de que você está fazendo algo errado. Sem código, é apenas uma adivinhação do que exatamente. O codificador de software da Microsoft é o MFT AFAIR de sincronização, portanto é muito provável que a parte da comunicação com o MFT assíncrono seja onde algo não está bem.
Roman R.

Aliás, o código desse link do fórum da Intel funciona para mim e produz vídeo.
Roman R.

@RomanR. Atualizei o thread com minha implementação do IMFAsyncCallback, criação de amostra e conversão de cores, ProcessInput & ProcessOutput. O conversor de cores é simplesmente retirado daqui ( github.com/NVIDIA/video-sdk-samples/blob/master/… ).
Ram

Respostas:


2

Eu olhei para o seu código.

De acordo com o seu post, suspeito de um problema no processador de vídeo Intel.

Meu sistema operacional é o Win7, por isso decido testar o comportamento do processador de vídeo com um D3D9Device na minha placa Nvidia e depois em um Intel HD Graphics 4000.

Suponho que os recursos do processador de vídeo se comportem da mesma maneira para um D3D9Device e para um D3D11Device. Claro que será necessário verificar.

Então, eu fiz este programa para verificar: https://github.com/mofo7777/DirectXVideoScreen (consulte o subprojeto D3D9VideoProcessor)

Parece que você não verifica coisas suficientes sobre os recursos do processador de vídeo.

Com IDXVAHD_Device :: GetVideoProcessorDeviceCaps, aqui está o que eu verifico:

DXVAHD_VPDEVCAPS.MaxInputStreams> 0

DXVAHD_VPDEVCAPS.VideoProcessorCount> 0

DXVAHD_VPDEVCAPS.OutputFormatCount> 0

DXVAHD_VPDEVCAPS.InputFormatCount> 0

DXVAHD_VPDEVCAPS.InputPool == D3DPOOL_DEFAULT

Também verifico o formato de entrada e saída suportado por IDXVAHD_Device :: GetVideoProcessorOutputFormats e IDXVAHD_Device :: GetVideoProcessorInputFormats.

Foi aqui que encontrei uma diferença entre a Nvidia GPU e a Intel GPU.

NVIDIA: formato de 4 saídas

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2
  • D3DFMT_NV12

Formato de saída INTEL: 3

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2

Na Intel HD Graphics 4000, não há suporte para o formato de saída NV12.

Também para o programa funcionar corretamente, preciso configurar o estado do fluxo antes de usar o VideoProcessBltHD:

  • DXVAHD_STREAM_STATE_D3DFORMAT
  • DXVAHD_STREAM_STATE_FRAME_FORMAT
  • DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE
  • DXVAHD_STREAM_STATE_SOURCE_RECT
  • DXVAHD_STREAM_STATE_DESTINATION_RECT

Para D3D11:

ID3D11VideoProcessorEnumerator :: GetVideoProcessorCaps == IDXVAHD_Device :: GetVideoProcessorDeviceCaps

(D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT) ID3D11VideoProcessorEnumerator :: CheckVideoProcessorFormat == IDXVAHD_Device :: GetVideoProcessorOutputFormats

(D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT) ID3D11VideoProcessorEnumerator :: CheckVideoProcessorFormat == IDXVAHD_Device :: GetVideoProcessorInputFormats

ID3D11VideoContext :: (...) == IDXVAHD_VideoProcessor :: SetVideoProcessStreamState

Você pode verificar primeiro os recursos do processador de vídeo da sua GPU. Você vê a mesma diferença que eu vejo?

Esta é a primeira coisa que precisamos saber, e parece que seu programa não verifica isso, pelo que vi no seu projeto do github.


Você está certo. GetVideoProcessorOutputFormats em gráficos Intel retornou apenas variantes RGB e YUY2.
Ram

Sou capaz de converter facilmente a textura RGBA em YUY2 nos processadores Intel. Mas o problema é que, parece que os gráficos da Intel suportam apenas o formato de entrada NV12. Agora, o conversor de cores e o codificador de vídeo são incompatíveis. Ainda estou me perguntando por que a Intel decidiu fazer assim. Existe alguma outra maneira de fazer a conversão RGB em NV12 com eficiência? Eu já tentei abordagens de software que não oferecem desempenho adequado.
Ram

Você tem sombreador ou sombreador de computação.
Mvc77 17/11/19

11
Estou trabalhando em uma abordagem de sombreador. Verifique github.com/mofo7777/DirectXVideoScreen para atualização.
Mvc77 17/11/19

Ótimo! Obrigado por compartilhar, é realmente útil.
Ram

1

Conforme mencionado no post, o erro MEError ("Erro não especificado") foi retornado pelo gerador de eventos do Transform imediatamente após alimentar a primeira amostra de entrada no hardware Intel e, mais chamadas acabaram de retornar "Transform Need more input", mas nenhuma saída foi produzida . O mesmo código funcionou bem em máquinas Nvidia. Depois de experimentar e pesquisar bastante, descobri que estava criando muitas instâncias do D3d11Device. No meu caso, criei 2 a 3 dispositivos para captura, conversão de cores e codificador de hardware, respectivamente. Visto que eu poderia simplesmente ter reutilizado uma única instância D3dDevice. Porém, a criação de várias instâncias do D3d11Device pode funcionar em máquinas de última geração. Isso não está documentado em nenhum lugar. Não consegui encontrar sequer uma pista para as causas do erro "MEError". Não é mencionado em lugar algum.

Reutilizar a instância D3D11Device resolveu o problema. Publicar esta solução, pois pode ser útil para pessoas que enfrentam o mesmo problema que o meu.


Não vejo em seu post onde o erro E_UNEXPECTED é mencionada ...
mofo77

@ mofo77, desculpe, era MEError = 1 ("erro não especificado"), conforme mencionado na publicação. Estou meio que perdi a cabeça. Corrigida minha resposta. Obrigado por apontar.
Ram
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.