Media Foundation API primitive styling of WinRT windows.mediaCodec

An interesting Media Foundation question on StackOverflow: Weird connection between CoInitializeSecurity() and Media Foundation Encoders

A developer has reasons to discard standard COM security and go RPC_C_IMP_LEVEL_ANONYMOUS. Surprisingly this has effect on Windows Media Foundation API in the part of available codecs (Media Foundation Transforms).

Sample code:

#include <iostream>

#include <winrt\base.h>
#include <mfapi.h>
#include <mftransform.h>

#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfuuid.lib")

int main()
{
	// https://stackoverflow.com/questions/59368680/weird-connection-between-coinitializesecurity-and-media-foundation-encoders
	WINRT_VERIFY(SUCCEEDED(MFStartup(MF_VERSION, MFSTARTUP_FULL)));
	WINRT_VERIFY(SUCCEEDED(CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_ANONYMOUS, nullptr, EOAC_NONE, nullptr)));
	//WINRT_VERIFY(SUCCEEDED(CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)));
	IMFActivate** Activates = nullptr;
	UINT32 ActivateCount = 0;
	WINRT_VERIFY(SUCCEEDED(MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, MFT_ENUM_FLAG_ALL, nullptr, nullptr, &Activates, &ActivateCount)));
	WINRT_ASSERT(Activates || !ActivateCount);
	BOOL Found = FALSE;
	for(UINT32 Index = 0; Index < ActivateCount; Index++)
	{
		IMFActivate*& Activate = Activates[Index];
		WINRT_ASSERT(Activate);
		WCHAR* FriendlyName = nullptr;
		UINT32 FriendlyNameLength;
		WINRT_VERIFY(SUCCEEDED(Activate->GetAllocatedString(MFT_FRIENDLY_NAME_Attribute, &FriendlyName, &FriendlyNameLength)));
		std::wcout << FriendlyName << std::endl;
		if(wcscmp(FriendlyName, L"HEVCVideoExtensionEncoder") == 0)
			Found = TRUE;
		CoTaskMemFree(FriendlyName);
	}
	WINRT_ASSERT(Found);
	CoTaskMemFree(Activates);
	//CoUninitialize();
	WINRT_VERIFY(SUCCEEDED(MFShutdown()));
}

CoInitializeSecurity line in the code above removes the following from enumeration:

  • HEIFImageExtension
  • VP9VideoExtensionEncoder
  • HEVCVideoExtensionEncoder

See the pattern? Why?

Similarly to other and older APIs like DirectShow enumeration function combines uniformly interfaced primitives coming from multiple sources. In this case of Media Foundation, enumeration combines (and filters/orders when requested) traditional transforms registered with the API with information in system registry, limited scope transforms and also transforms coming from Windows Store.

For example, H.256/HEVC video decoder and encoder is added to the system as HEVC Video Extension Windows Store item.

<Identity ProcessorArchitecture="x64" Version="1.0.23254.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Name="Microsoft.HEVCVideoExtension"/>

Its video encoder, in turn, is:

        <uap4:Extension Category="windows.mediaCodec">
          <uap4:MediaCodec DisplayName="HEVCVideoExtensionEncoder" Description="This is a video codec" Category="videoEncoder" wincap3:ActivatableClassId="H265Encoder.CH265EncoderTransform" wincap3:Path="x86\mfh265enc.dll" wincap3:ProcessorArchitecture="x86">
            <uap4:MediaEncodingProperties>
              <uap4:InputTypes>
                <!-- NV12 -->
                <uap4:InputType SubType="3231564e-0000-0010-8000-00aa00389b71" />
                <!-- IYUV -->
                <uap4:InputType SubType="56555949-0000-0010-8000-00AA00389B71" />
                <!-- YV12 -->
                <uap4:InputType SubType="32315659-0000-0010-8000-00AA00389B71" />
                <!-- YUY2 -->
                <uap4:InputType SubType="32595559-0000-0010-8000-00AA00389B71" />
              </uap4:InputTypes>
              <uap4:OutputTypes>
                <!-- HEVC -->
                <uap4:OutputType SubType="43564548-0000-0010-8000-00AA00389B71" />
              </uap4:OutputTypes>
            </uap4:MediaEncodingProperties>
          </uap4:MediaCodec>
        </uap4:Extension>
      </Extensions>

Media Foundation API is capable to pick such mediaCodec from Windows Store applications and make it available to desktop applications. However, there in COM security in the middle of the glue layer. Media Foundation would create a special activation object (CMFWinrtInprocActivate) to implement IMFActivate for such WinRT codec and once activated, the transform acts as usual and as documented. These codecs are also dual interfaced and in addition to traditional Media Foundation interfaces like IMFTransform expose UWP interfaces like IMediaExtension and so they are consumable by UWP applications as well.

Leave a Reply