* Remove directories with only one source file inside
authorClément Stenac <zorglub@videolan.org>
Sat, 6 Mar 2004 15:24:37 +0000 (15:24 +0000)
committerClément Stenac <zorglub@videolan.org>
Sat, 6 Mar 2004 15:24:37 +0000 (15:24 +0000)
* Drop the old scope plugin (not ported to aout3)

26 files changed:
configure.ac
modules/control/Modules.am
modules/control/lirc.c [new file with mode: 0644]
modules/control/lirc/Modules.am [deleted file]
modules/control/lirc/lirc.c [deleted file]
modules/control/rc.c [new file with mode: 0644]
modules/control/rc/Modules.am [deleted file]
modules/control/rc/rc.c [deleted file]
modules/misc/Modules.am
modules/misc/logger.c [new file with mode: 0644]
modules/misc/logger/Modules.am [deleted file]
modules/misc/logger/logger.c [deleted file]
modules/video_filter/Modules.am
modules/video_filter/deinterlace.c [new file with mode: 0644]
modules/video_filter/deinterlace/Modules.am [deleted file]
modules/video_filter/deinterlace/deinterlace.c [deleted file]
modules/video_output/Modules.am
modules/video_output/mga.c [new file with mode: 0644]
modules/video_output/mga/Modules.am [deleted file]
modules/video_output/mga/mga.c [deleted file]
modules/visualization/Modules.am
modules/visualization/scope/Modules.am [deleted file]
modules/visualization/scope/scope.c [deleted file]
modules/visualization/xosd.c [new file with mode: 0644]
modules/visualization/xosd/Modules.am [deleted file]
modules/visualization/xosd/xosd.c [deleted file]

index 173c188..62963d4 100644 (file)
@@ -1,5 +1,5 @@
 dnl Autoconf settings for vlc
-dnl $Id: configure.ac,v 1.190 2004/03/05 14:03:20 garf Exp $
+dnl $Id$
 
 AC_INIT(vlc,0.7.2-cvs)
 
@@ -890,7 +890,6 @@ AX_ADD_PLUGINS([trivial_resampler ugly_resampler linear_resampler bandlimited_re
 AX_ADD_PLUGINS([trivial_channel_mixer headphone_channel_mixer])
 AX_ADD_PLUGINS([trivial_mixer spdif_mixer float32_mixer])
 AX_ADD_PLUGINS([aout_file])
-#AX_ADD_PLUGINS([scope])
 AX_ADD_PLUGINS([i420_rgb i420_yuy2 i422_yuy2 i420_ymga])
 AX_ADD_PLUGINS([id3 m3u playlist export])
 AX_ADD_PLUGINS([rawvideo])
@@ -3765,8 +3764,6 @@ AC_CONFIG_FILES([
   modules/codec/spudec/Makefile
   modules/control/Makefile
   modules/control/corba/Makefile
-  modules/control/lirc/Makefile
-  modules/control/rc/Makefile
   modules/control/telnet/Makefile
   modules/demux/Makefile
   modules/demux/asf/Makefile
@@ -3790,7 +3787,6 @@ AC_CONFIG_FILES([
   modules/gui/wxwindows/Makefile
   modules/misc/Makefile
   modules/misc/dummy/Makefile
-  modules/misc/logger/Makefile
   modules/misc/memcpy/Makefile
   modules/misc/network/Makefile
   modules/misc/testsuite/Makefile
@@ -3802,15 +3798,11 @@ AC_CONFIG_FILES([
   modules/stream_out/transrate/Makefile
   modules/video_chroma/Makefile
   modules/video_filter/Makefile
-  modules/video_filter/deinterlace/Makefile
   modules/video_output/Makefile
   modules/video_output/directx/Makefile
-  modules/video_output/mga/Makefile
   modules/video_output/qte/Makefile
   modules/video_output/x11/Makefile
   modules/visualization/Makefile
-  modules/visualization/scope/Makefile
-  modules/visualization/xosd/Makefile
   modules/visualization/visual/Makefile
 ])
 
index 8a1e556..1c64745 100644 (file)
@@ -3,3 +3,5 @@ SOURCES_http = http.c
 SOURCES_ntservice = ntservice.c
 SOURCES_joystick = joystick.c
 SOURCES_hotkeys = hotkeys.c
+SOURCES_lirc = lirc.c
+SOURCES_rc = rc.c
diff --git a/modules/control/lirc.c b/modules/control/lirc.c
new file mode 100644 (file)
index 0000000..9e98fc7
--- /dev/null
@@ -0,0 +1,486 @@
+/*****************************************************************************
+ * lirc.c : lirc module for vlc
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id: lirc.c,v 1.11 2004/02/15 19:40:41 sigmunau Exp $
+ *
+ * Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
+ *
+ * This program 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 program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>
+
+#include <fcntl.h>
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <vlc/vout.h>
+#include <vlc/aout.h>
+#include <osd.h>
+
+#include <lirc/lirc_client.h>
+
+/*****************************************************************************
+ * intf_sys_t: description and status of FB interface
+ *****************************************************************************/
+struct intf_sys_t
+{
+    struct lirc_config *config;
+    vlc_mutex_t         change_lock;
+
+    input_thread_t *    p_input;
+    vout_thread_t *     p_vout;
+};
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  Open    ( vlc_object_t * );
+static void Close   ( vlc_object_t * );
+static void Run     ( intf_thread_t * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+    set_description( _("Infrared remote control interface") );
+    set_capability( "interface", 0 );
+    set_callbacks( Open, Close );
+vlc_module_end();
+
+/*****************************************************************************
+ * Open: initialize interface
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+    int i_fd;
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        msg_Err( p_intf, "out of memory" );
+        return 1;
+    }
+
+    p_intf->pf_run = Run;
+
+    i_fd = lirc_init( "vlc", 1 );
+    if( i_fd == -1 )
+    {
+        msg_Err( p_intf, "lirc_init failed" );
+        free( p_intf->p_sys );
+        return 1;
+    }
+
+    /* We want polling */
+    fcntl( i_fd, F_SETFL, fcntl( i_fd, F_GETFL ) | O_NONBLOCK );
+
+    if( lirc_readconfig( NULL, &p_intf->p_sys->config, NULL ) != 0 )
+    {
+        msg_Err( p_intf, "lirc_readconfig failed" );
+        lirc_deinit();
+        free( p_intf->p_sys );
+        return 1;
+    }
+
+    p_intf->p_sys->p_input = NULL;
+
+    return 0;
+}
+
+/*****************************************************************************
+ * Close: destroy interface
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+
+    if( p_intf->p_sys->p_input )
+    {
+        vlc_object_release( p_intf->p_sys->p_input );
+    }
+    if( p_intf->p_sys->p_vout )
+    {
+        vlc_object_release( p_intf->p_sys->p_vout );
+    }
+    /* Destroy structure */
+    lirc_freeconfig( p_intf->p_sys->config );
+    lirc_deinit();
+    free( p_intf->p_sys );
+}
+
+/*****************************************************************************
+ * Run: main loop
+ *****************************************************************************/
+static void Run( intf_thread_t *p_intf )
+{
+    char *code, *c;
+    playlist_t *p_playlist;
+    input_thread_t *p_input;
+    vout_thread_t *p_vout = NULL;
+
+    while( !p_intf->b_die )
+    {
+        /* Sleep a bit */
+        msleep( INTF_IDLE_SLEEP );
+
+        /* Update the input */
+        if( p_intf->p_sys->p_input == NULL )
+        {
+            p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
+                                                              FIND_ANYWHERE );
+        }
+        else if( p_intf->p_sys->p_input->b_dead )
+        {
+            vlc_object_release( p_intf->p_sys->p_input );
+            p_intf->p_sys->p_input = NULL;
+        }
+        p_input = p_intf->p_sys->p_input;
+
+        /* Update the vout */
+        if( p_vout == NULL )
+        {
+            p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
+                                      FIND_ANYWHERE );
+            p_intf->p_sys->p_vout = p_vout;
+        }
+        else if( p_vout->b_die )
+        {
+            vlc_object_release( p_vout );
+            p_vout = NULL;
+            p_intf->p_sys->p_vout = NULL;
+        }
+
+        /* We poll the lircsocket */
+        if( lirc_nextcode(&code) != 0 )
+        {
+            break;
+        }
+
+        if( code == NULL )
+        {
+            continue;
+        }
+
+        while( !p_intf->b_die
+                && lirc_code2char( p_intf->p_sys->config, code, &c ) == 0
+                && c != NULL )
+        {
+
+            if( !strcmp( c, "QUIT" ) )
+            {
+                p_intf->p_vlc->b_die = VLC_TRUE;
+                vout_OSDMessage( p_intf, _("Quit" ) );
+                continue;
+            }
+            else if( !strcmp( c, "VOL_UP" ) )
+            {
+                audio_volume_t i_newvol;
+                aout_VolumeUp( p_intf, 1, &i_newvol );
+                vout_OSDMessage( p_intf, _("Vol %%%d"), i_newvol*100/AOUT_VOLUME_MAX );
+            }
+            else if( !strcmp( c, "VOL_DOWN" ) )
+            {
+                audio_volume_t i_newvol;
+                aout_VolumeDown( p_intf, 1, &i_newvol );
+                vout_OSDMessage( p_intf, _("Vol %%%d"), i_newvol*100/AOUT_VOLUME_MAX );
+            }
+            else if( !strcmp( c, "MUTE" ) )
+            {
+                audio_volume_t i_newvol = -1;
+                aout_VolumeMute( p_intf, &i_newvol );
+                if( i_newvol == 0 )
+                {
+                    vout_OSDMessage( p_intf, _( "Mute" ) );
+                }
+                else
+                {
+                    vout_OSDMessage( p_intf, _("Vol %d%%"), i_newvol*100/AOUT_VOLUME_MAX );
+                }
+            }
+            if( p_vout )
+            {
+                if( !strcmp( c, "FULLSCREEN" ) )
+                {
+                    p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+                    continue;
+                }
+                if( !strcmp( c, "ACTIVATE" ) )
+                {
+                    vlc_value_t val;
+                    val.psz_string = "ENTER";
+                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
+                    {
+                        msg_Warn( p_intf, "key-press failed" );
+                    }
+                    continue;
+                }
+
+                if( !strcmp( c, "LEFT" ) )
+                {
+                    vlc_value_t val;
+                    val.psz_string = "LEFT";
+                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
+                    {
+                        msg_Warn( p_intf, "key-press failed" );
+                    }
+                    continue;
+                }
+
+                if( !strcmp( c, "RIGHT" ) )
+                {
+                    vlc_value_t val;
+                    val.psz_string = "RIGHT";
+                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
+                    {
+                        msg_Warn( p_intf, "key-press failed" );
+                    }
+                    continue;
+                }
+
+                if( !strcmp( c, "UP" ) )
+                {
+                    vlc_value_t val;
+                    val.psz_string = "UP";
+                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
+                    {
+                        msg_Warn( p_intf, "key-press failed" );
+                    }
+                    continue;
+                }
+
+                if( !strcmp( c, "DOWN" ) )
+                {
+                    vlc_value_t val;
+                    val.psz_string = "DOWN";
+                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
+                    {
+                        msg_Warn( p_intf, "key-press failed" );
+                    }
+                    continue;
+                }
+            }
+
+            if( !strcmp( c, "PLAY" ) )
+            {
+                p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                                      FIND_ANYWHERE );
+                if( p_playlist )
+                {
+                    vlc_mutex_lock( &p_playlist->object_lock );
+                    if( p_playlist->i_size )
+                    {
+                        vlc_mutex_unlock( &p_playlist->object_lock );
+                        playlist_Play( p_playlist );
+                        vlc_object_release( p_playlist );
+                    }
+                }
+                continue;
+            }
+
+            if( !strcmp( c, "PLAYPAUSE" ) )
+            {
+                vlc_value_t val;
+                val.i_int = PLAYING_S;
+                if( p_input )
+                {
+                    var_Get( p_input, "state", &val );
+                }
+                if( p_input && val.i_int != PAUSE_S )
+                {
+                    vout_OSDMessage( VLC_OBJECT(p_intf), _( "Pause" ) );
+                    val.i_int = PAUSE_S;
+                    var_Set( p_input, "state", val );
+                }
+                else
+                {
+                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                                  FIND_ANYWHERE );
+                    if( p_playlist )
+                    {
+                        vlc_mutex_lock( &p_playlist->object_lock );
+                        if( p_playlist->i_size )
+                        {
+                            vlc_mutex_unlock( &p_playlist->object_lock );
+                            vout_OSDMessage( p_intf, _( "Play" ) );
+                            playlist_Play( p_playlist );
+                            vlc_object_release( p_playlist );
+                        }
+                    }
+                }
+                continue;
+            }
+
+            else if( p_input )
+            {
+                if( !strcmp( c, "AUDIO_TRACK" ) )
+                {
+                    vlc_value_t val,list,list2;
+                    int i_count, i;
+                    var_Get( p_input, "audio-es", &val );
+                    var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES, &list, &list2 );
+                    i_count = list.p_list->i_count;
+                    for( i = 0; i < i_count; i++ )
+                    {
+                        if( val.i_int == list.p_list->p_values[i].i_int )
+                        {
+                            break;
+                        }
+                    }
+                    /* value of audio-es was not in choices list */
+                    if( i == i_count )
+                    {
+                        msg_Warn( p_input, "invalid current audio track, selecting 0" );
+                        var_Set( p_input, "audio-es", list.p_list->p_values[0] );
+                        i = 0;
+                    }
+                    else if( i == i_count - 1 )
+                    {
+                        var_Set( p_input, "audio-es", list.p_list->p_values[0] );
+                        i = 0;
+                    }
+                    else
+                    {
+                        var_Set( p_input, "audio-es", list.p_list->p_values[i+1] );
+                        i = i + 1;
+                    }
+                    vout_OSDMessage( VLC_OBJECT(p_input), _("Audio track: %s"), list2.p_list->p_values[i].psz_string );
+                }
+                else if( !strcmp( c, "SUBTITLE_TRACK" ) )
+                {
+                    vlc_value_t val,list,list2;
+                    int i_count, i;
+                    var_Get( p_input, "spu-es", &val );
+                    var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES, &list, &list2 );
+                    i_count = list.p_list->i_count;
+                    for( i = 0; i < i_count; i++ )
+                    {
+                        if( val.i_int == list.p_list->p_values[i].i_int )
+                        {
+                            break;
+                        }
+                    }
+                    /* value of audio-es was not in choices list */
+                    if( i == i_count )
+                    {
+                        msg_Warn( p_input, "invalid current subtitle track, selecting 0" );
+                        var_Set( p_input, "spu-es", list.p_list->p_values[0] );
+                        i = 0;
+                    }
+                    else if( i == i_count - 1 )
+                    {
+                        var_Set( p_input, "spu-es", list.p_list->p_values[0] );
+                        i = 0;
+                    }
+                    else
+                    {
+                        var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
+                        i = i + 1;
+                    }
+                    vout_OSDMessage( VLC_OBJECT(p_input), _("Subtitle track: %s"), list2.p_list->p_values[i].psz_string );
+                }
+                else if( !strcmp( c, "PAUSE" ) )
+                {
+                    vlc_value_t val;
+                    vout_OSDMessage( p_intf, _( "Pause" ) );
+                    val.i_int = PAUSE_S;
+                    var_Set( p_input, "state", val );
+                }
+                else if( !strcmp( c, "NEXT" ) )
+                {
+                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                                          FIND_ANYWHERE );
+                    if( p_playlist )
+                    {
+                        playlist_Next( p_playlist );
+                        vlc_object_release( p_playlist );
+                    }
+                }
+                else if( !strcmp( c, "PREV" ) )
+                {
+                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                                          FIND_ANYWHERE );
+                    if( p_playlist )
+                    {
+                        playlist_Prev( p_playlist );
+                        vlc_object_release( p_playlist );
+                    }
+                }
+                else if( !strcmp( c, "STOP" ) )
+                {
+                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                                          FIND_ANYWHERE );
+                    if( p_playlist )
+                    {
+                        playlist_Stop( p_playlist );
+                        vlc_object_release( p_playlist );
+                    }
+                }
+                else if( !strcmp( c, "FAST" ) )
+                {
+                    vlc_value_t val; val.b_bool = VLC_TRUE;
+                    var_Set( p_input, "rate-faster", val );
+                }
+                else if( !strcmp( c, "SLOW" ) )
+                {
+                    vlc_value_t val; val.b_bool = VLC_TRUE;
+                    var_Set( p_input, "rate-slower", val );
+                }
+/* beginning of modifications by stephane Thu Jun 19 15:29:49 CEST 2003 */
+                else if ( !strcmp(c, "CHAPTER_N" ) ||
+                          !strcmp( c, "CHAPTER_P" ) )
+                {
+                    unsigned int i_chapter = 0;
+
+                    if( !strcmp( c, "CHAPTER_N" ) )
+                    {
+                        vlc_mutex_lock( &p_input->stream.stream_lock );
+                        i_chapter = p_input->stream.p_selected_area->i_part + 1;
+                        vlc_mutex_unlock( &p_input->stream.stream_lock );
+                    }
+                    else if( !strcmp( c, "CHAPTER_P" ) )
+                    {
+                        vlc_mutex_lock( &p_input->stream.stream_lock );
+                        i_chapter = p_input->stream.p_selected_area->i_part - 1;
+                        vlc_mutex_unlock( &p_input->stream.stream_lock );
+                    }
+
+                    vlc_mutex_lock( &p_input->stream.stream_lock );
+                    if( ( i_chapter > 0 ) && ( i_chapter <
+                                               p_input->stream.p_selected_area->i_part_nb ) )
+                    {
+                        input_area_t *p_area = p_input->stream.p_selected_area;
+                        p_input->stream.p_selected_area->i_part = i_chapter;
+                        vlc_mutex_unlock( &p_input->stream.stream_lock );
+                        input_ChangeArea( p_input, p_area );
+                        input_SetStatus( p_input, INPUT_STATUS_PLAY );
+                        vlc_mutex_lock( &p_input->stream.stream_lock );
+                    }
+                    vlc_mutex_unlock( &p_input->stream.stream_lock );
+                }
+/* end of modification by stephane Thu Jun 19 15:29:49 CEST 2003 */
+            }
+        }
+
+        free( code );
+    }
+}
diff --git a/modules/control/lirc/Modules.am b/modules/control/lirc/Modules.am
deleted file mode 100644 (file)
index 5296eee..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SOURCES_lirc = lirc.c
diff --git a/modules/control/lirc/lirc.c b/modules/control/lirc/lirc.c
deleted file mode 100644 (file)
index 9e98fc7..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*****************************************************************************
- * lirc.c : lirc module for vlc
- *****************************************************************************
- * Copyright (C) 2004 VideoLAN
- * $Id: lirc.c,v 1.11 2004/02/15 19:40:41 sigmunau Exp $
- *
- * Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
- *
- * This program 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 program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>
-
-#include <fcntl.h>
-
-#include <vlc/vlc.h>
-#include <vlc/intf.h>
-#include <vlc/vout.h>
-#include <vlc/aout.h>
-#include <osd.h>
-
-#include <lirc/lirc_client.h>
-
-/*****************************************************************************
- * intf_sys_t: description and status of FB interface
- *****************************************************************************/
-struct intf_sys_t
-{
-    struct lirc_config *config;
-    vlc_mutex_t         change_lock;
-
-    input_thread_t *    p_input;
-    vout_thread_t *     p_vout;
-};
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int  Open    ( vlc_object_t * );
-static void Close   ( vlc_object_t * );
-static void Run     ( intf_thread_t * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-vlc_module_begin();
-    set_description( _("Infrared remote control interface") );
-    set_capability( "interface", 0 );
-    set_callbacks( Open, Close );
-vlc_module_end();
-
-/*****************************************************************************
- * Open: initialize interface
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
-    intf_thread_t *p_intf = (intf_thread_t *)p_this;
-    int i_fd;
-
-    /* Allocate instance and initialize some members */
-    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
-    if( p_intf->p_sys == NULL )
-    {
-        msg_Err( p_intf, "out of memory" );
-        return 1;
-    }
-
-    p_intf->pf_run = Run;
-
-    i_fd = lirc_init( "vlc", 1 );
-    if( i_fd == -1 )
-    {
-        msg_Err( p_intf, "lirc_init failed" );
-        free( p_intf->p_sys );
-        return 1;
-    }
-
-    /* We want polling */
-    fcntl( i_fd, F_SETFL, fcntl( i_fd, F_GETFL ) | O_NONBLOCK );
-
-    if( lirc_readconfig( NULL, &p_intf->p_sys->config, NULL ) != 0 )
-    {
-        msg_Err( p_intf, "lirc_readconfig failed" );
-        lirc_deinit();
-        free( p_intf->p_sys );
-        return 1;
-    }
-
-    p_intf->p_sys->p_input = NULL;
-
-    return 0;
-}
-
-/*****************************************************************************
- * Close: destroy interface
- *****************************************************************************/
-static void Close( vlc_object_t *p_this )
-{
-    intf_thread_t *p_intf = (intf_thread_t *)p_this;
-
-    if( p_intf->p_sys->p_input )
-    {
-        vlc_object_release( p_intf->p_sys->p_input );
-    }
-    if( p_intf->p_sys->p_vout )
-    {
-        vlc_object_release( p_intf->p_sys->p_vout );
-    }
-    /* Destroy structure */
-    lirc_freeconfig( p_intf->p_sys->config );
-    lirc_deinit();
-    free( p_intf->p_sys );
-}
-
-/*****************************************************************************
- * Run: main loop
- *****************************************************************************/
-static void Run( intf_thread_t *p_intf )
-{
-    char *code, *c;
-    playlist_t *p_playlist;
-    input_thread_t *p_input;
-    vout_thread_t *p_vout = NULL;
-
-    while( !p_intf->b_die )
-    {
-        /* Sleep a bit */
-        msleep( INTF_IDLE_SLEEP );
-
-        /* Update the input */
-        if( p_intf->p_sys->p_input == NULL )
-        {
-            p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
-                                                              FIND_ANYWHERE );
-        }
-        else if( p_intf->p_sys->p_input->b_dead )
-        {
-            vlc_object_release( p_intf->p_sys->p_input );
-            p_intf->p_sys->p_input = NULL;
-        }
-        p_input = p_intf->p_sys->p_input;
-
-        /* Update the vout */
-        if( p_vout == NULL )
-        {
-            p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
-                                      FIND_ANYWHERE );
-            p_intf->p_sys->p_vout = p_vout;
-        }
-        else if( p_vout->b_die )
-        {
-            vlc_object_release( p_vout );
-            p_vout = NULL;
-            p_intf->p_sys->p_vout = NULL;
-        }
-
-        /* We poll the lircsocket */
-        if( lirc_nextcode(&code) != 0 )
-        {
-            break;
-        }
-
-        if( code == NULL )
-        {
-            continue;
-        }
-
-        while( !p_intf->b_die
-                && lirc_code2char( p_intf->p_sys->config, code, &c ) == 0
-                && c != NULL )
-        {
-
-            if( !strcmp( c, "QUIT" ) )
-            {
-                p_intf->p_vlc->b_die = VLC_TRUE;
-                vout_OSDMessage( p_intf, _("Quit" ) );
-                continue;
-            }
-            else if( !strcmp( c, "VOL_UP" ) )
-            {
-                audio_volume_t i_newvol;
-                aout_VolumeUp( p_intf, 1, &i_newvol );
-                vout_OSDMessage( p_intf, _("Vol %%%d"), i_newvol*100/AOUT_VOLUME_MAX );
-            }
-            else if( !strcmp( c, "VOL_DOWN" ) )
-            {
-                audio_volume_t i_newvol;
-                aout_VolumeDown( p_intf, 1, &i_newvol );
-                vout_OSDMessage( p_intf, _("Vol %%%d"), i_newvol*100/AOUT_VOLUME_MAX );
-            }
-            else if( !strcmp( c, "MUTE" ) )
-            {
-                audio_volume_t i_newvol = -1;
-                aout_VolumeMute( p_intf, &i_newvol );
-                if( i_newvol == 0 )
-                {
-                    vout_OSDMessage( p_intf, _( "Mute" ) );
-                }
-                else
-                {
-                    vout_OSDMessage( p_intf, _("Vol %d%%"), i_newvol*100/AOUT_VOLUME_MAX );
-                }
-            }
-            if( p_vout )
-            {
-                if( !strcmp( c, "FULLSCREEN" ) )
-                {
-                    p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
-                    continue;
-                }
-                if( !strcmp( c, "ACTIVATE" ) )
-                {
-                    vlc_value_t val;
-                    val.psz_string = "ENTER";
-                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
-                    {
-                        msg_Warn( p_intf, "key-press failed" );
-                    }
-                    continue;
-                }
-
-                if( !strcmp( c, "LEFT" ) )
-                {
-                    vlc_value_t val;
-                    val.psz_string = "LEFT";
-                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
-                    {
-                        msg_Warn( p_intf, "key-press failed" );
-                    }
-                    continue;
-                }
-
-                if( !strcmp( c, "RIGHT" ) )
-                {
-                    vlc_value_t val;
-                    val.psz_string = "RIGHT";
-                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
-                    {
-                        msg_Warn( p_intf, "key-press failed" );
-                    }
-                    continue;
-                }
-
-                if( !strcmp( c, "UP" ) )
-                {
-                    vlc_value_t val;
-                    val.psz_string = "UP";
-                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
-                    {
-                        msg_Warn( p_intf, "key-press failed" );
-                    }
-                    continue;
-                }
-
-                if( !strcmp( c, "DOWN" ) )
-                {
-                    vlc_value_t val;
-                    val.psz_string = "DOWN";
-                    if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
-                    {
-                        msg_Warn( p_intf, "key-press failed" );
-                    }
-                    continue;
-                }
-            }
-
-            if( !strcmp( c, "PLAY" ) )
-            {
-                p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                                      FIND_ANYWHERE );
-                if( p_playlist )
-                {
-                    vlc_mutex_lock( &p_playlist->object_lock );
-                    if( p_playlist->i_size )
-                    {
-                        vlc_mutex_unlock( &p_playlist->object_lock );
-                        playlist_Play( p_playlist );
-                        vlc_object_release( p_playlist );
-                    }
-                }
-                continue;
-            }
-
-            if( !strcmp( c, "PLAYPAUSE" ) )
-            {
-                vlc_value_t val;
-                val.i_int = PLAYING_S;
-                if( p_input )
-                {
-                    var_Get( p_input, "state", &val );
-                }
-                if( p_input && val.i_int != PAUSE_S )
-                {
-                    vout_OSDMessage( VLC_OBJECT(p_intf), _( "Pause" ) );
-                    val.i_int = PAUSE_S;
-                    var_Set( p_input, "state", val );
-                }
-                else
-                {
-                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                                  FIND_ANYWHERE );
-                    if( p_playlist )
-                    {
-                        vlc_mutex_lock( &p_playlist->object_lock );
-                        if( p_playlist->i_size )
-                        {
-                            vlc_mutex_unlock( &p_playlist->object_lock );
-                            vout_OSDMessage( p_intf, _( "Play" ) );
-                            playlist_Play( p_playlist );
-                            vlc_object_release( p_playlist );
-                        }
-                    }
-                }
-                continue;
-            }
-
-            else if( p_input )
-            {
-                if( !strcmp( c, "AUDIO_TRACK" ) )
-                {
-                    vlc_value_t val,list,list2;
-                    int i_count, i;
-                    var_Get( p_input, "audio-es", &val );
-                    var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES, &list, &list2 );
-                    i_count = list.p_list->i_count;
-                    for( i = 0; i < i_count; i++ )
-                    {
-                        if( val.i_int == list.p_list->p_values[i].i_int )
-                        {
-                            break;
-                        }
-                    }
-                    /* value of audio-es was not in choices list */
-                    if( i == i_count )
-                    {
-                        msg_Warn( p_input, "invalid current audio track, selecting 0" );
-                        var_Set( p_input, "audio-es", list.p_list->p_values[0] );
-                        i = 0;
-                    }
-                    else if( i == i_count - 1 )
-                    {
-                        var_Set( p_input, "audio-es", list.p_list->p_values[0] );
-                        i = 0;
-                    }
-                    else
-                    {
-                        var_Set( p_input, "audio-es", list.p_list->p_values[i+1] );
-                        i = i + 1;
-                    }
-                    vout_OSDMessage( VLC_OBJECT(p_input), _("Audio track: %s"), list2.p_list->p_values[i].psz_string );
-                }
-                else if( !strcmp( c, "SUBTITLE_TRACK" ) )
-                {
-                    vlc_value_t val,list,list2;
-                    int i_count, i;
-                    var_Get( p_input, "spu-es", &val );
-                    var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES, &list, &list2 );
-                    i_count = list.p_list->i_count;
-                    for( i = 0; i < i_count; i++ )
-                    {
-                        if( val.i_int == list.p_list->p_values[i].i_int )
-                        {
-                            break;
-                        }
-                    }
-                    /* value of audio-es was not in choices list */
-                    if( i == i_count )
-                    {
-                        msg_Warn( p_input, "invalid current subtitle track, selecting 0" );
-                        var_Set( p_input, "spu-es", list.p_list->p_values[0] );
-                        i = 0;
-                    }
-                    else if( i == i_count - 1 )
-                    {
-                        var_Set( p_input, "spu-es", list.p_list->p_values[0] );
-                        i = 0;
-                    }
-                    else
-                    {
-                        var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
-                        i = i + 1;
-                    }
-                    vout_OSDMessage( VLC_OBJECT(p_input), _("Subtitle track: %s"), list2.p_list->p_values[i].psz_string );
-                }
-                else if( !strcmp( c, "PAUSE" ) )
-                {
-                    vlc_value_t val;
-                    vout_OSDMessage( p_intf, _( "Pause" ) );
-                    val.i_int = PAUSE_S;
-                    var_Set( p_input, "state", val );
-                }
-                else if( !strcmp( c, "NEXT" ) )
-                {
-                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                                          FIND_ANYWHERE );
-                    if( p_playlist )
-                    {
-                        playlist_Next( p_playlist );
-                        vlc_object_release( p_playlist );
-                    }
-                }
-                else if( !strcmp( c, "PREV" ) )
-                {
-                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                                          FIND_ANYWHERE );
-                    if( p_playlist )
-                    {
-                        playlist_Prev( p_playlist );
-                        vlc_object_release( p_playlist );
-                    }
-                }
-                else if( !strcmp( c, "STOP" ) )
-                {
-                    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                                          FIND_ANYWHERE );
-                    if( p_playlist )
-                    {
-                        playlist_Stop( p_playlist );
-                        vlc_object_release( p_playlist );
-                    }
-                }
-                else if( !strcmp( c, "FAST" ) )
-                {
-                    vlc_value_t val; val.b_bool = VLC_TRUE;
-                    var_Set( p_input, "rate-faster", val );
-                }
-                else if( !strcmp( c, "SLOW" ) )
-                {
-                    vlc_value_t val; val.b_bool = VLC_TRUE;
-                    var_Set( p_input, "rate-slower", val );
-                }
-/* beginning of modifications by stephane Thu Jun 19 15:29:49 CEST 2003 */
-                else if ( !strcmp(c, "CHAPTER_N" ) ||
-                          !strcmp( c, "CHAPTER_P" ) )
-                {
-                    unsigned int i_chapter = 0;
-
-                    if( !strcmp( c, "CHAPTER_N" ) )
-                    {
-                        vlc_mutex_lock( &p_input->stream.stream_lock );
-                        i_chapter = p_input->stream.p_selected_area->i_part + 1;
-                        vlc_mutex_unlock( &p_input->stream.stream_lock );
-                    }
-                    else if( !strcmp( c, "CHAPTER_P" ) )
-                    {
-                        vlc_mutex_lock( &p_input->stream.stream_lock );
-                        i_chapter = p_input->stream.p_selected_area->i_part - 1;
-                        vlc_mutex_unlock( &p_input->stream.stream_lock );
-                    }
-
-                    vlc_mutex_lock( &p_input->stream.stream_lock );
-                    if( ( i_chapter > 0 ) && ( i_chapter <
-                                               p_input->stream.p_selected_area->i_part_nb ) )
-                    {
-                        input_area_t *p_area = p_input->stream.p_selected_area;
-                        p_input->stream.p_selected_area->i_part = i_chapter;
-                        vlc_mutex_unlock( &p_input->stream.stream_lock );
-                        input_ChangeArea( p_input, p_area );
-                        input_SetStatus( p_input, INPUT_STATUS_PLAY );
-                        vlc_mutex_lock( &p_input->stream.stream_lock );
-                    }
-                    vlc_mutex_unlock( &p_input->stream.stream_lock );
-                }
-/* end of modification by stephane Thu Jun 19 15:29:49 CEST 2003 */
-            }
-        }
-
-        free( code );
-    }
-}
diff --git a/modules/control/rc.c b/modules/control/rc.c
new file mode 100644 (file)
index 0000000..884b32e
--- /dev/null
@@ -0,0 +1,847 @@
+/*****************************************************************************
+ * rc.c : remote control stdin/stdout module for vlc
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id$
+ *
+ * Author: Peter Surda <shurdeek@panorama.sth.ac.at>
+ *
+ * This program 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 program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <vlc/aout.h>
+#include <vlc/vout.h>
+
+#ifdef HAVE_UNISTD_H
+#    include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#    include <sys/time.h>
+#endif
+#include <sys/types.h>
+
+#include "vlc_error.h"
+
+#define MAX_LINE_LENGTH 256
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  Activate     ( vlc_object_t * );
+static void Run          ( intf_thread_t *p_intf );
+
+static int  Input        ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+static int  Playlist     ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+static int  Quit         ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+static int  Intf         ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+static int  Volume       ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+static int  VolumeMove   ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+static int  AudioConfig  ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+#define POS_TEXT N_("Show stream position")
+#define POS_LONGTEXT N_("Show the current position in seconds within the stream from time to time.")
+
+#define TTY_TEXT N_("Fake TTY")
+#define TTY_LONGTEXT N_("Force the rc module to use stdin as if it was a TTY.")
+
+vlc_module_begin();
+    set_description( _("Remote control interface") );
+    add_bool( "rc-show-pos", 0, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
+#ifdef HAVE_ISATTY
+    add_bool( "fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT, VLC_TRUE );
+#endif
+    set_capability( "interface", 20 );
+    set_callbacks( Activate, NULL );
+vlc_module_end();
+
+/*****************************************************************************
+ * Activate: initialize and create stuff
+ *****************************************************************************/
+static int Activate( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t*)p_this;
+
+#if defined(HAVE_ISATTY) && !defined(WIN32)
+    /* Check that stdin is a TTY */
+    if( !config_GetInt( p_intf, "fake-tty" ) && !isatty( 0 ) )
+    {
+        msg_Warn( p_intf, "fd 0 is not a TTY" );
+        return VLC_EGENERIC;
+    }
+#endif
+
+    /* Non-buffered stdout */
+    setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
+
+    p_intf->pf_run = Run;
+
+    CONSOLE_INTRO_MSG;
+
+    printf( "Remote control interface initialized, `h' for help\n" );
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Run: rc thread
+ *****************************************************************************
+ * This part of the interface is in a separate thread so that we can call
+ * exec() from within it without annoying the rest of the program.
+ *****************************************************************************/
+static void Run( intf_thread_t *p_intf )
+{
+    input_thread_t * p_input;
+    playlist_t *     p_playlist;
+
+    char       p_buffer[ MAX_LINE_LENGTH + 1 ];
+    vlc_bool_t b_showpos = config_GetInt( p_intf, "rc-show-pos" );
+    input_info_category_t * p_category;
+    input_info_t * p_info;
+
+    int        i_dummy;
+    off_t      i_oldpos = 0;
+    off_t      i_newpos;
+
+    double     f_ratio = 1.0;
+
+#ifdef WIN32
+    HANDLE hConsoleIn;
+    INPUT_RECORD input_record;
+    DWORD i_dummy2;
+#endif
+
+    p_input = NULL;
+    p_playlist = NULL;
+
+    /* Register commands that will be cleaned up upon object destruction */
+    var_Create( p_intf, "quit", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "quit", Quit, NULL );
+    var_Create( p_intf, "intf", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "intf", Intf, NULL );
+
+    var_Create( p_intf, "add", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "add", Playlist, NULL );
+    var_Create( p_intf, "playlist", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "playlist", Playlist, NULL );
+    var_Create( p_intf, "play", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "play", Playlist, NULL );
+    var_Create( p_intf, "stop", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "stop", Playlist, NULL );
+    var_Create( p_intf, "prev", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "prev", Playlist, NULL );
+    var_Create( p_intf, "next", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "next", Playlist, NULL );
+
+    var_Create( p_intf, "pause", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "pause", Input, NULL );
+    var_Create( p_intf, "seek", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "seek", Input, NULL );
+    var_Create( p_intf, "title", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "title", Input, NULL );
+    var_Create( p_intf, "title_n", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "title_n", Input, NULL );
+    var_Create( p_intf, "title_p", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "title_p", Input, NULL );
+    var_Create( p_intf, "chapter", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "chapter", Input, NULL );
+    var_Create( p_intf, "chapter_n", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "chapter_n", Input, NULL );
+    var_Create( p_intf, "chapter_p", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "chapter_p", Input, NULL );
+
+    var_Create( p_intf, "volume", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "volume", Volume, NULL );
+    var_Create( p_intf, "volup", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "volup", VolumeMove, NULL );
+    var_Create( p_intf, "voldown", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "voldown", VolumeMove, NULL );
+    var_Create( p_intf, "adev", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "adev", AudioConfig, NULL );
+    var_Create( p_intf, "achan", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+    var_AddCallback( p_intf, "achan", AudioConfig, NULL );
+
+#ifdef WIN32
+    /* Get the file descriptor of the console input */
+    hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
+    if( hConsoleIn == INVALID_HANDLE_VALUE )
+    {
+        msg_Err( p_intf, "Couldn't open STD_INPUT_HANDLE" );
+        p_intf->b_die = VLC_TRUE;
+    }
+#endif
+
+    while( !p_intf->b_die )
+    {
+        vlc_bool_t     b_complete = VLC_FALSE;
+
+#ifndef WIN32
+        fd_set         fds;
+        struct timeval tv;
+
+        /* Check stdin */
+        tv.tv_sec = 0;
+        tv.tv_usec = (long)INTF_IDLE_SLEEP;
+        FD_ZERO( &fds );
+        FD_SET( STDIN_FILENO, &fds );
+
+        i_dummy = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
+#else
+        /* On Win32, select() only works on socket descriptors */
+        i_dummy = ( WaitForSingleObject( hConsoleIn, INTF_IDLE_SLEEP/1000 )
+                    == WAIT_OBJECT_0 );
+#endif
+        if( i_dummy > 0 )
+        {
+            int i_size = 0;
+
+            while( !p_intf->b_die
+                    && i_size < MAX_LINE_LENGTH
+#ifndef WIN32
+                    && read( STDIN_FILENO, p_buffer + i_size, 1 ) > 0
+#else
+                    && ReadConsoleInput( hConsoleIn, &input_record, 1,
+                                         &i_dummy2 )
+#endif
+                   )
+            {
+#ifdef WIN32
+                if( input_record.EventType != KEY_EVENT ||
+                    !input_record.Event.KeyEvent.bKeyDown ||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_MENU ||
+                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_CAPITAL )
+                {
+                    /* nothing interesting */
+                    continue;
+                }
+
+                p_buffer[ i_size ] =
+                    input_record.Event.KeyEvent.uChar.AsciiChar;
+
+                /* Echo out the command */
+                putc( p_buffer[ i_size ], stdout );
+
+                /* Handle special keys */
+                if( p_buffer[ i_size ] == '\r' || p_buffer[ i_size ] == '\n' )
+                {
+                    putc( '\n', stdout );
+                    break;
+                }
+                switch( p_buffer[ i_size ] )
+                {
+                case '\b':
+                    if( i_size )
+                    {
+                        i_size -= 2;
+                        putc( ' ', stdout );
+                        putc( '\b', stdout );
+                    }
+                    break;
+                case '\r':
+                    i_size --;
+                    break;
+                }
+
+                i_size++;
+#else
+
+                if( p_buffer[ i_size ] == '\r' || p_buffer[ i_size ] == '\n' )
+                {
+                    break;
+                }
+
+                i_size++;
+#endif
+            }
+
+            if( i_size == MAX_LINE_LENGTH
+                 || p_buffer[ i_size ] == '\r'
+                 || p_buffer[ i_size ] == '\n' )
+            {
+                p_buffer[ i_size ] = 0;
+                b_complete = VLC_TRUE;
+            }
+        }
+
+        /* Manage the input part */
+        if( p_input == NULL )
+        {
+            if( p_playlist )
+            {
+                p_input = vlc_object_find( p_playlist, VLC_OBJECT_INPUT,
+                                                       FIND_CHILD );
+            }
+            else
+            {
+                p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
+                                                   FIND_ANYWHERE );
+                if( p_input )
+                {
+                    p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
+                                                           FIND_PARENT );
+                }
+            }
+        }
+        else if( p_input->b_dead )
+        {
+            vlc_object_release( p_input );
+            p_input = NULL;
+        }
+
+        if( p_input && b_showpos )
+        {
+            /* Get position */
+            vlc_mutex_lock( &p_input->stream.stream_lock );
+            if( !p_input->b_die && p_input->stream.i_mux_rate )
+            {
+#define A p_input->stream.p_selected_area
+                f_ratio = 1.0 / ( 50 * p_input->stream.i_mux_rate );
+                i_newpos = A->i_tell * f_ratio;
+
+                if( i_oldpos != i_newpos )
+                {
+                    i_oldpos = i_newpos;
+                    printf( "pos: %li s / %li s\n", (long int)i_newpos,
+                            (long int)(f_ratio * A->i_size) );
+                }
+#undef S
+            }
+            vlc_mutex_unlock( &p_input->stream.stream_lock );
+        }
+
+        /* Is there something to do? */
+        if( b_complete )
+        {
+            char *psz_cmd, *psz_arg;
+
+            /* Skip heading spaces */
+            psz_cmd = p_buffer;
+            while( *psz_cmd == ' ' )
+            {
+                psz_cmd++;
+            }
+
+            /* Split psz_cmd at the first space and make sure that
+             * psz_arg is valid */
+            psz_arg = strchr( psz_cmd, ' ' );
+            if( psz_arg )
+            {
+                *psz_arg++ = 0;
+                while( *psz_arg == ' ' )
+                {
+                    psz_arg++;
+                }
+            }
+            else
+            {
+                psz_arg = "";
+            }
+
+            /* If the user typed a registered local command, try it */
+            if( var_Type( p_intf, psz_cmd ) & VLC_VAR_ISCOMMAND )
+            {
+                vlc_value_t val;
+                int i_ret;
+
+                val.psz_string = psz_arg;
+                i_ret = var_Set( p_intf, psz_cmd, val );
+                printf( "%s: returned %i (%s)\n",
+                        psz_cmd, i_ret, vlc_error( i_ret ) );
+            }
+            /* Or maybe it's a global command */
+            else if( var_Type( p_intf->p_libvlc, psz_cmd ) & VLC_VAR_ISCOMMAND )
+            {
+                vlc_value_t val;
+                int i_ret;
+
+                val.psz_string = psz_arg;
+                /* FIXME: it's a global command, but we should pass the
+                 * local object as an argument, not p_intf->p_libvlc. */
+                i_ret = var_Set( p_intf->p_libvlc, psz_cmd, val );
+                printf( "%s: returned %i (%s)\n",
+                        psz_cmd, i_ret, vlc_error( i_ret ) );
+            }
+            else if( !strcmp( psz_cmd, "info" ) )
+            {
+                if ( p_input )
+                {
+                    vlc_mutex_lock( &p_input->stream.stream_lock );
+                    p_category = p_input->stream.p_info;
+                    while ( p_category )
+                    {
+                        printf( "+----[ %s ]\n", p_category->psz_name );
+                        printf( "| \n" );
+                        p_info = p_category->p_info;
+                        while ( p_info )
+                        {
+                            printf( "| %s: %s\n", p_info->psz_name,
+                                    p_info->psz_value );
+                            p_info = p_info->p_next;
+                        }
+                        p_category = p_category->p_next;
+                        printf( "| \n" );
+                    }
+                    printf( "+----[ end of stream info ]\n" );
+                    vlc_mutex_unlock( &p_input->stream.stream_lock );
+                }
+                else
+                {
+                    printf( "no input\n" );
+                }
+            }
+            else switch( psz_cmd[0] )
+            {
+            case 'f':
+            case 'F':
+                if( p_input )
+                {
+                    vout_thread_t *p_vout;
+                    p_vout = vlc_object_find( p_input,
+                                              VLC_OBJECT_VOUT, FIND_CHILD );
+
+                    if( p_vout )
+                    {
+                        p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+                        vlc_object_release( p_vout );
+                    }
+                }
+                break;
+
+            case 's':
+            case 'S':
+                ;
+                break;
+
+            case '?':
+            case 'h':
+            case 'H':
+                printf("+----[ Remote control commands ]\n");
+                printf("| \n");
+                printf("| add XYZ  . . . . . . . . . . add XYZ to playlist\n");
+                printf("| playlist . . .  show items currently in playlist\n");
+                printf("| play . . . . . . . . . . . . . . . . play stream\n");
+                printf("| stop . . . . . . . . . . . . . . . . stop stream\n");
+                printf("| next . . . . . . . . . . . .  next playlist item\n");
+                printf("| prev . . . . . . . . . .  previous playlist item\n");
+                printf("| title [X]  . . . . set/get title in current item\n");
+                printf("| title_n  . . . . . .  next title in current item\n");
+                printf("| title_p  . . . .  previous title in current item\n");
+                printf("| chapter [X]  . . set/get chapter in current item\n");
+                printf("| chapter_n  . . . .  next chapter in current item\n");
+                printf("| chapter_p  . .  previous chapter in current item\n");
+                printf("| \n");
+                printf("| seek X . seek in seconds, for instance `seek 12'\n");
+                printf("| pause  . . . . . . . . . . . . . .  toggle pause\n");
+                printf("| f  . . . . . . . . . . . . . . toggle fullscreen\n");
+                printf("| info . . .  information about the current stream\n");
+                printf("| \n");
+                printf("| volume [X] . . . . . . . .  set/get audio volume\n");
+                printf("| volup [X]  . . . . .  raise audio volume X steps\n");
+                printf("| voldown [X]  . . . .  lower audio volume X steps\n");
+                printf("| adev [X] . . . . . . . . .  set/get audio device\n");
+                printf("| achan [X]. . . . . . . .  set/get audio channels\n");
+                printf("| \n");
+                printf("| help . . . . . . . . . . . . . this help message\n");
+                printf("| quit . . . . . . . . . . . . . . . . .  quit vlc\n");
+                printf("| \n");
+                printf("+----[ end of help ]\n");
+                break;
+            case '\0':
+                /* Ignore empty lines */
+                break;
+            default:
+                printf( "unknown command `%s', type `help' for help\n", psz_cmd );
+                break;
+            }
+        }
+    }
+
+    if( p_input )
+    {
+        vlc_object_release( p_input );
+        p_input = NULL;
+    }
+
+    if( p_playlist )
+    {
+        vlc_object_release( p_playlist );
+        p_playlist = NULL;
+    }
+}
+
+static int Input( vlc_object_t *p_this, char const *psz_cmd,
+                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    input_thread_t * p_input;
+    vlc_value_t     val;
+
+    p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+
+    if( !p_input )
+    {
+        return VLC_ENOOBJ;
+    }
+
+    /* Parse commands that only require an input */
+    if( !strcmp( psz_cmd, "pause" ) )
+    {
+        val.i_int = PAUSE_S;
+
+        var_Set( p_input, "state", val );
+        vlc_object_release( p_input );
+        return VLC_SUCCESS;
+    }
+    else if( !strcmp( psz_cmd, "seek" ) )
+    {
+        if( strlen( newval.psz_string ) > 0 &&
+            newval.psz_string[strlen( newval.psz_string ) - 1] == '%' )
+        {
+            val.f_float = (float)atoi( newval.psz_string ) / 100.0;
+            var_Set( p_input, "position", val );
+        }
+        else
+        {
+            val.i_time = ((int64_t)atoi( newval.psz_string )) * 1000000;
+            var_Set( p_input, "time", val );
+        }
+        vlc_object_release( p_input );
+        return VLC_SUCCESS;
+    }
+    else if( !strcmp( psz_cmd, "chapter" ) ||
+             !strcmp( psz_cmd, "chapter_n" ) ||
+             !strcmp( psz_cmd, "chapter_p" ) )
+    {
+        if( !strcmp( psz_cmd, "chapter" ) )
+        {
+            if ( *newval.psz_string )
+            {
+                /* Set. */
+                val.i_int = atoi( newval.psz_string );
+                var_Set( p_input, "chapter", val );
+            }
+            else
+            {
+                vlc_value_t val_list;
+
+                /* Get. */
+                var_Get( p_input, "chapter", &val );
+                var_Change( p_input, "chapter", VLC_VAR_GETCHOICES, &val_list, NULL );
+                printf( "Currently playing chapter %d/%d\n", val.i_int, val_list.p_list->i_count );
+                var_Change( p_this, "chapter", VLC_VAR_FREELIST, &val_list, NULL );
+            }
+        }
+        else if( !strcmp( psz_cmd, "chapter_n" ) )
+        {
+            val.b_bool = VLC_TRUE;
+            var_Set( p_input, "next-chapter", val );
+        }
+        else if( !strcmp( psz_cmd, "chapter_p" ) )
+        {
+            val.b_bool = VLC_TRUE;
+            var_Set( p_input, "prev-chapter", val );
+        }
+
+        vlc_object_release( p_input );
+        return VLC_SUCCESS;
+    }
+    else if( !strcmp( psz_cmd, "title" ) ||
+             !strcmp( psz_cmd, "title_n" ) ||
+             !strcmp( psz_cmd, "title_p" ) )
+    {
+        if( !strcmp( psz_cmd, "title" ) )
+        {
+            if ( *newval.psz_string )
+            {
+                /* Set. */
+                val.i_int = atoi( newval.psz_string );
+                var_Set( p_input, "title", val );
+            }
+            else
+            {
+                vlc_value_t val_list;
+
+                /* Get. */
+                var_Get( p_input, "title", &val );
+                var_Change( p_input, "title", VLC_VAR_GETCHOICES, &val_list, NULL );
+                printf( "Currently playing title %d/%d\n", val.i_int, val_list.p_list->i_count );
+                var_Change( p_this, "title", VLC_VAR_FREELIST, &val_list, NULL );
+            }
+        }
+        else if( !strcmp( psz_cmd, "title_n" ) )
+        {
+            val.b_bool = VLC_TRUE;
+            var_Set( p_input, "next-title", val );
+        }
+        else if( !strcmp( psz_cmd, "title_p" ) )
+        {
+            val.b_bool = VLC_TRUE;
+            var_Set( p_input, "prev-title", val );
+        }
+
+        vlc_object_release( p_input );
+        return VLC_SUCCESS;
+    }
+
+    /* Never reached. */
+    return VLC_EGENERIC;
+}
+
+static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
+                     vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    playlist_t *     p_playlist;
+
+    p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
+                                           FIND_ANYWHERE );
+    if( !p_playlist )
+    {
+        return VLC_ENOOBJ;
+    }
+
+    /* Parse commands that require a playlist */
+    if( !strcmp( psz_cmd, "prev" ) )
+    {
+        playlist_Prev( p_playlist );
+    }
+    else if( !strcmp( psz_cmd, "next" ) )
+    {
+        playlist_Next( p_playlist );
+    }
+    else if( !strcmp( psz_cmd, "play" ) )
+    {
+        playlist_Play( p_playlist );
+    }
+    else if( !strcmp( psz_cmd, "stop" ) )
+    {
+        playlist_Stop( p_playlist );
+    }
+    else if( !strcmp( psz_cmd, "add" ) )
+    {
+        printf( "trying to add %s to playlist\n", newval.psz_string );
+        playlist_Add( p_playlist, newval.psz_string, newval.psz_string,
+                      PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
+    }
+    else if( !strcmp( psz_cmd, "playlist" ) )
+    {
+        int i;
+        for ( i = 0; i < p_playlist->i_size; i++ )
+        {
+            printf( "|%s%s   %s|\n", i == p_playlist->i_index?"*":" ",
+                    p_playlist->pp_items[i]->psz_name,
+                    p_playlist->pp_items[i]->psz_uri );
+        }
+        if ( i == 0 )
+        {
+            printf( "| no entries\n" );
+        }
+    }
+    /*
+     * sanity check
+     */
+    else
+    {
+        printf( "unknown command!\n" );
+    }
+
+    vlc_object_release( p_playlist );
+    return VLC_SUCCESS;
+}
+
+static int Quit( vlc_object_t *p_this, char const *psz_cmd,
+                 vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    p_this->p_vlc->b_die = VLC_TRUE;
+    return VLC_SUCCESS;
+}
+
+static int Intf( vlc_object_t *p_this, char const *psz_cmd,
+                 vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    intf_thread_t *p_newintf;
+
+    p_newintf = intf_Create( p_this->p_vlc, newval.psz_string );
+
+    if( p_newintf )
+    {
+        p_newintf->b_block = VLC_FALSE;
+        if( intf_RunThread( p_newintf ) )
+        {
+            vlc_object_detach( p_newintf );
+            intf_Destroy( p_newintf );
+        }
+    }
+
+    return VLC_SUCCESS;
+}
+
+static int Volume( vlc_object_t *p_this, char const *psz_cmd,
+                   vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    int i_error;
+
+    if ( *newval.psz_string )
+    {
+        /* Set. */
+        audio_volume_t i_volume = atoi( newval.psz_string );
+        if ( i_volume > AOUT_VOLUME_MAX )
+        {
+            printf( "Volume must be in the range %d-%d\n", AOUT_VOLUME_MIN,
+                    AOUT_VOLUME_MAX );
+            i_error = VLC_EBADVAR;
+        }
+        else i_error = aout_VolumeSet( p_this, i_volume );
+    }
+    else
+    {
+        /* Get. */
+        audio_volume_t i_volume;
+        if ( aout_VolumeGet( p_this, &i_volume ) < 0 )
+        {
+            i_error = VLC_EGENERIC;
+        }
+        else
+        {
+            printf( "Volume is %d\n", i_volume );
+            i_error = VLC_SUCCESS;
+        }
+    }
+
+    return i_error;
+}
+
+static int VolumeMove( vlc_object_t *p_this, char const *psz_cmd,
+                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    audio_volume_t i_volume;
+    int i_nb_steps = atoi(newval.psz_string);
+    int i_error = VLC_SUCCESS;
+
+    if ( i_nb_steps <= 0 || i_nb_steps > (AOUT_VOLUME_MAX/AOUT_VOLUME_STEP) )
+    {
+        i_nb_steps = 1;
+    }
+
+    if ( !strcmp(psz_cmd, "volup") )
+    {
+        if ( aout_VolumeUp( p_this, i_nb_steps, &i_volume ) < 0 )
+            i_error = VLC_EGENERIC;
+    }
+    else
+    {
+        if ( aout_VolumeDown( p_this, i_nb_steps, &i_volume ) < 0 )
+            i_error = VLC_EGENERIC;
+    }
+
+    if ( !i_error ) printf( "Volume is %d\n", i_volume );
+    return i_error;
+}
+
+static int AudioConfig( vlc_object_t *p_this, char const *psz_cmd,
+                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    aout_instance_t * p_aout;
+    const char * psz_variable;
+    vlc_value_t val_name;
+    int i_error;
+
+    p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
+    if ( p_aout == NULL ) return VLC_ENOOBJ;
+
+    if ( !strcmp( psz_cmd, "adev" ) )
+    {
+        psz_variable = "audio-device";
+    }
+    else
+    {
+        psz_variable = "audio-channels";
+    }
+
+    /* Get the descriptive name of the variable */
+    var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_GETTEXT,
+                 &val_name, NULL );
+    if( !val_name.psz_string ) val_name.psz_string = strdup(psz_variable);
+
+    if ( !*newval.psz_string )
+    {
+        /* Retrieve all registered ***. */
+        vlc_value_t val, text;
+        int i, i_value;
+
+        if ( var_Get( (vlc_object_t *)p_aout, psz_variable, &val ) < 0 )
+        {
+            vlc_object_release( (vlc_object_t *)p_aout );
+            return VLC_EGENERIC;
+        }
+        i_value = val.i_int;
+
+        if ( var_Change( (vlc_object_t *)p_aout, psz_variable,
+                         VLC_VAR_GETLIST, &val, &text ) < 0 )
+        {
+            vlc_object_release( (vlc_object_t *)p_aout );
+            return VLC_EGENERIC;
+        }
+
+        printf( "+----[ %s ]\n", val_name.psz_string );
+        for ( i = 0; i < val.p_list->i_count; i++ )
+        {
+            if ( i_value == val.p_list->p_values[i].i_int )
+                printf( "| %i - %s *\n", val.p_list->p_values[i].i_int,
+                        text.p_list->p_values[i].psz_string );
+            else
+                printf( "| %i - %s\n", val.p_list->p_values[i].i_int,
+                        text.p_list->p_values[i].psz_string );
+        }
+        var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_FREELIST,
+                    &val, &text );
+        printf( "+----[ end of %s ]\n", val_name.psz_string );
+
+        if( val_name.psz_string ) free( val_name.psz_string );
+        i_error = VLC_SUCCESS;
+    }
+    else
+    {
+        vlc_value_t val;
+        val.i_int = atoi( newval.psz_string );
+
+        i_error = var_Set( (vlc_object_t *)p_aout, psz_variable, val );
+    }
+    vlc_object_release( (vlc_object_t *)p_aout );
+
+    return i_error;
+}
diff --git a/modules/control/rc/Modules.am b/modules/control/rc/Modules.am
deleted file mode 100644 (file)
index fdb5e52..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SOURCES_rc = rc.c
diff --git a/modules/control/rc/rc.c b/modules/control/rc/rc.c
deleted file mode 100644 (file)
index 1fd1e12..0000000
+++ /dev/null
@@ -1,847 +0,0 @@
-/*****************************************************************************
- * rc.c : remote control stdin/stdout module for vlc
- *****************************************************************************
- * Copyright (C) 2004 VideoLAN
- * $Id: rc.c,v 1.43 2004/01/25 20:40:59 gbazin Exp $
- *
- * Author: Peter Surda <shurdeek@panorama.sth.ac.at>
- *
- * This program 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 program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>
-
-#include <errno.h>                                                 /* ENOMEM */
-#include <stdio.h>
-#include <ctype.h>
-#include <signal.h>
-
-#include <vlc/vlc.h>
-#include <vlc/intf.h>
-#include <vlc/aout.h>
-#include <vlc/vout.h>
-
-#ifdef HAVE_UNISTD_H
-#    include <unistd.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#    include <sys/time.h>
-#endif
-#include <sys/types.h>
-
-#include "vlc_error.h"
-
-#define MAX_LINE_LENGTH 256
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int  Activate     ( vlc_object_t * );
-static void Run          ( intf_thread_t *p_intf );
-
-static int  Input        ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-static int  Playlist     ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-static int  Quit         ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-static int  Intf         ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-static int  Volume       ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-static int  VolumeMove   ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-static int  AudioConfig  ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-#define POS_TEXT N_("Show stream position")
-#define POS_LONGTEXT N_("Show the current position in seconds within the stream from time to time.")
-
-#define TTY_TEXT N_("Fake TTY")
-#define TTY_LONGTEXT N_("Force the rc module to use stdin as if it was a TTY.")
-
-vlc_module_begin();
-    set_description( _("Remote control interface") );
-    add_bool( "rc-show-pos", 0, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
-#ifdef HAVE_ISATTY
-    add_bool( "fake-tty", 0, NULL, TTY_TEXT, TTY_LONGTEXT, VLC_TRUE );
-#endif
-    set_capability( "interface", 20 );
-    set_callbacks( Activate, NULL );
-vlc_module_end();
-
-/*****************************************************************************
- * Activate: initialize and create stuff
- *****************************************************************************/
-static int Activate( vlc_object_t *p_this )
-{
-    intf_thread_t *p_intf = (intf_thread_t*)p_this;
-
-#if defined(HAVE_ISATTY) && !defined(WIN32)
-    /* Check that stdin is a TTY */
-    if( !config_GetInt( p_intf, "fake-tty" ) && !isatty( 0 ) )
-    {
-        msg_Warn( p_intf, "fd 0 is not a TTY" );
-        return VLC_EGENERIC;
-    }
-#endif
-
-    /* Non-buffered stdout */
-    setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
-
-    p_intf->pf_run = Run;
-
-    CONSOLE_INTRO_MSG;
-
-    printf( "Remote control interface initialized, `h' for help\n" );
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * Run: rc thread
- *****************************************************************************
- * This part of the interface is in a separate thread so that we can call
- * exec() from within it without annoying the rest of the program.
- *****************************************************************************/
-static void Run( intf_thread_t *p_intf )
-{
-    input_thread_t * p_input;
-    playlist_t *     p_playlist;
-
-    char       p_buffer[ MAX_LINE_LENGTH + 1 ];
-    vlc_bool_t b_showpos = config_GetInt( p_intf, "rc-show-pos" );
-    input_info_category_t * p_category;
-    input_info_t * p_info;
-
-    int        i_dummy;
-    off_t      i_oldpos = 0;
-    off_t      i_newpos;
-
-    double     f_ratio = 1.0;
-
-#ifdef WIN32
-    HANDLE hConsoleIn;
-    INPUT_RECORD input_record;
-    DWORD i_dummy2;
-#endif
-
-    p_input = NULL;
-    p_playlist = NULL;
-
-    /* Register commands that will be cleaned up upon object destruction */
-    var_Create( p_intf, "quit", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "quit", Quit, NULL );
-    var_Create( p_intf, "intf", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "intf", Intf, NULL );
-
-    var_Create( p_intf, "add", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "add", Playlist, NULL );
-    var_Create( p_intf, "playlist", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "playlist", Playlist, NULL );
-    var_Create( p_intf, "play", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "play", Playlist, NULL );
-    var_Create( p_intf, "stop", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "stop", Playlist, NULL );
-    var_Create( p_intf, "prev", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "prev", Playlist, NULL );
-    var_Create( p_intf, "next", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "next", Playlist, NULL );
-
-    var_Create( p_intf, "pause", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "pause", Input, NULL );
-    var_Create( p_intf, "seek", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "seek", Input, NULL );
-    var_Create( p_intf, "title", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "title", Input, NULL );
-    var_Create( p_intf, "title_n", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "title_n", Input, NULL );
-    var_Create( p_intf, "title_p", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "title_p", Input, NULL );
-    var_Create( p_intf, "chapter", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "chapter", Input, NULL );
-    var_Create( p_intf, "chapter_n", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "chapter_n", Input, NULL );
-    var_Create( p_intf, "chapter_p", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "chapter_p", Input, NULL );
-
-    var_Create( p_intf, "volume", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "volume", Volume, NULL );
-    var_Create( p_intf, "volup", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "volup", VolumeMove, NULL );
-    var_Create( p_intf, "voldown", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "voldown", VolumeMove, NULL );
-    var_Create( p_intf, "adev", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "adev", AudioConfig, NULL );
-    var_Create( p_intf, "achan", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
-    var_AddCallback( p_intf, "achan", AudioConfig, NULL );
-
-#ifdef WIN32
-    /* Get the file descriptor of the console input */
-    hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
-    if( hConsoleIn == INVALID_HANDLE_VALUE )
-    {
-        msg_Err( p_intf, "Couldn't open STD_INPUT_HANDLE" );
-        p_intf->b_die = VLC_TRUE;
-    }
-#endif
-
-    while( !p_intf->b_die )
-    {
-        vlc_bool_t     b_complete = VLC_FALSE;
-
-#ifndef WIN32
-        fd_set         fds;
-        struct timeval tv;
-
-        /* Check stdin */
-        tv.tv_sec = 0;
-        tv.tv_usec = (long)INTF_IDLE_SLEEP;
-        FD_ZERO( &fds );
-        FD_SET( STDIN_FILENO, &fds );
-
-        i_dummy = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
-#else
-        /* On Win32, select() only works on socket descriptors */
-        i_dummy = ( WaitForSingleObject( hConsoleIn, INTF_IDLE_SLEEP/1000 )
-                    == WAIT_OBJECT_0 );
-#endif
-        if( i_dummy > 0 )
-        {
-            int i_size = 0;
-
-            while( !p_intf->b_die
-                    && i_size < MAX_LINE_LENGTH
-#ifndef WIN32
-                    && read( STDIN_FILENO, p_buffer + i_size, 1 ) > 0
-#else
-                    && ReadConsoleInput( hConsoleIn, &input_record, 1,
-                                         &i_dummy2 )
-#endif
-                   )
-            {
-#ifdef WIN32
-                if( input_record.EventType != KEY_EVENT ||
-                    !input_record.Event.KeyEvent.bKeyDown ||
-                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||
-                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL||
-                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_MENU ||
-                    input_record.Event.KeyEvent.wVirtualKeyCode == VK_CAPITAL )
-                {
-                    /* nothing interesting */
-                    continue;
-                }
-
-                p_buffer[ i_size ] =
-                    input_record.Event.KeyEvent.uChar.AsciiChar;
-
-                /* Echo out the command */
-                putc( p_buffer[ i_size ], stdout );
-
-                /* Handle special keys */
-                if( p_buffer[ i_size ] == '\r' || p_buffer[ i_size ] == '\n' )
-                {
-                    putc( '\n', stdout );
-                    break;
-                }
-                switch( p_buffer[ i_size ] )
-                {
-                case '\b':
-                    if( i_size )
-                    {
-                        i_size -= 2;
-                        putc( ' ', stdout );
-                        putc( '\b', stdout );
-                    }
-                    break;
-                case '\r':
-                    i_size --;
-                    break;
-                }
-
-                i_size++;
-#else
-
-                if( p_buffer[ i_size ] == '\r' || p_buffer[ i_size ] == '\n' )
-                {
-                    break;
-                }
-
-                i_size++;
-#endif
-            }
-
-            if( i_size == MAX_LINE_LENGTH
-                 || p_buffer[ i_size ] == '\r'
-                 || p_buffer[ i_size ] == '\n' )
-            {
-                p_buffer[ i_size ] = 0;
-                b_complete = VLC_TRUE;
-            }
-        }
-
-        /* Manage the input part */
-        if( p_input == NULL )
-        {
-            if( p_playlist )
-            {
-                p_input = vlc_object_find( p_playlist, VLC_OBJECT_INPUT,
-                                                       FIND_CHILD );
-            }
-            else
-            {
-                p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
-                                                   FIND_ANYWHERE );
-                if( p_input )
-                {
-                    p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
-                                                           FIND_PARENT );
-                }
-            }
-        }
-        else if( p_input->b_dead )
-        {
-            vlc_object_release( p_input );
-            p_input = NULL;
-        }
-
-        if( p_input && b_showpos )
-        {
-            /* Get position */
-            vlc_mutex_lock( &p_input->stream.stream_lock );
-            if( !p_input->b_die && p_input->stream.i_mux_rate )
-            {
-#define A p_input->stream.p_selected_area
-                f_ratio = 1.0 / ( 50 * p_input->stream.i_mux_rate );
-                i_newpos = A->i_tell * f_ratio;
-
-                if( i_oldpos != i_newpos )
-                {
-                    i_oldpos = i_newpos;
-                    printf( "pos: %li s / %li s\n", (long int)i_newpos,
-                            (long int)(f_ratio * A->i_size) );
-                }
-#undef S
-            }
-            vlc_mutex_unlock( &p_input->stream.stream_lock );
-        }
-
-        /* Is there something to do? */
-        if( b_complete )
-        {
-            char *psz_cmd, *psz_arg;
-
-            /* Skip heading spaces */
-            psz_cmd = p_buffer;
-            while( *psz_cmd == ' ' )
-            {
-                psz_cmd++;
-            }
-
-            /* Split psz_cmd at the first space and make sure that
-             * psz_arg is valid */
-            psz_arg = strchr( psz_cmd, ' ' );
-            if( psz_arg )
-            {
-                *psz_arg++ = 0;
-                while( *psz_arg == ' ' )
-                {
-                    psz_arg++;
-                }
-            }
-            else
-            {
-                psz_arg = "";
-            }
-
-            /* If the user typed a registered local command, try it */
-            if( var_Type( p_intf, psz_cmd ) & VLC_VAR_ISCOMMAND )
-            {
-                vlc_value_t val;
-                int i_ret;
-
-                val.psz_string = psz_arg;
-                i_ret = var_Set( p_intf, psz_cmd, val );
-                printf( "%s: returned %i (%s)\n",
-                        psz_cmd, i_ret, vlc_error( i_ret ) );
-            }
-            /* Or maybe it's a global command */
-            else if( var_Type( p_intf->p_libvlc, psz_cmd ) & VLC_VAR_ISCOMMAND )
-            {
-                vlc_value_t val;
-                int i_ret;
-
-                val.psz_string = psz_arg;
-                /* FIXME: it's a global command, but we should pass the
-                 * local object as an argument, not p_intf->p_libvlc. */
-                i_ret = var_Set( p_intf->p_libvlc, psz_cmd, val );
-                printf( "%s: returned %i (%s)\n",
-                        psz_cmd, i_ret, vlc_error( i_ret ) );
-            }
-            else if( !strcmp( psz_cmd, "info" ) )
-            {
-                if ( p_input )
-                {
-                    vlc_mutex_lock( &p_input->stream.stream_lock );
-                    p_category = p_input->stream.p_info;
-                    while ( p_category )
-                    {
-                        printf( "+----[ %s ]\n", p_category->psz_name );
-                        printf( "| \n" );
-                        p_info = p_category->p_info;
-                        while ( p_info )
-                        {
-                            printf( "| %s: %s\n", p_info->psz_name,
-                                    p_info->psz_value );
-                            p_info = p_info->p_next;
-                        }
-                        p_category = p_category->p_next;
-                        printf( "| \n" );
-                    }
-                    printf( "+----[ end of stream info ]\n" );
-                    vlc_mutex_unlock( &p_input->stream.stream_lock );
-                }
-                else
-                {
-                    printf( "no input\n" );
-                }
-            }
-            else switch( psz_cmd[0] )
-            {
-            case 'f':
-            case 'F':
-                if( p_input )
-                {
-                    vout_thread_t *p_vout;
-                    p_vout = vlc_object_find( p_input,
-                                              VLC_OBJECT_VOUT, FIND_CHILD );
-
-                    if( p_vout )
-                    {
-                        p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
-                        vlc_object_release( p_vout );
-                    }
-                }
-                break;
-
-            case 's':
-            case 'S':
-                ;
-                break;
-
-            case '?':
-            case 'h':
-            case 'H':
-                printf("+----[ Remote control commands ]\n");
-                printf("| \n");
-                printf("| add XYZ  . . . . . . . . . . add XYZ to playlist\n");
-                printf("| playlist . . .  show items currently in playlist\n");
-                printf("| play . . . . . . . . . . . . . . . . play stream\n");
-                printf("| stop . . . . . . . . . . . . . . . . stop stream\n");
-                printf("| next . . . . . . . . . . . .  next playlist item\n");
-                printf("| prev . . . . . . . . . .  previous playlist item\n");
-                printf("| title [X]  . . . . set/get title in current item\n");
-                printf("| title_n  . . . . . .  next title in current item\n");
-                printf("| title_p  . . . .  previous title in current item\n");
-                printf("| chapter [X]  . . set/get chapter in current item\n");
-                printf("| chapter_n  . . . .  next chapter in current item\n");
-                printf("| chapter_p  . .  previous chapter in current item\n");
-                printf("| \n");
-                printf("| seek X . seek in seconds, for instance `seek 12'\n");
-                printf("| pause  . . . . . . . . . . . . . .  toggle pause\n");
-                printf("| f  . . . . . . . . . . . . . . toggle fullscreen\n");
-                printf("| info . . .  information about the current stream\n");
-                printf("| \n");
-                printf("| volume [X] . . . . . . . .  set/get audio volume\n");
-                printf("| volup [X]  . . . . .  raise audio volume X steps\n");
-                printf("| voldown [X]  . . . .  lower audio volume X steps\n");
-                printf("| adev [X] . . . . . . . . .  set/get audio device\n");
-                printf("| achan [X]. . . . . . . .  set/get audio channels\n");
-                printf("| \n");
-                printf("| help . . . . . . . . . . . . . this help message\n");
-                printf("| quit . . . . . . . . . . . . . . . . .  quit vlc\n");
-                printf("| \n");
-                printf("+----[ end of help ]\n");
-                break;
-            case '\0':
-                /* Ignore empty lines */
-                break;
-            default:
-                printf( "unknown command `%s', type `help' for help\n", psz_cmd );
-                break;
-            }
-        }
-    }
-
-    if( p_input )
-    {
-        vlc_object_release( p_input );
-        p_input = NULL;
-    }
-
-    if( p_playlist )
-    {
-        vlc_object_release( p_playlist );
-        p_playlist = NULL;
-    }
-}
-
-static int Input( vlc_object_t *p_this, char const *psz_cmd,
-                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    input_thread_t * p_input;
-    vlc_value_t     val;
-
-    p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
-
-    if( !p_input )
-    {
-        return VLC_ENOOBJ;
-    }
-
-    /* Parse commands that only require an input */
-    if( !strcmp( psz_cmd, "pause" ) )
-    {
-        val.i_int = PAUSE_S;
-
-        var_Set( p_input, "state", val );
-        vlc_object_release( p_input );
-        return VLC_SUCCESS;
-    }
-    else if( !strcmp( psz_cmd, "seek" ) )
-    {
-        if( strlen( newval.psz_string ) > 0 &&
-            newval.psz_string[strlen( newval.psz_string ) - 1] == '%' )
-        {
-            val.f_float = (float)atoi( newval.psz_string ) / 100.0;
-            var_Set( p_input, "position", val );
-        }
-        else
-        {
-            val.i_time = ((int64_t)atoi( newval.psz_string )) * 1000000;
-            var_Set( p_input, "time", val );
-        }
-        vlc_object_release( p_input );
-        return VLC_SUCCESS;
-    }
-    else if( !strcmp( psz_cmd, "chapter" ) ||
-             !strcmp( psz_cmd, "chapter_n" ) ||
-             !strcmp( psz_cmd, "chapter_p" ) )
-    {
-        if( !strcmp( psz_cmd, "chapter" ) )
-        {
-            if ( *newval.psz_string )
-            {
-                /* Set. */
-                val.i_int = atoi( newval.psz_string );
-                var_Set( p_input, "chapter", val );
-            }
-            else
-            {
-                vlc_value_t val_list;
-
-                /* Get. */
-                var_Get( p_input, "chapter", &val );
-                var_Change( p_input, "chapter", VLC_VAR_GETCHOICES, &val_list, NULL );
-                printf( "Currently playing chapter %d/%d\n", val.i_int, val_list.p_list->i_count );
-                var_Change( p_this, "chapter", VLC_VAR_FREELIST, &val_list, NULL );
-            }
-        }
-        else if( !strcmp( psz_cmd, "chapter_n" ) )
-        {
-            val.b_bool = VLC_TRUE;
-            var_Set( p_input, "next-chapter", val );
-        }
-        else if( !strcmp( psz_cmd, "chapter_p" ) )
-        {
-            val.b_bool = VLC_TRUE;
-            var_Set( p_input, "prev-chapter", val );
-        }
-
-        vlc_object_release( p_input );
-        return VLC_SUCCESS;
-    }
-    else if( !strcmp( psz_cmd, "title" ) ||
-             !strcmp( psz_cmd, "title_n" ) ||
-             !strcmp( psz_cmd, "title_p" ) )
-    {
-        if( !strcmp( psz_cmd, "title" ) )
-        {
-            if ( *newval.psz_string )
-            {
-                /* Set. */
-                val.i_int = atoi( newval.psz_string );
-                var_Set( p_input, "title", val );
-            }
-            else
-            {
-                vlc_value_t val_list;
-
-                /* Get. */
-                var_Get( p_input, "title", &val );
-                var_Change( p_input, "title", VLC_VAR_GETCHOICES, &val_list, NULL );
-                printf( "Currently playing title %d/%d\n", val.i_int, val_list.p_list->i_count );
-                var_Change( p_this, "title", VLC_VAR_FREELIST, &val_list, NULL );
-            }
-        }
-        else if( !strcmp( psz_cmd, "title_n" ) )
-        {
-            val.b_bool = VLC_TRUE;
-            var_Set( p_input, "next-title", val );
-        }
-        else if( !strcmp( psz_cmd, "title_p" ) )
-        {
-            val.b_bool = VLC_TRUE;
-            var_Set( p_input, "prev-title", val );
-        }
-
-        vlc_object_release( p_input );
-        return VLC_SUCCESS;
-    }
-
-    /* Never reached. */
-    return VLC_EGENERIC;
-}
-
-static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
-                     vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    playlist_t *     p_playlist;
-
-    p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
-                                           FIND_ANYWHERE );
-    if( !p_playlist )
-    {
-        return VLC_ENOOBJ;
-    }
-
-    /* Parse commands that require a playlist */
-    if( !strcmp( psz_cmd, "prev" ) )
-    {
-        playlist_Prev( p_playlist );
-    }
-    else if( !strcmp( psz_cmd, "next" ) )
-    {
-        playlist_Next( p_playlist );
-    }
-    else if( !strcmp( psz_cmd, "play" ) )
-    {
-        playlist_Play( p_playlist );
-    }
-    else if( !strcmp( psz_cmd, "stop" ) )
-    {
-        playlist_Stop( p_playlist );
-    }
-    else if( !strcmp( psz_cmd, "add" ) )
-    {
-        printf( "trying to add %s to playlist\n", newval.psz_string );
-        playlist_Add( p_playlist, newval.psz_string, newval.psz_string,
-                      PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
-    }
-    else if( !strcmp( psz_cmd, "playlist" ) )
-    {
-        int i;
-        for ( i = 0; i < p_playlist->i_size; i++ )
-        {
-            printf( "|%s%s   %s|\n", i == p_playlist->i_index?"*":" ",
-                    p_playlist->pp_items[i]->psz_name,
-                    p_playlist->pp_items[i]->psz_uri );
-        }
-        if ( i == 0 )
-        {
-            printf( "| no entries\n" );
-        }
-    }
-    /*
-     * sanity check
-     */
-    else
-    {
-        printf( "unknown command!\n" );
-    }
-
-    vlc_object_release( p_playlist );
-    return VLC_SUCCESS;
-}
-
-static int Quit( vlc_object_t *p_this, char const *psz_cmd,
-                 vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    p_this->p_vlc->b_die = VLC_TRUE;
-    return VLC_SUCCESS;
-}
-
-static int Intf( vlc_object_t *p_this, char const *psz_cmd,
-                 vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    intf_thread_t *p_newintf;
-
-    p_newintf = intf_Create( p_this->p_vlc, newval.psz_string );
-
-    if( p_newintf )
-    {
-        p_newintf->b_block = VLC_FALSE;
-        if( intf_RunThread( p_newintf ) )
-        {
-            vlc_object_detach( p_newintf );
-            intf_Destroy( p_newintf );
-        }
-    }
-
-    return VLC_SUCCESS;
-}
-
-static int Volume( vlc_object_t *p_this, char const *psz_cmd,
-                   vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    int i_error;
-
-    if ( *newval.psz_string )
-    {
-        /* Set. */
-        audio_volume_t i_volume = atoi( newval.psz_string );
-        if ( i_volume > AOUT_VOLUME_MAX )
-        {
-            printf( "Volume must be in the range %d-%d\n", AOUT_VOLUME_MIN,
-                    AOUT_VOLUME_MAX );
-            i_error = VLC_EBADVAR;
-        }
-        else i_error = aout_VolumeSet( p_this, i_volume );
-    }
-    else
-    {
-        /* Get. */
-        audio_volume_t i_volume;
-        if ( aout_VolumeGet( p_this, &i_volume ) < 0 )
-        {
-            i_error = VLC_EGENERIC;
-        }
-        else
-        {
-            printf( "Volume is %d\n", i_volume );
-            i_error = VLC_SUCCESS;
-        }
-    }
-
-    return i_error;
-}
-
-static int VolumeMove( vlc_object_t *p_this, char const *psz_cmd,
-                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    audio_volume_t i_volume;
-    int i_nb_steps = atoi(newval.psz_string);
-    int i_error = VLC_SUCCESS;
-
-    if ( i_nb_steps <= 0 || i_nb_steps > (AOUT_VOLUME_MAX/AOUT_VOLUME_STEP) )
-    {
-        i_nb_steps = 1;
-    }
-
-    if ( !strcmp(psz_cmd, "volup") )
-    {
-        if ( aout_VolumeUp( p_this, i_nb_steps, &i_volume ) < 0 )
-            i_error = VLC_EGENERIC;
-    }
-    else
-    {
-        if ( aout_VolumeDown( p_this, i_nb_steps, &i_volume ) < 0 )
-            i_error = VLC_EGENERIC;
-    }
-
-    if ( !i_error ) printf( "Volume is %d\n", i_volume );
-    return i_error;
-}
-
-static int AudioConfig( vlc_object_t *p_this, char const *psz_cmd,
-                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    aout_instance_t * p_aout;
-    const char * psz_variable;
-    vlc_value_t val_name;
-    int i_error;
-
-    p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
-    if ( p_aout == NULL ) return VLC_ENOOBJ;
-
-    if ( !strcmp( psz_cmd, "adev" ) )
-    {
-        psz_variable = "audio-device";
-    }
-    else
-    {
-        psz_variable = "audio-channels";
-    }
-
-    /* Get the descriptive name of the variable */
-    var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_GETTEXT,
-                 &val_name, NULL );
-    if( !val_name.psz_string ) val_name.psz_string = strdup(psz_variable);
-
-    if ( !*newval.psz_string )
-    {
-        /* Retrieve all registered ***. */
-        vlc_value_t val, text;
-        int i, i_value;
-
-        if ( var_Get( (vlc_object_t *)p_aout, psz_variable, &val ) < 0 )
-        {
-            vlc_object_release( (vlc_object_t *)p_aout );
-            return VLC_EGENERIC;
-        }
-        i_value = val.i_int;
-
-        if ( var_Change( (vlc_object_t *)p_aout, psz_variable,
-                         VLC_VAR_GETLIST, &val, &text ) < 0 )
-        {
-            vlc_object_release( (vlc_object_t *)p_aout );
-            return VLC_EGENERIC;
-        }
-
-        printf( "+----[ %s ]\n", val_name.psz_string );
-        for ( i = 0; i < val.p_list->i_count; i++ )
-        {
-            if ( i_value == val.p_list->p_values[i].i_int )
-                printf( "| %i - %s *\n", val.p_list->p_values[i].i_int,
-                        text.p_list->p_values[i].psz_string );
-            else
-                printf( "| %i - %s\n", val.p_list->p_values[i].i_int,
-                        text.p_list->p_values[i].psz_string );
-        }
-        var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_FREELIST,
-                    &val, &text );
-        printf( "+----[ end of %s ]\n", val_name.psz_string );
-
-        if( val_name.psz_string ) free( val_name.psz_string );
-        i_error = VLC_SUCCESS;
-    }
-    else
-    {
-        vlc_value_t val;
-        val.i_int = atoi( newval.psz_string );
-
-        i_error = var_Set( (vlc_object_t *)p_aout, psz_variable, val );
-    }
-    vlc_object_release( (vlc_object_t *)p_aout );
-
-    return i_error;
-}
index a33a4eb..1d8c7ea 100644 (file)
@@ -6,3 +6,4 @@ SOURCES_sap = sap.c
 SOURCES_screensaver = screensaver.c
 SOURCES_qte_main = qte_main.cpp
 SOURCES_freetype = freetype.c
+SOURCES_logger = logger.c
diff --git a/modules/misc/logger.c b/modules/misc/logger.c
new file mode 100644 (file)
index 0000000..f912996
--- /dev/null
@@ -0,0 +1,301 @@
+/*****************************************************************************
+ * logger.c : file logging plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ * $Id$
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * This program 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 program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdio.h>
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+
+#define MODE_TEXT 0
+#define MODE_HTML 1
+
+#define LOG_FILE "vlc-log.txt"
+#define LOG_STRING( msg, file ) fwrite( msg, strlen( msg ), 1, file );
+
+#define TEXT_HEADER "-- logger module started --\n"
+#define TEXT_FOOTER "-- logger module stopped --\n"
+
+#define HTML_HEADER \
+    "<html>\n" \
+    "  <head>\n" \
+    "    <title>vlc log</title>\n" \
+    "  </head>\n" \
+    "  <body bgcolor=\"#000000\" text=\"#aaaaaa\">\n" \
+    "    <pre>\n" \
+    "      <b>-- logger module started --</b>\n"
+#define HTML_FOOTER \
+    "      <b>-- logger module stopped --</b>\n" \
+    "    </pre>\n" \
+    "  </body>\n" \
+    "</html>\n"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of log interface
+ *****************************************************************************/
+struct intf_sys_t
+{
+    int i_mode;
+
+    FILE *    p_file; /* The log file */
+    msg_subscription_t *p_sub;
+};
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  Open    ( vlc_object_t * );                  
+static void Close   ( vlc_object_t * );
+static void Run     ( intf_thread_t * );
+
+static void FlushQueue        ( msg_subscription_t *, FILE *, int );
+static void TextPrint         ( const msg_item_t *, FILE * );
+static void HtmlPrint         ( const msg_item_t *, FILE * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+static char *mode_list[] = { "text", "html" };
+static char *mode_list_text[] = { N_("Text"), N_("Html") };
+
+#define LOGMODE_TEXT N_("Log format")
+#define LOGMODE_LONGTEXT N_("Specify the log format. Available choices are \"text\" (default) and \"html\".")
+
+vlc_module_begin();
+    set_description( _("File logging interface") );
+
+    add_file( "logfile", NULL, NULL, N_("Log filename"), N_("Specify the log filename."), VLC_FALSE );
+    add_string( "logmode", "text", NULL, LOGMODE_TEXT, LOGMODE_LONGTEXT,
+                VLC_FALSE );
+        change_string_list( mode_list, mode_list_text, 0 );
+
+    set_capability( "interface", 0 );
+    set_callbacks( Open, Close );
+vlc_module_end();
+
+/*****************************************************************************
+ * Open: initialize and create stuff
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{   
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+    char *psz_mode, *psz_file;
+
+    CONSOLE_INTRO_MSG;
+    msg_Info( p_intf, "Using the logger interface module..." );
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        msg_Err( p_intf, "out of memory" );
+        return -1;
+    }
+
+    psz_mode = config_GetPsz( p_intf, "logmode" );
+    if( psz_mode )
+    {
+        if( !strcmp( psz_mode, "text" ) )
+        {
+            p_intf->p_sys->i_mode = MODE_TEXT;
+        }
+        else if( !strcmp( psz_mode, "html" ) )
+        {
+            p_intf->p_sys->i_mode = MODE_HTML;
+        }
+        else
+        {
+            msg_Err( p_intf, "invalid log mode `%s', using `text'", psz_mode );
+            p_intf->p_sys->i_mode = MODE_TEXT;
+        }
+
+        free( psz_mode );
+    }
+    else
+    {
+        msg_Warn( p_intf, "no log mode specified, using `text'" );
+        p_intf->p_sys->i_mode = MODE_TEXT;
+    }
+
+    psz_file = config_GetPsz( p_intf, "logfile" );
+    if( !psz_file )
+    {
+        switch( p_intf->p_sys->i_mode )
+        {
+        case MODE_HTML:
+            psz_file = strdup( "vlc-log.html" );
+            break;
+        case MODE_TEXT:
+        default:
+            psz_file = strdup( "vlc-log.txt" );
+            break;
+        }
+
+        msg_Warn( p_intf, "no log filename provided, using `%s'", psz_file );
+    }
+
+    /* Open the log file and remove any buffering for the stream */
+    msg_Dbg( p_intf, "opening logfile `%s'", psz_file );
+    p_intf->p_sys->p_file = fopen( psz_file, "wt" );
+    if( p_intf->p_sys->p_file == NULL )
+    {
+        msg_Err( p_intf, "error opening logfile `%s'", psz_file );
+        free( p_intf->p_sys );
+        free( psz_file );
+        return -1;
+    }
+    setvbuf( p_intf->p_sys->p_file, NULL, _IONBF, 0 );
+    p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
+
+    free( psz_file );
+
+    switch( p_intf->p_sys->i_mode )
+    {
+    case MODE_HTML:
+        LOG_STRING( HTML_HEADER, p_intf->p_sys->p_file );
+        break;
+    case MODE_TEXT:
+    default:
+        LOG_STRING( TEXT_HEADER, p_intf->p_sys->p_file );
+        break;
+    }
+
+    p_intf->pf_run = Run;
+
+    return 0;
+}
+
+/*****************************************************************************
+ * Close: destroy interface stuff
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )
+{       
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+        
+    /* Flush the queue and unsubscribe from the message queue */
+    FlushQueue( p_intf->p_sys->p_sub, p_intf->p_sys->p_file,
+                p_intf->p_sys->i_mode );
+    msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
+
+    switch( p_intf->p_sys->i_mode )
+    {
+    case MODE_HTML:
+        LOG_STRING( HTML_FOOTER, p_intf->p_sys->p_file );
+        break;
+    case MODE_TEXT:
+    default:
+        LOG_STRING( TEXT_FOOTER, p_intf->p_sys->p_file );
+        break;
+    }
+
+    /* Close the log file */
+    fclose( p_intf->p_sys->p_file );
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+/*****************************************************************************
+ * Run: rc thread
+ *****************************************************************************
+ * This part of the interface is in a separate thread so that we can call
+ * exec() from within it without annoying the rest of the program.
+ *****************************************************************************/
+static void Run( intf_thread_t *p_intf )
+{
+    while( !p_intf->b_die )
+    {
+        FlushQueue( p_intf->p_sys->p_sub, p_intf->p_sys->p_file,
+                    p_intf->p_sys->i_mode );
+
+        msleep( INTF_IDLE_SLEEP );
+    }
+}
+
+/*****************************************************************************
+ * FlushQueue: flush the message queue into the log file
+ *****************************************************************************/
+static void FlushQueue( msg_subscription_t *p_sub, FILE *p_file, int i_mode )
+{
+    int i_start, i_stop;
+
+    vlc_mutex_lock( p_sub->p_lock );
+    i_stop = *p_sub->pi_stop;
+    vlc_mutex_unlock( p_sub->p_lock );
+
+    if( p_sub->i_start != i_stop )
+    {
+        /* Append all messages to log file */
+        for( i_start = p_sub->i_start;
+             i_start != i_stop;
+             i_start = (i_start+1) % VLC_MSG_QSIZE )
+        {
+            switch( i_mode )
+            {
+            case MODE_HTML:
+                HtmlPrint( &p_sub->p_msg[i_start], p_file );
+                break;
+            case MODE_TEXT:
+            default:
+                TextPrint( &p_sub->p_msg[i_start], p_file );
+                break;
+            }
+        }
+
+        vlc_mutex_lock( p_sub->p_lock );
+        p_sub->i_start = i_start;
+        vlc_mutex_unlock( p_sub->p_lock );
+    }
+}
+
+static const char *ppsz_type[4] = { ": ", " error: ",
+                                    " warning: ", " debug: " };
+
+static void TextPrint( const msg_item_t *p_msg, FILE *p_file )
+{
+    LOG_STRING( p_msg->psz_module, p_file );
+    LOG_STRING( ppsz_type[p_msg->i_type], p_file );
+    LOG_STRING( p_msg->psz_msg, p_file );
+    LOG_STRING( "\n", p_file );
+}
+
+static void HtmlPrint( const msg_item_t *p_msg, FILE *p_file )
+{
+    static const char *ppsz_color[4] = { "<font color=\"#ffffff\">",
+                                         "<font color=\"#ff6666\">",
+                                         "<font color=\"#ffff66\">",
+                                         "<font color=\"#aaaaaa\">" };
+
+    LOG_STRING( p_msg->psz_module, p_file );
+    LOG_STRING( ppsz_type[p_msg->i_type], p_file );
+    LOG_STRING( ppsz_color[p_msg->i_type], p_file );
+    LOG_STRING( p_msg->psz_msg, p_file );
+    LOG_STRING( "</font>\n", p_file );
+}
+
diff --git a/modules/misc/logger/Modules.am b/modules/misc/logger/Modules.am
deleted file mode 100644 (file)
index f414909..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SOURCES_logger = logger.c
diff --git a/modules/misc/logger/logger.c b/modules/misc/logger/logger.c
deleted file mode 100644 (file)
index 7135f21..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*****************************************************************************
- * logger.c : file logging plugin for vlc
- *****************************************************************************
- * Copyright (C) 2002 VideoLAN
- * $Id: logger.c,v 1.11 2004/01/25 17:52:17 gbazin Exp $
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- *
- * This program 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 program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>
-
-#include <errno.h>                                                 /* ENOMEM */
-#include <stdio.h>
-
-#include <vlc/vlc.h>
-#include <vlc/intf.h>
-
-#define MODE_TEXT 0
-#define MODE_HTML 1
-
-#define LOG_FILE "vlc-log.txt"
-#define LOG_STRING( msg, file ) fwrite( msg, strlen( msg ), 1, file );
-
-#define TEXT_HEADER "-- logger module started --\n"
-#define TEXT_FOOTER "-- logger module stopped --\n"
-
-#define HTML_HEADER \
-    "<html>\n" \
-    "  <head>\n" \
-    "    <title>vlc log</title>\n" \
-    "  </head>\n" \
-    "  <body bgcolor=\"#000000\" text=\"#aaaaaa\">\n" \
-    "    <pre>\n" \
-    "      <b>-- logger module started --</b>\n"
-#define HTML_FOOTER \
-    "      <b>-- logger module stopped --</b>\n" \
-    "    </pre>\n" \
-    "  </body>\n" \
-    "</html>\n"
-
-/*****************************************************************************
- * intf_sys_t: description and status of log interface
- *****************************************************************************/
-struct intf_sys_t
-{
-    int i_mode;
-
-    FILE *    p_file; /* The log file */
-    msg_subscription_t *p_sub;
-};
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int  Open    ( vlc_object_t * );                  
-static void Close   ( vlc_object_t * );
-static void Run     ( intf_thread_t * );
-
-static void FlushQueue        ( msg_subscription_t *, FILE *, int );
-static void TextPrint         ( const msg_item_t *, FILE * );
-static void HtmlPrint         ( const msg_item_t *, FILE * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-static char *mode_list[] = { "text", "html" };
-static char *mode_list_text[] = { N_("Text"), N_("Html") };
-
-#define LOGMODE_TEXT N_("Log format")
-#define LOGMODE_LONGTEXT N_("Specify the log format. Available choices are \"text\" (default) and \"html\".")
-
-vlc_module_begin();
-    set_description( _("File logging interface") );
-
-    add_file( "logfile", NULL, NULL, N_("Log filename"), N_("Specify the log filename."), VLC_FALSE );
-    add_string( "logmode", "text", NULL, LOGMODE_TEXT, LOGMODE_LONGTEXT,
-                VLC_FALSE );
-        change_string_list( mode_list, mode_list_text, 0 );
-
-    set_capability( "interface", 0 );
-    set_callbacks( Open, Close );
-vlc_module_end();
-
-/*****************************************************************************
- * Open: initialize and create stuff
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{   
-    intf_thread_t *p_intf = (intf_thread_t *)p_this;
-    char *psz_mode, *psz_file;
-
-    CONSOLE_INTRO_MSG;
-    msg_Info( p_intf, "Using the logger interface module..." );
-
-    /* Allocate instance and initialize some members */
-    p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
-    if( p_intf->p_sys == NULL )
-    {
-        msg_Err( p_intf, "out of memory" );
-        return -1;
-    }
-
-    psz_mode = config_GetPsz( p_intf, "logmode" );
-    if( psz_mode )
-    {
-        if( !strcmp( psz_mode, "text" ) )
-        {
-            p_intf->p_sys->i_mode = MODE_TEXT;
-        }
-        else if( !strcmp( psz_mode, "html" ) )
-        {
-            p_intf->p_sys->i_mode = MODE_HTML;
-        }
-        else
-        {
-            msg_Err( p_intf, "invalid log mode `%s', using `text'", psz_mode );
-            p_intf->p_sys->i_mode = MODE_TEXT;
-        }
-
-        free( psz_mode );
-    }
-    else
-    {
-        msg_Warn( p_intf, "no log mode specified, using `text'" );
-        p_intf->p_sys->i_mode = MODE_TEXT;
-    }
-
-    psz_file = config_GetPsz( p_intf, "logfile" );
-    if( !psz_file )
-    {
-        switch( p_intf->p_sys->i_mode )
-        {
-        case MODE_HTML:
-            psz_file = strdup( "vlc-log.html" );
-            break;
-        case MODE_TEXT:
-        default:
-            psz_file = strdup( "vlc-log.txt" );
-            break;
-        }
-
-        msg_Warn( p_intf, "no log filename provided, using `%s'", psz_file );
-    }
-
-    /* Open the log file and remove any buffering for the stream */
-    msg_Dbg( p_intf, "opening logfile `%s'", psz_file );
-    p_intf->p_sys->p_file = fopen( psz_file, "wt" );
-    if( p_intf->p_sys->p_file == NULL )
-    {
-        msg_Err( p_intf, "error opening logfile `%s'", psz_file );
-        free( p_intf->p_sys );
-        free( psz_file );
-        return -1;
-    }
-    setvbuf( p_intf->p_sys->p_file, NULL, _IONBF, 0 );
-    p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
-
-    free( psz_file );
-
-    switch( p_intf->p_sys->i_mode )
-    {
-    case MODE_HTML:
-        LOG_STRING( HTML_HEADER, p_intf->p_sys->p_file );
-        break;
-    case MODE_TEXT:
-    default:
-        LOG_STRING( TEXT_HEADER, p_intf->p_sys->p_file );
-        break;
-    }
-
-    p_intf->pf_run = Run;
-
-    return 0;
-}
-
-/*****************************************************************************
- * Close: destroy interface stuff
- *****************************************************************************/
-static void Close( vlc_object_t *p_this )
-{       
-    intf_thread_t *p_intf = (intf_thread_t *)p_this;
-        
-    /* Flush the queue and unsubscribe from the message queue */
-    FlushQueue( p_intf->p_sys->p_sub, p_intf->p_sys->p_file,
-                p_intf->p_sys->i_mode );
-    msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
-
-    switch( p_intf->p_sys->i_mode )
-    {
-    case MODE_HTML:
-        LOG_STRING( HTML_FOOTER, p_intf->p_sys->p_file );
-        break;
-    case MODE_TEXT:
-    default:
-        LOG_STRING( TEXT_FOOTER, p_intf->p_sys->p_file );
-        break;
-    }
-
-    /* Close the log file */
-    fclose( p_intf->p_sys->p_file );
-
-    /* Destroy structure */
-    free( p_intf->p_sys );
-}
-
-/*****************************************************************************
- * Run: rc thread
- *****************************************************************************
- * This part of the interface is in a separate thread so that we can call
- * exec() from within it without annoying the rest of the program.
- *****************************************************************************/
-static void Run( intf_thread_t *p_intf )
-{
-    while( !p_intf->b_die )
-    {
-        FlushQueue( p_intf->p_sys->p_sub, p_intf->p_sys->p_file,
-                    p_intf->p_sys->i_mode );
-
-        msleep( INTF_IDLE_SLEEP );
-    }
-}
-
-/*****************************************************************************
- * FlushQueue: flush the message queue into the log file
- *****************************************************************************/
-static void FlushQueue( msg_subscription_t *p_sub, FILE *p_file, int i_mode )
-{
-    int i_start, i_stop;
-
-    vlc_mutex_lock( p_sub->p_lock );
-    i_stop = *p_sub->pi_stop;
-    vlc_mutex_unlock( p_sub->p_lock );
-
-    if( p_sub->i_start != i_stop )
-    {
-        /* Append all messages to log file */
-        for( i_start = p_sub->i_start;
-             i_start != i_stop;
-             i_start = (i_start+1) % VLC_MSG_QSIZE )
-        {
-            switch( i_mode )
-            {
-            case MODE_HTML:
-                HtmlPrint( &p_sub->p_msg[i_start], p_file );
-                break;
-            case MODE_TEXT:
-            default:
-                TextPrint( &p_sub->p_msg[i_start], p_file );
-                break;
-            }
-        }
-
-        vlc_mutex_lock( p_sub->p_lock );
-        p_sub->i_start = i_start;
-        vlc_mutex_unlock( p_sub->p_lock );
-    }
-}
-
-static const char *ppsz_type[4] = { ": ", " error: ",
-                                    " warning: ", " debug: " };
-
-static void TextPrint( const msg_item_t *p_msg, FILE *p_file )
-{
-    LOG_STRING( p_msg->psz_module, p_file );
-    LOG_STRING( ppsz_type[p_msg->i_type], p_file );
-    LOG_STRING( p_msg->psz_msg, p_file );
-    LOG_STRING( "\n", p_file );
-}
-
-static void HtmlPrint( const msg_item_t *p_msg, FILE *p_file )
-{
-    static const char *ppsz_color[4] = { "<font color=\"#ffffff\">",
-                                         "<font color=\"#ff6666\">",
-                                         "<font color=\"#ffff66\">",
-                                         "<font color=\"#aaaaaa\">" };
-
-    LOG_STRING( p_msg->psz_module, p_file );
-    LOG_STRING( ppsz_type[p_msg->i_type], p_file );
-    LOG_STRING( ppsz_color[p_msg->i_type], p_file );
-    LOG_STRING( p_msg->psz_msg, p_file );
-    LOG_STRING( "</font>\n", p_file );
-}
-
index c05c869..525a0b4 100644 (file)
@@ -7,4 +7,5 @@ SOURCES_clone = clone.c
 SOURCES_crop = crop.c
 SOURCES_motionblur = motionblur.c
 SOURCES_logo = logo.c
+SOURCES_deinterlace = deinterlace.c
 noinst_HEADERS += filter_common.h
diff --git a/modules/video_filter/deinterlace.c b/modules/video_filter/deinterlace.c
new file mode 100644 (file)
index 0000000..91aefdd
--- /dev/null
@@ -0,0 +1,1077 @@
+/*****************************************************************************
+ * deinterlace.c : deinterlacer plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000, 2001, 2002, 2003 VideoLAN
+ * $Id$
+ *
+ * Author: Sam Hocevar <sam@zoy.org>
+ *
+ * This program 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 program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <errno.h>
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+
+#include "../filter_common.h"
+
+#define DEINTERLACE_DISCARD 1
+#define DEINTERLACE_MEAN    2
+#define DEINTERLACE_BLEND   3
+#define DEINTERLACE_BOB     4
+#define DEINTERLACE_LINEAR  5
+
+/*****************************************************************************
+ * Local protypes
+ *****************************************************************************/
+static int  Create    ( vlc_object_t * );
+static void Destroy   ( vlc_object_t * );
+
+static int  Init      ( vout_thread_t * );
+static void End       ( vout_thread_t * );
+static void Render    ( vout_thread_t *, picture_t * );
+
+static void RenderDiscard( vout_thread_t *, picture_t *, picture_t *, int );
+static void RenderBob    ( vout_thread_t *, picture_t *, picture_t *, int );
+static void RenderMean   ( vout_thread_t *, picture_t *, picture_t * );
+static void RenderBlend  ( vout_thread_t *, picture_t *, picture_t * );
+static void RenderLinear ( vout_thread_t *, picture_t *, picture_t *, int );
+
+static void MergeGeneric ( void *, const void *, const void *, size_t );
+#if defined(CAN_COMPILE_C_ALTIVEC)
+static void MergeAltivec ( void *, const void *, const void *, size_t );
+#endif
+#if defined(CAN_COMPILE_MMX)
+static void MergeMMX     ( void *, const void *, const void *, size_t );
+#endif
+#if defined(CAN_COMPILE_SSE)
+static void MergeSSE2    ( void *, const void *, const void *, size_t );
+#endif
+#if defined(CAN_COMPILE_MMX) || defined(CAN_COMPILE_SSE)
+static void EndMMX       ( void );
+#endif
+
+static int  SendEvents   ( vlc_object_t *, char const *,
+                           vlc_value_t, vlc_value_t, void * );
+
+static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method );
+static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * Callback prototypes
+ *****************************************************************************/
+static int FilterCallback ( vlc_object_t *, char const *,
+                            vlc_value_t, vlc_value_t, void * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+#define MODE_TEXT N_("Deinterlace mode")
+#define MODE_LONGTEXT N_("You can choose the default deinterlace mode")
+
+static char *mode_list[] = { "discard", "blend", "mean", "bob", "linear" };
+static char *mode_list_text[] = { N_("Discard"), N_("Blend"), N_("Mean"),
+                                  N_("Bob"), N_("Linear") };
+
+vlc_module_begin();
+    set_description( _("Deinterlacing video filter") );
+    set_capability( "video filter", 0 );
+
+    add_string( "deinterlace-mode", "discard", NULL, MODE_TEXT,
+                MODE_LONGTEXT, VLC_FALSE );
+        change_string_list( mode_list, mode_list_text, 0 );
+
+    add_shortcut( "deinterlace" );
+    set_callbacks( Create, Destroy );
+vlc_module_end();
+
+/*****************************************************************************
+ * vout_sys_t: Deinterlace video output method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the Deinterlace specific properties of an output thread.
+ *****************************************************************************/
+struct vout_sys_t
+{
+    int        i_mode;        /* Deinterlace mode */
+    vlc_bool_t b_double_rate; /* Shall we double the framerate? */
+
+    mtime_t    last_date;
+    mtime_t    next_date;
+
+    vout_thread_t *p_vout;
+
+    vlc_mutex_t filter_lock;
+
+    void (*pf_merge) ( void *, const void *, const void *, size_t );
+    void (*pf_end_merge) ( void );
+};
+
+/*****************************************************************************
+ * Create: allocates Deinterlace video thread output method
+ *****************************************************************************
+ * This function allocates and initializes a Deinterlace vout method.
+ *****************************************************************************/
+static int Create( vlc_object_t *p_this )
+{
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
+    vlc_value_t val;
+
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        msg_Err( p_vout, "out of memory" );
+        return VLC_ENOMEM;
+    }
+
+    p_vout->pf_init = Init;
+    p_vout->pf_end = End;
+    p_vout->pf_manage = NULL;
+    p_vout->pf_render = Render;
+    p_vout->pf_display = NULL;
+
+    p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
+    p_vout->p_sys->b_double_rate = 0;
+    p_vout->p_sys->last_date = 0;
+    vlc_mutex_init( p_vout, &p_vout->p_sys->filter_lock );
+
+#if defined(CAN_COMPILE_C_ALTIVEC)
+    if( p_vout->p_libvlc->i_cpu & CPU_CAPABILITY_ALTIVEC )
+    {
+        p_vout->p_sys->pf_merge = MergeAltivec;
+        p_vout->p_sys->pf_end_merge = NULL;
+    }
+    else
+#endif
+#if defined(CAN_COMPILE_SSE)
+    if( p_vout->p_libvlc->i_cpu & CPU_CAPABILITY_SSE2 )
+    {
+        p_vout->p_sys->pf_merge = MergeSSE2;
+        p_vout->p_sys->pf_end_merge = EndMMX;
+    }
+    else
+#endif
+#if defined(CAN_COMPILE_MMX)
+    if( p_vout->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
+    {
+        p_vout->p_sys->pf_merge = MergeMMX;
+        p_vout->p_sys->pf_end_merge = EndMMX;
+    }
+    else
+#endif
+    {
+        p_vout->p_sys->pf_merge = MergeGeneric;
+        p_vout->p_sys->pf_end_merge = NULL;
+    }
+
+    /* Look what method was requested */
+    var_Create( p_vout, "deinterlace-mode", VLC_VAR_STRING );
+    var_Change( p_vout, "deinterlace-mode", VLC_VAR_INHERITVALUE, &val, NULL );
+
+    if( val.psz_string == NULL )
+    {
+        msg_Err( p_vout, "configuration variable deinterlace-mode empty" );
+        msg_Err( p_vout, "no deinterlace mode provided, using \"discard\"" );
+
+        val.psz_string = strdup( "discard" );
+    }
+
+    msg_Dbg( p_vout, "using %s deinterlace mode", val.psz_string );
+
+    SetFilterMethod( p_vout, val.psz_string );
+
+    free( val.psz_string );
+
+    var_AddCallback( p_vout, "deinterlace-mode", FilterCallback, NULL );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * SetFilterMethod: setup the deinterlace method to use.
+ *****************************************************************************/
+static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method )
+{
+    if( !strcmp( psz_method, "discard" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
+        p_vout->p_sys->b_double_rate = 0;
+    }
+    else if( !strcmp( psz_method, "mean" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_MEAN;
+        p_vout->p_sys->b_double_rate = 0;
+    }
+    else if( !strcmp( psz_method, "blend" )
+             || !strcmp( psz_method, "average" )
+             || !strcmp( psz_method, "combine-fields" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_BLEND;
+        p_vout->p_sys->b_double_rate = 0;
+    }
+    else if( !strcmp( psz_method, "bob" )
+             || !strcmp( psz_method, "progressive-scan" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_BOB;
+        p_vout->p_sys->b_double_rate = 1;
+    }
+    else if( !strcmp( psz_method, "linear" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_LINEAR;
+        p_vout->p_sys->b_double_rate = 1;
+    }
+    else
+    {
+        msg_Err( p_vout, "no valid deinterlace mode provided, "
+                 "using \"discard\"" );
+    }
+
+    msg_Dbg( p_vout, "using %s deinterlace method", psz_method );
+}
+
+/*****************************************************************************
+ * Init: initialize Deinterlace video thread output method
+ *****************************************************************************/
+static int Init( vout_thread_t *p_vout )
+{
+    int i_index;
+    picture_t *p_pic;
+
+    I_OUTPUTPICTURES = 0;
+
+    /* Initialize the output structure, full of directbuffers since we want
+     * the decoder to output directly to our structures. */
+    switch( p_vout->render.i_chroma )
+    {
+        case VLC_FOURCC('I','4','2','0'):
+        case VLC_FOURCC('I','Y','U','V'):
+        case VLC_FOURCC('Y','V','1','2'):
+        case VLC_FOURCC('I','4','2','2'):
+            p_vout->output.i_chroma = p_vout->render.i_chroma;
+            p_vout->output.i_width  = p_vout->render.i_width;
+            p_vout->output.i_height = p_vout->render.i_height;
+            p_vout->output.i_aspect = p_vout->render.i_aspect;
+            break;
+
+        default:
+            return VLC_EGENERIC; /* unknown chroma */
+            break;
+    }
+
+    /* Try to open the real video output */
+    p_vout->p_sys->p_vout = SpawnRealVout( p_vout );
+
+    if( p_vout->p_sys->p_vout == NULL )
+    {
+        /* Everything failed */
+        msg_Err( p_vout, "cannot open vout, aborting" );
+
+        return VLC_EGENERIC;
+    }
+
+    ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
+
+    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
+    ADD_PARENT_CALLBACKS( SendEventsToChild );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * SpawnRealVout: spawn the real video output.
+ *****************************************************************************/
+static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout )
+{
+    vout_thread_t *p_real_vout = NULL;
+
+    msg_Dbg( p_vout, "spawning the real video output" );
+
+    switch( p_vout->render.i_chroma )
+    {
+    case VLC_FOURCC('I','4','2','0'):
+    case VLC_FOURCC('I','Y','U','V'):
+    case VLC_FOURCC('Y','V','1','2'):
+        switch( p_vout->p_sys->i_mode )
+        {
+        case DEINTERLACE_MEAN:
+        case DEINTERLACE_DISCARD:
+            p_real_vout =
+                vout_Create( p_vout,
+                       p_vout->output.i_width, p_vout->output.i_height / 2,
+                       p_vout->output.i_chroma, p_vout->output.i_aspect );
+            break;
+
+        case DEINTERLACE_BOB:
+        case DEINTERLACE_BLEND:
+        case DEINTERLACE_LINEAR:
+            p_real_vout =
+                vout_Create( p_vout,
+                       p_vout->output.i_width, p_vout->output.i_height,
+                       p_vout->output.i_chroma, p_vout->output.i_aspect );
+            break;
+        }
+        break;
+
+    case VLC_FOURCC('I','4','2','2'):
+        p_real_vout =
+            vout_Create( p_vout,
+                       p_vout->output.i_width, p_vout->output.i_height,
+                       VLC_FOURCC('I','4','2','0'), p_vout->output.i_aspect );
+        break;
+
+    default:
+        break;
+    }
+
+    return p_real_vout;
+}
+
+/*****************************************************************************
+ * End: terminate Deinterlace video thread output method
+ *****************************************************************************/
+static void End( vout_thread_t *p_vout )
+{
+    int i_index;
+
+    /* Free the fake output buffers we allocated */
+    for( i_index = I_OUTPUTPICTURES ; i_index ; )
+    {
+        i_index--;
+        free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
+    }
+}
+
+/*****************************************************************************
+ * Destroy: destroy Deinterlace video thread output method
+ *****************************************************************************
+ * Terminate an output method created by DeinterlaceCreateOutputMethod
+ *****************************************************************************/
+static void Destroy( vlc_object_t *p_this )
+{
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
+
+    DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
+    vlc_object_detach( p_vout->p_sys->p_vout );
+    vout_Destroy( p_vout->p_sys->p_vout );
+
+    DEL_PARENT_CALLBACKS( SendEventsToChild );
+
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * Render: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to Deinterlace image,
+ * waits until it is displayed and switch the two rendering buffers, preparing
+ * next frame.
+ *****************************************************************************/
+static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
+{
+    picture_t *pp_outpic[2];
+
+    vlc_mutex_lock( &p_vout->p_sys->filter_lock );
+
+    /* Get a new picture */
+    while( ( pp_outpic[0] = vout_CreatePicture( p_vout->p_sys->p_vout,
+                                             0, 0, 0 ) )
+              == NULL )
+    {
+        if( p_vout->b_die || p_vout->b_error )
+        {
+            vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+            return;
+        }
+        msleep( VOUT_OUTMEM_SLEEP );
+     }
+
+    vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[0], p_pic->date );
+
+    /* If we are using double rate, get an additional new picture */
+    if( p_vout->p_sys->b_double_rate )
+    {
+        while( ( pp_outpic[1] = vout_CreatePicture( p_vout->p_sys->p_vout,
+                                                 0, 0, 0 ) )
+                  == NULL )
+        {
+            if( p_vout->b_die || p_vout->b_error )
+            {
+                vout_DestroyPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
+                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+                return;
+            }
+            msleep( VOUT_OUTMEM_SLEEP );
+        }
+
+        /* 20ms is a bit arbitrary, but it's only for the first image we get */
+        if( !p_vout->p_sys->last_date )
+        {
+            vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],
+                              p_pic->date + 20000 );
+        }
+        else
+        {
+            vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],
+                      (3 * p_pic->date - p_vout->p_sys->last_date) / 2 );
+        }
+        p_vout->p_sys->last_date = p_pic->date;
+    }
+
+    switch( p_vout->p_sys->i_mode )
+    {
+        case DEINTERLACE_DISCARD:
+            RenderDiscard( p_vout, pp_outpic[0], p_pic, 0 );
+            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
+            break;
+
+        case DEINTERLACE_BOB:
+            RenderBob( p_vout, pp_outpic[0], p_pic, 0 );
+            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
+            RenderBob( p_vout, pp_outpic[1], p_pic, 1 );
+            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[1] );
+            break;
+
+        case DEINTERLACE_LINEAR:
+            RenderLinear( p_vout, pp_outpic[0], p_pic, 0 );
+            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
+            RenderLinear( p_vout, pp_outpic[1], p_pic, 1 );
+            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[1] );
+            break;
+
+        case DEINTERLACE_MEAN:
+            RenderMean( p_vout, pp_outpic[0], p_pic );
+            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
+            break;
+
+        case DEINTERLACE_BLEND:
+            RenderBlend( p_vout, pp_outpic[0], p_pic );
+            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
+            break;
+    }
+
+    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+}
+
+/*****************************************************************************
+ * RenderDiscard: only keep TOP or BOTTOM field, discard the other.
+ *****************************************************************************/
+static void RenderDiscard( vout_thread_t *p_vout,
+                           picture_t *p_outpic, picture_t *p_pic, int i_field )
+{
+    int i_plane;
+
+    /* Copy image and skip lines */
+    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
+    {
+        uint8_t *p_in, *p_out_end, *p_out;
+        int i_increment;
+
+        p_in = p_pic->p[i_plane].p_pixels
+                   + i_field * p_pic->p[i_plane].i_pitch;
+
+        p_out = p_outpic->p[i_plane].p_pixels;
+        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
+                             * p_outpic->p[i_plane].i_lines;
+
+        switch( p_vout->render.i_chroma )
+        {
+        case VLC_FOURCC('I','4','2','0'):
+        case VLC_FOURCC('I','Y','U','V'):
+        case VLC_FOURCC('Y','V','1','2'):
+
+            for( ; p_out < p_out_end ; )
+            {
+                p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                          p_pic->p[i_plane].i_pitch );
+
+                p_out += p_pic->p[i_plane].i_pitch;
+                p_in += 2 * p_pic->p[i_plane].i_pitch;
+            }
+            break;
+
+        case VLC_FOURCC('I','4','2','2'):
+
+            i_increment = 2 * p_pic->p[i_plane].i_pitch;
+
+            if( i_plane == Y_PLANE )
+            {
+                for( ; p_out < p_out_end ; )
+                {
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+                    p_out += p_pic->p[i_plane].i_pitch;
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+                    p_out += p_pic->p[i_plane].i_pitch;
+                    p_in += i_increment;
+                }
+            }
+            else
+            {
+                for( ; p_out < p_out_end ; )
+                {
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+                    p_out += p_pic->p[i_plane].i_pitch;
+                    p_in += i_increment;
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+}
+
+/*****************************************************************************
+ * RenderBob: renders a BOB picture - simple copy
+ *****************************************************************************/
+static void RenderBob( vout_thread_t *p_vout,
+                       picture_t *p_outpic, picture_t *p_pic, int i_field )
+{
+    int i_plane;
+
+    /* Copy image and skip lines */
+    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
+    {
+        uint8_t *p_in, *p_out_end, *p_out;
+
+        p_in = p_pic->p[i_plane].p_pixels;
+        p_out = p_outpic->p[i_plane].p_pixels;
+        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
+                             * p_outpic->p[i_plane].i_lines;
+
+        switch( p_vout->render.i_chroma )
+        {
+            case VLC_FOURCC('I','4','2','0'):
+            case VLC_FOURCC('I','Y','U','V'):
+            case VLC_FOURCC('Y','V','1','2'):
+                /* For BOTTOM field we need to add the first line */
+                if( i_field == 1 )
+                {
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+                    p_in += p_pic->p[i_plane].i_pitch;
+                    p_out += p_pic->p[i_plane].i_pitch;
+                }
+
+                p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;
+
+                for( ; p_out < p_out_end ; )
+                {
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+
+                    p_out += p_pic->p[i_plane].i_pitch;
+
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+
+                    p_in += 2 * p_pic->p[i_plane].i_pitch;
+                    p_out += p_pic->p[i_plane].i_pitch;
+                }
+
+                p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                          p_pic->p[i_plane].i_pitch );
+
+                /* For TOP field we need to add the last line */
+                if( i_field == 0 )
+                {
+                    p_in += p_pic->p[i_plane].i_pitch;
+                    p_out += p_pic->p[i_plane].i_pitch;
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+                }
+                break;
+
+            case VLC_FOURCC('I','4','2','2'):
+                /* For BOTTOM field we need to add the first line */
+                if( i_field == 1 )
+                {
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+                    p_in += p_pic->p[i_plane].i_pitch;
+                    p_out += p_pic->p[i_plane].i_pitch;
+                }
+
+                p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;
+
+                if( i_plane == Y_PLANE )
+                {
+                    for( ; p_out < p_out_end ; )
+                    {
+                        p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                                  p_pic->p[i_plane].i_pitch );
+
+                        p_out += p_pic->p[i_plane].i_pitch;
+
+                        p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                                  p_pic->p[i_plane].i_pitch );
+
+                        p_in += 2 * p_pic->p[i_plane].i_pitch;
+                        p_out += p_pic->p[i_plane].i_pitch;
+                    }
+                }
+                else
+                {
+                    for( ; p_out < p_out_end ; )
+                    {
+                        p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                                  p_pic->p[i_plane].i_pitch );
+
+                        p_out += p_pic->p[i_plane].i_pitch;
+                        p_in += 2 * p_pic->p[i_plane].i_pitch;
+                    }
+                }
+
+                p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                          p_pic->p[i_plane].i_pitch );
+
+                /* For TOP field we need to add the last line */
+                if( i_field == 0 )
+                {
+                    p_in += p_pic->p[i_plane].i_pitch;
+                    p_out += p_pic->p[i_plane].i_pitch;
+                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                              p_pic->p[i_plane].i_pitch );
+                }
+                break;
+        }
+    }
+}
+
+#define Merge p_vout->p_sys->pf_merge
+#define EndMerge if(p_vout->p_sys->pf_end_merge) p_vout->p_sys->pf_end_merge
+
+/*****************************************************************************
+ * RenderLinear: BOB with linear interpolation
+ *****************************************************************************/
+static void RenderLinear( vout_thread_t *p_vout,
+                          picture_t *p_outpic, picture_t *p_pic, int i_field )
+{
+    int i_plane;
+
+    /* Copy image and skip lines */
+    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
+    {
+        uint8_t *p_in, *p_out_end, *p_out;
+
+        p_in = p_pic->p[i_plane].p_pixels;
+        p_out = p_outpic->p[i_plane].p_pixels;
+        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
+                             * p_outpic->p[i_plane].i_lines;
+
+        /* For BOTTOM field we need to add the first line */
+        if( i_field == 1 )
+        {
+            p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                      p_pic->p[i_plane].i_pitch );
+            p_in += p_pic->p[i_plane].i_pitch;
+            p_out += p_pic->p[i_plane].i_pitch;
+        }
+
+        p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;
+
+        for( ; p_out < p_out_end ; )
+        {
+            p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                      p_pic->p[i_plane].i_pitch );
+
+            p_out += p_pic->p[i_plane].i_pitch;
+
+            Merge( p_out, p_in, p_in + 2 * p_pic->p[i_plane].i_pitch,
+                   p_pic->p[i_plane].i_pitch );
+
+            p_in += 2 * p_pic->p[i_plane].i_pitch;
+            p_out += p_pic->p[i_plane].i_pitch;
+        }
+
+        p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                  p_pic->p[i_plane].i_pitch );
+
+        /* For TOP field we need to add the last line */
+        if( i_field == 0 )
+        {
+            p_in += p_pic->p[i_plane].i_pitch;
+            p_out += p_pic->p[i_plane].i_pitch;
+            p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                      p_pic->p[i_plane].i_pitch );
+        }
+    }
+    EndMerge();
+}
+
+static void RenderMean( vout_thread_t *p_vout,
+                        picture_t *p_outpic, picture_t *p_pic )
+{
+    int i_plane;
+
+    /* Copy image and skip lines */
+    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
+    {
+        uint8_t *p_in, *p_out_end, *p_out;
+
+        p_in = p_pic->p[i_plane].p_pixels;
+
+        p_out = p_outpic->p[i_plane].p_pixels;
+        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
+                             * p_outpic->p[i_plane].i_lines;
+
+        /* All lines: mean value */
+        for( ; p_out < p_out_end ; )
+        {
+            Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
+                   p_pic->p[i_plane].i_pitch );
+
+            p_out += p_pic->p[i_plane].i_pitch;
+            p_in += 2 * p_pic->p[i_plane].i_pitch;
+        }
+    }
+    EndMerge();
+}
+
+static void RenderBlend( vout_thread_t *p_vout,
+                         picture_t *p_outpic, picture_t *p_pic )
+{
+    int i_plane;
+
+    /* Copy image and skip lines */
+    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
+    {
+        uint8_t *p_in, *p_out_end, *p_out;
+
+        p_in = p_pic->p[i_plane].p_pixels;
+
+        p_out = p_outpic->p[i_plane].p_pixels;
+        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
+                             * p_outpic->p[i_plane].i_lines;
+
+        switch( p_vout->render.i_chroma )
+        {
+            case VLC_FOURCC('I','4','2','0'):
+            case VLC_FOURCC('I','Y','U','V'):
+            case VLC_FOURCC('Y','V','1','2'):
+                /* First line: simple copy */
+                p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                          p_pic->p[i_plane].i_pitch );
+                p_out += p_pic->p[i_plane].i_pitch;
+
+                /* Remaining lines: mean value */
+                for( ; p_out < p_out_end ; )
+                {
+                   Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
+                          p_pic->p[i_plane].i_pitch );
+
+                    p_out += p_pic->p[i_plane].i_pitch;
+                    p_in += p_pic->p[i_plane].i_pitch;
+                }
+                break;
+
+            case VLC_FOURCC('I','4','2','2'):
+                /* First line: simple copy */
+                p_vout->p_vlc->pf_memcpy( p_out, p_in,
+                                          p_pic->p[i_plane].i_pitch );
+                p_out += p_pic->p[i_plane].i_pitch;
+
+                /* Remaining lines: mean value */
+                if( i_plane == Y_PLANE )
+                {
+                    for( ; p_out < p_out_end ; )
+                    {
+                        Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
+                               p_pic->p[i_plane].i_pitch );
+
+                        p_out += p_pic->p[i_plane].i_pitch;
+                        p_in += p_pic->p[i_plane].i_pitch;
+                    }
+                }
+
+                else
+                {
+                    for( ; p_out < p_out_end ; )
+                    {
+                        Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
+                               p_pic->p[i_plane].i_pitch );
+
+                        p_out += p_pic->p[i_plane].i_pitch;
+                        p_in += 2*p_pic->p[i_plane].i_pitch;
+                    }
+                }
+                break;
+        }
+    }
+    EndMerge();
+}
+
+#undef Merge
+
+static void MergeGeneric( void *_p_dest, const void *_p_s1,
+                          const void *_p_s2, size_t i_bytes )
+{
+    uint8_t* p_dest = (uint8_t*)_p_dest;
+    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
+    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
+    uint8_t* p_end = p_dest + i_bytes - 8;
+
+    while( p_dest < p_end )
+    {
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+    }
+
+    p_end += 8;
+
+    while( p_dest < p_end )
+    {
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+    }
+}
+
+#if defined(CAN_COMPILE_MMX)
+static void MergeMMX( void *_p_dest, const void *_p_s1, const void *_p_s2,
+                      size_t i_bytes )
+{
+    uint8_t* p_dest = (uint8_t*)_p_dest;
+    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
+    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
+    uint8_t* p_end = p_dest + i_bytes - 8;
+    while( p_dest < p_end )
+    {
+        __asm__  __volatile__( "movq %2,%%mm1;"
+                               "pavgb %1, %%mm1;"
+                               "movq %%mm1, %0" :"=m" (*p_dest):
+                                                 "m" (*p_s1),
+                                                 "m" (*p_s2) );
+        p_dest += 8;
+        p_s1 += 8;
+        p_s2 += 8;
+    }
+
+    p_end += 8;
+
+    while( p_dest < p_end )
+    {
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+    }
+}
+#endif
+
+#if defined(CAN_COMPILE_SSE)
+static void MergeSSE2( void *_p_dest, const void *_p_s1, const void *_p_s2,
+                       size_t i_bytes )
+{
+    uint8_t* p_dest = (uint8_t*)_p_dest;
+    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
+    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
+    while( (int)p_s1 % 16 )
+    {
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+    }        
+    uint8_t* p_end = p_dest + i_bytes - 16;
+    while( p_dest < p_end )
+    {
+        __asm__  __volatile__( "movdqu %2,%%xmm1;"
+                               "pavgb %1, %%xmm1;"
+                               "movdqu %%xmm1, %0" :"=m" (*p_dest):
+                                                 "m" (*p_s1),
+                                                 "m" (*p_s2) );
+        p_dest += 16;
+        p_s1 += 16;
+        p_s2 += 16;
+    }
+
+    p_end += 16;
+
+    while( p_dest < p_end )
+    {
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+    }
+}
+#endif
+
+#if defined(CAN_COMPILE_MMX) || defined(CAN_COMPILE_SSE)
+static void EndMMX( void )
+{
+    __asm__ __volatile__( "emms" :: );
+}
+#endif
+
+#ifdef CAN_COMPILE_C_ALTIVEC
+static void MergeAltivec( void *_p_dest, const void *_p_s1,
+                          const void *_p_s2, size_t i_bytes )
+{
+    uint8_t *p_dest = (uint8_t*)_p_dest;
+    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
+    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
+    uint8_t *p_end = p_dest + i_bytes - 16;
+
+    if( ( (int)p_s1 & 0xF ) | ( (int)p_s2 & 0xF ) |
+        ( (int)p_dest & 0xF ) )
+    {
+        /* TODO Handle non 16-bytes aligned planes */
+        MergeGeneric( _p_dest, _p_s1, _p_s2, i_bytes );
+        return;
+    }
+
+    while( p_dest < p_end )
+    {
+        vec_st( vec_avg( vec_ld( 0, p_s1 ), vec_ld( 0, p_s2 ) ),
+                0, p_dest );
+        p_s1   += 16;
+        p_s2   += 16;
+        p_dest += 16;
+    }
+
+    p_end += 16;
+
+    while( p_dest < p_end )
+    {
+        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
+    }
+}
+#endif
+
+/*****************************************************************************
+ * SendEvents: forward mouse and keyboard events to the parent p_vout
+ *****************************************************************************/
+static int SendEvents( vlc_object_t *p_this, char const *psz_var,
+                       vlc_value_t oldval, vlc_value_t newval, void *_p_vout )
+{
+    vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
+    vlc_value_t sentval = newval;
+
+    if( !strcmp( psz_var, "mouse-y" ) )
+    {
+        switch( p_vout->p_sys->i_mode )
+        {
+            case DEINTERLACE_MEAN:
+            case DEINTERLACE_DISCARD:
+                sentval.i_int *= 2;
+                break;
+        }
+    }
+
+    var_Set( p_vout, psz_var, sentval );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * FilterCallback: called when changing the deinterlace method on the fly.
+ *****************************************************************************/
+static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,
+                           vlc_value_t oldval, vlc_value_t newval,
+                           void *p_data )
+{
+    vout_thread_t * p_vout = (vout_thread_t *)p_this;
+    int i_old_mode = p_vout->p_sys->i_mode;
+
+    msg_Dbg( p_vout, "using %s deinterlace mode", newval.psz_string );
+
+    vlc_mutex_lock( &p_vout->p_sys->filter_lock );
+
+    SetFilterMethod( p_vout, newval.psz_string );
+
+    switch( p_vout->render.i_chroma )
+    {
+    case VLC_FOURCC('I','4','2','2'):
+        vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+        return VLC_SUCCESS;
+        break;
+
+    case VLC_FOURCC('I','4','2','0'):
+    case VLC_FOURCC('I','Y','U','V'):
+    case VLC_FOURCC('Y','V','1','2'):
+        switch( p_vout->p_sys->i_mode )
+        {
+        case DEINTERLACE_MEAN:
+        case DEINTERLACE_DISCARD:
+            if( ( i_old_mode == DEINTERLACE_MEAN )
+                || ( i_old_mode == DEINTERLACE_DISCARD ) )
+            {
+                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+                return VLC_SUCCESS;
+            }
+            break;
+
+        case DEINTERLACE_BOB:
+        case DEINTERLACE_BLEND:
+        case DEINTERLACE_LINEAR:
+            if( ( i_old_mode == DEINTERLACE_BOB )
+                || ( i_old_mode == DEINTERLACE_BLEND )
+                || ( i_old_mode == DEINTERLACE_LINEAR ) )
+            {
+                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+                return VLC_SUCCESS;
+            }
+            break;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    /* We need to kill the old vout */
+
+    DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
+    vlc_object_detach( p_vout->p_sys->p_vout );
+    vout_Destroy( p_vout->p_sys->p_vout );
+
+    /* Try to open a new video output */
+    p_vout->p_sys->p_vout = SpawnRealVout( p_vout );
+
+    if( p_vout->p_sys->p_vout == NULL )
+    {
+        /* Everything failed */
+        msg_Err( p_vout, "cannot open vout, aborting" );
+
+        vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+        return VLC_EGENERIC;
+    }
+
+    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
+    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * SendEventsToChild: forward events to the child/children vout
+ *****************************************************************************/
+static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
+                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
+    var_Set( p_vout->p_sys->p_vout, psz_var, newval );
+    return VLC_SUCCESS;
+}
diff --git a/modules/video_filter/deinterlace/Modules.am b/modules/video_filter/deinterlace/Modules.am
deleted file mode 100644 (file)
index 61b9fd0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SOURCES_deinterlace = deinterlace.c
diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c
deleted file mode 100644 (file)
index 9c13dda..0000000
+++ /dev/null
@@ -1,1077 +0,0 @@
-/*****************************************************************************
- * deinterlace.c : deinterlacer plugin for vlc
- *****************************************************************************
- * Copyright (C) 2000, 2001, 2002, 2003 VideoLAN
- * $Id: deinterlace.c,v 1.25 2004/03/04 22:47:42 sigmunau Exp $
- *
- * Author: Sam Hocevar <sam@zoy.org>
- *
- * This program 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 program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <errno.h>
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>
-
-#include <vlc/vlc.h>
-#include <vlc/vout.h>
-
-#include "../filter_common.h"
-
-#define DEINTERLACE_DISCARD 1
-#define DEINTERLACE_MEAN    2
-#define DEINTERLACE_BLEND   3
-#define DEINTERLACE_BOB     4
-#define DEINTERLACE_LINEAR  5
-
-/*****************************************************************************
- * Local protypes
- *****************************************************************************/
-static int  Create    ( vlc_object_t * );
-static void Destroy   ( vlc_object_t * );
-
-static int  Init      ( vout_thread_t * );
-static void End       ( vout_thread_t * );
-static void Render    ( vout_thread_t *, picture_t * );
-
-static void RenderDiscard( vout_thread_t *, picture_t *, picture_t *, int );
-static void RenderBob    ( vout_thread_t *, picture_t *, picture_t *, int );
-static void RenderMean   ( vout_thread_t *, picture_t *, picture_t * );
-static void RenderBlend  ( vout_thread_t *, picture_t *, picture_t * );
-static void RenderLinear ( vout_thread_t *, picture_t *, picture_t *, int );
-
-static void MergeGeneric ( void *, const void *, const void *, size_t );
-#if defined(CAN_COMPILE_C_ALTIVEC)
-static void MergeAltivec ( void *, const void *, const void *, size_t );
-#endif
-#if defined(CAN_COMPILE_MMX)
-static void MergeMMX     ( void *, const void *, const void *, size_t );
-#endif
-#if defined(CAN_COMPILE_SSE)
-static void MergeSSE2    ( void *, const void *, const void *, size_t );
-#endif
-#if defined(CAN_COMPILE_MMX) || defined(CAN_COMPILE_SSE)
-static void EndMMX       ( void );
-#endif
-
-static int  SendEvents   ( vlc_object_t *, char const *,
-                           vlc_value_t, vlc_value_t, void * );
-
-static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method );
-static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout );
-
-/*****************************************************************************
- * Callback prototypes
- *****************************************************************************/
-static int FilterCallback ( vlc_object_t *, char const *,
-                            vlc_value_t, vlc_value_t, void * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-#define MODE_TEXT N_("Deinterlace mode")
-#define MODE_LONGTEXT N_("You can choose the default deinterlace mode")
-
-static char *mode_list[] = { "discard", "blend", "mean", "bob", "linear" };
-static char *mode_list_text[] = { N_("Discard"), N_("Blend"), N_("Mean"),
-                                  N_("Bob"), N_("Linear") };
-
-vlc_module_begin();
-    set_description( _("Deinterlacing video filter") );
-    set_capability( "video filter", 0 );
-
-    add_string( "deinterlace-mode", "discard", NULL, MODE_TEXT,
-                MODE_LONGTEXT, VLC_FALSE );
-        change_string_list( mode_list, mode_list_text, 0 );
-
-    add_shortcut( "deinterlace" );
-    set_callbacks( Create, Destroy );
-vlc_module_end();
-
-/*****************************************************************************
- * vout_sys_t: Deinterlace video output method descriptor
- *****************************************************************************
- * This structure is part of the video output thread descriptor.
- * It describes the Deinterlace specific properties of an output thread.
- *****************************************************************************/
-struct vout_sys_t
-{
-    int        i_mode;        /* Deinterlace mode */
-    vlc_bool_t b_double_rate; /* Shall we double the framerate? */
-
-    mtime_t    last_date;
-    mtime_t    next_date;
-
-    vout_thread_t *p_vout;
-
-    vlc_mutex_t filter_lock;
-
-    void (*pf_merge) ( void *, const void *, const void *, size_t );
-    void (*pf_end_merge) ( void );
-};
-
-/*****************************************************************************
- * Create: allocates Deinterlace video thread output method
- *****************************************************************************
- * This function allocates and initializes a Deinterlace vout method.
- *****************************************************************************/
-static int Create( vlc_object_t *p_this )
-{
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-    vlc_value_t val;
-
-    /* Allocate structure */
-    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
-    if( p_vout->p_sys == NULL )
-    {
-        msg_Err( p_vout, "out of memory" );
-        return VLC_ENOMEM;
-    }
-
-    p_vout->pf_init = Init;
-    p_vout->pf_end = End;
-    p_vout->pf_manage = NULL;
-    p_vout->pf_render = Render;
-    p_vout->pf_display = NULL;
-
-    p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
-    p_vout->p_sys->b_double_rate = 0;
-    p_vout->p_sys->last_date = 0;
-    vlc_mutex_init( p_vout, &p_vout->p_sys->filter_lock );
-
-#if defined(CAN_COMPILE_C_ALTIVEC)
-    if( p_vout->p_libvlc->i_cpu & CPU_CAPABILITY_ALTIVEC )
-    {
-        p_vout->p_sys->pf_merge = MergeAltivec;
-        p_vout->p_sys->pf_end_merge = NULL;
-    }
-    else
-#endif
-#if defined(CAN_COMPILE_SSE)
-    if( p_vout->p_libvlc->i_cpu & CPU_CAPABILITY_SSE2 )
-    {
-        p_vout->p_sys->pf_merge = MergeSSE2;
-        p_vout->p_sys->pf_end_merge = EndMMX;
-    }
-    else
-#endif
-#if defined(CAN_COMPILE_MMX)
-    if( p_vout->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
-    {
-        p_vout->p_sys->pf_merge = MergeMMX;
-        p_vout->p_sys->pf_end_merge = EndMMX;
-    }
-    else
-#endif
-    {
-        p_vout->p_sys->pf_merge = MergeGeneric;
-        p_vout->p_sys->pf_end_merge = NULL;
-    }
-
-    /* Look what method was requested */
-    var_Create( p_vout, "deinterlace-mode", VLC_VAR_STRING );
-    var_Change( p_vout, "deinterlace-mode", VLC_VAR_INHERITVALUE, &val, NULL );
-
-    if( val.psz_string == NULL )
-    {
-        msg_Err( p_vout, "configuration variable deinterlace-mode empty" );
-        msg_Err( p_vout, "no deinterlace mode provided, using \"discard\"" );
-
-        val.psz_string = strdup( "discard" );
-    }
-
-    msg_Dbg( p_vout, "using %s deinterlace mode", val.psz_string );
-
-    SetFilterMethod( p_vout, val.psz_string );
-
-    free( val.psz_string );
-
-    var_AddCallback( p_vout, "deinterlace-mode", FilterCallback, NULL );
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * SetFilterMethod: setup the deinterlace method to use.
- *****************************************************************************/
-static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method )
-{
-    if( !strcmp( psz_method, "discard" ) )
-    {
-        p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
-        p_vout->p_sys->b_double_rate = 0;
-    }
-    else if( !strcmp( psz_method, "mean" ) )
-    {
-        p_vout->p_sys->i_mode = DEINTERLACE_MEAN;
-        p_vout->p_sys->b_double_rate = 0;
-    }
-    else if( !strcmp( psz_method, "blend" )
-             || !strcmp( psz_method, "average" )
-             || !strcmp( psz_method, "combine-fields" ) )
-    {
-        p_vout->p_sys->i_mode = DEINTERLACE_BLEND;
-        p_vout->p_sys->b_double_rate = 0;
-    }
-    else if( !strcmp( psz_method, "bob" )
-             || !strcmp( psz_method, "progressive-scan" ) )
-    {
-        p_vout->p_sys->i_mode = DEINTERLACE_BOB;
-        p_vout->p_sys->b_double_rate = 1;
-    }
-    else if( !strcmp( psz_method, "linear" ) )
-    {
-        p_vout->p_sys->i_mode = DEINTERLACE_LINEAR;
-        p_vout->p_sys->b_double_rate = 1;
-    }
-    else
-    {
-        msg_Err( p_vout, "no valid deinterlace mode provided, "
-                 "using \"discard\"" );
-    }
-
-    msg_Dbg( p_vout, "using %s deinterlace method", psz_method );
-}
-
-/*****************************************************************************
- * Init: initialize Deinterlace video thread output method
- *****************************************************************************/
-static int Init( vout_thread_t *p_vout )
-{
-    int i_index;
-    picture_t *p_pic;
-
-    I_OUTPUTPICTURES = 0;
-
-    /* Initialize the output structure, full of directbuffers since we want
-     * the decoder to output directly to our structures. */
-    switch( p_vout->render.i_chroma )
-    {
-        case VLC_FOURCC('I','4','2','0'):
-        case VLC_FOURCC('I','Y','U','V'):
-        case VLC_FOURCC('Y','V','1','2'):
-        case VLC_FOURCC('I','4','2','2'):
-            p_vout->output.i_chroma = p_vout->render.i_chroma;
-            p_vout->output.i_width  = p_vout->render.i_width;
-            p_vout->output.i_height = p_vout->render.i_height;
-            p_vout->output.i_aspect = p_vout->render.i_aspect;
-            break;
-
-        default:
-            return VLC_EGENERIC; /* unknown chroma */
-            break;
-    }
-
-    /* Try to open the real video output */
-    p_vout->p_sys->p_vout = SpawnRealVout( p_vout );
-
-    if( p_vout->p_sys->p_vout == NULL )
-    {
-        /* Everything failed */
-        msg_Err( p_vout, "cannot open vout, aborting" );
-
-        return VLC_EGENERIC;
-    }
-
-    ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
-
-    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
-
-    ADD_PARENT_CALLBACKS( SendEventsToChild );
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * SpawnRealVout: spawn the real video output.
- *****************************************************************************/
-static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout )
-{
-    vout_thread_t *p_real_vout = NULL;
-
-    msg_Dbg( p_vout, "spawning the real video output" );
-
-    switch( p_vout->render.i_chroma )
-    {
-    case VLC_FOURCC('I','4','2','0'):
-    case VLC_FOURCC('I','Y','U','V'):
-    case VLC_FOURCC('Y','V','1','2'):
-        switch( p_vout->p_sys->i_mode )
-        {
-        case DEINTERLACE_MEAN:
-        case DEINTERLACE_DISCARD:
-            p_real_vout =
-                vout_Create( p_vout,
-                       p_vout->output.i_width, p_vout->output.i_height / 2,
-                       p_vout->output.i_chroma, p_vout->output.i_aspect );
-            break;
-
-        case DEINTERLACE_BOB:
-        case DEINTERLACE_BLEND:
-        case DEINTERLACE_LINEAR:
-            p_real_vout =
-                vout_Create( p_vout,
-                       p_vout->output.i_width, p_vout->output.i_height,
-                       p_vout->output.i_chroma, p_vout->output.i_aspect );
-            break;
-        }
-        break;
-
-    case VLC_FOURCC('I','4','2','2'):
-        p_real_vout =
-            vout_Create( p_vout,
-                       p_vout->output.i_width, p_vout->output.i_height,
-                       VLC_FOURCC('I','4','2','0'), p_vout->output.i_aspect );
-        break;
-
-    default:
-        break;
-    }
-
-    return p_real_vout;
-}
-
-/*****************************************************************************
- * End: terminate Deinterlace video thread output method
- *****************************************************************************/
-static void End( vout_thread_t *p_vout )
-{
-    int i_index;
-
-    /* Free the fake output buffers we allocated */
-    for( i_index = I_OUTPUTPICTURES ; i_index ; )
-    {
-        i_index--;
-        free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
-    }
-}
-
-/*****************************************************************************
- * Destroy: destroy Deinterlace video thread output method
- *****************************************************************************
- * Terminate an output method created by DeinterlaceCreateOutputMethod
- *****************************************************************************/
-static void Destroy( vlc_object_t *p_this )
-{
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-
-    DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
-
-    vlc_object_detach( p_vout->p_sys->p_vout );
-    vout_Destroy( p_vout->p_sys->p_vout );
-
-    DEL_PARENT_CALLBACKS( SendEventsToChild );
-
-    free( p_vout->p_sys );
-}
-
-/*****************************************************************************
- * Render: displays previously rendered output
- *****************************************************************************
- * This function send the currently rendered image to Deinterlace image,
- * waits until it is displayed and switch the two rendering buffers, preparing
- * next frame.
- *****************************************************************************/
-static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    picture_t *pp_outpic[2];
-
-    vlc_mutex_lock( &p_vout->p_sys->filter_lock );
-
-    /* Get a new picture */
-    while( ( pp_outpic[0] = vout_CreatePicture( p_vout->p_sys->p_vout,
-                                             0, 0, 0 ) )
-              == NULL )
-    {
-        if( p_vout->b_die || p_vout->b_error )
-        {
-            vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-            return;
-        }
-        msleep( VOUT_OUTMEM_SLEEP );
-     }
-
-    vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[0], p_pic->date );
-
-    /* If we are using double rate, get an additional new picture */
-    if( p_vout->p_sys->b_double_rate )
-    {
-        while( ( pp_outpic[1] = vout_CreatePicture( p_vout->p_sys->p_vout,
-                                                 0, 0, 0 ) )
-                  == NULL )
-        {
-            if( p_vout->b_die || p_vout->b_error )
-            {
-                vout_DestroyPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
-                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-                return;
-            }
-            msleep( VOUT_OUTMEM_SLEEP );
-        }
-
-        /* 20ms is a bit arbitrary, but it's only for the first image we get */
-        if( !p_vout->p_sys->last_date )
-        {
-            vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],
-                              p_pic->date + 20000 );
-        }
-        else
-        {
-            vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],
-                      (3 * p_pic->date - p_vout->p_sys->last_date) / 2 );
-        }
-        p_vout->p_sys->last_date = p_pic->date;
-    }
-
-    switch( p_vout->p_sys->i_mode )
-    {
-        case DEINTERLACE_DISCARD:
-            RenderDiscard( p_vout, pp_outpic[0], p_pic, 0 );
-            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
-            break;
-
-        case DEINTERLACE_BOB:
-            RenderBob( p_vout, pp_outpic[0], p_pic, 0 );
-            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
-            RenderBob( p_vout, pp_outpic[1], p_pic, 1 );
-            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[1] );
-            break;
-
-        case DEINTERLACE_LINEAR:
-            RenderLinear( p_vout, pp_outpic[0], p_pic, 0 );
-            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
-            RenderLinear( p_vout, pp_outpic[1], p_pic, 1 );
-            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[1] );
-            break;
-
-        case DEINTERLACE_MEAN:
-            RenderMean( p_vout, pp_outpic[0], p_pic );
-            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
-            break;
-
-        case DEINTERLACE_BLEND:
-            RenderBlend( p_vout, pp_outpic[0], p_pic );
-            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
-            break;
-    }
-
-    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-}
-
-/*****************************************************************************
- * RenderDiscard: only keep TOP or BOTTOM field, discard the other.
- *****************************************************************************/
-static void RenderDiscard( vout_thread_t *p_vout,
-                           picture_t *p_outpic, picture_t *p_pic, int i_field )
-{
-    int i_plane;
-
-    /* Copy image and skip lines */
-    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
-    {
-        uint8_t *p_in, *p_out_end, *p_out;
-        int i_increment;
-
-        p_in = p_pic->p[i_plane].p_pixels
-                   + i_field * p_pic->p[i_plane].i_pitch;
-
-        p_out = p_outpic->p[i_plane].p_pixels;
-        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
-                             * p_outpic->p[i_plane].i_lines;
-
-        switch( p_vout->render.i_chroma )
-        {
-        case VLC_FOURCC('I','4','2','0'):
-        case VLC_FOURCC('I','Y','U','V'):
-        case VLC_FOURCC('Y','V','1','2'):
-
-            for( ; p_out < p_out_end ; )
-            {
-                p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
-
-                p_out += p_pic->p[i_plane].i_pitch;
-                p_in += 2 * p_pic->p[i_plane].i_pitch;
-            }
-            break;
-
-        case VLC_FOURCC('I','4','2','2'):
-
-            i_increment = 2 * p_pic->p[i_plane].i_pitch;
-
-            if( i_plane == Y_PLANE )
-            {
-                for( ; p_out < p_out_end ; )
-                {
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-                    p_out += p_pic->p[i_plane].i_pitch;
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-                    p_out += p_pic->p[i_plane].i_pitch;
-                    p_in += i_increment;
-                }
-            }
-            else
-            {
-                for( ; p_out < p_out_end ; )
-                {
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-                    p_out += p_pic->p[i_plane].i_pitch;
-                    p_in += i_increment;
-                }
-            }
-            break;
-
-        default:
-            break;
-        }
-    }
-}
-
-/*****************************************************************************
- * RenderBob: renders a BOB picture - simple copy
- *****************************************************************************/
-static void RenderBob( vout_thread_t *p_vout,
-                       picture_t *p_outpic, picture_t *p_pic, int i_field )
-{
-    int i_plane;
-
-    /* Copy image and skip lines */
-    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
-    {
-        uint8_t *p_in, *p_out_end, *p_out;
-
-        p_in = p_pic->p[i_plane].p_pixels;
-        p_out = p_outpic->p[i_plane].p_pixels;
-        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
-                             * p_outpic->p[i_plane].i_lines;
-
-        switch( p_vout->render.i_chroma )
-        {
-            case VLC_FOURCC('I','4','2','0'):
-            case VLC_FOURCC('I','Y','U','V'):
-            case VLC_FOURCC('Y','V','1','2'):
-                /* For BOTTOM field we need to add the first line */
-                if( i_field == 1 )
-                {
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-                    p_in += p_pic->p[i_plane].i_pitch;
-                    p_out += p_pic->p[i_plane].i_pitch;
-                }
-
-                p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;
-
-                for( ; p_out < p_out_end ; )
-                {
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-
-                    p_out += p_pic->p[i_plane].i_pitch;
-
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-
-                    p_in += 2 * p_pic->p[i_plane].i_pitch;
-                    p_out += p_pic->p[i_plane].i_pitch;
-                }
-
-                p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
-
-                /* For TOP field we need to add the last line */
-                if( i_field == 0 )
-                {
-                    p_in += p_pic->p[i_plane].i_pitch;
-                    p_out += p_pic->p[i_plane].i_pitch;
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-                }
-                break;
-
-            case VLC_FOURCC('I','4','2','2'):
-                /* For BOTTOM field we need to add the first line */
-                if( i_field == 1 )
-                {
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-                    p_in += p_pic->p[i_plane].i_pitch;
-                    p_out += p_pic->p[i_plane].i_pitch;
-                }
-
-                p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;
-
-                if( i_plane == Y_PLANE )
-                {
-                    for( ; p_out < p_out_end ; )
-                    {
-                        p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                                  p_pic->p[i_plane].i_pitch );
-
-                        p_out += p_pic->p[i_plane].i_pitch;
-
-                        p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                                  p_pic->p[i_plane].i_pitch );
-
-                        p_in += 2 * p_pic->p[i_plane].i_pitch;
-                        p_out += p_pic->p[i_plane].i_pitch;
-                    }
-                }
-                else
-                {
-                    for( ; p_out < p_out_end ; )
-                    {
-                        p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                                  p_pic->p[i_plane].i_pitch );
-
-                        p_out += p_pic->p[i_plane].i_pitch;
-                        p_in += 2 * p_pic->p[i_plane].i_pitch;
-                    }
-                }
-
-                p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
-
-                /* For TOP field we need to add the last line */
-                if( i_field == 0 )
-                {
-                    p_in += p_pic->p[i_plane].i_pitch;
-                    p_out += p_pic->p[i_plane].i_pitch;
-                    p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
-                }
-                break;
-        }
-    }
-}
-
-#define Merge p_vout->p_sys->pf_merge
-#define EndMerge if(p_vout->p_sys->pf_end_merge) p_vout->p_sys->pf_end_merge
-
-/*****************************************************************************
- * RenderLinear: BOB with linear interpolation
- *****************************************************************************/
-static void RenderLinear( vout_thread_t *p_vout,
-                          picture_t *p_outpic, picture_t *p_pic, int i_field )
-{
-    int i_plane;
-
-    /* Copy image and skip lines */
-    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
-    {
-        uint8_t *p_in, *p_out_end, *p_out;
-
-        p_in = p_pic->p[i_plane].p_pixels;
-        p_out = p_outpic->p[i_plane].p_pixels;
-        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
-                             * p_outpic->p[i_plane].i_lines;
-
-        /* For BOTTOM field we need to add the first line */
-        if( i_field == 1 )
-        {
-            p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                      p_pic->p[i_plane].i_pitch );
-            p_in += p_pic->p[i_plane].i_pitch;
-            p_out += p_pic->p[i_plane].i_pitch;
-        }
-
-        p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;
-
-        for( ; p_out < p_out_end ; )
-        {
-            p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                      p_pic->p[i_plane].i_pitch );
-
-            p_out += p_pic->p[i_plane].i_pitch;
-
-            Merge( p_out, p_in, p_in + 2 * p_pic->p[i_plane].i_pitch,
-                   p_pic->p[i_plane].i_pitch );
-
-            p_in += 2 * p_pic->p[i_plane].i_pitch;
-            p_out += p_pic->p[i_plane].i_pitch;
-        }
-
-        p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                  p_pic->p[i_plane].i_pitch );
-
-        /* For TOP field we need to add the last line */
-        if( i_field == 0 )
-        {
-            p_in += p_pic->p[i_plane].i_pitch;
-            p_out += p_pic->p[i_plane].i_pitch;
-            p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                      p_pic->p[i_plane].i_pitch );
-        }
-    }
-    EndMerge();
-}
-
-static void RenderMean( vout_thread_t *p_vout,
-                        picture_t *p_outpic, picture_t *p_pic )
-{
-    int i_plane;
-
-    /* Copy image and skip lines */
-    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
-    {
-        uint8_t *p_in, *p_out_end, *p_out;
-
-        p_in = p_pic->p[i_plane].p_pixels;
-
-        p_out = p_outpic->p[i_plane].p_pixels;
-        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
-                             * p_outpic->p[i_plane].i_lines;
-
-        /* All lines: mean value */
-        for( ; p_out < p_out_end ; )
-        {
-            Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
-                   p_pic->p[i_plane].i_pitch );
-
-            p_out += p_pic->p[i_plane].i_pitch;
-            p_in += 2 * p_pic->p[i_plane].i_pitch;
-        }
-    }
-    EndMerge();
-}
-
-static void RenderBlend( vout_thread_t *p_vout,
-                         picture_t *p_outpic, picture_t *p_pic )
-{
-    int i_plane;
-
-    /* Copy image and skip lines */
-    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
-    {
-        uint8_t *p_in, *p_out_end, *p_out;
-
-        p_in = p_pic->p[i_plane].p_pixels;
-
-        p_out = p_outpic->p[i_plane].p_pixels;
-        p_out_end = p_out + p_outpic->p[i_plane].i_pitch
-                             * p_outpic->p[i_plane].i_lines;
-
-        switch( p_vout->render.i_chroma )
-        {
-            case VLC_FOURCC('I','4','2','0'):
-            case VLC_FOURCC('I','Y','U','V'):
-            case VLC_FOURCC('Y','V','1','2'):
-                /* First line: simple copy */
-                p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
-                p_out += p_pic->p[i_plane].i_pitch;
-
-                /* Remaining lines: mean value */
-                for( ; p_out < p_out_end ; )
-                {
-                   Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
-                          p_pic->p[i_plane].i_pitch );
-
-                    p_out += p_pic->p[i_plane].i_pitch;
-                    p_in += p_pic->p[i_plane].i_pitch;
-                }
-                break;
-
-            case VLC_FOURCC('I','4','2','2'):
-                /* First line: simple copy */
-                p_vout->p_vlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
-                p_out += p_pic->p[i_plane].i_pitch;
-
-                /* Remaining lines: mean value */
-                if( i_plane == Y_PLANE )
-                {
-                    for( ; p_out < p_out_end ; )
-                    {
-                        Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
-                               p_pic->p[i_plane].i_pitch );
-
-                        p_out += p_pic->p[i_plane].i_pitch;
-                        p_in += p_pic->p[i_plane].i_pitch;
-                    }
-                }
-
-                else
-                {
-                    for( ; p_out < p_out_end ; )
-                    {
-                        Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
-                               p_pic->p[i_plane].i_pitch );
-
-                        p_out += p_pic->p[i_plane].i_pitch;
-                        p_in += 2*p_pic->p[i_plane].i_pitch;
-                    }
-                }
-                break;
-        }
-    }
-    EndMerge();
-}
-
-#undef Merge
-
-static void MergeGeneric( void *_p_dest, const void *_p_s1,
-                          const void *_p_s2, size_t i_bytes )
-{
-    uint8_t* p_dest = (uint8_t*)_p_dest;
-    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
-    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
-    uint8_t* p_end = p_dest + i_bytes - 8;
-
-    while( p_dest < p_end )
-    {
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-    }
-
-    p_end += 8;
-
-    while( p_dest < p_end )
-    {
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-    }
-}
-
-#if defined(CAN_COMPILE_MMX)
-static void MergeMMX( void *_p_dest, const void *_p_s1, const void *_p_s2,
-                      size_t i_bytes )
-{
-    uint8_t* p_dest = (uint8_t*)_p_dest;
-    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
-    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
-    uint8_t* p_end = p_dest + i_bytes - 8;
-    while( p_dest < p_end )
-    {
-        __asm__  __volatile__( "movq %2,%%mm1;"
-                               "pavgb %1, %%mm1;"
-                               "movq %%mm1, %0" :"=m" (*p_dest):
-                                                 "m" (*p_s1),
-                                                 "m" (*p_s2) );
-        p_dest += 8;
-        p_s1 += 8;
-        p_s2 += 8;
-    }
-
-    p_end += 8;
-
-    while( p_dest < p_end )
-    {
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-    }
-}
-#endif
-
-#if defined(CAN_COMPILE_SSE)
-static void MergeSSE2( void *_p_dest, const void *_p_s1, const void *_p_s2,
-                       size_t i_bytes )
-{
-    uint8_t* p_dest = (uint8_t*)_p_dest;
-    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
-    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
-    while( (int)p_s1 % 16 )
-    {
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-    }        
-    uint8_t* p_end = p_dest + i_bytes - 16;
-    while( p_dest < p_end )
-    {
-        __asm__  __volatile__( "movdqu %2,%%xmm1;"
-                               "pavgb %1, %%xmm1;"
-                               "movdqu %%xmm1, %0" :"=m" (*p_dest):
-                                                 "m" (*p_s1),
-                                                 "m" (*p_s2) );
-        p_dest += 16;
-        p_s1 += 16;
-        p_s2 += 16;
-    }
-
-    p_end += 16;
-
-    while( p_dest < p_end )
-    {
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-    }
-}
-#endif
-
-#if defined(CAN_COMPILE_MMX) || defined(CAN_COMPILE_SSE)
-static void EndMMX( void )
-{
-    __asm__ __volatile__( "emms" :: );
-}
-#endif
-
-#ifdef CAN_COMPILE_C_ALTIVEC
-static void MergeAltivec( void *_p_dest, const void *_p_s1,
-                          const void *_p_s2, size_t i_bytes )
-{
-    uint8_t *p_dest = (uint8_t*)_p_dest;
-    const uint8_t *p_s1 = (const uint8_t *)_p_s1;
-    const uint8_t *p_s2 = (const uint8_t *)_p_s2;
-    uint8_t *p_end = p_dest + i_bytes - 16;
-
-    if( ( (int)p_s1 & 0xF ) | ( (int)p_s2 & 0xF ) |
-        ( (int)p_dest & 0xF ) )
-    {
-        /* TODO Handle non 16-bytes aligned planes */
-        MergeGeneric( _p_dest, _p_s1, _p_s2, i_bytes );
-        return;
-    }
-
-    while( p_dest < p_end )
-    {
-        vec_st( vec_avg( vec_ld( 0, p_s1 ), vec_ld( 0, p_s2 ) ),
-                0, p_dest );
-        p_s1   += 16;
-        p_s2   += 16;
-        p_dest += 16;
-    }
-
-    p_end += 16;
-
-    while( p_dest < p_end )
-    {
-        *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1;
-    }
-}
-#endif
-
-/*****************************************************************************
- * SendEvents: forward mouse and keyboard events to the parent p_vout
- *****************************************************************************/
-static int SendEvents( vlc_object_t *p_this, char const *psz_var,
-                       vlc_value_t oldval, vlc_value_t newval, void *_p_vout )
-{
-    vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
-    vlc_value_t sentval = newval;
-
-    if( !strcmp( psz_var, "mouse-y" ) )
-    {
-        switch( p_vout->p_sys->i_mode )
-        {
-            case DEINTERLACE_MEAN:
-            case DEINTERLACE_DISCARD:
-                sentval.i_int *= 2;
-                break;
-        }
-    }
-
-    var_Set( p_vout, psz_var, sentval );
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * FilterCallback: called when changing the deinterlace method on the fly.
- *****************************************************************************/
-static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,
-                           vlc_value_t oldval, vlc_value_t newval,
-                           void *p_data )
-{
-    vout_thread_t * p_vout = (vout_thread_t *)p_this;
-    int i_old_mode = p_vout->p_sys->i_mode;
-
-    msg_Dbg( p_vout, "using %s deinterlace mode", newval.psz_string );
-
-    vlc_mutex_lock( &p_vout->p_sys->filter_lock );
-
-    SetFilterMethod( p_vout, newval.psz_string );
-
-    switch( p_vout->render.i_chroma )
-    {
-    case VLC_FOURCC('I','4','2','2'):
-        vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-        return VLC_SUCCESS;
-        break;
-
-    case VLC_FOURCC('I','4','2','0'):
-    case VLC_FOURCC('I','Y','U','V'):
-    case VLC_FOURCC('Y','V','1','2'):
-        switch( p_vout->p_sys->i_mode )
-        {
-        case DEINTERLACE_MEAN:
-        case DEINTERLACE_DISCARD:
-            if( ( i_old_mode == DEINTERLACE_MEAN )
-                || ( i_old_mode == DEINTERLACE_DISCARD ) )
-            {
-                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-                return VLC_SUCCESS;
-            }
-            break;
-
-        case DEINTERLACE_BOB:
-        case DEINTERLACE_BLEND:
-        case DEINTERLACE_LINEAR:
-            if( ( i_old_mode == DEINTERLACE_BOB )
-                || ( i_old_mode == DEINTERLACE_BLEND )
-                || ( i_old_mode == DEINTERLACE_LINEAR ) )
-            {
-                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-                return VLC_SUCCESS;
-            }
-            break;
-        }
-        break;
-
-    default:
-        break;
-    }
-
-    /* We need to kill the old vout */
-
-    DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
-
-    vlc_object_detach( p_vout->p_sys->p_vout );
-    vout_Destroy( p_vout->p_sys->p_vout );
-
-    /* Try to open a new video output */
-    p_vout->p_sys->p_vout = SpawnRealVout( p_vout );
-
-    if( p_vout->p_sys->p_vout == NULL )
-    {
-        /* Everything failed */
-        msg_Err( p_vout, "cannot open vout, aborting" );
-
-        vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-        return VLC_EGENERIC;
-    }
-
-    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
-
-    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * SendEventsToChild: forward events to the child/children vout
- *****************************************************************************/
-static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
-                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-    var_Set( p_vout->p_sys->p_vout, psz_var, newval );
-    return VLC_SUCCESS;
-}
index 93330e7..3e3d203 100644 (file)
@@ -6,3 +6,4 @@ SOURCES_glide = glide.c
 SOURCES_vout_sdl = sdl.c
 SOURCES_svgalib = svgalib.c
 SOURCES_wingdi = wingdi.c
+SOURCES_mga = mga.c
diff --git a/modules/video_output/mga.c b/modules/video_output/mga.c
new file mode 100644 (file)
index 0000000..dc2d321
--- /dev/null
@@ -0,0 +1,343 @@
+/*****************************************************************************
+ * mga.c : Matrox Graphic Array plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000, 2001 VideoLAN
+ * $Id$
+ *
+ * Authors: Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *          Samuel Hocevar <sam@zoy.org>
+ *
+ * This program 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 program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <errno.h>                                                 /* ENOMEM */
+#include <unistd.h>                                               /* close() */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+#include <fcntl.h>                                                 /* open() */
+#include <sys/ioctl.h>                                            /* ioctl() */
+#include <sys/mman.h>                                          /* PROT_WRITE */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+
+#ifdef SYS_BSD
+#include <sys/types.h>                                     /* typedef ushort */
+#endif
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  Create    ( vlc_object_t * );
+static void Destroy   ( vlc_object_t * );
+
+static int  Init      ( vout_thread_t * );
+static void End       ( vout_thread_t * );
+static void Display   ( vout_thread_t *, picture_t * );
+
+static int  NewPicture     ( vout_thread_t *, picture_t * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+    set_description( _("Matrox Graphic Array video output") );
+    set_capability( "video output", 10 );
+    set_callbacks( Create, Destroy );
+vlc_module_end();
+
+/*****************************************************************************
+ * vout_sys_t: video output MGA method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the MGA specific properties of an output thread.
+ *****************************************************************************/
+#ifndef __LINUX_MGAVID_H
+#   define __LINUX_MGAVID_H
+
+#   define MGA_VID_CONFIG _IOR('J', 1, mga_vid_config_t)
+#   define MGA_VID_ON     _IO ('J', 2)
+#   define MGA_VID_OFF    _IO ('J', 3)
+#   define MGA_VID_FSEL   _IOR('J', 4, int)
+#   define MGA_G200 0x1234
+#   define MGA_G400 0x5678
+
+#   define MGA_VID_FORMAT_YV12 0x32315659
+#   define MGA_VID_FORMAT_IYUV (('I'<<24)|('Y'<<16)|('U'<<8)|'V')
+#   define MGA_VID_FORMAT_I420 (('I'<<24)|('4'<<16)|('2'<<8)|'0')
+#   define MGA_VID_FORMAT_YUY2 (('Y'<<24)|('U'<<16)|('Y'<<8)|'2')
+#   define MGA_VID_FORMAT_UYVY (('U'<<24)|('Y'<<16)|('V'<<8)|'Y')
+
+#   define MGA_VID_VERSION     0x0201
+
+#   define MGA_NUM_FRAMES      1
+
+typedef struct mga_vid_config_t
+{
+    uint16_t version;
+    uint16_t card_type;
+    uint32_t ram_size;
+    uint32_t src_width;
+    uint32_t src_height;
+    uint32_t dest_width;
+    uint32_t dest_height;
+    uint32_t x_org;
+    uint32_t y_org;
+    uint8_t  colkey_on;
+    uint8_t  colkey_red;
+    uint8_t  colkey_green;
+    uint8_t  colkey_blue;
+    uint32_t format;
+    uint32_t frame_size;
+    uint32_t num_frames;
+} mga_vid_config_t;
+#endif
+
+struct vout_sys_t
+{
+    mga_vid_config_t    mga;
+    int                 i_fd;
+    byte_t *            p_video;
+};
+
+struct picture_sys_t
+{
+    int     i_frame;
+};
+
+#define CEIL32(x) (((x)+31)&~31)
+
+/*****************************************************************************
+ * Create: allocates dummy video thread output method
+ *****************************************************************************
+ * This function allocates and initializes a dummy vout method.
+ *****************************************************************************/
+static int Create( vlc_object_t *p_this )
+{
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
+
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        msg_Err( p_vout, "out of memory" );
+        return( 1 );
+    }
+
+    p_vout->p_sys->i_fd = open( "/dev/mga_vid", O_RDWR );
+    if( p_vout->p_sys->i_fd == -1 )
+    {
+        msg_Err( p_vout, "cannot open MGA driver /dev/mga_vid" );
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    p_vout->pf_init = Init;
+    p_vout->pf_end = End;
+    p_vout->pf_manage = NULL;
+    p_vout->pf_render = NULL;
+    p_vout->pf_display = Display;
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * Init: initialize dummy video thread output method
+ *****************************************************************************/
+static int Init( vout_thread_t *p_vout )
+{
+    int i_index;
+    picture_t *p_pic;
+
+    I_OUTPUTPICTURES = 0;
+
+    /* create the MGA output */
+    p_vout->output.i_width = p_vout->render.i_width;
+    p_vout->output.i_height = p_vout->render.i_height;
+    p_vout->output.i_aspect = p_vout->render.i_aspect;
+
+    /* Set coordinates and aspect ratio */
+    p_vout->p_sys->mga.src_width = CEIL32(p_vout->output.i_width);
+    p_vout->p_sys->mga.src_height = p_vout->output.i_height;
+    vout_PlacePicture( p_vout, 1024, 768,
+                       &p_vout->p_sys->mga.x_org, &p_vout->p_sys->mga.y_org,
+                       &p_vout->p_sys->mga.dest_width,
+                       &p_vout->p_sys->mga.dest_height );
+
+    /* Initialize a video buffer */
+    p_vout->p_sys->mga.colkey_on = 0;
+    p_vout->p_sys->mga.num_frames = MGA_NUM_FRAMES;
+    p_vout->p_sys->mga.frame_size = CEIL32(p_vout->output.i_width)
+                                     * p_vout->output.i_height * 2;
+    p_vout->p_sys->mga.version = MGA_VID_VERSION;
+
+    /* Assume we only do YMGA for the moment. XXX: mga_vid calls this
+     * YV12, but it's actually some strange format with packed UV. */
+    p_vout->output.i_chroma = VLC_FOURCC('Y','M','G','A');
+    p_vout->p_sys->mga.format = MGA_VID_FORMAT_YV12;
+
+    if( ioctl(p_vout->p_sys->i_fd, MGA_VID_CONFIG, &p_vout->p_sys->mga) )
+    {
+        msg_Err( p_vout, "MGA config ioctl failed" );
+        return -1;
+    }
+
+    if( p_vout->p_sys->mga.card_type == MGA_G200 )
+    {
+        msg_Dbg( p_vout, "detected MGA G200 (%d MB Ram)",
+                         p_vout->p_sys->mga.ram_size );
+    }
+    else
+    {
+        msg_Dbg( p_vout, "detected MGA G400/G450 (%d MB Ram)",
+                         p_vout->p_sys->mga.ram_size );
+    }
+
+    p_vout->p_sys->p_video = mmap( 0, p_vout->p_sys->mga.frame_size
+                                       * MGA_NUM_FRAMES,
+                                   PROT_WRITE, MAP_SHARED,
+                                   p_vout->p_sys->i_fd, 0 );
+
+    /* Try to initialize up to MGA_NUM_FRAMES direct buffers */
+    while( I_OUTPUTPICTURES < MGA_NUM_FRAMES )
+    {
+        p_pic = NULL;
+
+        /* Find an empty picture slot */
+        for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
+        {
+            if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
+            {
+                p_pic = p_vout->p_picture + i_index;
+                break;
+            }
+        }
+
+        /* Allocate the picture */
+        if( p_pic == NULL || NewPicture( p_vout, p_pic ) )
+        {
+            break;
+        }
+
+        p_pic->i_status = DESTROYED_PICTURE;
+        p_pic->i_type   = DIRECT_PICTURE;
+
+        PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
+
+        I_OUTPUTPICTURES++;
+    }
+
+    /* Blank the windows */
+    for( i_index = 0; i_index < I_OUTPUTPICTURES; i_index++ )
+    {
+        memset( p_vout->p_sys->p_video
+                 + p_vout->p_sys->mga.frame_size * i_index,
+                0x00, p_vout->p_sys->mga.frame_size / 2 );
+        memset( p_vout->p_sys->p_video
+                 + p_vout->p_sys->mga.frame_size * ( 2*i_index + 1 ) / 2,
+                0x80, p_vout->p_sys->mga.frame_size / 2 );
+    }
+
+    /* Display the image */
+    ioctl( p_vout->p_sys->i_fd, MGA_VID_ON, 0 );
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * End: terminate dummy video thread output method
+ *****************************************************************************/
+static void End( vout_thread_t *p_vout )
+{
+    int i_index;
+
+    ioctl( p_vout->p_sys->i_fd, MGA_VID_OFF, 0 );
+
+    /* Free the output buffers we allocated */
+    for( i_index = I_OUTPUTPICTURES ; i_index ; )
+    {
+        i_index--;
+    }
+}
+
+/*****************************************************************************
+ * Destroy: destroy dummy video thread output method
+ *****************************************************************************
+ * Terminate an output method created by DummyCreateOutputMethod
+ *****************************************************************************/
+static void Destroy( vlc_object_t *p_this )
+{
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
+    close( p_vout->p_sys->i_fd );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * Display: displays previously rendered output
+ *****************************************************************************/
+static void Display( vout_thread_t *p_vout, picture_t *p_pic )
+{
+    ioctl( p_vout->p_sys->i_fd, MGA_VID_FSEL, &p_pic->p_sys->i_frame );
+}
+
+/* Following functions are local */
+
+/*****************************************************************************
+ * NewPicture: allocate a picture
+ *****************************************************************************
+ * Returns 0 on success, -1 otherwise
+ *****************************************************************************/
+static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
+{
+    /* We know the chroma, allocate a buffer which will be used
+     * directly by the decoder */
+    p_pic->p_data = p_vout->p_sys->p_video + I_OUTPUTPICTURES
+                                              * p_vout->p_sys->mga.frame_size;
+
+    p_pic->p_sys = malloc( sizeof( picture_sys_t ) );
+
+    if( p_pic->p_sys == NULL )
+    {
+        return -1;
+    }
+
+    p_pic->Y_PIXELS = p_pic->p_data;
+    p_pic->p[Y_PLANE].i_lines = p_vout->output.i_height;
+    p_pic->p[Y_PLANE].i_pitch = CEIL32( p_vout->output.i_width );
+    p_pic->p[Y_PLANE].i_pixel_pitch = 1;
+    p_pic->p[Y_PLANE].i_visible_pitch = p_vout->output.i_width;
+
+    p_pic->U_PIXELS = p_pic->p_data + p_vout->p_sys->mga.frame_size * 2/4;
+    p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2;
+    p_pic->p[U_PLANE].i_pitch = CEIL32( p_vout->output.i_width ) / 2;
+    p_pic->p[U_PLANE].i_pixel_pitch = 1;
+    p_pic->p[U_PLANE].i_visible_pitch = p_pic->p[U_PLANE].i_pitch;
+
+    p_pic->V_PIXELS = p_pic->p_data + p_vout->p_sys->mga.frame_size * 3/4;
+    p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2;
+    p_pic->p[V_PLANE].i_pitch = CEIL32( p_vout->output.i_width ) / 2;
+    p_pic->p[V_PLANE].i_pixel_pitch = 1;
+    p_pic->p[V_PLANE].i_visible_pitch = p_pic->p[V_PLANE].i_pitch;
+
+    p_pic->p_sys->i_frame = I_OUTPUTPICTURES;
+
+    p_pic->i_planes = 3;
+
+    return 0;
+}
+
diff --git a/modules/video_output/mga/Modules.am b/modules/video_output/mga/Modules.am
deleted file mode 100644 (file)
index 8b00883..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SOURCES_mga = mga.c
diff --git a/modules/video_output/mga/mga.c b/modules/video_output/mga/mga.c
deleted file mode 100644 (file)
index 9096b50..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*****************************************************************************
- * mga.c : Matrox Graphic Array plugin for vlc
- *****************************************************************************
- * Copyright (C) 2000, 2001 VideoLAN
- * $Id: mga.c,v 1.3 2003/10/25 00:49:14 sam Exp $
- *
- * Authors: Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
- *          Samuel Hocevar <sam@zoy.org>
- *
- * This program 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 program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <errno.h>                                                 /* ENOMEM */
-#include <unistd.h>                                               /* close() */
-#include <stdlib.h>                                                /* free() */
-#include <string.h>                                            /* strerror() */
-#include <fcntl.h>                                                 /* open() */
-#include <sys/ioctl.h>                                            /* ioctl() */
-#include <sys/mman.h>                                          /* PROT_WRITE */
-
-#include <vlc/vlc.h>
-#include <vlc/vout.h>
-
-#ifdef SYS_BSD
-#include <sys/types.h>                                     /* typedef ushort */
-#endif
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int  Create    ( vlc_object_t * );
-static void Destroy   ( vlc_object_t * );
-
-static int  Init      ( vout_thread_t * );
-static void End       ( vout_thread_t * );
-static void Display   ( vout_thread_t *, picture_t * );
-
-static int  NewPicture     ( vout_thread_t *, picture_t * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-vlc_module_begin();
-    set_description( _("Matrox Graphic Array video output") );
-    set_capability( "video output", 10 );
-    set_callbacks( Create, Destroy );
-vlc_module_end();
-
-/*****************************************************************************
- * vout_sys_t: video output MGA method descriptor
- *****************************************************************************
- * This structure is part of the video output thread descriptor.
- * It describes the MGA specific properties of an output thread.
- *****************************************************************************/
-#ifndef __LINUX_MGAVID_H
-#   define __LINUX_MGAVID_H
-
-#   define MGA_VID_CONFIG _IOR('J', 1, mga_vid_config_t)
-#   define MGA_VID_ON     _IO ('J', 2)
-#   define MGA_VID_OFF    _IO ('J', 3)
-#   define MGA_VID_FSEL   _IOR('J', 4, int)
-#   define MGA_G200 0x1234
-#   define MGA_G400 0x5678
-
-#   define MGA_VID_FORMAT_YV12 0x32315659
-#   define MGA_VID_FORMAT_IYUV (('I'<<24)|('Y'<<16)|('U'<<8)|'V')
-#   define MGA_VID_FORMAT_I420 (('I'<<24)|('4'<<16)|('2'<<8)|'0')
-#   define MGA_VID_FORMAT_YUY2 (('Y'<<24)|('U'<<16)|('Y'<<8)|'2')
-#   define MGA_VID_FORMAT_UYVY (('U'<<24)|('Y'<<16)|('V'<<8)|'Y')
-
-#   define MGA_VID_VERSION     0x0201
-
-#   define MGA_NUM_FRAMES      1
-
-typedef struct mga_vid_config_t
-{
-    uint16_t version;
-    uint16_t card_type;
-    uint32_t ram_size;
-    uint32_t src_width;
-    uint32_t src_height;
-    uint32_t dest_width;
-    uint32_t dest_height;
-    uint32_t x_org;
-    uint32_t y_org;
-    uint8_t  colkey_on;
-    uint8_t  colkey_red;
-    uint8_t  colkey_green;
-    uint8_t  colkey_blue;
-    uint32_t format;
-    uint32_t frame_size;
-    uint32_t num_frames;
-} mga_vid_config_t;
-#endif
-
-struct vout_sys_t
-{
-    mga_vid_config_t    mga;
-    int                 i_fd;
-    byte_t *            p_video;
-};
-
-struct picture_sys_t
-{
-    int     i_frame;
-};
-
-#define CEIL32(x) (((x)+31)&~31)
-
-/*****************************************************************************
- * Create: allocates dummy video thread output method
- *****************************************************************************
- * This function allocates and initializes a dummy vout method.
- *****************************************************************************/
-static int Create( vlc_object_t *p_this )
-{
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-
-    /* Allocate structure */
-    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
-    if( p_vout->p_sys == NULL )
-    {
-        msg_Err( p_vout, "out of memory" );
-        return( 1 );
-    }
-
-    p_vout->p_sys->i_fd = open( "/dev/mga_vid", O_RDWR );
-    if( p_vout->p_sys->i_fd == -1 )
-    {
-        msg_Err( p_vout, "cannot open MGA driver /dev/mga_vid" );
-        free( p_vout->p_sys );
-        return( 1 );
-    }
-
-    p_vout->pf_init = Init;
-    p_vout->pf_end = End;
-    p_vout->pf_manage = NULL;
-    p_vout->pf_render = NULL;
-    p_vout->pf_display = Display;
-
-    return( 0 );
-}
-
-/*****************************************************************************
- * Init: initialize dummy video thread output method
- *****************************************************************************/
-static int Init( vout_thread_t *p_vout )
-{
-    int i_index;
-    picture_t *p_pic;
-
-    I_OUTPUTPICTURES = 0;
-
-    /* create the MGA output */
-    p_vout->output.i_width = p_vout->render.i_width;
-    p_vout->output.i_height = p_vout->render.i_height;
-    p_vout->output.i_aspect = p_vout->render.i_aspect;
-
-    /* Set coordinates and aspect ratio */
-    p_vout->p_sys->mga.src_width = CEIL32(p_vout->output.i_width);
-    p_vout->p_sys->mga.src_height = p_vout->output.i_height;
-    vout_PlacePicture( p_vout, 1024, 768,
-                       &p_vout->p_sys->mga.x_org, &p_vout->p_sys->mga.y_org,
-                       &p_vout->p_sys->mga.dest_width,
-                       &p_vout->p_sys->mga.dest_height );
-
-    /* Initialize a video buffer */
-    p_vout->p_sys->mga.colkey_on = 0;
-    p_vout->p_sys->mga.num_frames = MGA_NUM_FRAMES;
-    p_vout->p_sys->mga.frame_size = CEIL32(p_vout->output.i_width)
-                                     * p_vout->output.i_height * 2;
-    p_vout->p_sys->mga.version = MGA_VID_VERSION;
-
-    /* Assume we only do YMGA for the moment. XXX: mga_vid calls this
-     * YV12, but it's actually some strange format with packed UV. */
-    p_vout->output.i_chroma = VLC_FOURCC('Y','M','G','A');
-    p_vout->p_sys->mga.format = MGA_VID_FORMAT_YV12;
-
-    if( ioctl(p_vout->p_sys->i_fd, MGA_VID_CONFIG, &p_vout->p_sys->mga) )
-    {
-        msg_Err( p_vout, "MGA config ioctl failed" );
-        return -1;
-    }
-
-    if( p_vout->p_sys->mga.card_type == MGA_G200 )
-    {
-        msg_Dbg( p_vout, "detected MGA G200 (%d MB Ram)",
-                         p_vout->p_sys->mga.ram_size );
-    }
-    else
-    {
-        msg_Dbg( p_vout, "detected MGA G400/G450 (%d MB Ram)",
-                         p_vout->p_sys->mga.ram_size );
-    }
-
-    p_vout->p_sys->p_video = mmap( 0, p_vout->p_sys->mga.frame_size
-                                       * MGA_NUM_FRAMES,
-                                   PROT_WRITE, MAP_SHARED,
-                                   p_vout->p_sys->i_fd, 0 );
-
-    /* Try to initialize up to MGA_NUM_FRAMES direct buffers */
-    while( I_OUTPUTPICTURES < MGA_NUM_FRAMES )
-    {
-        p_pic = NULL;
-
-        /* Find an empty picture slot */
-        for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
-        {
-            if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
-            {
-                p_pic = p_vout->p_picture + i_index;
-                break;
-            }
-        }
-
-        /* Allocate the picture */
-        if( p_pic == NULL || NewPicture( p_vout, p_pic ) )
-        {
-            break;
-        }
-
-        p_pic->i_status = DESTROYED_PICTURE;
-        p_pic->i_type   = DIRECT_PICTURE;
-
-        PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
-
-        I_OUTPUTPICTURES++;
-    }
-
-    /* Blank the windows */
-    for( i_index = 0; i_index < I_OUTPUTPICTURES; i_index++ )
-    {
-        memset( p_vout->p_sys->p_video
-                 + p_vout->p_sys->mga.frame_size * i_index,
-                0x00, p_vout->p_sys->mga.frame_size / 2 );
-        memset( p_vout->p_sys->p_video
-                 + p_vout->p_sys->mga.frame_size * ( 2*i_index + 1 ) / 2,
-                0x80, p_vout->p_sys->mga.frame_size / 2 );
-    }
-
-    /* Display the image */
-    ioctl( p_vout->p_sys->i_fd, MGA_VID_ON, 0 );
-
-    return( 0 );
-}
-
-/*****************************************************************************
- * End: terminate dummy video thread output method
- *****************************************************************************/
-static void End( vout_thread_t *p_vout )
-{
-    int i_index;
-
-    ioctl( p_vout->p_sys->i_fd, MGA_VID_OFF, 0 );
-
-    /* Free the output buffers we allocated */
-    for( i_index = I_OUTPUTPICTURES ; i_index ; )
-    {
-        i_index--;
-    }
-}
-
-/*****************************************************************************
- * Destroy: destroy dummy video thread output method
- *****************************************************************************
- * Terminate an output method created by DummyCreateOutputMethod
- *****************************************************************************/
-static void Destroy( vlc_object_t *p_this )
-{
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-    close( p_vout->p_sys->i_fd );
-    free( p_vout->p_sys );
-}
-
-/*****************************************************************************
- * Display: displays previously rendered output
- *****************************************************************************/
-static void Display( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    ioctl( p_vout->p_sys->i_fd, MGA_VID_FSEL, &p_pic->p_sys->i_frame );
-}
-
-/* Following functions are local */
-
-/*****************************************************************************
- * NewPicture: allocate a picture
- *****************************************************************************
- * Returns 0 on success, -1 otherwise
- *****************************************************************************/
-static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    /* We know the chroma, allocate a buffer which will be used
-     * directly by the decoder */
-    p_pic->p_data = p_vout->p_sys->p_video + I_OUTPUTPICTURES
-                                              * p_vout->p_sys->mga.frame_size;
-
-    p_pic->p_sys = malloc( sizeof( picture_sys_t ) );
-
-    if( p_pic->p_sys == NULL )
-    {
-        return -1;
-    }
-
-    p_pic->Y_PIXELS = p_pic->p_data;
-    p_pic->p[Y_PLANE].i_lines = p_vout->output.i_height;
-    p_pic->p[Y_PLANE].i_pitch = CEIL32( p_vout->output.i_width );
-    p_pic->p[Y_PLANE].i_pixel_pitch = 1;
-    p_pic->p[Y_PLANE].i_visible_pitch = p_vout->output.i_width;
-
-    p_pic->U_PIXELS = p_pic->p_data + p_vout->p_sys->mga.frame_size * 2/4;
-    p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2;
-    p_pic->p[U_PLANE].i_pitch = CEIL32( p_vout->output.i_width ) / 2;
-    p_pic->p[U_PLANE].i_pixel_pitch = 1;
-    p_pic->p[U_PLANE].i_visible_pitch = p_pic->p[U_PLANE].i_pitch;
-
-    p_pic->V_PIXELS = p_pic->p_data + p_vout->p_sys->mga.frame_size * 3/4;
-    p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2;
-    p_pic->p[V_PLANE].i_pitch = CEIL32( p_vout->output.i_width ) / 2;
-    p_pic->p[V_PLANE].i_pixel_pitch = 1;
-    p_pic->p[V_PLANE].i_visible_pitch = p_pic->p[V_PLANE].i_pitch;
-
-    p_pic->p_sys->i_frame = I_OUTPUTPICTURES;
-
-    p_pic->i_planes = 3;
-
-    return 0;
-}
-
index f075156..b46e015 100644 (file)
@@ -1 +1,2 @@
 SOURCES_goom = goom.c
+SOURCES_xosd = xosd.c
diff --git a/modules/visualization/scope/Modules.am b/modules/visualization/scope/Modules.am
deleted file mode 100644 (file)
index 378ae30..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SOURCES_scope = scope.c
diff --git a/modules/visualization/scope/scope.c b/modules/visualization/scope/scope.c
deleted file mode 100644 (file)
index 708244e..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*****************************************************************************
- * scope.c : Scope effect module
- *****************************************************************************
- * Copyright (C) 2002 VideoLAN
- * $Id: scope.c,v 1.4 2003/08/19 18:51:03 sigmunau Exp $
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- *
- * This program 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 program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>                                              /* strdup() */
-#include <errno.h>
-
-#include <vlc/vlc.h>
-#include <vlc/aout.h>
-#include <vlc/vout.h>
-#include "aout_internal.h"
-
-#define SCOPE_WIDTH 320
-#define SCOPE_HEIGHT 240
-#define SCOPE_ASPECT (VOUT_ASPECT_FACTOR*SCOPE_WIDTH/SCOPE_HEIGHT)
-
-/*****************************************************************************
- * aout_sys_t: scope audio output method descriptor
- *****************************************************************************
- * This structure is part of the audio output thread descriptor.
- * It describes some scope specific variables.
- *****************************************************************************/
-typedef struct aout_filter_sys_t
-{
-    aout_fifo_t *p_aout_fifo;
-    vout_thread_t *p_vout;
-} aout_filter_sys_t;
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int  Open         ( vlc_object_t * );             
-static void Close        ( vlc_object_t * );                   
-
-static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
-                        aout_buffer_t * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-vlc_module_begin();
-    set_description( _("scope effect") ); 
-    set_capability( "audio filter", 0 );
-    set_callbacks( Open, Close );
-    add_shortcut( "scope" );
-vlc_module_end();
-
-/*****************************************************************************
- * Open: open a scope effect plugin
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
-    aout_filter_t *p_aout = (aout_filter_t *)p_this;
-    aout_filter_t * p_filter = (aout_filter_t *)p_this;
-
-    if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2') //AOUT_FMT_U16_NE
-         || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )//AOUT_FMT_U16_NE )
-    {
-        msg_Warn( p_filter, "Bad input or output format" );
-        return -1;
-    }
-
-    if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
-    {
-        msg_Warn( p_filter, "input and output formats are not similar" );
-        return -1;
-    }
-
-    p_filter->pf_do_work = DoWork;
-    p_filter->b_in_place = 1;
-
-    /* Allocate structure */
-    p_aout->p_sys = malloc( sizeof( aout_filter_sys_t ) );
-    if( p_aout->p_sys == NULL )
-    {
-        msg_Err( p_aout, "out of memory" );
-        return -1;
-    }
-
-    /* Open video output */
-    p_aout->p_sys->p_vout =
-        vout_Create( p_aout, SCOPE_WIDTH, SCOPE_HEIGHT,
-                     VLC_FOURCC('I','4','2','0'), SCOPE_ASPECT );
-
-    if( p_aout->p_sys->p_vout == NULL )
-    {
-        msg_Err( p_aout, "no suitable vout module" );
-        free( p_aout->p_sys );
-        return -1;
-    }
-
-    return( 0 );
-}
-
-/*****************************************************************************
- * Play: play a sound samples buffer
- *****************************************************************************
- * This function writes a buffer of i_length bytes in the socket
- *****************************************************************************/
-static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
-                    aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
-{
-    picture_t *p_outpic;
-    int i_index, i_image;
-    byte_t *p_buffer = p_in_buf->p_buffer;
-    uint8_t  *ppp_area[2][3];
-    float *p_sample;
-
-    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
-    p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes;
-    for( i_image = 0; (i_image + 1) * SCOPE_WIDTH  < p_in_buf->i_nb_samples ; i_image++ )
-    {
-        /* Don't stay here forever */
-        if( mdate() >= p_in_buf->end_date - 10000 )
-        {
-            break;
-        }
-        /* This is a new frame. Get a structure from the video_output. */
-        while( ( p_outpic = vout_CreatePicture( p_filter->p_sys->p_vout, 0, 0, 0 ) )
-                  == NULL )
-        {
-            if( p_aout->b_die )
-            {
-                return;
-            }
-            msleep( 1 );/* Not sleeping here makes us use 100% cpu,
-                         * sleeping too much absolutly kills audio
-                         * quality. 1 seems to be a good value */
-        }
-
-        /* Blank the picture */
-        for( i_index = 0 ; i_index < p_outpic->i_planes ; i_index++ )
-        {
-            memset( p_outpic->p[i_index].p_pixels, i_index ? 0x80 : 0x00,
-                    p_outpic->p[i_index].i_lines * p_outpic->p[i_index].i_pitch );
-        }
-
-        /* We only support 2 channels for now */
-        for( i_index = 0 ; i_index < 2 ; i_index++ )
-        {
-            int j;
-            for( j = 0 ; j < 3 ; j++ )
-            {
-                ppp_area[i_index][j] =
-                    p_outpic->p[j].p_pixels + 3 * i_index * p_outpic->p[j].i_lines
-                                / p_filter->input.i_original_channels * p_outpic->p[j].i_pitch;
-            }
-        }
-
-        for( i_index = 0, p_sample = (float*)p_buffer;
-             i_index < SCOPE_WIDTH;
-             i_index++ )
-        {
-            int i;
-            int i_tmp_value;
-            uint8_t i_right_value, i_left_value;
-            if ( *p_sample >= 1.0 ) i_tmp_value = 32767;
-            else if ( *p_sample < -1.0 ) i_tmp_value = -32768;
-            else i_tmp_value = *p_sample * 32768.0;
-            i_left_value = i_tmp_value / 256 + 128;
-            p_sample++;
-            if ( *p_sample >= 1.0 ) i_tmp_value = 32767;
-            else if ( *p_sample < -1.0 ) i_tmp_value = -32768;
-            else i_tmp_value = *p_sample * 32768.0;
-            p_sample++;
-            i_right_value = i_tmp_value / 256 + 128;
-            for( i = 0 ; i < 2 ; i++ )
-            {
-                /* Left channel */
-                *(ppp_area[0][0]
-                   + p_outpic->p[0].i_pitch * i_index / SCOPE_WIDTH
-                   + p_outpic->p[0].i_lines * i_left_value / 512
-                       * p_outpic->p[0].i_pitch) = 0xbf;
-                *(ppp_area[0][1]
-                   + p_outpic->p[1].i_pitch * i_index / SCOPE_WIDTH
-                   + p_outpic->p[1].i_lines * i_left_value / 512
-                      * p_outpic->p[1].i_pitch) = 0xff;
-
-                /* Right channel */
-                *(ppp_area[1][0]
-                   + p_outpic->p[0].i_pitch * i_index / SCOPE_WIDTH
-                   + p_outpic->p[0].i_lines * i_right_value / 512
-                      * p_outpic->p[0].i_pitch) = 0x9f;
-                *(ppp_area[1][2]
-                   + p_outpic->p[2].i_pitch * i_index / SCOPE_WIDTH
-                   + p_outpic->p[2].i_lines * i_right_value / 512
-                      * p_outpic->p[2].i_pitch) = 0xdd;
-            }
-        }
-
-        /* Display the picture - FIXME: find a better date :-) */
-        vout_DatePicture( p_filter->p_sys->p_vout, p_outpic,
-                          p_in_buf->start_date + i_image * 20000 );
-        vout_DisplayPicture( p_filter->p_sys->p_vout, p_outpic );
-
-        p_buffer += SCOPE_WIDTH * 8;
-    }
-}
-
-/*****************************************************************************
- * Close: close the plugin
- *****************************************************************************/
-static void Close( vlc_object_t *p_this )
-{
-    aout_filter_t * p_filter = (aout_filter_t *)p_this;
-
-    /* Kill video output */
-    vout_Destroy( p_filter->p_sys->p_vout );
-
-    free( p_filter->p_sys );
-}
-
diff --git a/modules/visualization/xosd.c b/modules/visualization/xosd.c
new file mode 100644 (file)
index 0000000..485a900
--- /dev/null
@@ -0,0 +1,224 @@
+/*****************************************************************************
+ * xosd.c : X On Screen Display interface
+ *****************************************************************************
+ * Copyright (C) 2001 VideoLAN
+ * $Id$
+ *
+ * Authors: Loïc Minier <lool@videolan.org>
+ *
+ * This program 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 program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>
+
+#include <xosd.h>
+
+#include <vlc/intf.h>
+
+#ifdef HAVE_UNISTD_H
+#    include <unistd.h>
+#endif
+
+/*****************************************************************************
+ * intf_sys_t: description and status of rc interface
+ *****************************************************************************/
+struct intf_sys_t
+{
+    input_thread_t * p_input;   /* associated input thread */
+    xosd * p_osd;               /* libxosd handle */
+    char * psz_source;          /* current file || NULL */
+};
+
+#define MAX_LINE_LENGTH 256
+
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
+static int  Open         ( vlc_object_t * );
+static void Close        ( vlc_object_t * );
+
+static void Run          ( intf_thread_t * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+#define POSITION_TEXT N_("Flip vertical position")
+#define POSITION_LONGTEXT N_("Display xosd output on the bottom of the " \
+                             "screen instead of the top")
+
+#define TXT_OFS_TEXT N_("Vertical offset")
+#define TXT_OFS_LONGTEXT N_("Vertical offset in pixels of the displayed text")
+
+#define SHD_OFS_TEXT N_("Shadow offset")
+#define SHD_OFS_LONGTEXT N_("Offset in pixels of the shadow")
+
+#define FONT_TEXT N_("Font")
+#define FONT_LONGTEXT N_("Font used to display text in the xosd output")
+
+vlc_module_begin();
+    set_description( _("XOSD interface") );
+    add_bool( "xosd-position", 1, NULL, POSITION_TEXT, POSITION_LONGTEXT, VLC_TRUE );
+    add_integer( "xosd-text-offset", 0, NULL, TXT_OFS_TEXT, TXT_OFS_LONGTEXT, VLC_TRUE );
+    add_integer( "xosd-shadow-offset", 1, NULL,
+                 SHD_OFS_TEXT, SHD_OFS_LONGTEXT, VLC_TRUE );
+    add_string( "xosd-font", "-misc-fixed-medium-r-*-*-*-300-*-*-*-*-*-*",
+                NULL, FONT_TEXT, FONT_LONGTEXT, VLC_TRUE );
+    set_capability( "interface", 10 );
+    set_callbacks( Open, Close );
+vlc_module_end();
+
+/*****************************************************************************
+ * Open: initialize and create stuff
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        msg_Err( p_intf, "out of memory" );
+        return VLC_ENOMEM;
+    }
+
+    if( getenv( "DISPLAY" ) == NULL )
+    {
+        msg_Err( p_intf, "no display, please set the DISPLAY variable" );
+        return VLC_EGENERIC;
+    }
+
+    /* Initialize library */
+    p_intf->p_sys->p_osd =
+#if defined(HAVE_XOSD_VERSION_0) || defined(HAVE_XOSD_VERSION_1)
+        xosd_init( config_GetPsz( p_intf, "xosd-font" ),
+                   "LawnGreen", 3, XOSD_top, 0, 1 );
+#else
+        xosd_init( config_GetPsz( p_intf, "xosd-font" ),
+                   "LawnGreen", 3, XOSD_top, 0, 0, 1 );
+#endif
+
+    if( p_intf->p_sys->p_osd == NULL )
+    {
+        msg_Err( p_intf, "couldn't initialize libxosd" );
+        return VLC_EGENERIC;
+    }
+
+    /* Initialize to NULL */
+    p_intf->p_sys->psz_source = NULL;
+
+    xosd_display( p_intf->p_sys->p_osd,
+                  0,
+                  XOSD_string,
+                  "xosd interface initialized" );
+
+    p_intf->pf_run = Run;
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Close: destroy interface stuff
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+
+    if( p_intf->p_sys->psz_source ) free( p_intf->p_sys->psz_source );
+
+    /* Uninitialize library */
+    xosd_uninit( p_intf->p_sys->p_osd );
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+/*****************************************************************************
+ * Run: xosd thread
+ *****************************************************************************
+ * This part of the interface runs in a separate thread
+ *****************************************************************************/
+static void Run( intf_thread_t *p_intf )
+{
+    p_intf->p_sys->p_input = NULL;
+
+    while( !p_intf->b_die )
+    {
+        /* Manage the input part */
+        if( p_intf->p_sys->p_input == NULL )
+        {
+            p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
+                                                              FIND_ANYWHERE );
+        }
+        else if( p_intf->p_sys->p_input->b_dead )
+        {
+            vlc_object_release( p_intf->p_sys->p_input );
+            p_intf->p_sys->p_input = NULL;
+        }
+        else /* We have a valid input */
+        {
+            /* Did source change? */
+            if ( (p_intf->p_sys->psz_source == NULL)
+                 || (strcmp( p_intf->p_sys->psz_source,
+                             p_intf->p_sys->p_input->psz_source ) != 0)
+               )
+            {
+                if( p_intf->p_sys->psz_source )
+                    free( p_intf->p_sys->psz_source );
+
+                p_intf->p_sys->psz_source =
+                    strdup( p_intf->p_sys->p_input->psz_source );
+
+                /* Set user preferences */
+                xosd_set_font( p_intf->p_sys->p_osd,
+                               config_GetPsz( p_intf, "xosd-font" ) );
+#ifdef HAVE_XOSD_VERSION_2
+                xosd_set_horizontal_offset( p_intf->p_sys->p_osd,
+                    config_GetInt( p_intf, "xosd-text-offset" ) );
+                xosd_set_vertical_offset( p_intf->p_sys->p_osd,
+                    config_GetInt( p_intf, "xosd-text-offset" ) );
+#else
+                xosd_set_offset( p_intf->p_sys->p_osd,
+                    config_GetInt( p_intf, "xosd-text-offset" ) );
+#endif
+                xosd_set_shadow_offset( p_intf->p_sys->p_osd,
+                    config_GetInt( p_intf, "xosd-shadow-offset" ));
+                xosd_set_pos( p_intf->p_sys->p_osd,
+                    config_GetInt( p_intf, "xosd-position" ) ? XOSD_bottom
+                                                             : XOSD_top );
+
+                /* Display */
+                xosd_display( p_intf->p_sys->p_osd,
+                              0,                               /* first line */
+                              XOSD_string,
+                              p_intf->p_sys->psz_source );
+            }
+        }
+
+        msleep( INTF_IDLE_SLEEP );
+    }
+
+    if( p_intf->p_sys->p_input )
+    {
+        vlc_object_release( p_intf->p_sys->p_input );
+        p_intf->p_sys->p_input = NULL;
+    }
+
+}
+
diff --git a/modules/visualization/xosd/Modules.am b/modules/visualization/xosd/Modules.am
deleted file mode 100644 (file)
index 67bf672..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SOURCES_xosd = xosd.c
diff --git a/modules/visualization/xosd/xosd.c b/modules/visualization/xosd/xosd.c
deleted file mode 100644 (file)
index 6f2b239..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*****************************************************************************
- * xosd.c : X On Screen Display interface
- *****************************************************************************
- * Copyright (C) 2001 VideoLAN
- * $Id: xosd.c,v 1.12 2004/01/25 20:40:59 gbazin Exp $
- *
- * Authors: Loïc Minier <lool@videolan.org>
- *
- * This program 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 program 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <string.h>
-
-#include <xosd.h>
-
-#include <vlc/intf.h>
-
-#ifdef HAVE_UNISTD_H
-#    include <unistd.h>
-#endif
-
-/*****************************************************************************
- * intf_sys_t: description and status of rc interface
- *****************************************************************************/
-struct intf_sys_t
-{
-    input_thread_t * p_input;   /* associated input thread */
-    xosd * p_osd;               /* libxosd handle */
-    char * psz_source;          /* current file || NULL */
-};
-
-#define MAX_LINE_LENGTH 256
-
-/*****************************************************************************
- * Local prototypes.
- *****************************************************************************/
-static int  Open         ( vlc_object_t * );
-static void Close        ( vlc_object_t * );
-
-static void Run          ( intf_thread_t * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-#define POSITION_TEXT N_("Flip vertical position")
-#define POSITION_LONGTEXT N_("Display xosd output on the bottom of the " \
-                             "screen instead of the top")
-
-#define TXT_OFS_TEXT N_("Vertical offset")
-#define TXT_OFS_LONGTEXT N_("Vertical offset in pixels of the displayed text")
-
-#define SHD_OFS_TEXT N_("Shadow offset")
-#define SHD_OFS_LONGTEXT N_("Offset in pixels of the shadow")
-
-#define FONT_TEXT N_("Font")
-#define FONT_LONGTEXT N_("Font used to display text in the xosd output")
-
-vlc_module_begin();
-    set_description( _("XOSD interface") );
-    add_bool( "xosd-position", 1, NULL, POSITION_TEXT, POSITION_LONGTEXT, VLC_TRUE );
-    add_integer( "xosd-text-offset", 0, NULL, TXT_OFS_TEXT, TXT_OFS_LONGTEXT, VLC_TRUE );
-    add_integer( "xosd-shadow-offset", 1, NULL,
-                 SHD_OFS_TEXT, SHD_OFS_LONGTEXT, VLC_TRUE );
-    add_string( "xosd-font", "-misc-fixed-medium-r-*-*-*-300-*-*-*-*-*-*",
-                NULL, FONT_TEXT, FONT_LONGTEXT, VLC_TRUE );
-    set_capability( "interface", 10 );
-    set_callbacks( Open, Close );
-vlc_module_end();
-
-/*****************************************************************************
- * Open: initialize and create stuff
- *****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
-    intf_thread_t *p_intf = (intf_thread_t *)p_this;
-
-    /* Allocate instance and initialize some members */
-    p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
-    if( p_intf->p_sys == NULL )
-    {
-        msg_Err( p_intf, "out of memory" );
-        return VLC_ENOMEM;
-    }
-
-    if( getenv( "DISPLAY" ) == NULL )
-    {
-        msg_Err( p_intf, "no display, please set the DISPLAY variable" );
-        return VLC_EGENERIC;
-    }
-
-    /* Initialize library */
-    p_intf->p_sys->p_osd =
-#if defined(HAVE_XOSD_VERSION_0) || defined(HAVE_XOSD_VERSION_1)
-        xosd_init( config_GetPsz( p_intf, "xosd-font" ),
-                   "LawnGreen", 3, XOSD_top, 0, 1 );
-#else
-        xosd_init( config_GetPsz( p_intf, "xosd-font" ),
-                   "LawnGreen", 3, XOSD_top, 0, 0, 1 );
-#endif
-
-    if( p_intf->p_sys->p_osd == NULL )
-    {
-        msg_Err( p_intf, "couldn't initialize libxosd" );
-        return VLC_EGENERIC;
-    }
-
-    /* Initialize to NULL */
-    p_intf->p_sys->psz_source = NULL;
-
-    xosd_display( p_intf->p_sys->p_osd,
-                  0,
-                  XOSD_string,
-                  "xosd interface initialized" );
-
-    p_intf->pf_run = Run;
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * Close: destroy interface stuff
- *****************************************************************************/
-static void Close( vlc_object_t *p_this )
-{
-    intf_thread_t *p_intf = (intf_thread_t *)p_this;
-
-    if( p_intf->p_sys->psz_source ) free( p_intf->p_sys->psz_source );
-
-    /* Uninitialize library */
-    xosd_uninit( p_intf->p_sys->p_osd );
-
-    /* Destroy structure */
-    free( p_intf->p_sys );
-}
-
-/*****************************************************************************
- * Run: xosd thread
- *****************************************************************************
- * This part of the interface runs in a separate thread
- *****************************************************************************/
-static void Run( intf_thread_t *p_intf )
-{
-    p_intf->p_sys->p_input = NULL;
-
-    while( !p_intf->b_die )
-    {
-        /* Manage the input part */
-        if( p_intf->p_sys->p_input == NULL )
-        {
-            p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
-                                                              FIND_ANYWHERE );
-        }
-        else if( p_intf->p_sys->p_input->b_dead )
-        {
-            vlc_object_release( p_intf->p_sys->p_input );
-            p_intf->p_sys->p_input = NULL;
-        }
-        else /* We have a valid input */
-        {
-            /* Did source change? */
-            if ( (p_intf->p_sys->psz_source == NULL)
-                 || (strcmp( p_intf->p_sys->psz_source,
-                             p_intf->p_sys->p_input->psz_source ) != 0)
-               )
-            {
-                if( p_intf->p_sys->psz_source )
-                    free( p_intf->p_sys->psz_source );
-
-                p_intf->p_sys->psz_source =
-                    strdup( p_intf->p_sys->p_input->psz_source );
-
-                /* Set user preferences */
-                xosd_set_font( p_intf->p_sys->p_osd,
-                               config_GetPsz( p_intf, "xosd-font" ) );
-#ifdef HAVE_XOSD_VERSION_2
-                xosd_set_horizontal_offset( p_intf->p_sys->p_osd,
-                    config_GetInt( p_intf, "xosd-text-offset" ) );
-                xosd_set_vertical_offset( p_intf->p_sys->p_osd,
-                    config_GetInt( p_intf, "xosd-text-offset" ) );
-#else
-                xosd_set_offset( p_intf->p_sys->p_osd,
-                    config_GetInt( p_intf, "xosd-text-offset" ) );
-#endif
-                xosd_set_shadow_offset( p_intf->p_sys->p_osd,
-                    config_GetInt( p_intf, "xosd-shadow-offset" ));
-                xosd_set_pos( p_intf->p_sys->p_osd,
-                    config_GetInt( p_intf, "xosd-position" ) ? XOSD_bottom
-                                                             : XOSD_top );
-
-                /* Display */
-                xosd_display( p_intf->p_sys->p_osd,
-                              0,                               /* first line */
-                              XOSD_string,
-                              p_intf->p_sys->psz_source );
-            }
-        }
-
-        msleep( INTF_IDLE_SLEEP );
-    }
-
-    if( p_intf->p_sys->p_input )
-    {
-        vlc_object_release( p_intf->p_sys->p_input );
-        p_intf->p_sys->p_input = NULL;
-    }
-
-}
-