From 9356ea224efb83b438dd57c2fbc4ae7a8db6de94 Mon Sep 17 00:00:00 2001
From: Boris Grozev <boris@jitsi.org>
Date: Fri, 28 Sep 2012 09:01:52 +0000
Subject: [PATCH] Refactors EncodingConfigurationImpl

---
 .../jitsi/impl/neomedia/MediaServiceImpl.java |   9 +-
 .../EncodingConfigurationConfigImpl.java      |  82 +++++
 .../codec/EncodingConfigurationImpl.java      | 325 +-----------------
 .../codec/FMJPlugInConfiguration.java         | 313 +++++++++++++++++
 .../neomedia/MediaConfigurationService.java   |  18 +-
 .../neomedia/codec/EncodingConfiguration.java |  42 +--
 6 files changed, 413 insertions(+), 376 deletions(-)
 create mode 100644 src/org/jitsi/impl/neomedia/codec/EncodingConfigurationConfigImpl.java
 create mode 100644 src/org/jitsi/impl/neomedia/codec/FMJPlugInConfiguration.java

diff --git a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
index f4ddc4c9..6d937ed1 100644
--- a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java
@@ -228,9 +228,9 @@ public MediaServiceImpl()
         deviceConfiguration.addPropertyChangeListener(
                 deviceConfigurationPropertyChangeListener);
 
-        currentEncodingConfiguration = new EncodingConfigurationImpl();
-        currentEncodingConfiguration.loadFormatPreferencesFromConfig(
-                ENCODING_CONFIG_PROP_PREFIX);
+        currentEncodingConfiguration
+             = new EncodingConfigurationConfigImpl(ENCODING_CONFIG_PROP_PREFIX);
+
 
         /*
          * Perform one-time initialization after initializing the first instance
@@ -1510,6 +1510,9 @@ private static void setupFMJ()
                 }
             }
         }
+
+        FMJPlugInConfiguration.registerCustomPackages();
+        FMJPlugInConfiguration.registerCustomCodecs();
     }
 
     /**
diff --git a/src/org/jitsi/impl/neomedia/codec/EncodingConfigurationConfigImpl.java b/src/org/jitsi/impl/neomedia/codec/EncodingConfigurationConfigImpl.java
new file mode 100644
index 00000000..881afbda
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/codec/EncodingConfigurationConfigImpl.java
@@ -0,0 +1,82 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.codec;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.libjitsi.*;
+import org.jitsi.service.neomedia.format.MediaFormat;
+
+import java.util.*;
+
+
+/**
+ * An EncodingConfiguration implementation that synchronizes it's preferences
+ * with a ConfigurationService.
+ *
+ * @author Boris Grozev
+ */
+public class EncodingConfigurationConfigImpl
+       extends EncodingConfigurationImpl
+{
+    /**
+     * Holds the prefix that will be used to store properties
+     */
+    private String propPrefix;
+
+    /**
+     * The <tt>ConfigurationService</tt> instance that will be used to
+     * store properties
+     */
+    private ConfigurationService configurationService
+            = LibJitsi.getConfigurationService();
+
+    /**
+     * Constructor. Loads the configuration from <tt>prefix</tt>
+     *
+     * @param prefix the prefix to use when loading and storing properties
+     */
+    public EncodingConfigurationConfigImpl(String prefix)
+    {
+        propPrefix = prefix;
+        loadConfig();
+    }
+
+    /**
+     * Loads the properties stored under <tt>this.propPrefix</tt>
+     */
+    private void loadConfig()
+    {
+        Map<String, String> properties = new HashMap<String, String>();
+
+        for (String pName :
+               configurationService.getPropertyNamesByPrefix(propPrefix, false))
+            properties.put(pName, configurationService.getString(pName));
+
+        loadProperties(properties);
+    }
+
+    /**
+     * Sets the preference associated with <tt>encoding</tt> to
+     * <tt>priority</tt>, and stores the appropriate property in the
+     * configuration service.
+     *
+     * @param encoding the <tt>MediaFormat</tt> specifying the encoding to set
+     * the priority of
+     * @param priority a positive <tt>int</tt> indicating the priority of
+     * <tt>encoding</tt> to set
+     *
+     * @see EncodingConfigurationImpl#setPriority(MediaFormat, int)
+     */
+    @Override
+    public void setPriority(MediaFormat encoding, int priority)
+    {
+        super.setPriority(encoding, priority);
+        configurationService.setProperty(
+                propPrefix+"."+getEncodingPreferenceKey(encoding),
+                priority);
+    }
+}
diff --git a/src/org/jitsi/impl/neomedia/codec/EncodingConfigurationImpl.java b/src/org/jitsi/impl/neomedia/codec/EncodingConfigurationImpl.java
index 3425acf8..f3f5ad7a 100644
--- a/src/org/jitsi/impl/neomedia/codec/EncodingConfigurationImpl.java
+++ b/src/org/jitsi/impl/neomedia/codec/EncodingConfigurationImpl.java
@@ -6,16 +6,8 @@
  */
 package org.jitsi.impl.neomedia.codec;
 
-import java.io.*;
-import java.util.*;
-
-import javax.media.*;
-
-import org.jitsi.impl.neomedia.*;
 import org.jitsi.impl.neomedia.format.*;
-import org.jitsi.service.libjitsi.*;
 import org.jitsi.service.neomedia.codec.*;
-import org.jitsi.service.neomedia.format.*;
 
 /**
  * Configuration of encoding priorities.
@@ -36,83 +28,11 @@ public class EncodingConfigurationImpl extends EncodingConfiguration
     public static final boolean G729 = false;
 
     /**
-     * The additional custom JMF codecs.
-     */
-    private static final String[] CUSTOM_CODECS =
-        {
-            "org.jitsi.impl.neomedia.codec.audio.alaw.DePacketizer",
-            "org.jitsi.impl.neomedia.codec.audio.alaw.JavaEncoder",
-            "org.jitsi.impl.neomedia.codec.audio.alaw.Packetizer",
-            "org.jitsi.impl.neomedia.codec.audio.ulaw.JavaDecoder",
-            "org.jitsi.impl.neomedia.codec.audio.ulaw.JavaEncoder",
-            "org.jitsi.impl.neomedia.codec.audio.ulaw.Packetizer",
-            "org.jitsi.impl.neomedia.codec.audio.opus.JNIDecoder",
-            "org.jitsi.impl.neomedia.codec.audio.opus.JNIEncoder",
-            "org.jitsi.impl.neomedia.codec.audio.speex.JNIDecoder",
-            "org.jitsi.impl.neomedia.codec.audio.speex.JNIEncoder",
-            "org.jitsi.impl.neomedia.codec.audio.speex.SpeexResampler",
-            "org.jitsi.impl.neomedia.codec.audio.speex.JavaDecoder",
-            "org.jitsi.impl.neomedia.codec.audio.speex.JavaEncoder",
-            "org.jitsi.impl.neomedia.codec.audio.mp3.JNIEncoder",
-            "org.jitsi.impl.neomedia.codec.audio.ilbc.JavaDecoder",
-            "org.jitsi.impl.neomedia.codec.audio.ilbc.JavaEncoder",
-            G729
-                ? "org.jitsi.impl.neomedia.codec.audio.g729.JavaDecoder"
-                : null,
-            G729
-                ? "org.jitsi.impl.neomedia.codec.audio.g729.JavaEncoder"
-                : null,
-            "net.java.sip.communicator.impl.neomedia.codec.audio.g722.JNIDecoder",
-            "net.java.sip.communicator.impl.neomedia.codec.audio.g722.JNIEncoder",
-            "org.jitsi.impl.neomedia.codec.audio.gsm.Decoder",
-            "org.jitsi.impl.neomedia.codec.audio.gsm.Encoder",
-            "org.jitsi.impl.neomedia.codec.audio.gsm.DePacketizer",
-            "org.jitsi.impl.neomedia.codec.audio.gsm.Packetizer",
-            "org.jitsi.impl.neomedia.codec.audio.silk.JavaDecoder",
-            "org.jitsi.impl.neomedia.codec.audio.silk.JavaEncoder",
-            "org.jitsi.impl.neomedia.codec.video.h263p.DePacketizer",
-            "org.jitsi.impl.neomedia.codec.video.h263p.JNIDecoder",
-            "org.jitsi.impl.neomedia.codec.video.h263p.JNIEncoder",
-            "org.jitsi.impl.neomedia.codec.video.h263p.Packetizer",
-            "org.jitsi.impl.neomedia.codec.video.h264.DePacketizer",
-            "org.jitsi.impl.neomedia.codec.video.h264.JNIDecoder",
-            "org.jitsi.impl.neomedia.codec.video.h264.JNIEncoder",
-            "org.jitsi.impl.neomedia.codec.video.h264.Packetizer",
-            "org.jitsi.impl.neomedia.codec.video.SwScaler"
-        };
-
-    /**
-     * Whether custom codecs have been registered with JFM
-     */
-    private static boolean codecsRegistered = false;
-
-    /**
-     * Whether custom packages have been registered with JFM
-     */
-    private static boolean packagesRegistered = false;
-
-    /**
-     * The package prefixes of the additional JMF <tt>DataSource</tt>s (e.g. low
-     * latency PortAudio and ALSA <tt>CaptureDevice</tt>s).
-     */
-    private static final String[] CUSTOM_PACKAGES
-        = new String[]
-                {
-                    "org.jitsi.impl.neomedia.jmfext",
-                    "net.java.sip.communicator.impl.neomedia.jmfext",
-                    "net.sf.fmj"
-                };
-
-    /**
-     * Constructor. Loads the hard-coded default preferences and registers
-     * packages and codecs with JMF.
+     * Constructor. Loads the default preferences.
      */
     public EncodingConfigurationImpl()
     {
         initializeFormatPreferences();
-
-        registerCustomPackages();
-        registerCustomCodecs();
     }
 
     /**
@@ -170,247 +90,4 @@ private void initializeFormatPreferences()
         // priority as it is not needed to order it with audio codecs
         setEncodingPreference(Constants.TELEPHONE_EVENT, 8000, 1);
     }
-
-    /**
-     * Sets the priority of the given encoding and updates the configuration
-     * via the configuration service.
-     *
-     * @param encoding the <tt>MediaFormat</tt> specifying the encoding to set
-     * the priority of
-     * @param priority a positive <tt>int</tt> indicating the priority of
-     * <tt>encoding</tt> to set
-     * @param updateConfig Whether configuration should be updated.
-     */
-    @Override
-    public void setPriority(MediaFormat encoding, int priority,
-        boolean updateConfig)
-    {
-        super.setPriority(encoding, priority);
-        
-        if(updateConfig)
-        {
-            // save the settings
-            //TODO: remove the whole method
-            LibJitsi.getConfigurationService().setProperty(
-                    "net.java.sip.communicator.impl.neomedia.codec.EncodingConfiguration"
-                        + "."
-                        + getEncodingPreferenceKey(encoding),
-                    priority);
-        }
-    }
-
-    /**
-     * Register in JMF the custom codecs we provide
-     */
-    private void registerCustomCodecs()
-    {
-        if(codecsRegistered)
-        {
-            return;
-        }
-        
-        // Register the custom codec which haven't already been registered.
-        @SuppressWarnings("unchecked")
-        Collection<String> registeredPlugins
-            = new HashSet<String>(
-                    PlugInManager.getPlugInList(
-                            null,
-                            null,
-                            PlugInManager.CODEC));
-        boolean commit = false;
-
-        // Remove JavaRGBToYUV.
-        PlugInManager.removePlugIn(
-                "com.sun.media.codec.video.colorspace.JavaRGBToYUV",
-                PlugInManager.CODEC);
-        PlugInManager.removePlugIn(
-                "com.sun.media.codec.video.colorspace.JavaRGBConverter",
-                PlugInManager.CODEC);
-        PlugInManager.removePlugIn(
-                "com.sun.media.codec.video.colorspace.RGBScaler",
-                PlugInManager.CODEC);
-
-        // Remove JMF's H263 codec.
-        PlugInManager.removePlugIn(
-                "com.sun.media.codec.video.vh263.NativeDecoder",
-                PlugInManager.CODEC);
-        PlugInManager.removePlugIn(
-                "com.ibm.media.codec.video.h263.NativeEncoder",
-                PlugInManager.CODEC);
-
-        // Remove JMF's GSM codec. As working only on some OS.
-        String gsmCodecPackage = "com.ibm.media.codec.audio.gsm.";
-        String[] gsmCodecClasses
-            = new String[]
-                    {
-                        "JavaDecoder",
-                        "JavaDecoder_ms",
-                        "JavaEncoder",
-                        "JavaEncoder_ms",
-                        "NativeDecoder",
-                        "NativeDecoder_ms",
-                        "NativeEncoder",
-                        "NativeEncoder_ms",
-                        "Packetizer"
-                    };
-        for(String gsmCodecClass : gsmCodecClasses)
-        {
-            PlugInManager.removePlugIn(
-                gsmCodecPackage + gsmCodecClass,
-                PlugInManager.CODEC);
-        }
-
-        /*
-         * Remove FMJ's JavaSoundCodec because it seems to slow down the
-         * building of the filter graph and we do not currently seem to need it.
-         */
-        PlugInManager.removePlugIn(
-                "net.sf.fmj.media.codec.JavaSoundCodec",
-                PlugInManager.CODEC);
-
-        for (String className : CUSTOM_CODECS)
-        {
-
-            /*
-             * A codec with a className of null is configured at compile time to
-             * not be registered.
-             */
-            if (className == null)
-                continue;
-
-            if (registeredPlugins.contains(className))
-            {
-                if (logger.isDebugEnabled())
-                    logger.debug(
-                        "Codec " + className + " is already registered");
-            }
-            else
-            {
-                commit = true;
-
-                boolean registered;
-                Throwable exception = null;
-
-                try
-                {
-                    Codec codec = (Codec)
-                        Class.forName(className).newInstance();
-
-                    registered =
-                        PlugInManager.addPlugIn(
-                            className,
-                            codec.getSupportedInputFormats(),
-                            codec.getSupportedOutputFormats(null),
-                            PlugInManager.CODEC);
-                }
-                catch (Throwable ex)
-                {
-                    registered = false;
-                    exception = ex;
-                }
-                if (registered)
-                {
-                    if (logger.isDebugEnabled())
-                        logger.debug(
-                            "Codec "
-                                + className
-                                + " is successfully registered");
-                }
-                else
-                {
-                    if (logger.isDebugEnabled())
-                        logger.debug(
-                            "Codec "
-                                + className
-                                + " is NOT succsefully registered", exception);
-                }
-            }
-        }
-
-        /*
-         * If Jitsi provides a codec which is also provided by FMJ and/or JMF,
-         * use Jitsi's version.
-         */
-        @SuppressWarnings("unchecked")
-        Vector<String> codecs
-            = PlugInManager.getPlugInList(null, null, PlugInManager.CODEC);
-
-        if (codecs != null)
-        {
-            boolean setPlugInList = false;
-
-            for (int i = CUSTOM_CODECS.length - 1; i >= 0; i--)
-            {
-                String className = CUSTOM_CODECS[i];
-
-                if (className != null)
-                {
-                    int classNameIndex = codecs.indexOf(className);
-
-                    if (classNameIndex != -1)
-                    {
-                        codecs.remove(classNameIndex);
-                        codecs.add(0, className);
-                        setPlugInList = true;
-                    }
-                }
-            }
-
-            if (setPlugInList)
-                PlugInManager.setPlugInList(codecs, PlugInManager.CODEC);
-        }
-
-        if (commit && !MediaServiceImpl.isJmfRegistryDisableLoad())
-        {
-            try
-            {
-                PlugInManager.commit();
-            }
-            catch (IOException ex)
-            {
-                logger.error("Cannot commit to PlugInManager", ex);
-            }
-        }
-        
-        codecsRegistered = true;
-    }
-
-    /**
-     * Register in JMF the custom packages we provide
-     */
-    private void registerCustomPackages()
-    {
-        if(packagesRegistered)
-            return;
-        
-        @SuppressWarnings("unchecked")
-        Vector<String> packages = PackageManager.getProtocolPrefixList();
-        boolean loggerIsDebugEnabled = logger.isDebugEnabled();
-
-        for (String customPackage : CUSTOM_PACKAGES)
-        {
-            /*
-             * Linear search in a loop but it doesn't have to scale since the
-             * list is always short.
-             */
-            if (!packages.contains(customPackage))
-            {
-                packages.add(customPackage);
-                if (loggerIsDebugEnabled)
-                    if (logger.isDebugEnabled())
-                        logger.debug("Adding package  : " + customPackage);
-            }
-        }
-
-        PackageManager.setProtocolPrefixList(packages);
-        PackageManager.commitProtocolPrefixList();
-        if (loggerIsDebugEnabled)
-        {
-            if (logger.isDebugEnabled())
-                logger.debug(
-                    "Registering new protocol prefix list: " + packages);
-        }
-        
-        packagesRegistered = true;
-    }
 }
diff --git a/src/org/jitsi/impl/neomedia/codec/FMJPlugInConfiguration.java b/src/org/jitsi/impl/neomedia/codec/FMJPlugInConfiguration.java
new file mode 100644
index 00000000..1e3b60c1
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/codec/FMJPlugInConfiguration.java
@@ -0,0 +1,313 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.codec;
+
+import java.io.*;
+import java.util.*;
+
+import javax.media.*;
+
+import org.jitsi.impl.neomedia.*;
+import org.jitsi.util.*;
+
+/**
+ * Utility class that handles registration of JFM packages and plugins
+ *
+ * @author Damian Minkov
+ * @author Lyubomir Marinov
+ * @author Boris Grozev
+ */
+public class FMJPlugInConfiguration
+{
+    /**
+     * The <tt>Logger</tt> used by the <tt>FMJPlugInConfiguration</tt> class
+     * for logging output.
+     */
+    private static final Logger logger
+            = Logger.getLogger(FMJPlugInConfiguration.class);
+
+    /**
+     * The additional custom JMF codecs.
+     */
+    private static final String[] CUSTOM_CODECS =
+            {
+                    "org.jitsi.impl.neomedia.codec.audio.alaw.DePacketizer",
+                    "org.jitsi.impl.neomedia.codec.audio.alaw.JavaEncoder",
+                    "org.jitsi.impl.neomedia.codec.audio.alaw.Packetizer",
+                    "org.jitsi.impl.neomedia.codec.audio.ulaw.JavaDecoder",
+                    "org.jitsi.impl.neomedia.codec.audio.ulaw.JavaEncoder",
+                    "org.jitsi.impl.neomedia.codec.audio.ulaw.Packetizer",
+                    "org.jitsi.impl.neomedia.codec.audio.opus.JNIDecoder",
+                    "org.jitsi.impl.neomedia.codec.audio.opus.JNIEncoder",
+                    "org.jitsi.impl.neomedia.codec.audio.speex.JNIDecoder",
+                    "org.jitsi.impl.neomedia.codec.audio.speex.JNIEncoder",
+                    "org.jitsi.impl.neomedia.codec.audio.speex.SpeexResampler",
+                    "org.jitsi.impl.neomedia.codec.audio.speex.JavaDecoder",
+                    "org.jitsi.impl.neomedia.codec.audio.speex.JavaEncoder",
+                    "org.jitsi.impl.neomedia.codec.audio.mp3.JNIEncoder",
+                    "org.jitsi.impl.neomedia.codec.audio.ilbc.JavaDecoder",
+                    "org.jitsi.impl.neomedia.codec.audio.ilbc.JavaEncoder",
+                    EncodingConfigurationImpl.G729
+                            ? "org.jitsi.impl.neomedia.codec.audio.g729.JavaDecoder"
+                            : null,
+                    EncodingConfigurationImpl.G729
+                            ? "org.jitsi.impl.neomedia.codec.audio.g729.JavaEncoder"
+                            : null,
+                    "net.java.sip.communicator.impl.neomedia.codec.audio.g722.JNIDecoder",
+                    "net.java.sip.communicator.impl.neomedia.codec.audio.g722.JNIEncoder",
+                    "org.jitsi.impl.neomedia.codec.audio.gsm.Decoder",
+                    "org.jitsi.impl.neomedia.codec.audio.gsm.Encoder",
+                    "org.jitsi.impl.neomedia.codec.audio.gsm.DePacketizer",
+                    "org.jitsi.impl.neomedia.codec.audio.gsm.Packetizer",
+                    "org.jitsi.impl.neomedia.codec.audio.silk.JavaDecoder",
+                    "org.jitsi.impl.neomedia.codec.audio.silk.JavaEncoder",
+                    "org.jitsi.impl.neomedia.codec.video.h263p.DePacketizer",
+                    "org.jitsi.impl.neomedia.codec.video.h263p.JNIDecoder",
+                    "org.jitsi.impl.neomedia.codec.video.h263p.JNIEncoder",
+                    "org.jitsi.impl.neomedia.codec.video.h263p.Packetizer",
+                    "org.jitsi.impl.neomedia.codec.video.h264.DePacketizer",
+                    "org.jitsi.impl.neomedia.codec.video.h264.JNIDecoder",
+                    "org.jitsi.impl.neomedia.codec.video.h264.JNIEncoder",
+                    "org.jitsi.impl.neomedia.codec.video.h264.Packetizer",
+                    "org.jitsi.impl.neomedia.codec.video.SwScaler"
+            };
+
+    /**
+     * The package prefixes of the additional JMF <tt>DataSource</tt>s (e.g. low
+     * latency PortAudio and ALSA <tt>CaptureDevice</tt>s).
+     */
+    private static final String[] CUSTOM_PACKAGES
+            = new String[]
+            {
+                    "org.jitsi.impl.neomedia.jmfext",
+                    "net.java.sip.communicator.impl.neomedia.jmfext",
+                    "net.sf.fmj"
+            };
+
+    /**
+     * Whether custom codecs have been registered with JFM
+     */
+    private static boolean codecsRegistered = false;
+
+    /**
+     * Whether custom packages have been registered with JFM
+     */
+    private static boolean packagesRegistered = false;
+
+    /**
+     * Register in JMF the custom codecs we provide
+     */
+    public static void registerCustomCodecs()
+    {
+        if(codecsRegistered)
+            return;
+
+        // Register the custom codecs which haven't already been registered.
+        @SuppressWarnings("unchecked")
+        Collection<String> registeredPlugins
+                = new HashSet<String>(
+                PlugInManager.getPlugInList(
+                        null,
+                        null,
+                        PlugInManager.CODEC));
+        boolean commit = false;
+
+        // Remove JavaRGBToYUV.
+        PlugInManager.removePlugIn(
+                "com.sun.media.codec.video.colorspace.JavaRGBToYUV",
+                PlugInManager.CODEC);
+        PlugInManager.removePlugIn(
+                "com.sun.media.codec.video.colorspace.JavaRGBConverter",
+                PlugInManager.CODEC);
+        PlugInManager.removePlugIn(
+                "com.sun.media.codec.video.colorspace.RGBScaler",
+                PlugInManager.CODEC);
+
+        // Remove JMF's H263 codec.
+        PlugInManager.removePlugIn(
+                "com.sun.media.codec.video.vh263.NativeDecoder",
+                PlugInManager.CODEC);
+        PlugInManager.removePlugIn(
+                "com.ibm.media.codec.video.h263.NativeEncoder",
+                PlugInManager.CODEC);
+
+        // Remove JMF's GSM codec. As working only on some OS.
+        String gsmCodecPackage = "com.ibm.media.codec.audio.gsm.";
+        String[] gsmCodecClasses
+                = new String[]
+                {
+                        "JavaDecoder",
+                        "JavaDecoder_ms",
+                        "JavaEncoder",
+                        "JavaEncoder_ms",
+                        "NativeDecoder",
+                        "NativeDecoder_ms",
+                        "NativeEncoder",
+                        "NativeEncoder_ms",
+                        "Packetizer"
+                };
+        for(String gsmCodecClass : gsmCodecClasses)
+        {
+            PlugInManager.removePlugIn(
+                    gsmCodecPackage + gsmCodecClass,
+                    PlugInManager.CODEC);
+        }
+
+        /*
+         * Remove FMJ's JavaSoundCodec because it seems to slow down the
+         * building of the filter graph and we do not currently seem to need it.
+         */
+        PlugInManager.removePlugIn(
+                "net.sf.fmj.media.codec.JavaSoundCodec",
+                PlugInManager.CODEC);
+
+        for (String className : CUSTOM_CODECS)
+        {
+
+            /*
+             * A codec with a className of null is configured at compile time to
+             * not be registered.
+             */
+            if (className == null)
+                continue;
+
+            if (registeredPlugins.contains(className))
+            {
+                if (logger.isDebugEnabled())
+                    logger.debug(
+                            "Codec " + className + " is already registered");
+            }
+            else
+            {
+                commit = true;
+
+                boolean registered;
+                Throwable exception = null;
+
+                try
+                {
+                    Codec codec = (Codec)
+                            Class.forName(className).newInstance();
+
+                    registered =
+                            PlugInManager.addPlugIn(
+                                    className,
+                                    codec.getSupportedInputFormats(),
+                                    codec.getSupportedOutputFormats(null),
+                                    PlugInManager.CODEC);
+                }
+                catch (Throwable ex)
+                {
+                    registered = false;
+                    exception = ex;
+                }
+                if (registered)
+                {
+                    if (logger.isDebugEnabled())
+                        logger.debug(
+                                "Codec "
+                                        + className
+                                        + " is successfully registered");
+                }
+                else
+                {
+                    if (logger.isDebugEnabled())
+                        logger.debug(
+                                "Codec "
+                                        + className
+                                        + " is NOT succsefully registered", exception);
+                }
+            }
+        }
+
+        /*
+         * If Jitsi provides a codec which is also provided by FMJ and/or JMF,
+         * use Jitsi's version.
+         */
+        @SuppressWarnings("unchecked")
+        Vector<String> codecs
+                = PlugInManager.getPlugInList(null, null, PlugInManager.CODEC);
+
+        if (codecs != null)
+        {
+            boolean setPlugInList = false;
+
+            for (int i = CUSTOM_CODECS.length - 1; i >= 0; i--)
+            {
+                String className = CUSTOM_CODECS[i];
+
+                if (className != null)
+                {
+                    int classNameIndex = codecs.indexOf(className);
+
+                    if (classNameIndex != -1)
+                    {
+                        codecs.remove(classNameIndex);
+                        codecs.add(0, className);
+                        setPlugInList = true;
+                    }
+                }
+            }
+
+            if (setPlugInList)
+                PlugInManager.setPlugInList(codecs, PlugInManager.CODEC);
+        }
+
+        if (commit && !MediaServiceImpl.isJmfRegistryDisableLoad())
+        {
+            try
+            {
+                PlugInManager.commit();
+            }
+            catch (IOException ex)
+            {
+                logger.error("Cannot commit to PlugInManager", ex);
+            }
+        }
+
+        codecsRegistered = true;
+    }
+
+    /**
+     * Register in JMF the custom packages we provide
+     */
+    public static void registerCustomPackages()
+    {
+        if(packagesRegistered)
+            return;
+
+        @SuppressWarnings("unchecked")
+        Vector<String> packages = PackageManager.getProtocolPrefixList();
+        boolean loggerIsDebugEnabled = logger.isDebugEnabled();
+
+        for (String customPackage : CUSTOM_PACKAGES)
+        {
+            /*
+             * Linear search in a loop but it doesn't have to scale since the
+             * list is always short.
+             */
+            if (!packages.contains(customPackage))
+            {
+                packages.add(customPackage);
+                if (loggerIsDebugEnabled)
+                    if (logger.isDebugEnabled())
+                        logger.debug("Adding package  : " + customPackage);
+            }
+        }
+
+        PackageManager.setProtocolPrefixList(packages);
+        PackageManager.commitProtocolPrefixList();
+        if (loggerIsDebugEnabled)
+        {
+            if (logger.isDebugEnabled())
+                logger.debug(
+                        "Registering new protocol prefix list: " + packages);
+        }
+
+        packagesRegistered = true;
+    }
+}
diff --git a/src/org/jitsi/service/neomedia/MediaConfigurationService.java b/src/org/jitsi/service/neomedia/MediaConfigurationService.java
index 112964f5..f0a0aee5 100644
--- a/src/org/jitsi/service/neomedia/MediaConfigurationService.java
+++ b/src/org/jitsi/service/neomedia/MediaConfigurationService.java
@@ -22,30 +22,26 @@ public interface MediaConfigurationService
      * @return A <tt>Component</tt> for audio configuration
      */
     public Component createAudioConfigPanel();
-    
+
     /**
      * Returns a <tt>Component</tt> for video configuration
      * 
      * @return A <tt>Component</tt> for video configuration
      */
     public Component createVideoConfigPanel();
-    
+
     /**
-     * Returns a <tt>Component</tt> for encodings configuration (either audio or video)
+     * Returns a <tt>Component</tt> for encodings configuration (either audio
+     * or video)
+     *
      * @param mediaType The type of media -- either MediaType.AUDIO or
      * MediaType.VIDEO
      * @param encodingConfiguration The <tt>EncodingConfiguration</tt> instance
-     * to use. If null, creates one on it's own.
-     * @param autoUpdateConfig Whether we should update the configuration after
-     * every change. Useful, because in the main audio/video encoding 
-     * configuration we want the changes to apply instantaneously, while in the
-     * account creation wizards we want to delay the update until the form is
-     * committed.
+     * to use.
      * @return The <tt>Component</tt> for encodings configuration
      */
     public Component createEncodingControls(MediaType mediaType,
-            EncodingConfiguration encodingConfiguration,
-            boolean autoUpdateConfig);
+            EncodingConfiguration encodingConfiguration);
 
     /**
      * Returns the <tt>MediaService</tt> instance
diff --git a/src/org/jitsi/service/neomedia/codec/EncodingConfiguration.java b/src/org/jitsi/service/neomedia/codec/EncodingConfiguration.java
index 0948b01c..936e9a63 100644
--- a/src/org/jitsi/service/neomedia/codec/EncodingConfiguration.java
+++ b/src/org/jitsi/service/neomedia/codec/EncodingConfiguration.java
@@ -9,21 +9,19 @@
 import java.util.*;
 
 import org.jitsi.impl.neomedia.*;
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.libjitsi.*;
 import org.jitsi.service.neomedia.*;
 import org.jitsi.service.neomedia.format.*;
 import org.jitsi.util.*;
 
 /**
- * Abstract class that manages encoding configurations. It holds information
+ * A base class that manages encoding configurations. It holds information
  * about supported formats.
  * 
  * @author Damian Minkov
  * @author Lyubomir Marinov
  * @author Boris Grozev
  */
-public abstract class EncodingConfiguration
+public class EncodingConfiguration
 {
     /**
      * The <tt>Logger</tt> used by this <tt>EncodingConfiguration</tt> instance
@@ -169,23 +167,9 @@ public void setPriority(MediaFormat encoding, int priority)
         updateSupportedEncodings();
     }
 
-    //TODO: remove
-    /**
-     * Sets <tt>priority</tt> as the preference associated with
-     * <tt>encoding</tt> (with a call to <tt>setPriority(MediaFormat, int)</tt>
-     * for example), and also, if <tt>updateConfig</tt> is <tt>true</tt>,
-     * updates configuration. 
-     * @param encoding the <tt>MediaFormat</tt> specifying the encoding to set
-     * the priority of
-     * @param priority a positive <tt>int</tt> indicating the priority of
-     * <tt>encoding</tt> to set
-     * @param updateConfig Whether to update configuration or not.
-     */
-    public abstract void setPriority(MediaFormat encoding, int priority,
-            boolean updateConfig);
-
     /**
      * Get the priority for a <tt>MediaFormat</tt>.
+     *
      * @param encoding the <tt>MediaFormat</tt>
      * @return the priority
      */
@@ -338,24 +322,6 @@ protected String getEncodingPreferenceKey(MediaFormat encoding)
         return encoding.getEncoding() + "/" + encoding.getClockRateString();
     }
 
-    /**
-     * Parses the properties under <tt>prefix</tt> and loads them.
-     * 
-     * @param prefix The prefix to search the configuration under
-     */
-    public void loadFormatPreferencesFromConfig(String prefix)
-    {
-        ConfigurationService cfg = LibJitsi.getConfigurationService();
-        Map<String, String> properties = new HashMap<String, String>();
-
-        if (cfg != null)
-        {
-            for (String pName : cfg.getPropertyNamesByPrefix(prefix, false))
-                properties.put(pName, cfg.getString(pName));
-            loadProperties(properties);
-        }
-    }
-
     /**
      * Stores the format preferences in this instance in the given <tt>Map</tt>,
      * using <tt>prefix</tt> as a prefix to the key.
@@ -403,7 +369,7 @@ public void loadProperties(Map<String, String> properties)
     {
         loadProperties(properties, "");
     }
-    
+
     /**
      * Parses a <tt>Map<String, String></tt> and updates the format preferences
      * according to it. For each entry, if it's key does not begin with
-- 
GitLab