]> git.sesse.net Git - vlc/blobdiff - projects/mozilla/control/npolibvlc.cpp
The plugin now works with firefox 3.6 and 3.5.3
[vlc] / projects / mozilla / control / npolibvlc.cpp
index d5b1e9d3224be0d7a472a2a11133251f538be2bb..2e6440ec06840e8bbf39432e3d664f6db4a40382 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 
-/* Mozilla stuff */
-#ifdef HAVE_MOZILLA_CONFIG_H
-#   include <mozilla-config.h>
-#endif
-
 #include "vlcplugin.h"
 #include "npolibvlc.h"
 
 ** Local helper macros and function
 */
 #define COUNTNAMES(a,b,c) const int a::b = sizeof(a::c)/sizeof(NPUTF8 *)
-#define RETURN_ON_EXCEPTION(this,ex) \
-    do { if( libvlc_exception_raised(&ex) ) \
-    { \
-        NPN_SetException(this, libvlc_errmsg()); \
-        libvlc_exception_clear(&ex); \
-        return INVOKERESULT_GENERIC_ERROR; \
-    } } while(false)
+#define RETURN_ON_ERROR                             \
+    do {                                            \
+        NPN_SetException(this, libvlc_errmsg());    \
+        return INVOKERESULT_GENERIC_ERROR;          \
+    }while(0)
+
+#define ERROR_EVENT_NOT_FOUND "ERROR: One or more events could not be found."
+#define ERROR_API_VERSION "ERROR: NPAPI version not high enough. (Gecko >= 1.9 needed)"
+
+// Make a copy of an NPVariant.
+NPVariant copyNPVariant(const NPVariant& original)
+{
+    NPVariant res;
+
+    if (NPVARIANT_IS_STRING(original))
+        STRINGZ_TO_NPVARIANT(strdup(NPVARIANT_TO_STRING(original).UTF8Characters), res);
+    else if (NPVARIANT_IS_INT32(original))
+        INT32_TO_NPVARIANT(NPVARIANT_TO_INT32(original), res);
+    else if (NPVARIANT_IS_DOUBLE(original))
+        DOUBLE_TO_NPVARIANT(NPVARIANT_TO_DOUBLE(original), res);
+    else if (NPVARIANT_IS_OBJECT(original))
+    {
+        NPObject *obj = NPVARIANT_TO_OBJECT(original);
+        NPN_RetainObject(obj);
+        OBJECT_TO_NPVARIANT(obj, res);
+    }
+    else if (NPVARIANT_IS_BOOLEAN(original))
+        BOOLEAN_TO_NPVARIANT(NPVARIANT_TO_BOOLEAN(original), res);
+
+    return res;
+}
 
 /*
 ** implementation of libvlc root object
@@ -69,6 +88,7 @@ LibvlcRootNPObject::~LibvlcRootNPObject()
         if( audioObj    ) NPN_ReleaseObject(audioObj);
         if( inputObj    ) NPN_ReleaseObject(inputObj);
         if( playlistObj ) NPN_ReleaseObject(playlistObj);
+        if( subtitleObj ) NPN_ReleaseObject(subtitleObj);
         if( videoObj    ) NPN_ReleaseObject(videoObj);
     }
 }
@@ -134,34 +154,62 @@ LibvlcRootNPObject::getProperty(int index, NPVariant &result)
 const NPUTF8 * const LibvlcRootNPObject::methodNames[] =
 {
     "versionInfo",
+    "addEventListener",
+    "removeEventListener",
 };
 COUNTNAMES(LibvlcRootNPObject,methodCount,methodNames);
 
 enum LibvlcRootNPObjectMethodIds
 {
     ID_root_versionInfo,
+    ID_root_addeventlistener,
+    ID_root_removeeventlistener,
 };
 
 RuntimeNPObject::InvokeResult LibvlcRootNPObject::invoke(int index,
                   const NPVariant *args, uint32_t argCount, NPVariant &result)
 {
     /* is plugin still running */
-    if( isPluginRunning() )
-    {
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
+    if( !isPluginRunning() )
+        return INVOKERESULT_GENERIC_ERROR;
 
-        switch( index )
+    switch( index )
+    {
+    case ID_root_versionInfo:
+        if( 0 != argCount )
+            return INVOKERESULT_NO_SUCH_METHOD;
+        return invokeResultString(libvlc_get_version(),result);
+
+    case ID_root_addeventlistener:
+    case ID_root_removeeventlistener:
+        if( (3 != argCount) ||
+            !NPVARIANT_IS_STRING(args[0]) ||
+            !NPVARIANT_IS_OBJECT(args[1]) ||
+            !NPVARIANT_IS_BOOLEAN(args[2]) )
+            break;
+
+        if( !VlcPlugin::canUseEventListener() )
         {
-            case ID_root_versionInfo:
-                if( 0 != argCount )
-                    return INVOKERESULT_NO_SUCH_METHOD;
-                return invokeResultString(libvlc_get_version(),result);
-            default:
-                ;
+            NPN_SetException(this, ERROR_API_VERSION);
+            return INVOKERESULT_GENERIC_ERROR;
         }
+
+        NPObject *listener = NPVARIANT_TO_OBJECT(args[1]);
+        VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
+
+        bool b;
+        if(ID_root_removeeventlistener!=index)
+            b = p_plugin->events.insert(NPVARIANT_TO_STRING(args[0]),
+                                     listener, NPVARIANT_TO_BOOLEAN(args[2]));
+        else
+            b = p_plugin->events.remove(NPVARIANT_TO_STRING(args[0]),
+                                     listener, NPVARIANT_TO_BOOLEAN(args[2]));
+
+        VOID_TO_NPVARIANT(result);
+
+        return b ? INVOKERESULT_NO_ERROR : INVOKERESULT_GENERIC_ERROR;
     }
-    return INVOKERESULT_GENERIC_ERROR;
+    return INVOKERESULT_NO_SUCH_METHOD;
 }
 
 /*
@@ -194,47 +242,42 @@ LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
+
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
             case ID_audio_mute:
             {
-                bool muted = libvlc_audio_get_mute(p_plugin->getVLC());
+                bool muted = libvlc_audio_get_mute(p_md);
                 BOOLEAN_TO_NPVARIANT(muted, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_audio_volume:
             {
-                int volume = libvlc_audio_get_volume(p_plugin->getVLC());
+                int volume = libvlc_audio_get_volume(p_md);
                 INT32_TO_NPVARIANT(volume, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_audio_track:
             {
-                libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-                RETURN_ON_EXCEPTION(this,ex);
-                int track = libvlc_audio_get_track(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int track = libvlc_audio_get_track(p_md);
                 INT32_TO_NPVARIANT(track, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_audio_count:
             {
-                libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-                RETURN_ON_EXCEPTION(this,ex);
                 // get the number of audio track available
-                int i_track = libvlc_audio_get_track_count(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int i_track = libvlc_audio_get_track_count(p_md);
                 // return it
                 INT32_TO_NPVARIANT(i_track, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_audio_channel:
             {
-                int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int channel = libvlc_audio_get_channel(p_md);
                 INT32_TO_NPVARIANT(channel, result);
                 return INVOKERESULT_NO_ERROR;
             }
@@ -252,15 +295,17 @@ LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
+
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
             case ID_audio_mute:
                 if( NPVARIANT_IS_BOOLEAN(value) )
                 {
-                    libvlc_audio_set_mute(p_plugin->getVLC(),
+                    libvlc_audio_set_mute(p_md,
                                           NPVARIANT_TO_BOOLEAN(value));
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -268,28 +313,21 @@ LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
             case ID_audio_volume:
                 if( isNumberValue(value) )
                 {
-                    libvlc_audio_set_volume(p_plugin->getVLC(),
-                                            numberValue(value), &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    libvlc_audio_set_volume(p_md, numberValue(value));
                     return INVOKERESULT_NO_ERROR;
                 }
                 return INVOKERESULT_INVALID_VALUE;
             case ID_audio_track:
                 if( isNumberValue(value) )
                 {
-                    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
-                    libvlc_audio_set_track(p_md, numberValue(value), &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    libvlc_audio_set_track(p_md, numberValue(value));
                     return INVOKERESULT_NO_ERROR;
                 }
                 return INVOKERESULT_INVALID_VALUE;
             case ID_audio_channel:
                 if( isNumberValue(value) )
                 {
-                    libvlc_audio_set_channel(p_plugin->getVLC(),
-                                             numberValue(value), &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    libvlc_audio_set_channel(p_md, numberValue(value));
                     return INVOKERESULT_NO_ERROR;
                 }
                 return INVOKERESULT_INVALID_VALUE;
@@ -321,15 +359,16 @@ LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
             case ID_audio_togglemute:
                 if( argCount == 0 )
                 {
-                    libvlc_audio_toggle_mute(p_plugin->getVLC());
+                    libvlc_audio_toggle_mute(p_md);
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -342,18 +381,13 @@ LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
                     int i_trackID, i_limit, i;
                     libvlc_track_description_t *p_trackDesc;
 
-                    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
-
                     /* get tracks description */
-                    p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_trackDesc = libvlc_audio_get_track_description(p_md);
                     if( !p_trackDesc )
                         return INVOKERESULT_GENERIC_ERROR;
 
                     /* get the number of track available */
-                    i_limit = libvlc_audio_get_track_count(p_md, &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    i_limit = libvlc_audio_get_track_count(p_md);
 
                     /* check if a number is given by the user
                      * and get the track number */
@@ -419,23 +453,15 @@ LibvlcInputNPObject::getProperty(int index, NPVariant &result)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        if( libvlc_exception_raised(&ex) )
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
         {
             if( index != ID_input_state )
-            {
-                NPN_SetException(this, libvlc_errmsg());
-                libvlc_exception_clear(&ex);
-                return INVOKERESULT_GENERIC_ERROR;
-            }
+                RETURN_ON_ERROR;
             else
             {
                 /* for input state, return CLOSED rather than an exception */
                 INT32_TO_NPVARIANT(0, result);
-                libvlc_exception_clear(&ex);
                 return INVOKERESULT_NO_ERROR;
             }
         }
@@ -444,50 +470,43 @@ LibvlcInputNPObject::getProperty(int index, NPVariant &result)
         {
             case ID_input_length:
             {
-                double val = (double)libvlc_media_player_get_length(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                double val = (double)libvlc_media_player_get_length(p_md);
                 DOUBLE_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_position:
             {
-                double val = libvlc_media_player_get_position(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                double val = libvlc_media_player_get_position(p_md);
                 DOUBLE_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_time:
             {
-                double val = (double)libvlc_media_player_get_time(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                double val = (double)libvlc_media_player_get_time(p_md);
                 DOUBLE_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_state:
             {
                 int val = libvlc_media_player_get_state(p_md);
-                RETURN_ON_EXCEPTION(this,ex);
                 INT32_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_rate:
             {
-                float val = libvlc_media_player_get_rate(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                float val = libvlc_media_player_get_rate(p_md);
                 DOUBLE_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_fps:
             {
-                double val = libvlc_media_player_get_fps(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                double val = libvlc_media_player_get_fps(p_md);
                 DOUBLE_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_hasvout:
             {
-                bool val = p_plugin->player_has_vout(&ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                bool val = p_plugin->player_has_vout();
                 BOOLEAN_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
@@ -505,11 +524,9 @@ LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
@@ -521,8 +538,7 @@ LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
                 }
 
                 float val = (float)NPVARIANT_TO_DOUBLE(value);
-                libvlc_media_player_set_position(p_md, val, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                libvlc_media_player_set_position(p_md, val);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_time:
@@ -537,8 +553,7 @@ LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
                     return INVOKERESULT_INVALID_VALUE;
                 }
 
-                libvlc_media_player_set_time(p_md, val, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                libvlc_media_player_set_time(p_md, val);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_input_rate:
@@ -553,8 +568,7 @@ LibvlcInputNPObject::setProperty(int index, const NPVariant &value)
                     return INVOKERESULT_INVALID_VALUE;
                 }
 
-                libvlc_media_player_set_rate(p_md, val, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                libvlc_media_player_set_rate(p_md, val);
                 return INVOKERESULT_NO_ERROR;
             }
             default:
@@ -653,16 +667,13 @@ LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
 
         switch( index )
         {
             case ID_playlistitems_clear:
                 if( argCount == 0 )
                 {
-                    p_plugin->playlist_clear(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->playlist_clear();
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -670,8 +681,8 @@ LibvlcPlaylistItemsNPObject::invoke(int index, const NPVariant *args,
             case ID_playlistitems_remove:
                 if( (argCount == 1) && isNumberValue(args[0]) )
                 {
-                    p_plugin->playlist_delete_item(numberValue(args[0]),&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    if( !p_plugin->playlist_delete_item(numberValue(args[0])) )
+                        return INVOKERESULT_GENERIC_ERROR;
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -779,8 +790,6 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
 
         switch( index )
         {
@@ -857,24 +866,25 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
                 }
 
                 int item = p_plugin->playlist_add_extended_untrusted(url, name,
-                      i_options, const_cast<const char **>(ppsz_options), &ex);
+                      i_options, const_cast<const char **>(ppsz_options));
                 free(url);
                 free(name);
+                if( item == -1 )
+                    RETURN_ON_ERROR;
+
                 for( int i=0; i< i_options; ++i )
                 {
                     free(ppsz_options[i]);
                 }
                 free(ppsz_options);
 
-                RETURN_ON_EXCEPTION(this,ex);
                 INT32_TO_NPVARIANT(item, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_playlist_play:
                 if( argCount == 0 )
                 {
-                    p_plugin->playlist_play(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->playlist_play();
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -882,8 +892,7 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
             case ID_playlist_playItem:
                 if( (argCount == 1) && isNumberValue(args[0]) )
                 {
-                    p_plugin->playlist_play_item(numberValue(args[0]),&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->playlist_play_item(numberValue(args[0]));
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -891,8 +900,7 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
             case ID_playlist_togglepause:
                 if( argCount == 0 )
                 {
-                    p_plugin->playlist_pause(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->playlist_pause();
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -908,8 +916,7 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
             case ID_playlist_next:
                 if( argCount == 0 )
                 {
-                    p_plugin->playlist_next(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->playlist_next();
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -917,8 +924,7 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
             case ID_playlist_prev:
                 if( argCount == 0 )
                 {
-                    p_plugin->playlist_prev(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->playlist_prev();
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -926,8 +932,7 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
             case ID_playlist_clear: /* deprecated */
                 if( argCount == 0 )
                 {
-                    p_plugin->playlist_clear(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->playlist_clear();
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -935,8 +940,8 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
             case ID_playlist_removeitem: /* deprecated */
                 if( (argCount == 1) && isNumberValue(args[0]) )
                 {
-                    p_plugin->playlist_delete_item(numberValue(args[0]), &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    if( !p_plugin->playlist_delete_item(numberValue(args[0])) )
+                        return INVOKERESULT_GENERIC_ERROR;
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -957,7 +962,7 @@ LibvlcPlaylistNPObject::invoke(int index, const NPVariant *args,
 void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
                                          int *i_options, char*** ppsz_options)
 {
-    if( nps.utf8length )
+    if( nps.UTF8Length )
     {
         char *s = stringValue(nps);
         char *val = s;
@@ -969,7 +974,7 @@ void LibvlcPlaylistNPObject::parseOptions(const NPString &nps,
             {
                 int nOptions = 0;
 
-                char *end = val + nps.utf8length;
+                char *end = val + nps.UTF8Length;
                 while( val < end )
                 {
                     // skip leading blanks
@@ -1110,19 +1115,16 @@ LibvlcSubtitleNPObject::getProperty(int index, NPVariant &result)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
             case ID_subtitle_track:
             {
                 /* get the current subtitle ID */
-                int i_spu = libvlc_video_get_spu(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int i_spu = libvlc_video_get_spu(p_md);
                 /* return it */
                 INT32_TO_NPVARIANT(i_spu, result);
                 return INVOKERESULT_NO_ERROR;
@@ -1130,8 +1132,7 @@ LibvlcSubtitleNPObject::getProperty(int index, NPVariant &result)
             case ID_subtitle_count:
             {
                 /* get the number of subtitles available */
-                int i_spu = libvlc_video_get_spu_count(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int i_spu = libvlc_video_get_spu_count(p_md);
                 /* return it */
                 INT32_TO_NPVARIANT(i_spu, result);
                 return INVOKERESULT_NO_ERROR;
@@ -1148,11 +1149,9 @@ LibvlcSubtitleNPObject::setProperty(int index, const NPVariant &value)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
@@ -1161,8 +1160,7 @@ LibvlcSubtitleNPObject::setProperty(int index, const NPVariant &value)
                 if( isNumberValue(value) )
                 {
                     /* set the new subtitle track to show */
-                    libvlc_video_set_spu(p_md, numberValue(value), &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    libvlc_video_set_spu(p_md, numberValue(value));
 
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -1192,11 +1190,9 @@ LibvlcSubtitleNPObject::invoke(int index, const NPVariant *args,
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
@@ -1209,14 +1205,12 @@ LibvlcSubtitleNPObject::invoke(int index, const NPVariant *args,
                     libvlc_track_description_t *p_spuDesc;
 
                     /* get subtitles description */
-                    p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_spuDesc = libvlc_video_get_spu_description(p_md);
                     if( !p_spuDesc )
                         return INVOKERESULT_GENERIC_ERROR;
 
                     /* get the number of subtitle available */
-                    i_limit = libvlc_video_get_spu_count(p_md, &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    i_limit = libvlc_video_get_spu_count(p_md);
 
                     /* check if a number is given by the user
                      * and get the subtitle number */
@@ -1252,6 +1246,16 @@ LibvlcSubtitleNPObject::invoke(int index, const NPVariant *args,
 ** implementation of libvlc video object
 */
 
+LibvlcVideoNPObject::~LibvlcVideoNPObject()
+{
+    if( isValid() )
+    {
+        if( marqueeObj ) NPN_ReleaseObject(marqueeObj);
+        if( logoObj    ) NPN_ReleaseObject(logoObj);
+        if( deintObj   ) NPN_ReleaseObject(deintObj);
+    }
+}
+
 const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
 {
     "fullscreen",
@@ -1262,7 +1266,8 @@ const NPUTF8 * const LibvlcVideoNPObject::propertyNames[] =
     "crop",
     "teletext",
     "marquee",
-    "logo"
+    "logo",
+    "deinterlace",
 };
 
 enum LibvlcVideoNPObjectPropertyIds
@@ -1275,7 +1280,8 @@ enum LibvlcVideoNPObjectPropertyIds
     ID_video_crop,
     ID_video_teletext,
     ID_video_marquee,
-    ID_video_logo
+    ID_video_logo,
+    ID_video_deinterlace,
 };
 COUNTNAMES(LibvlcVideoNPObject,propertyCount,propertyNames);
 
@@ -1286,39 +1292,33 @@ LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
             case ID_video_fullscreen:
             {
-                int val = p_plugin->get_fullscreen(&ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int val = p_plugin->get_fullscreen();
                 BOOLEAN_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_video_height:
             {
-                int val = libvlc_video_get_height(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int val = libvlc_video_get_height(p_md);
                 INT32_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_video_width:
             {
-                int val = libvlc_video_get_width(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int val = libvlc_video_get_width(p_md);
                 INT32_TO_NPVARIANT(val, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_video_aspectratio:
             {
-                NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                NPUTF8 *psz_aspect = libvlc_video_get_aspect_ratio(p_md);
                 if( !psz_aspect )
                     return INVOKERESULT_GENERIC_ERROR;
 
@@ -1327,15 +1327,13 @@ LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
             }
             case ID_video_subtitle:
             {
-                int i_spu = libvlc_video_get_spu(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int i_spu = libvlc_video_get_spu(p_md);
                 INT32_TO_NPVARIANT(i_spu, result);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_video_crop:
             {
-                NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                NPUTF8 *psz_geometry = libvlc_video_get_crop_geometry(p_md);
                 if( !psz_geometry )
                     return INVOKERESULT_GENERIC_ERROR;
 
@@ -1344,12 +1342,11 @@ LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
             }
             case ID_video_teletext:
             {
-/*                int i_page = libvlc_video_get_teletext(p_md, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                int i_page = libvlc_video_get_teletext(p_md);
+                if( i_page < 0 )
+                    return INVOKERESULT_GENERIC_ERROR;
                 INT32_TO_NPVARIANT(i_page, result);
                 return INVOKERESULT_NO_ERROR;
-*/
-                return INVOKERESULT_NO_SUCH_METHOD;
             }
             case ID_video_marquee:
             {
@@ -1363,6 +1360,12 @@ LibvlcVideoNPObject::getProperty(int index, NPVariant &result)
                 OBJECT_TO_NPVARIANT(NPN_RetainObject(logoObj), result);
                 return INVOKERESULT_NO_ERROR;
             }
+            case ID_video_deinterlace:
+            {
+                InstantObj<LibvlcDeinterlaceNPObject>( deintObj );
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(deintObj), result);
+                return INVOKERESULT_NO_ERROR;
+            }
         }
     }
     return INVOKERESULT_GENERIC_ERROR;
@@ -1375,11 +1378,9 @@ LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
@@ -1391,8 +1392,7 @@ LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
                 }
 
                 int val = NPVARIANT_TO_BOOLEAN(value);
-                p_plugin->set_fullscreen(val, &ex);
-                RETURN_ON_EXCEPTION(this,ex);
+                p_plugin->set_fullscreen(val);
                 return INVOKERESULT_NO_ERROR;
             }
             case ID_video_aspectratio:
@@ -1410,9 +1410,8 @@ LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
                     return INVOKERESULT_GENERIC_ERROR;
                 }
 
-                libvlc_video_set_aspect_ratio(p_md, psz_aspect, &ex);
+                libvlc_video_set_aspect_ratio(p_md, psz_aspect);
                 free(psz_aspect);
-                RETURN_ON_EXCEPTION(this,ex);
 
                 return INVOKERESULT_NO_ERROR;
             }
@@ -1420,8 +1419,7 @@ LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
             {
                 if( isNumberValue(value) )
                 {
-                    libvlc_video_set_spu(p_md, numberValue(value), &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    libvlc_video_set_spu(p_md, numberValue(value));
 
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -1442,9 +1440,8 @@ LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
                     return INVOKERESULT_GENERIC_ERROR;
                 }
 
-                libvlc_video_set_crop_geometry(p_md, psz_geometry, &ex);
+                libvlc_video_set_crop_geometry(p_md, psz_geometry);
                 free(psz_geometry);
-                RETURN_ON_EXCEPTION(this,ex);
 
                 return INVOKERESULT_NO_ERROR;
             }
@@ -1452,13 +1449,8 @@ LibvlcVideoNPObject::setProperty(int index, const NPVariant &value)
             {
                 if( isNumberValue(value) )
                 {
-/*
-                    libvlc_video_set_teletext(p_md, numberValue(value), &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
-
+                    libvlc_video_set_teletext(p_md, numberValue(value));
                     return INVOKERESULT_NO_ERROR;
-*/
-                    return INVOKERESULT_NO_SUCH_METHOD;
                 }
                 return INVOKERESULT_INVALID_VALUE;
             }
@@ -1471,8 +1463,6 @@ const NPUTF8 * const LibvlcVideoNPObject::methodNames[] =
 {
     "toggleFullscreen",
     "toggleTeletext",
-    "deinterlaceEnable",
-    "deinterlaceDisable"
 };
 COUNTNAMES(LibvlcVideoNPObject,methodCount,methodNames);
 
@@ -1480,8 +1470,6 @@ enum LibvlcVideoNPObjectMethodIds
 {
     ID_video_togglefullscreen,
     ID_video_toggleteletext,
-    ID_video_deinterlaceenable,
-    ID_video_deinterlacedisable
 };
 
 RuntimeNPObject::InvokeResult
@@ -1492,11 +1480,9 @@ LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
     if( isPluginRunning() )
     {
         VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-        libvlc_exception_t ex;
-        libvlc_exception_init(&ex);
-
-        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_media_player_t *p_md = p_plugin->getMD();
+        if( !p_md )
+            RETURN_ON_ERROR;
 
         switch( index )
         {
@@ -1504,8 +1490,7 @@ LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
             {
                 if( argCount == 0 )
                 {
-                    p_plugin->toggle_fullscreen(&ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    p_plugin->toggle_fullscreen();
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
@@ -1515,39 +1500,12 @@ LibvlcVideoNPObject::invoke(int index, const NPVariant *args,
             {
                 if( argCount == 0 )
                 {
-                    libvlc_toggle_teletext(p_md, &ex);
-                    RETURN_ON_EXCEPTION(this,ex);
+                    libvlc_toggle_teletext(p_md);
                     VOID_TO_NPVARIANT(result);
                     return INVOKERESULT_NO_ERROR;
                 }
                 return INVOKERESULT_NO_SUCH_METHOD;
             }
-            case ID_video_deinterlacedisable:
-            {
-                libvlc_video_set_deinterlace(p_md, 0, "", &ex);
-                RETURN_ON_EXCEPTION(this,ex);
-                return INVOKERESULT_NO_ERROR;
-            }
-            case ID_video_deinterlaceenable:
-            {
-                if(argCount == 1)
-                {
-                    if( NPVARIANT_IS_STRING( args[0] ) )
-                    {
-                        /* get deinterlace mode from the user */
-                        char *psz_mode = stringValue( NPVARIANT_TO_STRING( args[0] ) );
-                        /* enable deinterlace filter if possible */
-                        libvlc_video_set_deinterlace(p_md, 1, psz_mode, &ex);
-                        free(psz_mode);
-                        RETURN_ON_EXCEPTION(this,ex);
-                        return INVOKERESULT_NO_ERROR;
-                    }
-                    else
-                    {
-                        return INVOKERESULT_INVALID_VALUE;
-                    }
-                }
-            }
             default:
                 return INVOKERESULT_NO_SUCH_METHOD;
         }
@@ -1608,11 +1566,9 @@ LibvlcMarqueeNPObject::getProperty(int index, NPVariant &result)
         return INVOKERESULT_GENERIC_ERROR;
 
     VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
-
-    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-    RETURN_ON_EXCEPTION(this,ex);
+    libvlc_media_player_t *p_md = p_plugin->getMD();
+    if( !p_md )
+        RETURN_ON_ERROR;
 
     switch( index )
     {
@@ -1624,21 +1580,19 @@ LibvlcMarqueeNPObject::getProperty(int index, NPVariant &result)
     case ID_marquee_x:
     case ID_marquee_y:
         INT32_TO_NPVARIANT(
-            libvlc_video_get_marquee_int(p_md, marquee_idx[index], &ex),
+            libvlc_video_get_marquee_int(p_md, marquee_idx[index]),
             result );
-        RETURN_ON_EXCEPTION(this,ex);
         return INVOKERESULT_NO_ERROR;
 
     case ID_marquee_position:
         STRINGZ_TO_NPVARIANT( position_bynumber(
-            libvlc_video_get_marquee_int(p_md, libvlc_marquee_Position, &ex) ),
+            libvlc_video_get_marquee_int(p_md, libvlc_marquee_Position) ),
             result );
 
-        RETURN_ON_EXCEPTION(this,ex);
         break;
 
     case ID_marquee_text:
-        psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text, &ex);
+        psz = libvlc_video_get_marquee_string(p_md, libvlc_marquee_Text);
         if( psz )
         {
             STRINGZ_TO_NPVARIANT(psz, result);
@@ -1658,10 +1612,9 @@ LibvlcMarqueeNPObject::setProperty(int index, const NPVariant &value)
         return INVOKERESULT_GENERIC_ERROR;
 
     VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
-    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-    RETURN_ON_EXCEPTION(this,ex);
+    libvlc_media_player_t *p_md = p_plugin->getMD();
+    if( !p_md )
+        RETURN_ON_ERROR;
 
     switch( index )
     {
@@ -1674,19 +1627,17 @@ LibvlcMarqueeNPObject::setProperty(int index, const NPVariant &value)
         if( NPVARIANT_IS_INT32( value ) )
         {
             libvlc_video_set_marquee_int(p_md, marquee_idx[index],
-                                         NPVARIANT_TO_INT32( value ), &ex);
-            RETURN_ON_EXCEPTION(this,ex);
+                                         NPVARIANT_TO_INT32( value ));
             return INVOKERESULT_NO_ERROR;
         }
         break;
 
     case ID_marquee_position:
         if( !NPVARIANT_IS_STRING(value) ||
-            !position_byname( NPVARIANT_TO_STRING(value).utf8characters, i ) )
+            !position_byname( NPVARIANT_TO_STRING(value).UTF8Characters, i ) )
             return INVOKERESULT_INVALID_VALUE;
 
-        libvlc_video_set_marquee_int(p_md, libvlc_marquee_Position, i, &ex);
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_video_set_marquee_int(p_md, libvlc_marquee_Position, i);
         return INVOKERESULT_NO_ERROR;
 
     case ID_marquee_text:
@@ -1694,9 +1645,8 @@ LibvlcMarqueeNPObject::setProperty(int index, const NPVariant &value)
         {
             char *psz_text = stringValue( NPVARIANT_TO_STRING( value ) );
             libvlc_video_set_marquee_string(p_md, libvlc_marquee_Text,
-                                            psz_text, &ex);
+                                            psz_text);
             free(psz_text);
-            RETURN_ON_EXCEPTION(this,ex);
             return INVOKERESULT_NO_ERROR;
         }
         break;
@@ -1725,19 +1675,16 @@ LibvlcMarqueeNPObject::invoke(int index, const NPVariant *args,
         return INVOKERESULT_GENERIC_ERROR;
 
     VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
-
-    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-    RETURN_ON_EXCEPTION(this,ex);
+    libvlc_media_player_t *p_md = p_plugin->getMD();
+    if( !p_md )
+        RETURN_ON_ERROR;
 
     switch( index )
     {
     case ID_marquee_enable:
     case ID_marquee_disable:
         libvlc_video_set_marquee_int(p_md, libvlc_marquee_Enable,
-                                     index!=ID_marquee_disable, &ex);
-        RETURN_ON_EXCEPTION(this,ex);
+                                     index!=ID_marquee_disable);
         VOID_TO_NPVARIANT(result);
         return INVOKERESULT_NO_ERROR;
     }
@@ -1777,10 +1724,9 @@ LibvlcLogoNPObject::getProperty(int index, NPVariant &result)
         return INVOKERESULT_GENERIC_ERROR;
 
     VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
-    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-    RETURN_ON_EXCEPTION(this,ex);
+    libvlc_media_player_t *p_md = p_plugin->getMD();
+    if( !p_md )
+        RETURN_ON_ERROR;
 
     switch( index )
     {
@@ -1791,17 +1737,13 @@ LibvlcLogoNPObject::getProperty(int index, NPVariant &result)
     case ID_logo_y:
 
         INT32_TO_NPVARIANT(
-            libvlc_video_get_logo_int(p_md, logo_idx[index], &ex), result);
-
-        RETURN_ON_EXCEPTION(this,ex);
+            libvlc_video_get_logo_int(p_md, logo_idx[index]), result);
         break;
 
     case ID_logo_position:
         STRINGZ_TO_NPVARIANT( position_bynumber(
-            libvlc_video_get_logo_int(p_md, libvlc_logo_position, &ex) ),
+            libvlc_video_get_logo_int(p_md, libvlc_logo_position) ),
             result );
-
-        RETURN_ON_EXCEPTION(this,ex);
         break;
     default:
         return INVOKERESULT_GENERIC_ERROR;
@@ -1818,11 +1760,9 @@ LibvlcLogoNPObject::setProperty(int index, const NPVariant &value)
         return INVOKERESULT_GENERIC_ERROR;
 
     VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
-
-    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
-    RETURN_ON_EXCEPTION(this,ex);
+    libvlc_media_player_t *p_md = p_plugin->getMD();
+    if( !p_md )
+        RETURN_ON_ERROR;
 
     switch( index )
     {
@@ -1835,19 +1775,15 @@ LibvlcLogoNPObject::setProperty(int index, const NPVariant &value)
             return INVOKERESULT_INVALID_VALUE;
 
         libvlc_video_set_logo_int(p_md, logo_idx[index],
-                                  NPVARIANT_TO_INT32( value ), &ex);
-
-        RETURN_ON_EXCEPTION(this,ex);
+                                  NPVARIANT_TO_INT32( value ));
         break;
 
     case ID_logo_position:
         if( !NPVARIANT_IS_STRING(value) ||
-            !position_byname( NPVARIANT_TO_STRING(value).utf8characters, i ) )
+            !position_byname( NPVARIANT_TO_STRING(value).UTF8Characters, i ) )
             return INVOKERESULT_INVALID_VALUE;
 
-        libvlc_video_set_logo_int(p_md, libvlc_logo_position, i, &ex);
-
-        RETURN_ON_EXCEPTION(this,ex);
+        libvlc_video_set_logo_int(p_md, libvlc_logo_position, i);
         break;
     default:
         return INVOKERESULT_GENERIC_ERROR;
@@ -1878,10 +1814,9 @@ LibvlcLogoNPObject::invoke(int index, const NPVariant *args,
     if( !isPluginRunning() )
         return INVOKERESULT_GENERIC_ERROR;
 
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
-    libvlc_media_player_t *p_md = getPrivate<VlcPlugin>()->getMD(&ex);
-    RETURN_ON_EXCEPTION(this,ex);
+    libvlc_media_player_t *p_md = getPrivate<VlcPlugin>()->getMD();
+    if( !p_md )
+        RETURN_ON_ERROR;
 
     switch( index )
     {
@@ -1891,8 +1826,7 @@ LibvlcLogoNPObject::invoke(int index, const NPVariant *args,
             return INVOKERESULT_GENERIC_ERROR;
 
         libvlc_video_set_logo_int(p_md, libvlc_logo_enable,
-                                  index != ID_logo_disable, &ex);
-        RETURN_ON_EXCEPTION(this,ex);
+                                  index != ID_logo_disable);
         VOID_TO_NPVARIANT(result);
         break;
 
@@ -1904,7 +1838,7 @@ LibvlcLogoNPObject::invoke(int index, const NPVariant *args,
         {
             if( !NPVARIANT_IS_STRING(args[i]) )
                 return INVOKERESULT_INVALID_VALUE;
-            len+=NPVARIANT_TO_STRING(args[i]).utf8length+1;
+            len+=NPVARIANT_TO_STRING(args[i]).UTF8Length+1;
         }
 
         buf = (char *)malloc( len+1 );
@@ -1914,17 +1848,82 @@ LibvlcLogoNPObject::invoke(int index, const NPVariant *args,
         for( h=buf,i=0;i<argCount;++i )
         {
             if(i) *h++=';';
-            len=NPVARIANT_TO_STRING(args[i]).utf8length;
-            memcpy(h,NPVARIANT_TO_STRING(args[i]).utf8characters,len);
+            len=NPVARIANT_TO_STRING(args[i]).UTF8Length;
+            memcpy(h,NPVARIANT_TO_STRING(args[i]).UTF8Characters,len);
             h+=len;
         }
         *h='\0';
 
-        libvlc_video_set_logo_string(p_md, libvlc_logo_file, buf, &ex);
+        libvlc_video_set_logo_string(p_md, libvlc_logo_file, buf);
         free( buf );
-        RETURN_ON_EXCEPTION(this,ex);
         VOID_TO_NPVARIANT(result);
         break;
+    default:
+        return INVOKERESULT_NO_SUCH_METHOD;
+    }
+    return INVOKERESULT_NO_ERROR;
+}
+
+
+const NPUTF8 * const LibvlcDeinterlaceNPObject::propertyNames[] = {
+};
+enum LibvlcDeinterlaceNPObjectPropertyIds {
+};
+COUNTNAMES(LibvlcDeinterlaceNPObject,propertyCount,propertyNames);
+
+RuntimeNPObject::InvokeResult
+LibvlcDeinterlaceNPObject::getProperty(int index, NPVariant &result)
+{
+    return INVOKERESULT_GENERIC_ERROR;
+}
+
+RuntimeNPObject::InvokeResult
+LibvlcDeinterlaceNPObject::setProperty(int index, const NPVariant &value)
+{
+    return INVOKERESULT_GENERIC_ERROR;
+}
+
+
+const NPUTF8 * const LibvlcDeinterlaceNPObject::methodNames[] = {
+    "enable",
+    "disable",
+};
+enum LibvlcDeinterlaceNPObjectMethodIds {
+    ID_deint_enable,
+    ID_deint_disable,
+};
+COUNTNAMES(LibvlcDeinterlaceNPObject,methodCount,methodNames);
+
+RuntimeNPObject::InvokeResult
+LibvlcDeinterlaceNPObject::invoke(int index, const NPVariant *args,
+                           uint32_t argCount, NPVariant &result)
+{
+    char *psz;
+
+    if( !isPluginRunning() )
+        return INVOKERESULT_GENERIC_ERROR;
+
+    libvlc_media_player_t *p_md = getPrivate<VlcPlugin>()->getMD();
+    if( !p_md )
+        RETURN_ON_ERROR;
+
+    switch( index )
+    {
+    case ID_deint_disable:
+        libvlc_video_set_deinterlace(p_md, NULL);
+        break;
+
+    case ID_deint_enable:
+        if( argCount != 1 || !NPVARIANT_IS_STRING( args[0] ) )
+            return INVOKERESULT_INVALID_VALUE;
+
+        psz = stringValue( NPVARIANT_TO_STRING( args[0] ) );
+        libvlc_video_set_deinterlace(p_md, psz);
+        free(psz);
+        break;
+
+    default:
+        return INVOKERESULT_NO_SUCH_METHOD;
     }
     return INVOKERESULT_NO_ERROR;
 }