Published by Arto Jarvinen on 20 Mar 2010

Reference hunting

This is one of the most time-consuming debugging sessions I’ve been doing so far. Partly because I have not written all the code myself and there are few or no comments and partly because COM reference counting is hard, period. Enough whining.

Dead beef
Microsoft humor.

I have tracked down my problem to the IDirect3DDeviceManager9::ResetDevice method. When calling it with a new DirectX device as a parameter, it decrements the reference count of the old DirectX device by one and increments the reference count of the new one by four! The balance of the references to the old device are later released on one of 21 (!) active threads when renegotiating formats or something like that. The unreleased “zombie device” causes problems when exiting exclusive mode full-screen since it still has exclusive access to the full-screen. When the new device tries to present something it causes a lost device. This baffled me quite a bit in the beginning because it looked like I got a lost windowed device but I’m pretty certain that it was the old full-screen device that was lost before it was properly released (I don’t even know if one can lose a windowed device).

Ideally I need to find where the last few references are released and see to it that that piece of code is called from the thread on which the device was once created. The hunt goes on…

Published by Arto Jarvinen on 14 Mar 2010

Some help needed

Device lost
A very useful window.

Ok, I’m stuck. I’m trying to implement toggling between windowed mode and exclusive mode full-screen on a 2 monitor setup. It works – almost. This is how it doesn’t work (for more detailed player settings see below):

  1. Start the player
  2. Move the window to the secondary monitor
  3. Start a movie
  4. Double-click to go into full-screen (see to it that the option D3D Fullscreen is checked)
  5. Double-click to go back into windowed mode
  6. The video freezes but audio goes on playing. Trace output says that the device is lost even though it should be a windowed device
  7. Double-click again to go into full-screen
  8. And double-click one more time to go back to windowed
  9. Now, if your computer behaves like my two XP machines, the video plays and subsequent toggles work

Toggling between windowed and exclusive mode full-screen works fine on my primary monitor. Once it has started working on the secondary monitor (and this is the really weird part) it keeps on working even if playback is closed and then restarted. It seems as if either the player or the gfx board stores some useful data enabling it to work the second time. Everything works fine if windowed (non-D3D) full-screen is used.

Not everything is implemented yet so the above experiment only works with the following MPC-HC settings:

  • Windows XP
  • 2 monitors
  • EVR Sync
  • D3D Fullscreen
  • Reinitialize when changing display
  • Fullscreen monitor: Current
  • Use worker thread to construct the filter graph: Unchecked

If anybody would like to help out with some interesting debugging, you can find the modified files here. They are updated with trunk revision 1752.

Published by Arto Jarvinen on 14 Mar 2010

A good thing – and a bad thing

I got my image back with an old 6600GT card. Noisy but works fine. That’s the good thing.

The bad thing is that the behavior of my app can not be explained by a driver bug. It is perfectly repeatable with an NVidia card. It appears both in debug builds and in release builds which means that it is probably not just a spurious memory allocation problem or something like that. I have to get used to the thought that it might be a real programmer mistake, as tough as that is.

Published by Arto Jarvinen on 14 Mar 2010

Even more struggle

Just to keep the perspective, I have to remind myself that everything I write about are problems of the industrialized world and therefore – really – not problems at all. But I think it is fair to say that I’ve never had a problem-free upgrade of an ATI driver – ever.

I decided to upgrade the driver on my development machine. The bug I’m chasing might, I say just might, be a driver bug. It appears when going from exclusive mode full-screen to windowed mode, but only the first time, and only when using the second monitor. Everything works fine the second time I toggle between exclusive mode full-screen and windowed mode on the second monitor and it always works on the primary monitor.

Anyway, after upgrade, the computer went totally black. I have a spare NVidia board in the closet and I think this might just be a good time to bring it out and give it a spin. All my NVidia upgrades have been painless as far as I can remember.

Published by Arto Jarvinen on 13 Mar 2010

Struggle

When I first started working on the Sync Renderer solution a few years back (at that time in my own player) I pretty much started from scratch in every respect. I had not written a professional line of code in maybe 17 years. And i had no knowledge at all about the Windows environment or DirectShow or DirectX. I struggled for many weeks with some (afterwards) pretty obvious things.

I’m feeling a bit of a deja-vu all over again (as Yogi Berra is said to have said – if you can’t find anybody else to attribute a quote to, you can always suggest Mr Berra). I would very much like to simplify things but I have for instance realized that a child window in MFC can not be a top-most window and can therefore not be used for exclusive mode full-screen. Took me a few ours to realize that. So there was a need for that other specific and seemingly superfluous full-screen window after all.

Bloated frameworks like MFC are maybe good for experienced programmers but they mostly add complexity for the weekend programmer. In this case for instance one has to find a way to code around the built-in behavior of MFC. So it goes.

I’m from time to time on the verge of scrapping my whole MPC-HC effort in favor of my own MFC-free and about 100 times simpler player. But then I hear this inner voice which urges me to give it just another try. The same voice that I kept hearing a few years back. So I’ll give it one more weekend. And then we will see…

Published by Arto Jarvinen on 07 Mar 2010

Some code

The toggling between windowed and exclusive mode full-screen turned out to be more time-consuming than I thought from the beginning. There is now some code on my ftp site. It took me a while to realize that one can not (I believe) reset a DirectX device and change monitor at the same time when switching to exclusive mode full-screen. Windowed mode works fine. I have not seen this documented anywhere but it’s a strong hypothesis backed up with some empirical work (= frustrating debugging). The other road-block was the fact that the MPC-HC built in DXVA decoder doesn’t seem to react well to device resets. If you check the Reinitialize when changing display option and move the window from one screen to the next while playing e.g. something coded in VC-1, then the video window turns black on the new screen (with EVR Sync and EVR Custom at least).

The D3D Fullscreen option now means that when exclusive mode full-screen will be used when toggling into full-screen. The player will not start in full-screen though unless you tick Launch files in fullscreen on the Fullscreen Options page.

The code on the ftp site is not finished. It needs the following amendments:

  • Recovery from lost device. Now it seems that the exclusive mode full-screen window behaves as it should, i.e. you lose the device if the window loses key-board focus. Now, if you lose focus, it’s lost forever (or you might get some sort of zombie full-screen window that isn’t to be trusted.
  • DXVA support is not stable. The toggling works fine for ffdshow and the internal filters when not in DXVA mode.
  • It only works with EVR Sync right now.
  • It requires that the option Use worker thread to construct the filter graph is unchecked.

There are probably other bugs but it’s a start.

Published by Arto Jarvinen on 20 Feb 2010

A small step for mankind…

I have finally managed to toggle between windowed and full-screen mode in MPC-HC using Sync Renderer! This may not sound like news at all but it’s not just any old full-screen, it is exclusive mode full-screen. Once fully implemented and debugged this should make it much more convenient to use exclusive mode (aka D3D mode) full-screen in MPC-HC.

In my experience, the exclusive mode full-screen GUI support destroys the tear-free nature of the exclusive mode full-screen. This means that it is hard to manage for instance subtitles in exclusive mode. The possibility to toggle between windowed and exclusive mode full-screen means that you can use the full GUI in windowed mode for your settings before going into tear-free full-screen. The best of two worlds!

There is still plenty of coding left before this can be released as I need to combine the new behavior for the Sync Renderer with the old behaviors of the other custom renderers (I don’t dare to touch them yet). An initial test is shown in the picture below. I’m using a sync offset of about 4 ms together with bicubic interpolation and a shader (gray-scale) without any tearing.

Toggle FS
A gray full-screen without tearing.

Published by Arto Jarvinen on 31 Jan 2010

Threads and devices

“Device” – isn’t that a funny word? I’m not a native English speaker so I don’t know but I get the feeling that engineers are sometimes running out of imagination and sometimes they (or I should really say “we” as I’m as guilty as the next guy) associate along very convoluted paths. Anyway…

The graphics “device” is a piece of software that represents the graphics output unit of the PC. It is in effect a COM object that obeys all the intricate and very mathematical rules of COM programming. It’s today used for pretty much everything you write or draw on the display. In MPC-HC the graphics device sometimes needs to be “reset”, meaning that memory needs to be reallocated due to a new video pixel format or some other reason.

If a COM object like the graphics device is created on one thread and naively destroyed or reset (reallocation of memory) on another, a dangling pointer to the object may remain on the thread of creation. This may cause all kinds of strange behavior. The safest thing (and the recommended thing according to Microsoft docs [1][2]) is therefore to create, reset and destroy the graphics device object on one and the same thread. This is not done in MPC-HC today and my plan is to fix that.

Another funny thing is that the exclusive mode full-screen will keep rendering through ALT+TAB and clicking on other windows, unlike other exclusive mode full-screen applications. The thing with exclusive mode is exactly that an application in this mode is supposed to have exclusive access to the driver without passing through any window manager and without sharing the device with any other application that may bother it. I may need to edit this post later if I find that this is a feature, not a bug. But that will be then.

My plan is to make it possible to toggle between windowed mode and exclusive mode (aka D3D) full-screen while streaming. This worked in my old player so at least it is feasible. But as always, time is scarce so don’t start holding your breath just yet.

Links

[1] IDirect3DDevice9::Reset

[2] Creating a Device (Direct3D 9)

Published by Arto Jarvinen on 06 Jan 2010

Voddler woes

I have just joined as a beta-tester of Voddler, the “Spotify for movies”. It is currently beta-tested in Sweden (only). Unfortunately I don’t have any good news to report yet as I can not get the client up and running at all. It seems to be very sensitive to router settings, firewalls etc. Even disabling every millimeter of protection, and enabling UPNP in the router as per the user guide, I can’t get it to pass the initial test. I’m not alone having these problems it seems.

I do like the idea that the client is built on open source but of course I’m missing a Linux client. The client is still a bit clunky. You can’t use the mouse for instance. That is not a big deal for an HTPC that you control with a remote. It is a bit inconvenient on the desktop though.

I’m sure they (or I) will figure it out eventually. The concept is totally right. I’m a happy subscriber to Spotify Premium and wouldn’t hesitate to shell out a similar amount to get access to a stable stream of good movies.

Unfortunately my small switch broke so there is no easy way currently for me to connect to the Internet directly, without a router. And I will still want to use the program through a router in the end as I want all my computers on the same network. But before that I guess I need a new switch for some unprotected troubleshooting. I did sign up as a beta-tester after all.

Links

[1] www.voddler.com

Published by Arto Jarvinen on 02 Jan 2010

Time to write some code

Christmas
Time to write some code.

Christmas is a blessing in many ways, not the least because I chose to take four days of vacation to catch up with some hobby projects and some horse riding after a hectic fall work-wise. As seen from an earlier post I built a new HTPC and also took time to do some changes in the GothSync code. I was perhaps procrastinating a bit since I was afraid that I had been struck by amnesia and that I would have to learn everything all over again. I haven’t looked much into the code since my summer vacation. Starting from scratch would have been a little bit like going to the gym after half a year of sedentary life: it would have hurt! Luckily some synapses remained intact and it wasn’t too hard to catch up and do what I had planned to do a long time.

I added the Sync Renderer (I will probably drop the “Goth” part for brevity and because it seems to give associations to the kind of music that my teenage son is listening to) as an optional renderer to the regular build of MPC-HC. This means that all the other renderers are intact. When I started experimenting I took a shortcut and hacked away on two of the existing renderers, effectively destroying the original renderers. They are now restored.

The Sync Renderer is now added as the last option in the increasingly long list of available renderers. Once it is selected, further synchronization options can be selected from the Synchronization options page. For more documentation, see the Get started page (may be slightly out of date when I write this).

The new version has been committed into the trunk (main development branch) of MPC-HC at SourceForge. Executables are available through the Download page.

Please give any feedback either as a comment here or on this thread at Doom9′s. Report bugs on the SourceForge bug tracker. (A comment on Doom9′s thread would be useful even if you submit a formal bug report. I haven’t got used to visiting the bug tracker regularly yet since I just recently added my code to MPC-HC trunk.)

« Prev - Next »