Media Foundation support for Opus 5.1 audio

There is some support for Opus in Windows, unfortunately however it is not documented. IIRC it came to extend media codec support in Microsoft Edge browser, and since internally Microsoft Edge is using standard platform media API Media Foundation, the decoder came in format of Media Foundation Transform.

It is interesting that Opus decoding was put deep enough to appear across multiple environments, including even Windows IoT:

However, Microsoft did not update Media Foundation API itself to indicate presence of new codec support. The documentation has no mention for Opus decoder. The thing has been present in Windows for four years, but it is not exposed to developers…

Apart from this, stock support for Opus either decoder or WebM parser, or both, are limited to mono or stereo audio. There is no support for more sophisticated channel configurations. Neither in Media Foundation, nor in Edge itself. Edge Beta has it because it inherited the capability from Chrome, which in turn bundles libopus directly, through use of FFmpeg.

5.1 Opus audio fragment played by Edge Beta but not Edge:

Edge Beta’s internals:

Since the limitation is in Media Foundation primitives, other Media Foundation based applications exhibit similar behavior. For example, Movies and TV application similarly fails on this media file.

Native registration free COM dependency for .NET 5 application

Isolated property is supposed to enable referencing in-process COM servers as a registration free COM dependency, but something got broken on the way: Visual Studio 2019 Preview and .NET 5 produce applications that lose the link.

It is still preview so hopefully things get resolved timely.

The reproducer itself is a nice template for checking out C#/C++ COM interop.

Windows 10 SDK 10.0.19041 needs some massaging

In:

#include <unknwn.h>
#include <winrt\base.h>
#include <winrt\Windows.Foundation.h>

int main()
{
}

Out:

1>—— Build started: Project: CppWinrt01, Configuration: Debug x64 ——
1>CppWinrt01.cpp
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(983,26): error C2039: ‘wait_for’: is not a member of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(103): message : see declaration of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(985): message : see reference to class template instantiation ‘winrt::impl::consume_Windows_Foundation_IAsyncAction’ being compiled
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(1004,26): error C2039: ‘wait_for’: is not a member of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(103): message : see declaration of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(1006): message : see reference to class template instantiation ‘winrt::impl::consume_Windows_Foundation_IAsyncActionWithProgress’ being compiled
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(1038,26): error C2039: ‘wait_for’: is not a member of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(103): message : see declaration of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(1040): message : see reference to class template instantiation ‘winrt::impl::consume_Windows_Foundation_IAsyncOperationWithProgress’ being compiled
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(1057,26): error C2039: ‘wait_for’: is not a member of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(103): message : see declaration of ‘winrt::impl’
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt\winrt\impl\Windows.Foundation.0.h(1059): message : see reference to class template instantiation ‘winrt::impl::consume_Windows_Foundation_IAsyncOperation’ being compiled
1>Done building project “CppWinrt01.vcxproj” — FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

For the record, stepping down to 10.18362 heals the build:

Concurrent H.264 encoder sessions with AMD GPUs

I was under impression that AMD hardware allows just one video encoding session and prevents from having multiple side by side. This has been the consistent behavior I was seeing and I was always wondering why it had to be that tight.

To my surprise, the actual limitation is higher and, in particular, is sixteen (16!) sessions runnable in parallel. In particular, with the GPU in my dev box…

The problem has been a bug in AMD driver and/or AMD AMF runtime, which triggered an exception when in low latency mode. With this bug it is indeed just one session at a time. Even though the bug has been present for literally years, it is good that AMD engineers do respond on github and this results in problem identification, workaround and I hope resolution as well.

The good thing is that just 2+ low latency sessions are not allowed. Multiple regular sessions and zero or one low latency, up to 16 in total, is still fine. That is, a fallback to non low latency session is a possible workaround.

UPDATE: This is a hardware limitation for AMD Polaris Architecture: only one process can own low latency hardware queue. Newer GPUs are not affected.

AMD could do better in notifying of their updates and fixes for the video adapter hardware drivers

Quite a number of AMD GPU based video cards are running outdated drivers for such modern task as low latency game streaming, and users have no clue that the video driver is letting them down. For example, a slice of version structure for those who “have things going rather well”:

Current recommended (“stable”?) version is 20.4.2 (just 20%) released on 15-May-2020 10 weeks ago, and optional (“latest”, “beta”?) is 20.7.2. Many users have 19.xx just because they install the driver pulled by Windows Update expecting this to be a good driver. It is not and with many adapters it simply does not work for some of the video encoding tasks because it does not follow the documented behavior. Quite some users just have no guess that their “standard” video driver brought to them via Windows Update channel is hugely outdated and multiple updates have been available.

Now the structure for AMD RX 5×00 XT series (especially popular RX 5700 XT):

The small fraction of 20.5.1 reflects the broken state of the driver: video encoder there fails to process video. Yes, it is fixed in 20.7.1 but only users who check and install optional updates of AMD Adrenaline 2020 have a chance to be aware of availability of fixing update.

Another confusing thing is that there is a recommended version of AMD driver software and it seems to be the default setting to pull recommended updates. Yet the driver download section (link above) suggests to install optional/latest version 20.7.2 of the driver software package.

1 GB limit for Windows::Storage::FileIO::ReadLinesAsync?

There seem to be a limit of 1GB for FileIO::ReadLinesAsync API even though documentation is silent on this.

StorageFile EventStorageFile { TryGetFile(m_Configuration.m_ApplicationStorageFolder, m_FileName) };
if(!EventStorageFile)
    return;
using namespace winrt::Windows::Storage;
auto const LineVector { FileIO::ReadLinesAsync(EventStorageFile).get() };

The exception message itself adds no clarity:

WinRT originate error – 0x80070057 : ‘The parameter is incorrect.’.

The function starts working well when the input file is slightly reduced in size (under 1050 MB).