इंटेल ग्राफिक्स हार्डवेयर H264 MFT ProcessInput कॉल कुछ इनपुट नमूनों को खिलाने के बाद विफल हो जाता है, वही एनवीडिया हार्डवेयर एमएफटी के साथ ठीक काम करता है


9

मैं DesktopDuplication API का उपयोग करके डेस्कटॉप पर कब्जा कर रहा हूं और RGBA से NV12 में नमूने को GPU में परिवर्तित कर रहा हूं और MediaFoundation हार्डवेयर H264 MFT को खिला रहा हूं। यह एनवीडिया ग्राफिक्स के साथ ठीक काम करता है, और सॉफ्टवेयर एनकोडर के साथ भी लेकिन विफल रहता है जब केवल इंटेल ग्राफिक्स हार्डवेयर एमएफटी उपलब्ध होता है। यदि मैं सॉफ़्टवेयर MFT में वापस आता हूं तो कोड उसी इंटेल ग्राफिक्स मशीन पर ठीक काम करता है। मैंने यह भी सुनिश्चित किया है कि एन्कोडिंग वास्तव में एनवीडिया ग्राफिक्स मशीनों पर हार्डवेयर में किया गया है।

इंटेल ग्राफिक्स पर, एमएफटी MEError ( "अनिर्दिष्ट त्रुटि" ) देता है, जो केवल पहले नमूने के खिलाए जाने के बाद होता है, और बाद में ProcessInput को कॉल करता है (जब ईवेंट जेनरेटर METransformNeedInput को ट्रिगर करता है) " केली वर्तमान में आगे के इनपुट को स्वीकार नहीं कर रहा है" । यह दुर्लभ है कि एमएफटी इन त्रुटियों को वापस करने से पहले कुछ और नमूने लेता है। यह व्यवहार भ्रामक है, मैं केवल एक नमूना खिला रहा हूं, जब इवेंट जेनरेटर METFAformNeedInput को ट्रिगर करता है, IMFAsyncCallback के माध्यम से अतुल्यकालिक रूप से, और यह भी ठीक से जाँचता है कि क्या नमूना खिलाते ही METransformHaveOutput ट्रिगर है या नहीं। यह वास्तव में मुझे चकित करता है जब समान अतुल्यकालिक तर्क एनवीडिया हार्डवेयर एमएफटी और माइक्रोसॉफ्ट सॉफ्टवेयर एनकोडर के साथ ठीक काम करता है।

इंटेल फोरम में भी इसी तरह का एक अनसुलझा सवाल है। मेरा कोड इंटेल थ्रेड में वर्णित एक के समान है, इस तथ्य को छोड़कर कि मैं नीचे की तरह एनकोडर के लिए d3d डिवाइस मैनेजर भी सेट कर रहा हूं।

और, तीन अन्य ढेर अतिप्रवाह धागे दी कोई समाधान के साथ एक समान मुद्दे की रिपोर्टिंग कर रहे हैं ( MFTransform encoder-> ProcessInput रिटर्न E_FAIL और कैसे इंटेल MFT एनकोडर के लिए D11 बनावट से IMFSample बनाने के लिए और अतुल्यकालिक MFT MFTransformHaveOutput घटना (इंटेल हार्डवेयर MJPEG डिकोडर नहीं भेज रहा है एमएफटी) )। मैंने इस पर कोई सुधार नहीं होने के साथ हर संभव विकल्प की कोशिश की है।

कलर कन्वर्टर कोड इंटेल मीडिया sdk नमूनों से लिया जाता है। मैंने यहां अपना पूरा कोड भी अपलोड कर दिया है

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

Async कॉलबैक कार्यान्वयन:

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

नमूना विधि उत्पन्न करें:

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

वीडियो नमूना और रंग रूपांतरण बनाएं:

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

मशीन में इंटेल ग्राफिक्स ड्राइवर पहले से ही अद्यतित है।

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

केवल TransformNeedInput घटना हर समय चालू हो रही है फिर भी एनकोडर शिकायत करता है कि यह किसी भी अधिक इनपुट को स्वीकार नहीं कर सकता है। TransformHaveOutput ईवेंट को कभी ट्रिगर नहीं किया गया है।

यहां छवि विवरण दर्ज करें

इंटेल और msdn मंचों पर रिपोर्ट किए गए समान मुद्दे: 1) https://software.intel.com/en-us/forums/intel-media-sdk/topic/607189 2) https://social.msdn.microsoft.com/ मंच / सुरक्षा / en-US / fe051dd5-b522-4e4b-9cbb-2c06a5450e40 / imfsinkwriter-योग्यता-मान्यता-में विफल रहा है के लिए MFT-इंटेल-जल्दी-सिंक-वीडियो-h264-एनकोडर-MFT? मंच = mediafoundationdevelopment

अद्यतन: मैंने केवल इनपुट स्रोत का उपयोग करने की कोशिश की है (क्रमिक रूप से एक एनिमेटेड आयत NV12 नमूना बनाकर) बाकी सब कुछ छोड़ दिया। इस बार, इंटेल एनकोडर कुछ भी शिकायत नहीं करता है, मुझे आउटपुट नमूने भी मिले हैं। इस तथ्य को छोड़कर कि इंटेल एनकोडर का आउटपुट वीडियो विकृत है, जबकि एनवीडिया एनकोडर पूरी तरह से ठीक काम करता है।

इसके अलावा, मैं अभी भी Intel एनकोडर के साथ अपने मूल NV12 स्रोत के लिए ProcessInput त्रुटि प्राप्त कर रहा हूं। मेरे पास एनवीडिया एमएफटी और सॉफ्टवेयर एनकोडर के साथ कोई समस्या नहीं है।

इंटेल हार्डवेयर एमएफटी का आउटपुट: (एनवीडिया एनकोडर के आउटपुट को देखें) यहां छवि विवरण दर्ज करें

एनवीडिया हार्डवेयर एमएफटी का आउटपुट: यहां छवि विवरण दर्ज करें

एनवीडिया ग्राफिक्स उपयोग आँकड़े: यहां छवि विवरण दर्ज करें

इंटेल ग्राफिक्स उपयोग आँकड़े (मुझे समझ नहीं आता कि GPU इंजन को वीडियो डिकोड के रूप में क्यों प्रदर्शित किया जाता है): यहां छवि विवरण दर्ज करें


कोई प्रासंगिक कोड नहीं दिखाया गया है। यह संभावना है कि "इनपुट की आवश्यकता" प्राप्त करने और इसे प्रदान करने के आसपास कुछ गलत हो जाता है ProcessInput
रोमन आर

@RomanR। अगर ऐसा है, तो यह सॉफ्टवेयर और एनवीडिया हार्डवेयर एमएफटी के लिए भी विफल हो सकता है, है ना? मैं MFT और इनपुट और आउटपुट विन्यास की गणना से संबंधित किसी भी कोड क्योंकि यह एक धागा के लिए बहुत लंबा, निरर्थक अनावश्यक हो सकता है और के रूप में मैंने कहा था कि मैं बिल्कुल वैसा ही इंटेल मंच (में दिए गए कोड का पालन किया है नहीं दिखाया software.intel.com / एन-यूएस / फोरम / इंटेल-मीडिया-एसडीके / विषय / ६ us१५ .१ )। मैं इस धागे को आवश्यक कोड ब्लॉक के साथ अपडेट करने का प्रयास करूंगा।
राम

नहीं ऐसा नहीं है। एएमडी, इंटेल और एनवीआईडीआई से हार्डवेयर एमएफटी एक जैसे लागू होते हैं लेकिन एक ही समय में थोड़ा अलग व्यवहार करते हैं। तीनों ज्यादातर async MFT के रूप में काम करते हैं इसलिए आपका प्रश्न एक स्पष्ट संकेत है कि आप कुछ गलत कर रहे हैं। कोई कोड के साथ यह सिर्फ एक अनुमान है कि वास्तव में क्या है। Microsoft का सॉफ्टवेयर एनकोडर MFT AFAIR है, इसलिए इसकी संभावना है कि यह async MFT के साथ संचार करने का हिस्सा है, जहाँ कुछ ठीक नहीं है।
रोमन आर।

बीटीडब्ल्यू उस इंटेल फोरम लिंक से कोड मेरे लिए काम करता है और वीडियो बनाता है।
रोमन आर

@RomanR। मैंने IMFAsyncCallback, नमूना निर्माण और रंग रूपांतरण, ProcessInput और ProcessOutput के अपने कार्यान्वयन के साथ थ्रेड को अद्यतन किया है। रंग परिवर्तक बस यहाँ से लिया गया है ( github.com/NVodia/video-sdk-samples/blob/master/… )।
राम

जवाबों:


2

मैंने आपके कोड को देखा।

आपकी पोस्ट के अनुसार, मुझे इंटेल वीडियो प्रोसेसर की समस्या पर संदेह है।

मेरा OS Win7 है, इसलिए मैं अपने Nvidia कार्ड पर और फिर एक Intel HD ग्राफिक्स 4000 पर एक D3D9Device के साथ वीडियो प्रोसेसर व्यवहार का परीक्षण करने का निर्णय लेता हूं।

मुझे लगता है कि वीडियो प्रोसेसर क्षमताओं को एक D3D9Device के लिए एक D3D11Device के समान व्यवहार होगा। निश्चित रूप से यह जांचना आवश्यक होगा।

इसलिए मैंने यह जाँचने के लिए कार्यक्रम बनाया: https://github.com/mofo7777/DirectXVideoScreen (देखें D3D9VideoProcessor उप-परियोजना)

ऐसा लगता है कि आप वीडियो प्रोसेसर क्षमताओं के बारे में पर्याप्त चीजों की जांच नहीं करते हैं।

IDXVAHD_Device :: GetVideoProcessorDeviceCaps के साथ, यहाँ मैं जाँच कर रहा हूँ:

DXVAHD_VPDEVCAPS.MaxInputStreams> 0

DXVAHD_VPDEVCAPS.VideoProcessorCount> 0

DXVAHD_VPDEVCAPS.utputFormatCount> 0

DXVAHD_VPDEVCAPS.InputFormatCount> 0

DXVAHD_VPDEVCAPS.InputPool == D3DPOOL_DEFAULT

मैं भी IDXVAHD_Device :: GetVideoProcessorOutputFormats और IDXVAHD_Device :: GetVideoProcessorInputFormats के साथ समर्थित इनपुट और आउटपुट प्रारूप की जाँच करता हूँ।

यह वह जगह है जहां मैंने एनवीडिया जीपीयू और इंटेल जीपीयू के बीच अंतर पाया।

NVIDIA: 4 आउटपुट स्वरूप

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2
  • D3DFMT_NV12

INTEL: 3 आउटपुट स्वरूप

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2

Intel HD ग्राफिक्स 4000 पर, NV12 आउटपुट स्वरूप के लिए कोई समर्थन नहीं है।

प्रोग्राम को सही ढंग से काम करने के लिए, मुझे 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

D3D11 के लिए:

ID3D11VideoProcessorEnumerator :: GetVideoProcessorCaps == IDXVAHD_Device :: GetVideoProcessorDeviceCaps

{

{

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

क्या आप पहले अपने GPU की वीडियो प्रोसेसर क्षमताओं को सत्यापित कर सकते हैं। क्या आप वैसा ही अंतर देखते हैं जैसा मैं देख रहा हूं?

यह पहली चीज है जिसे हमें जानना चाहिए, और ऐसा लगता है कि आपका कार्यक्रम इस बात की जांच नहीं करता है, जो मैंने आपके गीथब प्रोजेक्ट पर देखा है।


तुम सही हो। इंटेल ग्राफिक्स पर GetVideoProcessorOutputFormats केवल RGB वेरिएंट और YUY2 लौटा।
राम

मैं आसानी से RGB प्रोसेसर को Intel प्रोसेसर पर YUY2 में बदलने में सक्षम हूं। लेकिन पकड़ है, लगता है कि इंटेल ग्राफिक्स केवल NV12 इनपुट प्रारूप का समर्थन करते हैं। अब कलर कन्वर्टर और वीडियो एनकोडर असंगत हैं। मैं अभी भी सोच रहा हूं कि इंटेल ने इसे इस तरह बनाने का फैसला क्यों किया। वहाँ rgb को NV12 रूपांतरण कुशलता से करने के लिए कोई अन्य तरीका है? मैंने पहले से ही ऐसे सॉफ्टवेयर दृष्टिकोण आजमाए हैं जो पर्याप्त प्रदर्शन की पेशकश नहीं करते हैं।
राम

आपके पास shader या कंप्यूट shader है।
mofo77

1
मैं एक shader दृष्टिकोण पर काम कर रहा हूँ। अद्यतन के लिए github.com/mofo7777/DirectXVideoScreen की जाँच करें।
mofo77

महान! साझा करने के लिए धन्यवाद, यह वास्तव में उपयोगी है।
राम

1

जैसा कि पोस्ट में उल्लेख किया गया है, त्रुटि MEError ("अनिर्दिष्ट त्रुटि") को इंटेल के हार्डवेयर पर पहला इनपुट नमूना खिलाने के तुरंत बाद ट्रांसफॉर्म के इवेंट जनरेटर द्वारा वापस कर दिया गया था, और, आगे की कॉल ने केवल "ट्रांसफ़ॉर्म नीडी अधिक इनपुट" की वापसी की, लेकिन कोई आउटपुट उत्पन्न नहीं हुआ। । हालांकि Nvidia मशीनों पर समान कोड ने ठीक काम किया। बहुत प्रयोग करने और शोध करने के बाद, मुझे पता चला कि मैं D3d11Device के बहुत सारे उदाहरण बना रहा हूं, मेरे मामले में, मैंने क्रमशः कैप्चरिंग, रंग रूपांतरण और हार्डवेयर एनकोडर के लिए 2 से 3 डिवाइस बनाए। जबकि, मैं बस एक एकल d3dDevice उदाहरण पुन: उपयोग कर सकता है। हालांकि कई उच्च-स्तरीय मशीनों पर कई डी 3 डी 11 डेविस इंस्टेंस बनाने का काम हो सकता है। यह कहीं भी प्रलेखित नहीं है। मुझे "MEError" त्रुटि के कारणों का भी कोई सुराग नहीं मिल पा रहा था। इसका उल्लेख कहीं नहीं है।

D3D11Device उदाहरण का पुन: उपयोग करने से समस्या हल हो गई। इस समाधान को पोस्ट करना क्योंकि यह उन लोगों के लिए मददगार हो सकता है जो इस मुद्दे का सामना करते हैं।


मैं आपकी उस पोस्ट को नहीं देखता जहाँ E_UNEXPECTED त्रुटि का उल्लेख किया गया है ...
mofo77

@ mofo77, क्षमा करें, यह पोस्ट में उल्लिखित MEError = 1 ("अनिर्दिष्ट त्रुटि") था। मैं मन से हार गया। मेरा उत्तर ठीक कर दिया। इशारा करने के लिए धन्यवाद।
राम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.