Saved searches

Use saved searches to filter your results more quickly

Cancel Create saved search Sign up Reseting focus

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Sample implementations of different Microsoft Media Foundation components

License

Notifications You must be signed in to change notification settings

joekickass/ms-media-foundation-samples

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Go to file

Folders and files

Last commit message Last commit date

Latest commit

History

View all files

Repository files navigation

media-foundation-samples

Sample implementations of different Microsoft Media Foundation components

References

Core MF concepts

An architectural overview of the Media Foundation Architecture:

Media Foundation Architecture

Two different programming models:

Examples

See github projects:

https://github.com/joekickass/media-foundation-samples 

Plumbing

As usual when it comes to creating components that should fit into a complex framework (e.g. MF) there are some plumbing involved. With plumbing I mean all the bulk code that has to be written to hande the packaging of the component as well as to fulfill interfaces that allows the component to be loaded by the framework. In the case of MF , below is a short list:

Windows Runtime Template Language (WRL)

In most situations, it is recommended to use C++/CX to interact with the Windows Runtime. But in the case of hybrid components that implement both COM and Windows Runtime interfaces, such as Media Foundation objects, this is not possible. C++/CX can only create Windows Runtime objects. So, for hybrid objects it is recommended that you use WRL to interact with the Windows Runtime. Be aware that Windows Runtime C++ Template Library has limited support for implementing COM interfaces.

DLLs, linking and exporting

An MF extension is usually implemented as a DLL. The following few steps are a common procedure:

  1. Create a Win (Phone) 8.x DLL project
  2. Add a definition file (*.def) that defines all exported functions of the shared library (the export list) *.def:

EXPORTS DllGetActivationFactory PRIVATE DllCanUnloadNow PRIVATE DllGetClassObject PRIVATE 
Note: The *.def file needs to be referenced in project settings under:
Setting Value
Linker -> Input -> Definition File mydefinitionfile.def
#include "pch.h" // pch.h should include  using namespace Microsoft::WRL; BOOL APIENTRY DllMain(HMODULE hInstance, DWORD ul_reason_for_call, LPVOID) < switch (ul_reason_for_call) < case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstance); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; > return TRUE; > HRESULT WINAPI DllGetActivationFactory(HSTRING activatibleClassId, IActivationFactory** factory) < return Module::GetModule().GetActivationFactory(activatibleClassId, factory); > HRESULT WINAPI DllCanUnloadNow() < return Module::GetModule().Terminate() ? S_OK : S_FALSE; > STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv) < return Module::GetModule().GetClassObject(rclsid, riid, ppv); >

More info on DLLs and linking can be found on http://www.tenouk.com/ModuleBB.html

MIDL and MIDLRT

The Microsoft Interface Description Language is used to describe the interface exposed through the windows runtime. The following MSDN project template summarizes the steps needed to do this:

  1. An .idl file that declares the MIDL attributes for a basic interface and its class implementation
  2. A .cpp file that defines the class implementation.
  3. A file that defines the library exports DllMain() , DllCanUnloadNow() , DllGetActivationFactory() , and DllGetClassObject() .

In addition to this, the MIDLRT compiler needs to be set up to generate a .winmd file for the DLL. Without it the library won't be exposed throught the Windows Runtime and thus cannot be used as a reference in managed code. More info:

An example *.idl file for a custom MFT:

import "Windows.Media.idl"; #include sdkddkver.h> namespace Transform < [version(NTDDI_WIN8)] runtimeclass Effect < [default] interface Windows.Media.IMediaExtension; > >

Right clicking on the idl file and selecting Properties is a shortcut to the project properties for MIDL. To genereate a .winmd file, add the following settings.

Setting Value
MIDL -> General -> Enable Windows Runtime Yes (/winrt)
MIDL -> Output -> Metadata File $(OutDir)%(RootNamespace).winmd
MIDL -> Output -> Header File %(RootNamespace)_h.h

Note that the generated .winmd file needs to be modified in order to work properly. See StackOverflow for more info:

This means adding the following build step under project settings:

Setting Value
Custom Build Step -> General -> Command Line mdmerge -v -i "$(OutDir)." -o "$(OutDir)Output" -partial -metadata_dir "$(WindowsSDK_MetadataPath)" && copy /y "$(OutDir)Output*" "$(OutDir)"
Custom Build Step -> General -> Output $(OutDir)%(RootNamespace).winmd
Custom Build Step -> General -> Execute After Midl

Finally, the generated header file (_%(RootNamespace)h.h) needs to be referenced in the class definition file (*.cpp) as shown in the generic example below. Notice the InspectableClass using a string definition from the header, and the ActivatableClass section.

#include "pch.h" #include "RootNamespace_h.h" #include wrl.h> using namespace Microsoft::WRL; using namespace Windows::Foundation; namespace ABI < namespace RootNamespace < class WinRTClass: public RuntimeClass < InspectableClass(RuntimeClass_RootNamespace_ClassName, BaseTrust) public: WinRTClass()<> >; ActivatableClass(WinRTClass); > >

MFTs

A few libraries need to be referenced when creating an Effect MFT:

Add them to Linker -> Input -> Additional Dependencies.

In managed code (e.g. the C# application where the MFT library is referenced), the class needs to be activated using the following section added to the Package.appxmanifest file:

Extensions> Extension Category="windows.activatableClass.inProcessServer"> InProcessServer> Path>EffectTransform.dllPath> ActivatableClass ActivatableClassId="EffectTransform.Effect" ThreadingModel="both" /> InProcessServer> Extension> Extensions>

Threading

MF is a free-threaded system, which means that COM interface methods can be invoked from arbitrary threads. Therefore, when calling CoInitializeEx(), you must initialize COM with the apartment-threaded object concurrency by passing in the COINIT_APARTMENTTHREADED parameter. Your objects might also need to use synchronization primitives, such as locks, to control access to internal variables by concurrently running threads.