La chiamata ProcessInput dell'hardware grafico Intel H264 MFT non riesce dopo aver alimentato alcuni campioni di input, lo stesso funziona bene con l'hardware Nvidia MFT


9

Sto acquisendo il desktop utilizzando l'API DesktopDuplication e convertendo i campioni da RGBA a NV12 in GPU e fornendo lo stesso all'hardware MediaFoundation H264 MFT. Funziona bene con la grafica Nvidia e anche con i codificatori software, ma fallisce quando è disponibile solo l'hardware grafico Intel MFT. Il codice funziona perfettamente sulla stessa macchina grafica Intel se fallback su Software MFT. Ho anche assicurato che la codifica sia effettivamente eseguita in hardware su macchine grafiche Nvidia.

Sulla grafica Intel, MFT restituisce MEError ( "Errore non specificato" ), che si verifica solo dopo l'alimentazione del primo campione e le successive chiamate a ProcessInput (quando il generatore di eventi attiva METransformNeedInput) restituisce "La chiamata attualmente non accetta ulteriori input" . È raro che MFT consumi qualche altro campione prima di restituire questi errori. Questo comportamento è confuso, sto alimentando un campione solo quando il generatore di eventi innesca METransformNeedInput in modo asincrono tramite IMFAsyncCallback, e anche controllando correttamente se METransformHaveOutput viene attivato non appena viene alimentato un campione. Questo mi sorprende davvero quando la stessa logica asincrona funziona bene con i codificatori hardware MFT e software Microsoft Nvidia.

C'è anche una domanda analoga non risolta nel forum di Intel stesso. Il mio codice è simile a quello menzionato nel thread Intel, tranne per il fatto che sto anche impostando d3d Device Manager sull'encoder come di seguito.

E, ci sono altri tre thread di overflow dello stack che segnalano un problema simile senza soluzione fornita ( codificatore MFTransform-> ProcessInput restituisce E_FAIL e come creare IMFSample dalla trama D11 per encoder Intel MFT e MFT asincrono non invia MFTransformHaveOutput Event (decodificatore Intel Hardware MJPEG MFT) ). Ho provato ogni possibile opzione senza alcun miglioramento su questo.

Il codice del convertitore di colore viene prelevato dai campioni di Intel Media SDK. Ho anche caricato il mio codice completo qui .

Metodo per impostare il gestore 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;
}

Implementazione del callback asincrono:

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;
};

Genera metodo di esempio:

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;
}

Crea campione video e conversione colore:

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;
}

Il driver grafico Intel nella macchina è già aggiornato.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Solo l'evento TransformNeedInput viene sempre attivato, tuttavia l'encoder si lamenta di non poter accettare più input. L'evento TransformHaveOutput non è mai stato attivato.

inserisci qui la descrizione dell'immagine

Problemi simili riportati nei forum Intel e msdn: 1) https://software.intel.com/en-us/forums/intel-media-sdk/topic/607189 2) https://social.msdn.microsoft.com/ Forum / SICUREZZA / it-IT / fe051dd5-b522-4e4b-9cbb-2c06a5450e40 / imfsinkwriter-meritocratica validazione-failed-for-MFT-intel-quick-sync-video-H264-encoder-MFT? forum = mediafoundationdevelopment

Aggiornamento: ho provato a deridere solo la fonte di input (creando programmaticamente un campione NV12 di rettangolo animato) lasciando tutto il resto intatto. Questa volta, il codificatore Intel non si lamenta di nulla, ho persino ottenuto dei campioni di output. Tranne il fatto che il video di uscita dell'encoder Intel è distorto mentre l'encoder Nvidia funziona perfettamente.

Inoltre, sto ancora ricevendo l'errore ProcessInput per la mia sorgente NV12 originale con encoder Intel. Non ho problemi con Nvidia MFT e codificatori software.

Output dell'hardware Intel MFT: (guarda l'output del codificatore Nvidia) inserisci qui la descrizione dell'immagine

Uscita dell'hardware MFT Nvidia: inserisci qui la descrizione dell'immagine

Statistiche di utilizzo della grafica Nvidia: inserisci qui la descrizione dell'immagine

Statistiche sull'utilizzo della grafica Intel (non capisco perché il motore GPU sia visualizzato come decodifica video): inserisci qui la descrizione dell'immagine


Nessun codice rilevante mostrato. È probabile che qualcosa vada storto esattamente nel ricevere "input di bisogno" e nel fornirlo ProcessInput.
Roman R.

@RomanR. in tal caso, potrebbe anche essere fallito per MFT software e hardware Nvidia, non è vero? Non ho mostrato alcun codice relativo all'enumerazione delle configurazioni MFT e di input e output perché sarà ridondante, non necessario e troppo lungo per un thread poiché ho detto che ho seguito esattamente lo stesso codice indicato nel forum di Intel ( software.intel.com / it-it / forum / intel-media-sdk / topic / 681571 ). Proverò ad aggiornare questo thread con i blocchi di codice necessari.
Ram

No non lo è. Le MFT hardware di AMD, Intel e NVIDIA implementano allo stesso modo ma allo stesso tempo un comportamento leggermente diverso. Tutti e tre funzionano principalmente come MFT asincroni, quindi la tua domanda è un'indicazione evidente che stai facendo qualcosa di sbagliato. Senza codice è solo una supposizione che cosa esattamente. Il codificatore software di Microsoft è sincronizzare MFT AFAIR, quindi è molto probabile che sia la parte della comunicazione con MFT asincrono è dove qualcosa non va bene.
Roman R.

A proposito il codice da quel link del forum Intel funziona per me e produce video.
Roman R.

@RomanR. Ho aggiornato il thread con la mia implementazione di IMFAsyncCallback, creazione del campione e conversione del colore, ProcessInput e ProcessOutput. Il convertitore di colore è semplicemente preso da qui ( github.com/NVIDIA/video-sdk-samples/blob/master/… ).
Ram

Risposte:


2

Ho guardato il tuo codice.

Secondo il tuo post, sospetto un problema con il processore video Intel.

Il mio sistema operativo è Win7, quindi decido di testare il comportamento del processore video con un dispositivo D3D9 sulla mia scheda Nvidia e quindi su una Intel HD Graphics 4000.

Suppongo che le capacità del processore video si comporteranno allo stesso modo per un dispositivo D3D9 come per un dispositivo D3D11. Naturalmente sarà necessario verificare.

Quindi ho creato questo programma per controllare: https://github.com/mofo7777/DirectXVideoScreen (vedi sotto-progetto D3D9VideoProcessor)

Sembra che tu non controlli cose sufficienti sulle capacità del processore video.

Con IDXVAHD_Device :: GetVideoProcessorDeviceCaps, ecco cosa controllo:

DXVAHD_VPDEVCAPS.MaxInputStreams> 0

DXVAHD_VPDEVCAPS.VideoProcessorCount> 0

DXVAHD_VPDEVCAPS.OutputFormatCount> 0

DXVAHD_VPDEVCAPS.InputFormatCount> 0

DXVAHD_VPDEVCAPS.InputPool == D3DPOOL_DEFAULT

Controllo anche il formato di input e output supportato con IDXVAHD_Device :: GetVideoProcessorOutputFormats e IDXVAHD_Device :: GetVideoProcessorInputFormats.

Qui ho trovato una differenza tra GPU Nvidia e GPU Intel.

NVIDIA: 4 formati di output

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2
  • D3DFMT_NV12

INTEL: 3 formati di output

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2

Su Intel HD Graphics 4000, non è supportato il formato di output NV12.

Inoltre, affinché il programma funzioni correttamente, devo impostare lo stato del flusso prima di utilizzare 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

Per 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

Potresti prima verificare le capacità del processore video della tua GPU. Vedi la stessa differenza che vedo io?

Questa è la prima cosa che dobbiamo sapere, e sembra che il tuo programma non lo controlli, da quello che ho visto sul tuo progetto Github.


Hai ragione. GetVideoProcessorOutputFormats sulla grafica Intel ha restituito solo varianti RGB e YUY2.
Ram

Sono facilmente in grado di convertire la trama RGBA in YUY2 su processori Intel. Ma il problema è che sembra che la grafica Intel supporti solo il formato di input NV12. Ora il convertitore di colore e il codificatore video sono incompatibili. Mi chiedo ancora perché Intel abbia deciso di farlo in questo modo. Esiste un altro modo per eseguire la conversione da RGB a NV12 in modo efficiente? Ho già provato approcci software che non offrono prestazioni adeguate.
Ram

Hai shader o compute shader.
mofo77,

1
Sto lavorando ad un approccio shader. Controllare github.com/mofo7777/DirectXVideoScreen per l'aggiornamento.
mofo77,

Grande! Grazie per la condivisione, è davvero utile.
Ram

1

Come menzionato nel post, l'errore MEError ("Errore non specificato") è stato restituito dal generatore di eventi Transform subito dopo aver alimentato il primo campione di input su hardware Intel e, ulteriori chiamate hanno appena restituito "Transform Need more input", ma non è stato prodotto alcun output . Lo stesso codice ha funzionato bene su macchine Nvidia. Dopo aver sperimentato e ricercato molto, ho capito che stavo creando troppe istanze di D3d11Device, Nel mio caso, ho creato da 2 a 3 dispositivi rispettivamente per la cattura, la conversione del colore e l'encoder hardware. Considerando che avrei potuto semplicemente riutilizzare una singola istanza di D3dDevice. La creazione di più istanze di D3d11Device potrebbe funzionare su macchine di fascia alta. Questo non è documentato da nessuna parte. Non sono riuscito a trovare nemmeno un indizio per le cause dell'errore "MEError". Non è menzionato da nessuna parte.

Il riutilizzo dell'istanza D3D11Device ha risolto il problema. Pubblicare questa soluzione in quanto potrebbe essere utile per le persone che affrontano lo stesso problema mio.


Nel tuo post non vedo dove viene menzionato l'errore E_UNEXPECTED ...
mofo77

@ mofo77, Siamo spiacenti, è stato MEError = 1 ("Errore non specificato") come indicato nel post. Ho perso la testa. Ho corretto la mia risposta. Grazie per averlo segnalato.
Ram
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.