Le matériel graphique Intel H264 MFT ProcessInput call échoue après avoir alimenté quelques échantillons d'entrée, la même chose fonctionne bien avec le matériel Nvidia MFT

9

Je capture le bureau à l'aide de l'API DesktopDuplication et convertis les échantillons de RGBA en NV12 dans le GPU et les transfère au matériel MediaFoundation H264 MFT. Cela fonctionne très bien avec les graphiques Nvidia, ainsi qu'avec les encodeurs logiciels, mais échoue lorsque seul le matériel graphique Intel MFT est disponible. Le code fonctionne très bien sur la même machine graphique Intel si je reviens au logiciel MFT. J'ai également veillé à ce que l'encodage soit réellement effectué sur le matériel des machines graphiques Nvidia.

Sur les graphiques Intel, MFT renvoie MEError ( "erreur non spécifiée" ), qui ne se produit que juste après le chargement du premier échantillon, et les appels suivants à ProcessInput (lorsque le générateur d'événements déclenche METransformNeedInput) renvoie "L'appelé n'accepte actuellement aucune entrée supplémentaire" . Il est rare que MFT consomme quelques échantillons supplémentaires avant de renvoyer ces erreurs. Ce comportement est déroutant, j'alimente un échantillon uniquement lorsque le générateur d'événements déclenche METransformNeedInput de manière asynchrone via IMFAsyncCallback, et vérifie également correctement si METransformHaveOutput est déclenché dès qu'un échantillon est alimenté. Cela me déconcerte vraiment lorsque la même logique asynchrone fonctionne correctement avec les encodeurs logiciels MFT Nvidia et Microsoft.

Il existe également une question similaire non résolue dans le forum Intel lui-même. Mon code est similaire à celui mentionné dans le thread Intel, sauf pour le fait que je configure également le gestionnaire de périphériques d3d sur l'encodeur comme ci-dessous.

Et, il existe trois autres threads de débordement de pile signalant un problème similaire sans solution donnée ( encodeur MFTransform-> ProcessInput renvoie E_FAIL et comment créer IMFSample à partir de la texture D11 pour l'encodeur MFT Intel et MFT asynchrone n'envoie pas d'événement MFTransformHaveOutput (décodeur Intel Hardware MJPEG MFT) ). J'ai essayé toutes les options possibles sans amélioration à ce sujet.

Le code du convertisseur de couleur est extrait d'échantillons Intel Media SDK. J'ai également téléchargé mon code complet ici .

Méthode pour définir le gestionnaire 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;
}

Implémentation de rappel asynchrone:

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

Générer un exemple de méthode:

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

Créer un échantillon vidéo et une conversion des couleurs:

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

Le pilote graphique Intel de la machine est déjà à jour.

entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici

Seul l'événement TransformNeedInput est déclenché tout le temps, mais l'encodeur se plaint de ne plus pouvoir accepter d'entrée. L'événement TransformHaveOutput n'a jamais été déclenché.

entrez la description de l'image ici

Problèmes similaires signalés sur les forums Intel et MSDN: 1) https://software.intel.com/en-us/forums/intel-media-sdk/topic/607189 2) https://social.msdn.microsoft.com/ Forums / SECURITY / en-US / fe051dd5-b522-4e4b-9cbb-2c06a5450e40 / imfsinkwriter-merit-validation-failed-for-mft-intel-quick-sync-video-h264-encoder-mft? Forum = mediafoundationdevelopment

Mise à jour: J'ai essayé de se moquer uniquement de la source d'entrée (en créant par programmation un échantillon NV12 de rectangle animé) en laissant tout le reste intact. Cette fois, l'encodeur Intel ne se plaint de rien, j'ai même des échantillons de sortie. Sauf que la vidéo de sortie de l'encodeur Intel est déformée alors que l'encodeur Nvidia fonctionne parfaitement bien.

De plus, je reçois toujours l'erreur ProcessInput pour ma source NV12 d'origine avec l'encodeur Intel. Je n'ai aucun problème avec Nvidia MFT et les encodeurs logiciels.

Sortie du matériel Intel MFT: (Veuillez regarder la sortie de l'encodeur Nvidia) entrez la description de l'image ici

Sortie du matériel Nvidia MFT: entrez la description de l'image ici

Statistiques d'utilisation des graphiques Nvidia: entrez la description de l'image ici

Statistiques d'utilisation des graphiques Intel (je ne comprends pas pourquoi le moteur GPU est affiché comme décodage vidéo): entrez la description de l'image ici

RAM
la source
Aucun code pertinent affiché. Il est probable que quelque chose ne va pas exactement autour de la réception des «besoins d'entrée» et de leur fourniture ProcessInput.
Roman R.
@RomanR. si tel est le cas, cela pourrait également avoir échoué pour les logiciels et les MFT Nvidia Hardware, n'est-ce pas? Je n'ai montré aucun code lié à l'énumération des configurations MFT et d'entrée et de sortie car il sera redondant, inutile et trop long pour un thread car j'ai mentionné que j'avais suivi exactement le même code donné dans le forum Intel ( software.intel.com / fr-fr / forums / intel-media-sdk / topic / 681571 ). Je vais essayer de mettre à jour ce fil avec les blocs de code nécessaires.
Ram
Non ça ne l'est pas. Les MFT matériels d'AMD, Intel et NVIDIA implémentent de la même façon mais en même temps un comportement légèrement différent. Tous les trois fonctionnent principalement comme des MFT asynchrones, donc votre question est une indication apparente que vous faites quelque chose de mal. Sans code, c'est juste une supposition quoi exactement. L'encodeur logiciel de Microsoft est la synchronisation MFT AFAIR, il est donc très probable que c'est la partie de la communication avec async MFT que quelque chose ne va pas.
Roman R.
BTW le code de ce lien de forum Intel fonctionne pour moi et produit de la vidéo.
Roman R.
@RomanR. J'ai mis à jour le fil avec mon implémentation d'IMFAsyncCallback, la création d'échantillons et la conversion des couleurs, ProcessInput & ProcessOutput. Le convertisseur de couleur est simplement extrait d'ici ( github.com/NVIDIA/video-sdk-samples/blob/master/… ).
Ram

Réponses:

2

J'ai regardé ton code.

Selon votre article, je soupçonne un problème de processeur vidéo Intel.

Mon système d'exploitation est Win7, je décide donc de tester le comportement du processeur vidéo avec un D3D9Device sur ma carte Nvidia, puis sur un Intel HD Graphics 4000.

Je suppose que les capacités du processeur vidéo se comporteront de la même manière pour un D3D9Device que pour un D3D11Device. Bien sûr, il faudra vérifier.

J'ai donc fait ce programme pour vérifier: https://github.com/mofo7777/DirectXVideoScreen (voir le sous-projet D3D9VideoProcessor)

Il semble que vous ne vérifiez pas suffisamment les capacités du processeur vidéo.

Avec IDXVAHD_Device :: GetVideoProcessorDeviceCaps, voici ce que je vérifie:

DXVAHD_VPDEVCAPS.MaxInputStreams> 0

DXVAHD_VPDEVCAPS.VideoProcessorCount> 0

DXVAHD_VPDEVCAPS.OutputFormatCount> 0

DXVAHD_VPDEVCAPS.InputFormatCount> 0

DXVAHD_VPDEVCAPS.InputPool == D3DPOOL_DEFAULT

Je vérifie également le format d'entrée et de sortie pris en charge avec IDXVAHD_Device :: GetVideoProcessorOutputFormats et IDXVAHD_Device :: GetVideoProcessorInputFormats.

C'est là que j'ai trouvé une différence entre le GPU Nvidia et le GPU Intel.

NVIDIA: 4 formats de sortie

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2
  • D3DFMT_NV12

INTEL: 3 formats de sortie

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2

Sur Intel HD Graphics 4000, le format de sortie NV12 n'est pas pris en charge.

De plus, pour que le programme fonctionne correctement, j'ai besoin de configurer l'état du flux avant d'utiliser 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

Pour 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

Pourriez-vous d'abord vérifier les capacités du processeur vidéo de votre GPU. Voyez-vous la même différence que je vois?

C'est la première chose que nous devons savoir, et il semble que votre programme ne vérifie pas cela, d'après ce que j'ai vu sur votre projet github.

mofo77
la source
Tu as raison. GetVideoProcessorOutputFormats sur les graphiques Intel n'a renvoyé que les variantes RVB et YUY2.
Ram
Je peux facilement convertir la texture RGBA en YUY2 sur les processeurs Intel. Mais le hic, c'est que les graphiques Intel ne prennent en charge que le format d'entrée NV12. Maintenant, le convertisseur de couleurs et l'encodeur vidéo sont incompatibles. Je me demande toujours pourquoi Intel a décidé de le faire comme ça. Existe-t-il un autre moyen de faire efficacement la conversion RVB en NV12?. J'ai déjà essayé des approches logicielles qui n'offrent pas des performances adéquates.
Ram
Vous avez un shader ou un shader de calcul.
mofo77
1
Je travaille sur une approche shader. Consultez github.com/mofo7777/DirectXVideoScreen pour la mise à jour.
mofo77
Génial! Merci pour le partage, c'est vraiment utile.
Ram
1

Comme mentionné dans la publication, l'erreur MEError ("erreur non spécifiée") a été renvoyée par le générateur d'événements de Transform immédiatement après avoir alimenté le premier échantillon d'entrée sur le matériel Intel et, d'autres appels viennent de renvoyer "Transform Need more input", mais aucune sortie n'a été produite . Le même code a bien fonctionné sur les machines Nvidia. Après avoir expérimenté et recherché beaucoup, je me suis rendu compte que je créais trop d'instances de D3d11Device.Dans mon cas, j'ai créé 2 à 3 appareils pour la capture, la conversion des couleurs et l'encodeur matériel respectivement. Alors que j'aurais pu simplement réutiliser une seule instance D3dDevice. La création de plusieurs instances D3d11Device peut cependant fonctionner sur des machines haut de gamme. Cela n'est documenté nulle part. Je n'ai pas pu trouver même un indice pour les causes de l'erreur "MEError". Cela n'est mentionné nulle part.

La réutilisation de l'instance D3D11Device a résolu le problème. Publier cette solution car elle pourrait être utile pour les personnes confrontées au même problème que le mien.

RAM
la source
Je ne vois pas dans votre message où l'erreur E_UNEXPECTED est mentionnée ...
mofo77
@ mofo77, Désolé, c'était MEError = 1 ("Erreur non spécifiée") comme mentionné dans le message. J'ai un peu perdu la tête. Correction de ma réponse. Merci d'avoir souligné.
Ram