Archive for March, 2010

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.