Perangkat keras Intel graphics H264 MFT ProsesInput panggilan gagal setelah memberi makan beberapa sampel input, yang sama berfungsi dengan baik dengan Nvidia hardware MFT


9

Saya menangkap desktop menggunakan DesktopDuplication API dan mengkonversi sampel dari RGBA ke NV12 dalam GPU dan memberi makan yang sama dengan perangkat keras MediaFoundation H264 MFT. Ini berfungsi baik dengan grafis Nvidia, dan juga dengan encoders perangkat lunak tetapi gagal ketika hanya perangkat grafik intel MFT yang tersedia. Kode berfungsi dengan baik pada mesin grafis intel yang sama jika saya mundur ke Perangkat Lunak MFT. Saya juga telah memastikan bahwa pengkodean sebenarnya dilakukan dalam perangkat keras pada mesin grafis Nvidia.

Pada grafik Intel, MFT mengembalikan MEError ( "Kesalahan yang tidak ditentukan" ), yang terjadi hanya setelah sampel pertama dimasukkan, dan panggilan berikutnya ke ProcessInput (ketika generator acara memicu METransformNeedInput) mengembalikan " Callee saat ini tidak menerima input lebih lanjut" . Jarang MFT mengkonsumsi beberapa sampel lagi sebelum mengembalikan kesalahan ini. Perilaku ini membingungkan, saya hanya memberi sampel ketika generator memicu METransformNeedInput secara asinkron melalui IMFAsyncCallback, dan juga memeriksa dengan benar apakah METransformHaveOutput dipicu segera setelah sampel dimasukkan. Ini benar-benar membuat saya bingung ketika logika asinkron yang sama berfungsi dengan baik dengan perangkat keras Nvidia MFT & encoders perangkat lunak Microsoft.

Ada juga pertanyaan serupa yang belum terselesaikan di forum intel itu sendiri. Kode saya mirip dengan yang disebutkan di utas intel, kecuali kenyataan bahwa saya juga mengatur manajer perangkat d3d ke encoder seperti di bawah ini.

Dan, ada tiga thread stack overflow lainnya yang melaporkan masalah serupa tanpa solusi yang diberikan ( MFTransform encoder-> ProcessInput mengembalikan E_FAIL & Cara membuat IMFSample dari tekstur D11 untuk encoder Intel MFT & MFT Asinkron tidak mengirimkan MFTransformHaveOutput Event (Intel Hardware MJPEG Decoder) MFT) ). Saya telah mencoba setiap opsi yang mungkin tanpa perbaikan pada ini.

Kode konverter warna diambil dari sampel media intel SDK. Saya juga telah mengunggah kode lengkap saya di sini .

Metode untuk mengatur manajer 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;
}

Implementasi panggilan balik 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;
};

Hasilkan metode Sampel:

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

Buat contoh video & konversi warna:

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

Driver grafis intel di mesin sudah terbaru.

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Hanya acara TransformNeedInput yang dipicu setiap saat namun pembuat kode mengeluh bahwa ia tidak dapat menerima input lagi. Acara TransformHaveOutput tidak pernah dipicu.

masukkan deskripsi gambar di sini

Masalah serupa dilaporkan di forum intel & msdn: 1) https://software.intel.com/en-us/forums/intel-media-sdk/topic/607189 2) https://social.msdn.microsoft.com/ Forum / KEAMANAN / id-AS / fe051dd5-b522-4e4b-9cbb-2c06a5450e40 / imfsinkwriter-merit-validasi-gagal-untuk-mft-intel-quick-sync-video-h264-encoder-mft? Forum = mediafoundationdevelopment

Pembaruan: Saya telah mencoba untuk mengejek hanya sumber input (Dengan pemrograman membuat sampel NV12 persegi panjang animating) meninggalkan segala sesuatu yang lain tidak tersentuh. Kali ini, intel encoder tidak mengeluh apa-apa, saya bahkan punya sampel keluaran. Kecuali fakta bahwa video output dari intel encoder terdistorsi sedangkan encoder Nvidia berfungsi dengan baik.

Selain itu, saya masih mendapatkan error ProcessInput untuk sumber NV12 asli saya dengan intel encoder. Saya tidak punya masalah dengan Nvidia MFT dan pembuat enkode perangkat lunak.

Output dari MFT perangkat keras Intel: (Silakan lihat output encoder Nvidia) masukkan deskripsi gambar di sini

Output dari perangkat Nvidia MFT: masukkan deskripsi gambar di sini

Statistik penggunaan grafis Nvidia: masukkan deskripsi gambar di sini

Statistik penggunaan grafis Intel (saya tidak mengerti mengapa mesin GPU ditampilkan sebagai decode video): masukkan deskripsi gambar di sini


Tidak ada kode yang relevan ditampilkan. Kemungkinan ada yang tidak beres dengan menerima "butuh input" dan menyediakannya ProcessInput.
Roman R.

@RomanR. jika itu masalahnya, bisa juga gagal untuk perangkat lunak & Nvidia Hardware MFT, bukan? Saya belum menunjukkan kode apa pun yang berkaitan dengan penghitungan MFT dan konfigurasi input dan output karena itu akan berlebihan, tidak perlu dan terlalu lama untuk utas seperti yang saya sebutkan bahwa saya telah mengikuti persis kode yang sama yang diberikan dalam forum intel ( software.intel.com / en-us / forum / intel-media-SDK / topik / 681571 ). Saya akan mencoba memperbarui utas ini dengan blok kode yang diperlukan.
Ram

Tidak, bukan itu. MFT perangkat keras dari AMD, Intel dan NVIDIA menerapkan hal yang sama tetapi pada saat yang sama perilaku yang sedikit berbeda. Ketiganya sebagian besar berfungsi sebagai MFT asinkron sehingga pertanyaan Anda merupakan indikasi nyata bahwa Anda melakukan sesuatu yang salah. Tanpa kode itu hanya dugaan apa tepatnya. Encoder perangkat lunak Microsoft adalah sinkronisasi MFT AFAIR, sehingga sangat mungkin bahwa bagian dari berkomunikasi dengan async MFT adalah di mana ada sesuatu yang tidak beres.
Roman R.

BTW kode dari tautan forum Intel itu berfungsi untuk saya dan menghasilkan video.
Roman R.

@RomanR. Saya telah memperbarui utas dengan penerapan IMFAsyncCallback, kreasi sampel, dan Konversi warna, ProcessInput & ProcessOutput saya. Konverter warna hanya diambil dari sini ( github.com/NVIDIA/video-sdk-samples/blob/master/… ).
Ram

Jawaban:


2

Saya melihat kode Anda.

Menurut posting Anda, saya curiga ada masalah prosesor video Intel.

OS saya adalah Win7, jadi saya memutuskan untuk menguji perilaku prosesor video dengan D3D9Device pada kartu Nvidia saya, dan kemudian pada Intel HD Graphics 4000.

Saya kira kemampuan prosesor video akan berperilaku dengan cara yang sama untuk D3D9Device seperti untuk D3D11Device. Tentu saja perlu untuk memeriksa.

Jadi saya membuat program ini untuk memeriksa: https://github.com/mofo7777/DirectXVideoScreen (lihat sub-proyek D3D9VideoProcessor)

Sepertinya Anda tidak memeriksa hal-hal yang cukup tentang kemampuan prosesor video.

Dengan IDXVAHD_Device :: GetVideoProcessorDeviceCaps, berikut ini yang saya periksa:

DXVAHD_VPDEVCAPS.MaxInputStreams> 0

DXVAHD_VPDEVCAPS.VideoProcessorCount> 0

DXVAHD_VPDEVCAPS.OutputFormatCount> 0

DXVAHD_VPDEVCAPS.InputFormatCount> 0

DXVAHD_VPDEVCAPS.InputPool == D3DPOOL_DEFAULT

Saya juga memeriksa format input dan output yang didukung dengan IDXVAHD_Device :: GetVideoProcessorOutputFormats dan IDXVAHD_Device :: GetVideoProcessorInputFormats.

Di sinilah saya menemukan perbedaan antara Nvidia GPU dan Intel GPU.

NVIDIA: 4 format output

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2
  • D3DFMT_NV12

INTEL: 3 format output

  • D3DFMT_A8R8G8B8
  • D3DFMT_X8R8G8B8
  • D3DFMT_YUY2

Pada Intel HD Graphics 4000, tidak ada dukungan untuk format output NV12.

Agar program dapat bekerja dengan benar, saya perlu mengatur status aliran sebelum menggunakan 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

Untuk 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

Bisakah Anda memverifikasi kemampuan prosesor video GPU Anda terlebih dahulu. Apakah Anda melihat perbedaan yang sama seperti yang saya lihat?

Ini adalah hal pertama yang perlu kita ketahui, dan sepertinya program Anda tidak memeriksanya, dari apa yang saya lihat di proyek github Anda.


Kamu benar. GetVideoProcessorOutputFormats pada grafik Intel hanya mengembalikan varian RGB dan YUY2.
Ram

Saya dengan mudah dapat mengubah tekstur RGBA menjadi YUY2 pada prosesor Intel. Namun yang menarik adalah, sepertinya grafis Intel hanya mendukung format input NV12. Sekarang konverter warna dan encoder video tidak kompatibel. Saya masih bertanya-tanya mengapa Intel memutuskan untuk membuatnya seperti ini. Apakah ada cara lain untuk melakukan konversi RGB ke NV12 secara efisien? Saya sudah mencoba pendekatan perangkat lunak yang tidak menawarkan kinerja yang memadai.
Ram

Anda memiliki shader atau menghitung shader.
mofo77

1
Saya sedang mengerjakan pendekatan shader. Periksa github.com/mofo7777/DirectXVideoScreen untuk pembaruan.
mofo77

Bagus! Terima kasih telah berbagi, Ini sangat membantu.
Ram

1

Seperti yang disebutkan dalam posting, kesalahan MEError ("Kesalahan tidak ditentukan") dikembalikan oleh generator Transform's Event segera setelah mengumpankan sampel input pertama pada perangkat keras Intel, dan, panggilan selanjutnya baru saja dikembalikan "Transform Need more input", tetapi tidak ada output yang diproduksi . Kode yang sama bekerja dengan baik pada mesin Nvidia. Setelah banyak bereksperimen dan meneliti, saya menemukan bahwa saya membuat terlalu banyak contoh D3d11Device, Dalam kasus saya, saya membuat 2 hingga 3 perangkat masing-masing untuk Pengambilan, konversi warna, dan encoder Perangkat Keras. Padahal, saya bisa saja menggunakan kembali contoh D3dDevice tunggal. Membuat beberapa instance D3d11Device mungkin bekerja pada mesin kelas atas. Ini tidak didokumentasikan di mana pun. Saya bahkan tidak dapat menemukan petunjuk untuk penyebab kesalahan "MEError". Itu tidak disebutkan di mana pun.

Menggunakan kembali instance D3D11Device memecahkan masalah. Posting solusi ini karena mungkin bermanfaat bagi orang yang menghadapi masalah yang sama dengan saya.


Saya tidak melihat di pos Anda di mana kesalahan E_UNEXPECTED disebutkan ...
mofo77

@ mofo77, Maaf, MEError = 1 ("Kesalahan tidak ditentukan") sebagaimana disebutkan dalam pos. Saya agak kehilangan akal. Memperbaiki jawaban saya. Terima kasih telah menunjukkan.
Ram
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.