Git Product home page Git Product logo

media-foundation's Introduction

What is this repo?

A collection of Microsoft Media Foundation sample apps along with tooling and documentation. Our goal is to share code samples, documentation, our favorite tools, and tips and tricks for troubleshooting Media Foundation issues.

Samples

  • MediaEngineUWP - A sample UWP C++/WinRT application which demonstrates media playback using the MediaFoundation MediaEngine API and the WinRT composition APIs.
  • MediaEngineEMEUWP - A sample UWP application written in C++ which demonstrates protected Playready EME media playback using the MediaFoundation MediaEngine API and the WinRT composition APIs.
  • MediaEngineDCompWin32Sample - A sample native C++ Win32 application which demonstrates media playback using the MediaFoundation MediaEngine API and the DirectComposition API.
  • storeCDM - A UWP app which loads a native implementation of the clearkey CDM.

Documentation

Tracing and Debugging

Microsoft Tools

  1. Media Experience Analyzer (MXA) - An advanced analysis tool used by Media experts to analyze Media Foundation performance traces. MXA Screenshot

    • Available for download packaged with the Windows ADK here. You can opt to install only MXA using the installer. MXA ADK Installer
    • Microsofts Channel9 has produced a series of training videos for MXA available here
  2. GPUView - A development tool for determining the performance of the graphics processing unit (GPU) and CPU. It looks at performance with regard to direct memory access (DMA) buffer processing and all other video processing on the video hardware.

    GPUView Screenshot

  3. TopoEdit - A visual tool for building and testing Media Foundation topologies.

    TopoEdit Screenshot

Other useful links

Contributing

We're always looking for your help to fix bugs and improve the samples. Create a pull request, and we'll be happy to take a look.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

media-foundation's People

Contributors

alsepkow avatar brbeec avatar cjrog avatar daoyuanli9 avatar isuru-c-p avatar kumraj avatar mastanki avatar microsoft-github-operations[bot] avatar microsoftopensource avatar yassermkhan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

media-foundation's Issues

MediaEngineDCompWin32Sample for PlayReady content // AV in IMFContentDecryptionModuleSession::GenerateRequest call

I am looking into extending MediaEngineDCompWin32Sample application to enable it play PlayReady content. Given that playback asset in #60 is fixed the application starts the playback.

I would like to enable it to also play PlayReady protected content (and then playready content coming from our source).

To define a simple initial case I would like to play asset from MediaEngineEMEUWPSample which also plays well there. Apparently there should be some PMP reference involved, discussion about something related I found in #37.

There is a discussion about IMFContentDecryptionModule::SetPMPHostApp for which I would need IMFContentDecryptionModule and it seems I have a problem even getting this. The initialization copy from MediaEngineEMEUWPSample starting from IMFContentDecryptionModuleFactory4::CreateContentDecryptionModuleFactory gives me type supported, and then fails at IMFContentDecryptionModuleAccess->CreateContentDecryptionModule so that I can't even have a CDM pointer:

0xC00D36BA : 'The object does not support the specified service.'.

Even though the arguments are the asme as in UWP EME

        // This is equivalent to the following Javascript EME call:
        // Navigator.requestMediaKeySystemAccess("com.microsoft.playready.recommendation", [{ initDataTypes: ['cenc'], persistentState: 'optional', distinctiveIdentifier: 'required'])

From the MF Media Engine end, execution reaches Windows::Media::Protection::IMediaProtectionManager::Properties() call where I seem to need to pass properties obtained from CDM and I don't have it.

If I use C++/WinRT defined MediaProtectionManager instead with properties borrowed from UWP PlayReady sample, this does not work either because, as I assume, the application is outside of UWP and requires additional steps.

Could you please give some guidance how to connect the pieces together?

MediaFoundation seems incompatible with Arbitrary Code Guard

Adding:

    PROCESS_MITIGATION_DYNAMIC_CODE_POLICY policy = {0};
    policy.ProhibitDynamicCode = 1;
    SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &policy, sizeof(policy));

to wWinMain of MediaEngineDCompWin32Sample causes a crash in 32 bit builds. i.e. jrmuizel@3507e8c

Is this expected? Can anything be done to prevent MediaFoundation from crashing when ACG is enabled?

Does IMFExtendedDRMTypeSupport::IsTypeSupportedEx and IMFMediaEngine::CanPlayType supported on ARM64?

I use those two APIs to query H264 codec capability on ARM64 device, both of them report "not supported".
But H264 video can be played by Media Player and Movie&TV on that device, looks API's results are not accurate.

  • IMFExtendedDRMTypeSupport::IsTypeSupportedEx
  • IMFMediaEngine::CanPlayType

Queried results:

IMFExtendedDRMTypeSupport::IsTypeSupportedEx:
PROBABLY        : video/mp4; codecs="hvc1";features="ext-profile=dvhe.05,decode-bpp=8,decode-res-x=1920,decode-res-y=1080,decode-bitrate=10000000,decode-fps=30"
NOT_SUPPORTED   : video/mp4; codecs="avc1.42E01E";features="decode-bpp=8,decode-res-x=1920,decode-res-y=1080,decode-bitrate=10000000,decode-fps=30"
NOT_SUPPORTED   : video/mp4; codecs="avc1.640033";features="decode-bpp=8,decode-res-x=1920,decode-res-y=1080,decode-bitrate=10000000,decode-fps=30"
================================================
IMFMediaEngine::CanPlayType:
PROBABLY        : video/mp4; codecs="hvc1";features="ext-profile=dvhe.05,decode-bpp=8,decode-res-x=1920,decode-res-y=1080,decode-bitrate=10000000,decode-fps=30"
NOT_SUPPORTED   : video/mp4; codecs="avc1.42E01E";features="decode-bpp=8,decode-res-x=1920,decode-res-y=1080,decode-bitrate=10000000,decode-fps=30"
NOT_SUPPORTED   : video/mp4; codecs="avc1.640033";features="decode-bpp=8,decode-res-x=1920,decode-res-y=1080,decode-bitrate=10000000,decode-fps=30" 

Query for HEVC has no such problem.

Test code
https://github.com/cjw1115/windows-media-capability/blob/main/MediaCapability/main.cpp

Test device:

  • Surface Pro 9 Microsoft SQ3
  • Windows 11 Pro 22H2 22621.1992

GPU memory leak with HEVC hardware decoder when draining and sending MFT_MESSAGE_NOTIFY_END_STREAMING message

There appears to be a leak with GPU dedicated memory for some HEVC video streams when using the HEVC hardware decoder and sending the MFT_MESSAGE_COMMAND_DRAIN message followed by the MFT_MESSAGE_NOTIFY_END_STREAMING message.

Reproduced on:

  • Windows 11, AMD Radeon RX 5700 XT
  • Windows 11, NVIDIA GeForce RTX 4070 Laptop GPU

Steps to reproduce:

  1. Build the attached sample code twice, once with sending the MFT_MESSAGE_NOTIFY_END_STREAMING message enabled (line 510) and another time with it disabled.
  2. Run the program and observe the GPU dedicated memory usage.
  3. The program requires an HEVC encoded sample (attached). This is the first frame (an IDR sample) from an HEVC video stream.

hevc10bit.cpp.txt
sample.zip

The sample code has a loop (the iterations can be adjusted with the RepeatCount variable) with these steps:

  1. Push HEVC IDR sample to decoder
  2. Send Drain message
  3. Process output, confirm that it retrieves the decoded frame
  4. Send the End Streaming message (optional: test with / without this step)
  5. Send the Flush message

When sending MFT_MESSAGE_NOTIFY_END_STREAMING we observe growth in GPU memory usage that grows unbounded for as long as the test runs:

image

When we don't send MFT_MESSAGE_NOTIFY_END_STREAMING we observe flat GPU dedicated memory usage:

image

License persistent in IMFContentDecryptionModuleSession::Update

I created a MF_MEDIAKEYSESSION_TYPE_TEMPORARY session, but I get a persistent PlayReady license after genereateRequest.
Then I try to call IMFContentDecryptionModuleSession::Update, it will told me session type are not match.

Here is data format pass into IMFContentDecryptionModuleSession::Update(),

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <AcquireLicenseResponse xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols">
            <AcquireLicenseResult>
                <Response xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols/messages">
                    <LicenseResponse xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols">
                        <Version>1</Version>
                        <Licenses>
                            <License>{{base64 XMR data}}</License>
                        </Licenses>
                        <Acknowledgement>
                            <TransactionID>{{id}}</TransactionID>
                        </Acknowledgement>
                    </LicenseResponse>
                </Response>
            </AcquireLicenseResult>
        </AcquireLicenseResponse>
    </soap:Body>
</soap:Envelope>

the major license info is a base64 encoded. And it used XMR format. I didn't found any standard or document about XMR format. I can only get brief structure.

My question is how can I know the license is persistent or just temporary?

Because I want to create two sessions, one is temporary, and another one is persistent.

If I can know the response license type, then I can use correct one session to call IMFContentDecryptionModuleSession::Update

Thanks!

Samples throw exceptions on start

I just downloaded and built these 3 samples. The only one that executes is MediaEngineEMEUWP. The other 2 throw exceptions on debug start. Using VS 2019 16.8.3, with latest C++ redistributable.

I can provide stack traces if not reproducible.

I assume since one works, I have any necessary pre-req's installed.

MediaEngineDCompWin32Sample WM_SIZE issue

Working with the latest VS2019 and SDK (as of today 2021-09-24), I'm finding that resizing the host window by pulling an edge causes the video area to snap to the 0,0 of the host window - thus overwriting the title bar.

If I then move the window, the video snaps back to the client area of the host window.

image

MXA links are broken

Looks like the MXA MSDN page, MXA getting started guide, and stand alone download links have been taken down.

Crash when using VP8 decoder with D3D11

I have enabled VP8/VP9 decoding through MediaFoundation in VLC. When using the software decoder everything works fine. But If I enable the D3D manager, it crashes when I select the NV12 output.

Here is the pseudo code:

  • MFTEnumEx with MFT_ENUM_FLAG_SORTANDFILTER | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_ASYNCMFT | MFT_ENUM_FLAG_HARDWARE (only 1 output found, which loads C:\Program Files\WindowsApps\Microsoft.VP9VideoExtensions_1.0.52781.0_x64__8wekyb3d8bbwe\x64\msvp9dec_store.dll)
  • ActivateObject of the IMFTtransform
  • MFSetAttributeSize(MF_MT_FRAME_SIZE)
  • SetInputType(MFMediaType_Video.MFVideoFormat_VP80)
  • GetUINT32(MF_SA_D3D11_AWARE) gives S_OK and 1.
  • MFCreateDXGIDeviceManager()
  • IMFDXGIDeviceManager::ResetDevice()
  • IMFDXGIDeviceManager::OpenDeviceHandle()
  • IMFTtransform::ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER)
  • IMFTtransform::GetOutputStreamAttributes(0, &attr)
  • attr.SetUINT32(MF_SA_D3D11_BINDFLAGS, D3D11_BIND_SHADER_RESOURCE)
  • IMFTtransform::GetOutputAvailableType(0, 0, &output_media_type)
  • IMFTtransform::SetOutputType(0, output_media_type)

It crashes with the following logs:

D3D11 ERROR: ID3D11Device::CheckFeatureSupport: Returning E_INVALIDARG, meaning the parameters were invalid. [ STATE_GETTING ERROR #2097315: DEVICE_CHECKFEATURESUPPORT_INVALIDARG_RETURN]
Exception thrown at 0x00007FFEA0D6CD29 in vlc.exe: Microsoft C++ exception: _com_error at memory location 0x000000B7E55FDC00.
D3D11 ERROR: ID3D11DeviceContext::CreateVideoDecoder: Invalid DXGI_FORMAT 67 specified, failing! [ STATE_CREATION ERROR #3145760: CREATEVIDEODECODER_INVALIDFORMAT]
Exception thrown at 0x00007FFEA0D6CD29 in vlc.exe: Microsoft C++ exception: _com_error at memory location 0x000000B7E55FDCF0.
Exception thrown at 0x00007FFEA0D6CD29 in vlc.exe: Microsoft C++ exception: _com_error at memory location 0x000000B7E55FDC00.
D3D11 ERROR: ID3D11DeviceContext::CreateVideoDecoder: Invalid DXGI_FORMAT 67 specified, failing! [ STATE_CREATION ERROR #3145760: CREATEVIDEODECODER_INVALIDFORMAT]
Exception thrown at 0x00007FFEA0D6CD29 in vlc.exe: Microsoft C++ exception: _com_error at memory location 0x000000B7E55FDCF0.
Exception thrown at 0x00007FFE1071B338 (msvp9dec_store.dll) in vlc.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

output_media_type has a MF_MT_SUBTYPE of MFVideoFormat_NV12

This is with an NVIDIA 3070 with drivers 31.0.15.3141 on Win10 19045.2728

If I don't do this part it works fine (but it will never use the hardware decoder which the GPU supports):

  • MFCreateDXGIDeviceManager()
  • IMFDXGIDeviceManager::ResetDevice()
  • IMFDXGIDeviceManager::OpenDeviceHandle()
  • IMFTtransform::ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER)
  • IMFTtransform::GetOutputStreamAttributes(0, &attr)
  • attr.SetUINT32(MF_SA_D3D11_BINDFLAGS, D3D11_BIND_SHADER_RESOURCE)

The same code works to decode H264 with the hardware decoder and D3D11 output (using SetInputType(MFMediaType_Video.MFVideoFormat_h264))

TransferVideoFrame in MediaEngineDCompWin32Sample always returns black

I added TransferVideoFrame to MediaEngineDCompWin32Sample to get a screen capture, but I am not able to capture the current video image.

Here is the code I added

In the class

   ID3D11Texture2D *TransferVideoFrame(ID3D11Device *&pDevice, ID3D11DeviceContext *&pContext);
    winrt::com_ptr<ID3D11Device> _d3d11Device;
      winrt::com_ptr<ID3D11DeviceContext> _context;

Getting the context when creating the device

      
    ID3D11DeviceContext *context;

        THROW_IF_FAILED(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels),
                                          D3D11_SDK_VERSION, d3d11Device.put(), nullptr, &context));

        _context.copy_from(context);


TransferVideoFrame function

    ID3D11Texture2D *MediaEngineWrapper::TransferVideoFrame(ID3D11Device *&pDevice, ID3D11DeviceContext *&pContext)
    {

        ID3D11Texture2D *returnTexture;

        RunSyncInMTA(
            [&]()
            {
                HRESULT hr;
                auto lock = m_lock.lock();

                DWORD width, height;
                m_mediaEngine->GetNativeVideoSize(&width, &height);

                pDevice  = _d3d11Device.get();
                pContext = _context.get();

                HANDLE swapChainHandle;
                hr = m_mediaEngineEx->GetVideoSwapchainHandle(&swapChainHandle);

                D3D11_TEXTURE2D_DESC desc;
                RtlZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
                desc.Width     = width;
                desc.Height    = height;
                desc.MipLevels = 1;
                desc.ArraySize = 1;
                desc.Format           = DXGI_FORMAT_B8G8R8A8_UNORM;


                desc.SampleDesc.Count = 1;
                desc.Usage            = D3D11_USAGE_DEFAULT;
                desc.BindFlags        = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
                desc.CPUAccessFlags   = 0;
                desc.MiscFlags        = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;

                winrt::com_ptr<ID3D11Texture2D> pTexture;
                hr = _d3d11Device->CreateTexture2D(&desc, nullptr, pTexture.put());

                auto rcNormalized = MFVideoNormalizedRect();

                RECT rect;
                rect.top    = 0;
                rect.left   = 0;
                rect.bottom = height;
                rect.right  = width;

                LONGLONG pts;
                if (m_mediaEngine->OnVideoStreamTick(&pts) == S_OK)
                {
                    hr = m_mediaEngine->TransferVideoFrame(pTexture.get(), &rcNormalized, &rect, nullptr);

                    if (hr == S_OK)
                    {
                        pTexture.copy_to(&returnTexture);
                    }
                }
            });

        return returnTexture;
    }

The texture is always black, I have tried different formats, but nothing works. hr is S_OK is all calls.

Few issues with sample

  1. The MediaEngineEMEUWPSample has no audio. I used the same url for both UWP and Win32 (both work)
    https://www.radiantmediaplayer.com/media/big-buck-bunny-360p.mp4

  2. When I close the win32 sample window while playing, get an exception in.

void MediaEngineWrapper::OnTimeUpdate()
{
    if(m_timeUpdateCB)
    {
        m_timeUpdateCB();
    }
}
  1. This was the original sample https://github.com/oldnewthing/old-Windows8-samples/blob/master/MEPlaybackNative/cpp/meplayer.cpp
    The above sample does'nt not bother to call MF api's in a separate MTA thread. Was that incorrect ?

  2. the new sample creates a separate STA thread for each window and an MTA thread ? Is the pattern to be followed for each instance of a player in an app

  3. The player needs to be hosted as a child window in the main thread (main STA) is that possible ? what changes are required in the sample.

  4. Finally, is there a modern media session sample - for both win32/uwp

[MediaEngineEMEUWPSample] The sample protection algorithms supported by components are not compatible. (0xC00D7176)))

I tried to play an encrypted mp4 by project MediaEngineEMEUWPSample, the mp4 is audio only and codec is Dolby AC4, encrypted by PlayReady.
And IMFMediaEngineNotify::EventNotify will be invoked with below args:

  • eventCode -> MF_MEDIA_ENGINE_EVENT_ERROR
  • MF_MEDIA_ENGINE_ERR -> 4
  • HRESULT-> 0xC00D7176

I tried to encrypt a Dolby AC3 mp4 with same way. It can be play correctly.

So I want to know why MediaEngine throw such error for AC4 codec?

Thanks!

MPEG-4 Media Source will not open files with bitrate greater than 4Gbps

Hi,

I hope I'm posting this in the right place. Is this where some of the Media Foundation / Media dev team live? :) I sure hope so, it's really hard to report issues in Media Foundation.

I've posted the details and files for this issue here:
https://stackoverflow.com/questions/63732879/how-to-get-microsoft-mpeg4-source-to-open-mov-with-bitrate-higher-than-4gbps

It seems to be a genuine bug in the MPEG-4 Source and it would be great to get it fixed.

Thanks,

mpg video cannot be loaded.

Loading this video into MediaEngineDCompWin32Sample fails with the following error reported.

Exception thrown at 0x00007FFADC17039C (KernelBase.dll) in QtVideoApp.exe: WinRT originate error - 0xC004F011 : 'The text associated with this error code could not be found.'. avcore\audiocore\client\audioclient\audioclientcore.cpp(467)\AUDIOSES.DLL!00007FFAC4B6C7C7: (caller: 00007FFAC4B6C8ED) ReturnHr(1) tid(c94) 88890008 Exception thrown at 0x00007FFADC17039C (KernelBase.dll) in QtVideoApp.exe: WinRT originate error - 0xC00D5212 : 'Decoder error'.

Error 0xC004F011 is SL_E_LICENSE_FILE_NOT_INSTALLED

I am not able to install a suitable codec to play these videos

UVS050417-003-4.zip

Sample pull-request checks fail

Error:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\Microsoft.Cpp.WindowsSDK.targets(46,5): Error MSB8036: The Windows SDK version 10.0.19041.0 was not found. Install the required version of Windows SDK or change the SDK version in the project property pages or by right-clicking the solution and selecting "Retarget solution".

Windows Media Player fails to play Opus audio track of AV1 files with MP4 container

Windows Media Player in Windows 11 fails to play Opus audio track of AV1 files when MP4 container (ISO base media file format) is used.

The Opus audio track is played when the container is MKV (Matroska).

The standard plans to use AV1 with MKV and AV1 (This is the format used by YouTube) : https://en.wikipedia.org/wiki/AV1#Supported_container_formats

PC used: Windows Media Player 12.0 + Windows 11 21H2 with AV1 video extension installed.

Sample MP4 video file: https://lafibre.info/videos/test/202008_fortnite_1984_24fps_1080p_av1.mp4

  • Video track: AV1 1080p
  • Audio track: Opus

MF_MPEG4SINK_MOOV_BEFORE_MDAT = TRUE : invalid output file

Hi,

I am trying to encode a mp4-file with "fast start" using a IMFSourceReader and a IMFSinkWriter. If a use the default settings, with no extra stuff the output file is ok:

  • ftyp
  • uuid
  • mdat
  • moov

If I then add the attribute: sinkAttr->SetUINT32(MF_MPEG4SINK_MOOV_BEFORE_MDAT, TRUE) the output file gets corrupted, the mdat box is gone and the file is not playable.

  • ftyp
  • uuid
  • moov
    ?
// output file
// stream gets the following caps: 
// MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_WRITABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK
winrt::com_ptr<IMFByteStream> stream;
::MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, L"movie.mp4", stream.put());

"In order for the mpeg4 sink to use this attribute, the byte stream passed in must not be slow seek or remote for" ✅

// Media Sink creation
winrt::com_ptr<IMFMediaSink> sink;
::MFCreateMPEG4MediaSink(stream.get(), h264.get(), nullptr, sink.put());
auto sinkAttr = sink.as<IMFAttributes>();
sinkAttr->SetUINT32(MF_MPEG4SINK_MOOV_BEFORE_MDAT, TRUE);
// SinkWriter configuration
winrt::com_ptr<IMFSinkWriter> writer;
::MFCreateSinkWriterFromMediaSink(sink.get(), attr.get(), writer.put());
writer->SetInputMediaType(0, inputType.get(), nullptr);
writer->BeginWriting()
while (framesToEncode > 0)
{
    winrt::com_ptr<IMFSample> sample;
    DWORD flags{};
    int64_t timestamp{};
    HRESULT hr = reader->ReadSample(0, 0, nullptr, &flags, &timestamp, sample.put());
    if (sample)
    {
        int64_t duration{};
        sample->GetSampleDuration(&duration);
        sample->SetSampleTime(time);
        winrt::check_hresult(writer->WriteSample(0, sample.get()));
        time += duration;
        --framesToEncode;
    }
    else
    {
        if (flags & MF_SOURCE_READERF_ERROR)
        {
            throw winrt::hresult_error(hr);
        }
        else if (flags & MF_SOURCE_READERF_NATIVEMEDIATYPECHANGED)
        {
           ...
        }
        else if (flags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED)
        {
            ...
        }
        else if (flags & MF_SOURCE_READERF_STREAMTICK)
        {
            ...
        }
        else
        {
            ...
        }
    }
}
writer->NotifyEndOfSegment(0);
writer->Finalize();

Is this feature working? Or am I doing something wrong?

I am running this on the following system:

  • Edition Windows 11 Pro
  • Version 22H2
  • Installed on ‎2022-‎09-‎28
  • OS build 22621.2283
  • Experience Windows Feature Experience Pack 1000.22662.1000.0

MediaEngineEMEUWPSample doesn't display anything

I get an exception thrown in MediaEngineExtension::BeginCreateObject because the type is MF_OBJECT_BYTESTREAM and not MF_OBJECT_MEDIASOURCE. I'm not sure if the exception is expected or not. MediaEngineExtension::BeginCreateObject is called a second time with MF_OBJECT_MEDIASOURCE and succeeds that time.

IMFContentDecryptionModuleSession::GenerateRequest failed with code 0x8004c3e8

Hi,
I tried to create a AppContainer and use the sample code from MediaEngineEMEUWPSample, but I got below errors:

  1. When I try to create CDM object, below infomation is printed in OUTPUT windows:
    Exception thrown at 0x00007FF89C2D474C (KernelBase.dll) in MediaEngineEMEConsoleSample.exe: WinRT originate error - 0xC00D36BA : 'The object does not support the specified service.'.
    however, the hresult is S_OK. Then I can continue other steps.
  2. When generate a request in founction IMFContentDecryptionModuleSession::GenerateRequest, it failed with error code ‘0x8004c3e8’

Since there is no any docs on internet about this, could you help to help me from Microsoft side. Thanks!

BTW, I found MSEdge.exe also have #1 problem when I attach its process, but it can play Playready content by MediaFoundation successfully.

ID3D12Fence leak

As mentioned in #21 (comment) I have tried to get D3D12 decoding with Media Foundation. It more or less works, but eventually it leaks internal ID3D12Fence each time it's created. I can end up with thousands of dead ID3D12Fence in my process.

To exhibit the issue I made this sample code which decodes a frame, attempt to drain, flushes and then exit.

/* compile: g++ d3d12_mft.cpp -o d3d12_mft.exe -ld3d12 -ldxgi -lmfplat -lmfreadwrite */

#undef WINVER
#define WINVER 0x0A00

#define NTDDI_VERSION  0x0A00000B // NTDDI_WIN10_CO

#include <windows.h>

#include <d3dx12.h>
#include <assert.h>

#include <dxgi.h>
#include <dxgi1_5.h>

#include <initguid.h>

#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <mferror.h>
#include <mfd3d12.h>

#include <wrl.h>

#if !defined(NDEBUG)
# include <d3d12sdklayers.h>
#endif

using Microsoft::WRL::ComPtr;

static void init_direct3d(ComPtr<ID3D12Device> &d3device)
{
    HRESULT hr;
    UINT creationFlags = 0;
#ifndef NDEBUG
    {
        ComPtr<ID3D12Debug> debugController;
        if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf()))))
        {
            debugController->EnableDebugLayer();
            creationFlags |= DXGI_CREATE_FACTORY_DEBUG;
        }
    }
#endif

    ComPtr<IDXGIFactory2> factory;
    hr = CreateDXGIFactory2(creationFlags, IID_PPV_ARGS(factory.GetAddressOf()));

    ComPtr<IDXGIAdapter1> adapter;
    for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != factory->EnumAdapters1(adapterIndex, adapter.GetAddressOf()); ++adapterIndex)
    {
        DXGI_ADAPTER_DESC1 desc;
        adapter->GetDesc1(&desc);

        if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
            continue;

        if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(d3device.GetAddressOf()))))
            break;
    }
}

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    ComPtr<ID3D12Device> d3device;
    (void)hPrevInstance;
    (void)hInstance;
    (void)nCmdShow;
    (void)lpCmdLine;
    HRESULT hr;

    CoInitializeEx(0, COINIT_MULTITHREADED);

    init_direct3d(d3device);
#ifndef NDEBUG
    ComPtr<ID3D12DebugDevice> debugDevice;
    hr = d3device.As(&debugDevice);
#endif

    MFStartup(MF_VERSION, MFSTARTUP_FULL);

    UINT resetToken;
    ComPtr<IMFDXGIDeviceManager> dxgiDeviceManager;
    MFCreateDXGIDeviceManager(&resetToken, dxgiDeviceManager.GetAddressOf());

    dxgiDeviceManager->ResetDevice(d3device.Get(), resetToken);

    ComPtr<IMFSourceReader> sourceReader;
    {
        ComPtr<IMFAttributes> creationAttributes;
        MFCreateAttributes(creationAttributes.GetAddressOf(), 1);
        creationAttributes->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, dxgiDeviceManager.Get());
        // creationAttributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);

        MFCreateSourceReaderFromURL(L"http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4",
                                    creationAttributes.Get(), sourceReader.GetAddressOf());
    }

    {
        ComPtr<IMFMediaType> pVideoMediaType;
        hr = MFCreateMediaType(&pVideoMediaType);

        hr = pVideoMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
        hr = pVideoMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
        // hr = pVideoMediaType->SetUINT32(MF_MT_D3D_RESOURCE_VERSION, MF_D3D12_RESOURCE);
        // hr = pVideoMediaType->SetUINT32(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS, TRUE);

        hr = sourceReader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, pVideoMediaType.Get());
        assert(SUCCEEDED(hr));
    }

    ComPtr<IMFTransform> transform;
   {
        ComPtr<IMFSourceReaderEx> sourceReaderEx;
        sourceReader.As(&sourceReaderEx);
        GUID cat = MFT_CATEGORY_VIDEO_DECODER;

        hr = sourceReaderEx->GetTransformForStream(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &cat, transform.GetAddressOf());

        hr = transform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)dxgiDeviceManager.Get());
    }

    hr = sourceReader->SetStreamSelection(MF_SOURCE_READER_ALL_STREAMS, FALSE);
    hr = sourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE);

    size_t decodedFrames = 0;
    ComPtr<IMFD3D12SynchronizationObjectCommands> pMFSyncCmd;
    ComPtr<IMFD3D12SynchronizationObject> pMFSyncObjs;
    HANDLE sampleResourceReady = CreateEvent(NULL, TRUE, FALSE, NULL);
    HANDLE sampleResourceFinalRelease = CreateEvent(NULL, TRUE, FALSE, NULL);
    while (true)
    {
        DWORD readFlags = decodedFrames == 0 ? 0 : MF_SOURCE_READER_CONTROLF_DRAIN;
        DWORD dwActualStreamIndex;
        DWORD dwStreamFlags;
        LONGLONG llTimestamp;
        ComPtr<IMFSample> sample;
        hr = sourceReader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, readFlags, &dwActualStreamIndex, &dwStreamFlags, &llTimestamp, sample.GetAddressOf());
        assert(SUCCEEDED(hr));

        if (decodedFrames++ == 0)
        {
        }

        if (!sample.Get())
            break; // finished draining

        DWORD bufferCount;
        sample->GetBufferCount(&bufferCount);

        ComPtr<IMFMediaBuffer> output_media_buffer;
        hr = sample->GetBufferByIndex(0, output_media_buffer.GetAddressOf());

        ComPtr<IMFDXGIBuffer> spDXGIBuffer;
        hr = output_media_buffer.As(&spDXGIBuffer);
        if (SUCCEEDED(hr))
        {
            ComPtr<ID3D12Resource> texture;
            hr = spDXGIBuffer->GetResource(IID_PPV_ARGS(&texture));
            assert(SUCCEEDED(hr));
            texture->SetName(L"MFT texture");

            hr = spDXGIBuffer->GetUnknown(MF_D3D12_SYNCHRONIZATION_OBJECT, IID_PPV_ARGS(pMFSyncCmd.GetAddressOf()));
            assert(SUCCEEDED(hr));
            hr = spDXGIBuffer->GetUnknown(MF_D3D12_SYNCHRONIZATION_OBJECT, IID_PPV_ARGS(pMFSyncObjs.GetAddressOf()));
            assert(SUCCEEDED(hr));

            pMFSyncCmd->SignalEventOnResourceReady(sampleResourceReady);
        }
    }

    hr = WaitForSingleObjectEx(sampleResourceReady, INFINITE, TRUE);
    assert(hr == WAIT_OBJECT_0);

    if (false)
    {
        ComPtr<IMFMediaSource> mediaSource;
        const GUID GUID_NULL = {0x0000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
        sourceReader->GetServiceForStream(MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&mediaSource));
        if (mediaSource.Get())
            mediaSource->Stop();
    }

    sourceReader->Flush(MF_SOURCE_READER_ALL_STREAMS);

    // pMFSyncObjs->Reset();

    pMFSyncObjs->SignalEventOnFinalResourceRelease(sampleResourceFinalRelease);
    hr = WaitForSingleObjectEx(sampleResourceFinalRelease, INFINITE, TRUE);
    assert(hr == WAIT_OBJECT_0);

    // ERROR: A ID3D12Resource is referenced by GPU operations in-flight on Command Queue
    // hr = transform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, 0);

    transform.Reset();
    hr = dxgiDeviceManager->ResetDevice(nullptr, resetToken);

#ifndef NDEBUG
    if (debugDevice.Get())
        debugDevice->ReportLiveDeviceObjects((D3D12_RLDO_FLAGS)(D3D12_RLDO_IGNORE_INTERNAL | D3D12_RLDO_DETAIL));
#endif

    MFShutdown();
    CloseHandle(sampleResourceReady);
    CloseHandle(sampleResourceFinalRelease);

    d3device.Reset();

    CoUninitialize();

    return 0;
}

When you run this code, you can see a report of live objects before the program exits, with a lot of internal things to the Media Foundation decoder, ie things I did not create myself.

D3D12 WARNING: Live ID3D12Device at 0x000001FF74BB0208, Refcount: 76 [ STATE_CREATION WARNING #274: LIVE_DEVICE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7C1B1120, Name: MFT texture, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA69AC0, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA6BF50, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA6E3E0, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA70870, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA72D00, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA755A0, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA77A30, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA79EC0, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA7C350, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA7E7E0, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA80C70, Refcount: 2, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA83100, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7BA83DC0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA862E0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7BA86FA0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA874B0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7BA8A180, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7BA8E6A0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7BA8EB00, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7C1B5700, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7BA8ED80, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7C1B5270, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7C1B7C70, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7C1B4950, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7C1BA0B0, Refcount: 1, IntRef: 1 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Resource at 0x000001FF7C1B3710, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: 	Live ID3D12CommandAllocator at 0x000001FF7C1BA5B0, Refcount: 1, IntRef: 1 [ STATE_CREATION WARNING #571: LIVE_COMMANDALLOCATOR]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7B82C890, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12CommandQueue at 0x000001FF7C1BD780, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #1054: LIVE_VIDEODECODECOMMANDQUEUE]
D3D12 WARNING: 	Live ID3D12VideoDecodeCommandList at 0x000001FF7C1EE7C0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #982: LIVE_VIDEODECODECOMMANDLIST]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FD410, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2F9A40, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FB160, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FAA70, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2F9EE0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FA130, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FA380, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FBCF0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FCD20, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FA820, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FD1C0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12Fence at 0x000001FF7C2FACC0, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #580: LIVE_MONITOREDFENCE]
D3D12 WARNING: 	Live ID3D12VideoDecoder at 0x000001FF74E16A60, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #983: LIVE_VIDEODECODER]
D3D12 WARNING: 	Live ID3D12VideoDecoderHeap at 0x000001FF7C1BA330, Refcount: 1, IntRef: 0 [ STATE_CREATION WARNING #1084: LIVE_VIDEODECODERHEAP]

When the app is closing, there is this report, where the pointers correspond to the ID3D12Fence seen above:

D3D12 WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: Live Producer at 0x000001FF74BB01E8, Refcount: 26. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF72D6A030, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF74E7DF70, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF74E79A30, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF74C48E30, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF74D8ABF0, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF74C49D40, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF74C49F90, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7B7026E0, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FD410, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2F9A40, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FB160, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FAA70, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2F9EE0, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FA130, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FA380, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FBCF0, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FCD20, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FA820, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FD1C0, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: 	Live Object at 0x000001FF7C2FACC0, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D12 WARNING: Live                         Object :     20 [ STATE_CREATION WARNING #0: UNKNOWN]

I tried using the IMFD3D12SynchronizationObject and IMFD3D12SynchronizationObjectCommands interfaces but with no luck.

MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID support in IMFMediaEngine

Is there any way to propgrammatically specify the audio renderer used by the IMFMediaEngine? Assigning MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID to a different device ID in the creation IMFAttributes seems to have no effect. Is this not supported at all or is there a different interface I can access in order to send the audio to a different output?

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.