Follow-up report about the WinRT port
Like last post, I've spent too much time working on VLC than writing updates and communicating, and I'm sorry again.
We are still working a lot of time, with almost a couple of persons spending most of their time on the WinRT port of VLC media player.
The biggest issue is that we have not managed to pass the store validation yet, because the VLC backend is not ready yet. I'll explain in this blog post where we are.
VLC backend on WinRT
Reminder: So, the core of VLC and most of the modules, named libVLC, are the target to adapt to run on WinRT. The UI will integrate this core to show the videos.
As I previously explained, the build process of VLC is not integrated with Windows Tools, notably Visual Studio, because VLC uses Unix Tools to run on all platforms. This is one of the reasons why VLC media player works on Windows, Linux, BSD, Solaris, iOS, Android, OS/2 and so many other operating systems.
The of the KickStarter was the compliance of this core to the WinRT Store Application limitations. We're almost there, but not quite.
The issues we were facing with the compliance were mainly 2 things:
- Extra Security,
- Forbidden APIs.
The security enforcements (SafeSEH, packagedlibraries) where quickly done (and backported to the main VLC port). The forbidden symbols were a bit more complex.
When we started the project, we had over 600 unique symbols (Windows API calls) used in VLC, for a total of over 15000.
We are now at 16 left. And 32 more if we activate the networking code. This is cool, but not enough, since we must be at 0 to enter the store.
I'll explain now how we did it.
Simple symbols replacements
Some symbols were easy to replace, when you knew that you are targeting only Windows 8, because they had some similar methods.
So, for each symbol, we provided a replacement with a newer API. This was quite long, but easy to do
You can see the result of our work here: mingw-w64 code.
Removal of code and Unicode
The second part was to remove some code in VLC that was not meant to be used in WinRT mode; this was mostly the code for the Console, the multimedia timers and some NT services. This improved the port of VLC media player for Windows, not only the one on WinRT.
We also removed some code from libVLC to move it to VLC, when it made sense. This is a good move for libVLC, in general.
Finally, we moved all the code of VLC and the dependencies (8 millions LoC) to UNICODE and Wide Chars. Once again, a task not too difficult, but a bit boring and long.
Most of that part was done mid-March. Then we hit a wall.
The wall is called MSVCRT, aka Microsoft C Runtime, the equivalent of the libc, the C standard library,
Every version of Visual Studio and Windows comes with a new version, with version numbers from 2.0 to 11.0. It is often a dependency headache for big projects. Most open source projects use the old version named msvcrt.dll, the version 6.0.
But on WinRT, one MUST use MSVCRT 11.0 in order to pass the validation. This meant that we had to modify our compiler and toolchain to be able to link with this version.
This took us weeks of work, reading documentation, testing, asking Microsoft, doing it step by step and finally arriving to the result.
First, we had some mismatch between Debug and Release versions of the libraries when trying the validation. But as we were doing it manually, it was quite hard to understand what was going on, and the documentation was very scarce.
And then, running the application with MSVCRT 110 was just crashing without meaningful messages or usable debug reports or crashes.
When we asked Microsoft, some engineers told us that this could not possibly succeed, since the validation would not allow application compiled with 3rd party compilers to link with MSVCRT110. We did not want to believe them, since this would have killed the project.
And, they were wrong. We did it, but this took us way more time than anything we had anticipated. The final work was shared and integrated in our toolchain, Mingw-W64. All other open source applications will benefit from that, from now on.
So, the final piece is composed of symbols that only have replacements using the WinRT APIs.
Those WinRT APIs are a bit like extensions of Windows COM APIs. They work in a similar way, and are usable with methods similar to CoCreateInstance, named RoActivateInstance. However, they are not the same. People using Visual Studio, use a language named C++/CX that has a bit of magic to hide all the details.
But, of course, we need Visual Studio to use C++/CX. And we have GCC, targeting C code :D
Again, accessing those APIs directly from C code compiled with GCC should not be possible (according to some engineers), but we have been trying that path for quite a bit of time.
2 weeks ago, we had a good success: we were able to call a simple functions from a sample code, using RoActivateInstance. So, the hardest part was done.
What we are doing now is just rewriting the Microsoft WinRT headers and adapting the toolchain to munch those and call those symbols. We're working full time on that part!
It's been a hard time working on this port, with many more technical issues than expected. Therefore, we've been slower than expected.
We've done things that people (even from Microsoft) advised us against, and so far we've passed all the issues. So a great outcome is arriving!
We have a bit of work still to go on rewriting the headers to call the new WinRT APIs, and kill the remaining 16 symbols. We're working full time to fix those!