Anteru's blog
  • Consulting
  • Research
    • Assisted environment probe placement
    • Assisted texture assignment
    • Edge-Friend: Fast and Deterministic Catmull-Clark Subdivision Surfaces
    • Error Metrics for Smart Image Refinement
    • High-Quality Shadows for Streaming Terrain Rendering
    • Hybrid Sample-based Surface Rendering
    • Interactive rendering of Giga-Particle Fluid Simulations
    • Quantitative Analysis of Voxel Raytracing Acceleration Structures
    • Real-time Hybrid Hair Rendering
    • Real-Time Procedural Generation with GPU Work Graphs
    • Scalable rendering for very large meshes
    • Spatiotemporal Variance-Guided Filtering for Motion Blur
    • Subpixel Reconstruction Antialiasing
    • Tiled light trees
    • Towards Practical Meshlet Compression
  • About
  • Archive

Windows Media Player madness

September 11, 2005
  • Programming
approximately 4 minutes to read

Recently, I tried to write a simple tool using C#/.NET Framework that would allow me to gather information about movie files. As I wanted to be able to get the size, format and length of every movie file that WMP can open, I decided to use its SDK. Read on to see why this is not as easy as it sounds.

Step 0 - Preparation

I downloaded the WMP 10 SDK, including all sample files and I read the documentation :)

Step I - The simple approach

The simple, obvious approach:

WindowsMediaPlayer player = new WindowsMediaPlayer ();
Media = player.newMedia ();
duration = media.duration; // etc. 
// more queries using getItemInfo

Doesn’t work, as the player’s openState must change to MediaOpen before you can start to query it.

Step II - Being clever

Ok, I thought, that would have been too easy. Reading the documentation, I discovered that the player would trigger the OpenStateChanged event when it opens a media. Beware, as this will only work for the current file - i.e. player.currentMedia. Which means you can only wait for one media to open at a time. Great, I thought. I wrote a quick event handler, and ran it inside a foreach loop. The OpenStateChanged event was fired exactly once. Time for another approach.

Step III - Threads to the rescue

Obvioulsy, what was needed was a way to start up a load process and let it run until it finishes, and then return to the main process. My aim was to create a process function that would create a new WindowsMediaPlayer instance, call the newMedia method and wait until the OpenStateChanged event occurs. Then, it would get the data about the movie inside the event handler and store them. Finally, it would trigger some signal so the main thread knows the open/read/close cycle ended. I looked into the threading examples that ship with VS.NET 2003. After some reading, I discovered that I was supposed to create a ManualResetEvent, pass this to the working thread and wait for it using a WaitHandle.

Side battle field

One thing I tried during this was to use the WaitHandle.WaitAll method on an array of objects. Don’t do this, enabling this needs some tricks in a Windows Forms application (as it is STAThreaded but WaitAll depends on MTAThreaded code). I created an array of ManualResetEvents, passed one to each worker thread and called WaitAll - hoping this would work. It didn’t, for several reasons: First of all, it created around 800 threads, as every worker thread had it’s own local media player which was multithreaded on its own. This thread count (several thousand threads!) eventually crashed the application. Second, the individual threads did start and end at different times, and it was impossible to nail down when each thread was done - sometimes, they started working after the WaitAll call!.

Step IV - The end

My last approach was to create a special object that would have a ManualResetEvent embedded and which would only return when the event handler finished its work. This does indeed work, but, as usual, it’s not possible to use it in production code. As I started working more with this approach, I found out that the media player tries to open sometimes files that are not of type “video”. To address this issue, I added a special call inside the event handler:

if (media.getItemInfo ("MediaType") == "video")
this.valid = true;

Later, I wanted to query this bool to decide whether to trigger the OnValidMovie or the OnInvalidFile of my backend. The curious thing was the events were fired before the object finished creating, meaning that it was in an undefined state. Even when I tried to throw an exception inside the object the event handler was already called before the exception had a chance to be thrown, although the object would not return before its internal ManualResetEvent occured! Moving the reset event outside the object didn’t help, starting the object inside an own thread did also not help. The events would be triggered before the exception was thrown, no matter what I did. The code is:

System.Diagnostics.Trace.WriteLine ("openStateChangedHandler finished");
manualResetEvent.Set ();

Guess what, the output happens after the event was set! That’s it, I’ve got enough of this kind of stuff, it takes far too much time which I don’t want to spend on such a stupid problem.

Previous post
Next post

Recent posts

  • Data formats: Why CSV and JSON aren't the best
    Posted on 2024-12-29
  • Replacing cron with systemd-timers
    Posted on 2024-04-21
  • Open Source Maintenance
    Posted on 2024-04-02
  • Angular, Caddy, Gunicorn and Django
    Posted on 2023-10-21
  • Effective meetings
    Posted on 2022-09-12
  • Older posts

Find me on the web

  • GitHub
  • GPU database
  • Projects

Follow me

Anteru NIV_Anteru
Contents © 2005-2025
Anteru
Imprint/Impressum
Privacy policy/Datenschutz
Made with Liara
Last updated February 03, 2019