/** * This package provides classes to handle video in Processing. The API is compatible with the built-in video library of Processing. * GSVideo uses the multimedia toolkit GStreamer (http://www.gstreamer.net/) through the gstreamer-java bindings by Wayne Meissener: * http://code.google.com/p/gstreamer-java/ * @author Andres Colubri * @version 0.5.1 * * Copyright (c) 2008 Andres Colubri * * This source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This code is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * A copy of the GNU General Public License is available on the World * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also * obtain it by writing to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package codeanticode.gsvideo; import java.util.HashMap; import java.util.Map; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Platform; // Library loader class by Tal Shalif public class JnaLibLoaderChain { public interface DummyLibrary extends Library { } private static JnaLibLoaderChain instance; static final Object[][] WIN32_DEPENDENCIES = { { "SDL", new String[] { }, false }, { "glew32", new String[] { }, false }, { "iconv", new String[] { }, false }, { "liba52-0", new String[] { }, false }, { "libbz2", new String[] { }, false }, { "libcairo-2", new String[] { }, false }, { "libdca-0", new String[] { }, false }, { "libdl", new String[] { }, false }, { "libdvdcss-2", new String[] { }, false }, { "libdvdnav-4", new String[] { }, false }, { "libdvdnavmini-4", new String[] { }, false }, { "libdvdread-4", new String[] { }, false }, { "libfaac-0", new String[] { }, false }, { "libfaad-2", new String[] { }, false }, { "libfontconfig-1", new String[] { }, false }, { "libfreetype-6", new String[] { }, false }, { "libgcrypt-11", new String[] { }, false }, { "libgnutls-26", new String[] { }, false }, { "libgnutls-extra-26", new String[] { }, false }, { "libgnutls-openssl-26", new String[] { }, false }, { "libgnutlsxx-26", new String[] { }, false }, { "libgpg-error-0", new String[] { }, false }, { "libjpeg", new String[] { }, false }, { "libmms-0", new String[] { }, false }, { "libmp3lame-0", new String[] { }, false }, { "libmpeg2-0", new String[] { }, false }, { "libmpeg2convert-0", new String[] { }, false }, { "libneon-27", new String[] { }, false }, { "libnice", new String[] { }, false }, { "libogg-0", new String[] { }, false }, { "liboil-0.3-0", new String[] { }, false }, { "libopenjpeg-2", new String[] { }, false }, { "libpango-1.0-0", new String[] { }, false }, { "libpangocairo-1.0-0", new String[] { }, false }, { "libpangoft2-1.0-0", new String[] { }, false }, { "libpangowin32-1.0-0", new String[] { }, false }, { "libpixman-1-0", new String[] { }, true }, { "libpng12-0", new String[] { }, false }, { "libschroedinger-1.0-0", new String[] { }, false }, { "libsoup-2.4-1", new String[] { }, false }, { "libspeex-1", new String[] { }, false }, { "libspeexdsp-1", new String[] { }, false }, { "libtheora-0", new String[] { }, false }, { "libtheoradec-1", new String[] { }, false }, { "libtheoraenc-1", new String[] { }, false }, { "libvorbis-0", new String[] { }, false }, { "libvorbisenc-2", new String[] { }, false }, { "libvorbisfile-3", new String[] { }, false }, { "libwavpack-1", new String[] { }, false }, { "libx264-67", new String[] { }, false }, { "libxml2-2", new String[] { }, false }, { "pthreadGC2", new String[] { }, false }, { "xvidcore", new String[] { }, false }, { "zlib1", new String[] { }, false }, { "gio-2.0", new String[] { }, true }, { "glib-2.0", new String[] { }, true }, { "gmodule-2.0", new String[] { }, true }, { "gobject-2.0", new String[] { }, true }, { "gthread-2.0", new String[] { }, true }, { "gstapp-0.10", new String[] { }, true }, { "gstaudio-0.10", new String[] { }, true }, { "gstbase-0.10", new String[] { }, true }, { "gstcdda-0.10", new String[] { }, true }, { "gstcontroller-0.10", new String[] { }, true }, { "gstdataprotocol-0.10", new String[] { }, true }, { "gstdshow-0.10", new String[] { }, true }, { "gstfarsight-0.10", new String[] { }, true }, { "gstfft-0.10", new String[] { }, true }, { "gstgl-0.10", new String[] { }, true }, { "gstinterfaces-0.10", new String[] { }, true }, { "gstnet-0.10", new String[] { }, true }, { "gstnetbuffer-0.10", new String[] { }, true }, { "gstpbutils-0.10", new String[] { }, true }, { "gstphotography-0.10", new String[] { }, true }, { "gstreamer-0.10", new String[] { }, true }, { "gstriff-0.10", new String[] { }, true }, { "gstrtp-0.10", new String[] { }, true }, { "gstrtsp-0.10", new String[] { }, true }, { "gstsdp-0.10", new String[] { }, true }, { "gsttag-0.10", new String[] { }, true }, { "gstvideo-0.10", new String[] { }, true } }; static final Object[][] OSX_DEPENDENCIES = { { "gstreamer-0.10", new String[] { }, true }, { "gstbase-0.10", new String[] { "gstreamer-0.10" }, true }, { "gstinterfaces-0.10", new String[] { "gstreamer-0.10" }, true }, { "gstcontroller-0.10", new String[] { "gstreamer-0.10" }, true }, { "gstaudio-0.10", new String[] { "gstbase-0.10" }, true }, { "gstvideo-0.10", new String[] { "gstbase-0.10" }, true }, }; static final Object[][] DEFAULT_DEPENDENCIES = { { "gstreamer-0.10", new String[] { }, true }, { "gstbase-0.10", new String[] { "gstreamer-0.10" }, true }, { "gstinterfaces-0.10", new String[] { "gstreamer-0.10" }, true }, { "gstcontroller-0.10", new String[] { "gstreamer-0.10" }, true }, { "gstaudio-0.10", new String[] { "gstbase-0.10" }, true }, { "gstvideo-0.10", new String[] { "gstbase-0.10" }, true }, }; static final Object[][] dependencies = Platform.isWindows() ? WIN32_DEPENDENCIES : Platform.isMac() ? OSX_DEPENDENCIES : DEFAULT_DEPENDENCIES; private static final Map<String, Object> loadedMap = new HashMap<String, Object>(); private static final int RECURSIVE_LOAD_MAX_DEPTH = 5; private JnaLibLoaderChain() { } private void preLoadLibs() { for (Object[] a : dependencies) { load(a[0].toString(), DummyLibrary.class, true, 0, (Boolean)a[2]); } } private String[] findDeps(String name) { for (Object[] a : dependencies) { if (name.equals(a[0])) { return (String[]) a[1]; } } return new String[] {}; // library dependancy load chain unspecified - probably client call } public Object load(String name, Class<?> clazz, boolean reqLib) { return load(name, clazz, true, 0, reqLib); } private Object load(String name, Class<?> clazz, boolean forceReload, int depth, boolean reqLib) { assert depth < RECURSIVE_LOAD_MAX_DEPTH: String.format("recursive max load depth %s has been exceeded", depth); Object library = loadedMap.get(name); if (null == library || forceReload) { //Logger.getAnonymousLogger().info(String.format("%" + ((depth + 1) * 2) + "sloading %s", "->", name)); try { String[] deps = findDeps(name); for (String lib : deps) { load(lib, DummyLibrary.class, false, depth + 1, reqLib); } library = loadLibrary(name, clazz, reqLib); if (library != null) loadedMap.put(name, library); } catch (Exception e) { if (reqLib) throw new RuntimeException(String.format("can not load library %s", name, e)); else System.out.println(String.format("can not load library %s", name, e)); } } return library; } private static Object loadLibrary(String name, Class<?> clazz, boolean reqLib) { //Logger.getAnonymousLogger().info(String.format("loading %s", name)); String[] nameFormats; nameFormats = Platform.isWindows() ? new String[]{ "lib%s", "lib%s-0", "%s" } : new String[]{ "%s-0", "%s" }; UnsatisfiedLinkError linkError = null; for (String fmt : nameFormats) { try { String s = String.format(fmt, name); //System.out.println("Trying to load library file " + s); Object obj = Native.loadLibrary(s, clazz); //System.out.println("Loaded library " + s + " succesfully!"); return obj; } catch (UnsatisfiedLinkError ex) { linkError = ex; } } if (reqLib) throw new UnsatisfiedLinkError(String.format("can't load library %s (%1$s|lib%1$s|lib%1$s-0) with -Djna.library.path=%s. Last error:%s" , name, System.getProperty("jna.library.path"), linkError)); else { System.out.println(String.format("can't load library %s (%1$s|lib%1$s|lib%1$s-0) with -Djna.library.path=%s. Last error:%s" , name, System.getProperty("jna.library.path"), linkError)); return null; } } public static synchronized JnaLibLoaderChain getInstance() { if (null == instance) { instance = new JnaLibLoaderChain(); instance.preLoadLibs(); } return instance; } }