JNI and media playback frameworks

In the last 2 days I have assembled 3 more playback engines for Morrigan, bring the count to a total of 4.

– SPI (as released before)
– Java Media Framework (JMF)
– DirectShow (native Windows)
– GStreamer (native Linux)

The addition of the 2 native plugins really does make Morrigan much more versatile. As DirectShow and GStreamer are the dominant frameworks on their respective platforms, Morrigan can now essentially play almost everything. This is cool because it means that CPU usage should be comparable to using any other media player on that OS.

While the GStreamer implementation fairly clean and even uses video-overlay to take advantage of hardware acceleration where available, my DirectShow plugin has an ugly skeleton hiding under the desk. To access DirectShow from java, I am using the DirectShow Java wrapper from http://www.humatic.de/htools/dsj.htm. This very functional library is implemented using JNI to talk to a .dll that it expects to be present on the Java Library-path.

I don’t know much about JNI, so the only supported method I know for getting .ddl files on the library-path is to specify them when launching the JVM. But I am using RCP and while it probably possible to do that, its really not a great approach. So this leaves me with the need to pull in the .dll onto the library-path at runtime. Turns out this is somewhat nastier than using Class Loaders, so after some research I ended up with the following monstrosity.

try {
clazz = ClassLoader.class;
Field field = clazz.getDeclaredField("sys_paths");
boolean accessible = field.isAccessible();
if (!accessible) field.setAccessible(true);
field.set(clazz, null);
} catch (Exception e) {
System.setProperty("java.library.path", "D:\\haku\\development\\eclipseWorkspace-java\\dsjtest\\lib");

Hard-coded paths aside (this is easy to fix), this is really ugly. The use of reflection to modify the inner works of the ClassLoader is about as not supported as code gets. But at the moment I am out of other ideas…

So if you are reading this and understand this stuff, then please let me know the right way to do this! Thanks in advance.

Leave a Reply