]> git.sesse.net Git - vlc/blobdiff - modules/video_output/sdl.c
Copyright fixes
[vlc] / modules / video_output / sdl.c
index d5e9bd1ae205f7077d6c219b0a3389ad7f66aa9e..d140d593523e3f660f9b9c3b08e97492bee5432b 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * sdl.c: SDL video output display method
  *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: sdl.c,v 1.5 2002/12/23 21:58:33 jpsaman Exp $
+ * Copyright (C) 1998-2001 VideoLAN (Centrale Réseaux) and its contributors
+ * $Id$
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Pierre Baillet <oct@zoy.org>
@@ -12,7 +12,7 @@
  * 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
@@ -33,6 +33,7 @@
 #include <vlc/vlc.h>
 #include <vlc/intf.h>
 #include <vlc/vout.h>
+#include <vlc/aout.h>
 
 #include <sys/types.h>
 #ifndef WIN32
@@ -41,8 +42,6 @@
 
 #include SDL_INCLUDE_FILE
 
-#include "netutils.h"
-
 #define SDL_MAX_DIRECTBUFFERS 10
 #define SDL_DEFAULT_BPP 16
 
@@ -95,16 +94,26 @@ static void Display   ( vout_thread_t *, picture_t * );
 static int  OpenDisplay     ( vout_thread_t * );
 static void CloseDisplay    ( vout_thread_t * );
 static int  NewPicture      ( vout_thread_t *, picture_t * );
-static void SetPalette      ( vout_thread_t *, u16 *, u16 *, u16 * );
+static void SetPalette      ( vout_thread_t *,
+                              uint16_t *, uint16_t *, uint16_t * );
 
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
 vlc_module_begin();
-    set_description( _("Simple DirectMedia Layer video module") );
+    set_shortname( "SDL" );
+    set_category( CAT_VIDEO );
+    set_subcategory( SUBCAT_VIDEO_VOUT );
+    set_description( _("Simple DirectMedia Layer video output") );
     set_capability( "video output", 60 );
     add_shortcut( "sdl" );
     set_callbacks( Open, Close );
+    /* XXX: check for conflicts with the SDL audio output */
+    var_Create( p_module->p_libvlc, "sdl", VLC_VAR_MUTEX );
+#if defined( __i386__ ) || defined( __x86_64__ )
+    /* On i386, SDL is linked against svgalib */
+    linked_with_a_crap_library_which_uses_atexit();
+#endif
 vlc_module_end();
 
 /*****************************************************************************
@@ -114,17 +123,22 @@ vlc_module_end();
  * vout properties to choose the correct mode, and change them according to the
  * mode actually used.
  *****************************************************************************/
-static int Open ( vlc_object_t *p_this )                         
+static int Open ( vlc_object_t *p_this )
 {
-    vout_thread_t * p_vout = (vout_thread_t *)p_this;          
+    vout_thread_t * p_vout = (vout_thread_t *)p_this;
+    vlc_value_t lockval;
 
 #ifdef HAVE_SETENV
     char *psz_method;
 #endif
 
+    var_Get( p_this->p_libvlc, "sdl", &lockval );
+    vlc_mutex_lock( lockval.p_address );
+
     if( SDL_WasInit( SDL_INIT_VIDEO ) != 0 )
     {
-        return( 1 );
+        vlc_mutex_unlock( lockval.p_address );
+        return VLC_EGENERIC;
     }
 
     /* Allocate structure */
@@ -132,7 +146,8 @@ static int Open ( vlc_object_t *p_this )
     if( p_vout->p_sys == NULL )
     {
         msg_Err( p_vout, "out of memory" );
-        return( 1 );
+        vlc_mutex_unlock( lockval.p_address );
+        return VLC_ENOMEM;
     }
 
     p_vout->pf_init = Init;
@@ -172,9 +187,12 @@ static int Open ( vlc_object_t *p_this )
     {
         msg_Err( p_vout, "cannot initialize SDL (%s)", SDL_GetError() );
         free( p_vout->p_sys );
-        return( 1 );
+        vlc_mutex_unlock( lockval.p_address );
+        return VLC_EGENERIC;
     }
 
+    vlc_mutex_unlock( lockval.p_address );
+
     p_vout->p_sys->b_cursor = 1;
     p_vout->p_sys->b_cursor_autohidden = 0;
     p_vout->p_sys->i_lastmoved = mdate();
@@ -184,10 +202,10 @@ static int Open ( vlc_object_t *p_this )
         msg_Err( p_vout, "cannot set up SDL (%s)", SDL_GetError() );
         SDL_QuitSubSystem( SDL_INIT_VIDEO );
         free( p_vout->p_sys );
-        return( 1 );
+        return VLC_EGENERIC;
     }
 
-    return( 0 );
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -252,7 +270,7 @@ static int Init( vout_thread_t *p_vout )
         I_OUTPUTPICTURES++;
     }
 
-    return( 0 );
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -288,9 +306,9 @@ static void End( vout_thread_t *p_vout )
  *****************************************************************************
  * Terminate an output method created by vout_SDLCreate
  *****************************************************************************/
-static void Close ( vlc_object_t *p_this )                         
+static void Close ( vlc_object_t *p_this )
 {
-    vout_thread_t * p_vout = (vout_thread_t *)p_this;          
+    vout_thread_t * p_vout = (vout_thread_t *)p_this;
 
     CloseDisplay( p_vout );
     SDL_QuitSubSystem( SDL_INIT_VIDEO );
@@ -302,7 +320,7 @@ static void Close ( vlc_object_t *p_this )
  * Manage: handle Sys events
  *****************************************************************************
  * This function should be called regularly by video output thread. It returns
- * a non null value if an error occured.
+ * a non null value if an error occurred.
  *****************************************************************************/
 static int Manage( vout_thread_t *p_vout )
 {
@@ -390,11 +408,9 @@ static int Manage( vout_thread_t *p_vout )
                 break;
 
             case 4:
-                input_Seek( p_vout, 15, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                 break;
 
             case 5:
-                input_Seek( p_vout, -15, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                 break;
             }
             break;
@@ -445,7 +461,7 @@ static int Manage( vout_thread_t *p_vout )
                 p_vout->b_interface = ! p_vout->b_interface;
                 p_vout->i_changes |= VOUT_INTF_CHANGE;
                 break;
-            
+
             case SDLK_MENU:
                 {
                     intf_thread_t *p_intf;
@@ -460,72 +476,41 @@ static int Manage( vout_thread_t *p_vout )
                 break;
 
             case SDLK_LEFT:
-                input_Seek( p_vout, -5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                 break;
 
             case SDLK_RIGHT:
-                input_Seek( p_vout, 5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                 break;
 
             case SDLK_UP:
-                input_Seek( p_vout, 60, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                 break;
 
             case SDLK_DOWN:
-                input_Seek( p_vout, -60, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
                 break;
 
-            case SDLK_F1: network_ChannelJoin( p_vout, 1 ); break;
-            case SDLK_F2: network_ChannelJoin( p_vout, 2 ); break;
-            case SDLK_F3: network_ChannelJoin( p_vout, 3 ); break;
-            case SDLK_F4: network_ChannelJoin( p_vout, 4 ); break;
-            case SDLK_F5: network_ChannelJoin( p_vout, 5 ); break;
-            case SDLK_F6: network_ChannelJoin( p_vout, 6 ); break;
-            case SDLK_F7: network_ChannelJoin( p_vout, 7 ); break;
-            case SDLK_F8: network_ChannelJoin( p_vout, 8 ); break;
-            case SDLK_F9: network_ChannelJoin( p_vout, 9 ); break;
-            case SDLK_F10: network_ChannelJoin( p_vout, 10 ); break;
-            case SDLK_F11: network_ChannelJoin( p_vout, 11 ); break;
-            case SDLK_F12: network_ChannelJoin( p_vout, 12 ); break;
-
             case SDLK_b:
                 {
-                    aout_instance_t * p_aout;
                     audio_volume_t i_volume;
-                    p_aout = vlc_object_find( p_vout, VLC_OBJECT_AOUT,
-                                                      FIND_ANYWHERE );
-                    if( p_aout != NULL )
+                    if ( !aout_VolumeDown( p_vout, 1, &i_volume ) )
                     {
-                        if ( !aout_VolumeDown( p_aout, 1, &i_volume ) )
-                        {
-                            msg_Dbg( p_vout, "audio volume is now %d", i_volume );
-                        }
-                        else
-                        {
-                            msg_Dbg( p_vout, "audio volume: operation not supported" );
-                        }
-                        vlc_object_release( (vlc_object_t *)p_aout );
+                        msg_Dbg( p_vout, "audio volume is now %d", i_volume );
+                    }
+                    else
+                    {
+                        msg_Dbg( p_vout, "audio volume: operation not supported" );
                     }
                 }
                 break;
 
             case SDLK_n:
                 {
-                    aout_instance_t * p_aout;
                     audio_volume_t i_volume;
-                    p_aout = vlc_object_find( p_vout, VLC_OBJECT_AOUT,
-                                                      FIND_ANYWHERE );
-                    if( p_aout != NULL )
+                    if ( !aout_VolumeUp( p_vout, 1, &i_volume ) )
+                    {
+                        msg_Dbg( p_vout, "audio volume is now %d", i_volume );
+                    }
+                    else
                     {
-                        if ( !aout_VolumeUp( p_aout, 1, &i_volume ) )
-                        {
-                            msg_Dbg( p_vout, "audio volume is now %d", i_volume );
-                        }
-                        else
-                        {
-                            msg_Dbg( p_vout, "audio volume: operation not supported" );
-                        }
-                        vlc_object_release( (vlc_object_t *)p_aout );
+                        msg_Dbg( p_vout, "audio volume: operation not supported" );
                     }
                 }
                 break;
@@ -560,7 +545,7 @@ static int Manage( vout_thread_t *p_vout )
     {
         msg_Dbg( p_vout, "video display resized (%dx%d)",
                  p_vout->p_sys->i_width, p_vout->p_sys->i_height );
+
         CloseDisplay( p_vout );
         OpenDisplay( p_vout );
 
@@ -580,7 +565,7 @@ static int Manage( vout_thread_t *p_vout )
         SDL_ShowCursor( 0 );
     }
 
-    return( 0 );
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -624,8 +609,11 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
  *****************************************************************************/
 static int OpenDisplay( vout_thread_t *p_vout )
 {
-    Uint32 i_flags;
-    int    i_bpp;
+    uint32_t i_flags;
+    int i_bpp;
+
+    /* SDL fucked up fourcc definitions on bigendian machines */
+    uint32_t i_sdl_chroma;
 
     /* Set main window's size */
     p_vout->p_sys->i_width = p_vout->b_fullscreen ? p_vout->output.i_width :
@@ -642,7 +630,7 @@ static int OpenDisplay( vout_thread_t *p_vout )
     if( i_bpp == 0 )
     {
         msg_Err( p_vout, "no video mode available" );
-        return( 1 );
+        return VLC_EGENERIC;
     }
 
     p_vout->p_sys->p_display = SDL_SetVideoMode( p_vout->p_sys->i_width,
@@ -652,7 +640,7 @@ static int OpenDisplay( vout_thread_t *p_vout )
     if( p_vout->p_sys->p_display == NULL )
     {
         msg_Err( p_vout, "cannot set video mode" );
-        return( 1 );
+        return VLC_EGENERIC;
     }
 
     SDL_LockSurface( p_vout->p_sys->p_display );
@@ -662,52 +650,55 @@ static int OpenDisplay( vout_thread_t *p_vout )
     {
         case VLC_FOURCC('Y','U','Y','2'):
         case VLC_FOURCC('Y','U','N','V'):
-            p_vout->output.i_chroma = SDL_YUY2_OVERLAY;
+            p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
+            i_sdl_chroma = SDL_YUY2_OVERLAY;
             break;
         case VLC_FOURCC('U','Y','V','Y'):
         case VLC_FOURCC('U','Y','N','V'):
         case VLC_FOURCC('Y','4','2','2'):
-            p_vout->output.i_chroma = SDL_UYVY_OVERLAY;
+            p_vout->output.i_chroma = VLC_FOURCC('U','Y','V','Y');
+            i_sdl_chroma = SDL_UYVY_OVERLAY;
             break;
         case VLC_FOURCC('Y','V','Y','U'):
-            p_vout->output.i_chroma = SDL_YVYU_OVERLAY;
+            p_vout->output.i_chroma = VLC_FOURCC('Y','V','Y','U');
+            i_sdl_chroma = SDL_YVYU_OVERLAY;
             break;
         case VLC_FOURCC('Y','V','1','2'):
         case VLC_FOURCC('I','4','2','0'):
         case VLC_FOURCC('I','Y','U','V'):
         default:
-            p_vout->output.i_chroma = SDL_YV12_OVERLAY;
+            p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
+            i_sdl_chroma = SDL_YV12_OVERLAY;
             break;
     }
 
     p_vout->p_sys->p_overlay =
-        SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
-                              p_vout->p_sys->p_display );
+        SDL_CreateYUVOverlay( 32, 32, i_sdl_chroma, p_vout->p_sys->p_display );
     /* FIXME: if the first overlay we find is software, don't stop,
      * because we may find a hardware one later ... */
 
     /* If this best choice failed, fall back to other chromas */
     if( p_vout->p_sys->p_overlay == NULL )
     {
-        p_vout->output.i_chroma = SDL_IYUV_OVERLAY;
+        p_vout->output.i_chroma = VLC_FOURCC('I','Y','U','V');
         p_vout->p_sys->p_overlay =
-            SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
+            SDL_CreateYUVOverlay( 32, 32, SDL_IYUV_OVERLAY,
                                   p_vout->p_sys->p_display );
     }
 
     if( p_vout->p_sys->p_overlay == NULL )
     {
-        p_vout->output.i_chroma = SDL_YV12_OVERLAY;
+        p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
         p_vout->p_sys->p_overlay =
-            SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
+            SDL_CreateYUVOverlay( 32, 32, SDL_YV12_OVERLAY,
                                   p_vout->p_sys->p_display );
     }
 
     if( p_vout->p_sys->p_overlay == NULL )
     {
-        p_vout->output.i_chroma = SDL_YUY2_OVERLAY;
+        p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
         p_vout->p_sys->p_overlay =
-            SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
+            SDL_CreateYUVOverlay( 32, 32, SDL_YUY2_OVERLAY,
                                   p_vout->p_sys->p_display );
     }
 
@@ -739,7 +730,7 @@ static int OpenDisplay( vout_thread_t *p_vout )
                          p_vout->p_sys->p_display->format->BitsPerPixel );
                 SDL_UnlockSurface( p_vout->p_sys->p_display );
                 SDL_FreeSurface( p_vout->p_sys->p_display );
-                return( -1 );
+                return VLC_EGENERIC;
         }
 
         p_vout->output.i_rmask = p_vout->p_sys->p_display->format->Rmask;
@@ -765,7 +756,7 @@ static int OpenDisplay( vout_thread_t *p_vout )
 
     SDL_EventState( SDL_KEYUP, SDL_IGNORE );               /* ignore keys up */
 
-    return( 0 );
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
@@ -797,14 +788,14 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
         if( p_vout->p_sys->i_surfaces )
         {
             /* We already allocated this surface, return */
-            return -1;
+            return VLC_EGENERIC;
         }
 
         p_pic->p_sys = malloc( sizeof( picture_sys_t ) );
 
         if( p_pic->p_sys == NULL )
         {
-            return -1;
+            return VLC_ENOMEM;
         }
 
         switch( p_vout->p_sys->p_display->format->BitsPerPixel )
@@ -821,11 +812,12 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
                 p_pic->p->i_pixel_pitch = 4;
                 break;
             default:
-                return( -1 );
+                return VLC_EGENERIC;
         }
 
         p_pic->p->p_pixels = p_vout->p_sys->p_display->pixels;
         p_pic->p->i_lines = p_vout->p_sys->p_display->h;
+        p_pic->p->i_visible_lines = p_vout->p_sys->p_display->h;
         p_pic->p->i_pitch = p_vout->p_sys->p_display->pitch;
         p_pic->p->i_visible_pitch =
             p_pic->p->i_pixel_pitch * p_vout->p_sys->p_display->w;
@@ -840,7 +832,7 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
 
         if( p_pic->p_sys == NULL )
         {
-            return -1;
+            return VLC_ENOMEM;
         }
 
         p_pic->p_sys->p_overlay =
@@ -851,75 +843,81 @@ static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
         if( p_pic->p_sys->p_overlay == NULL )
         {
             free( p_pic->p_sys );
-            return -1;
+            return VLC_EGENERIC;
         }
 
         SDL_LockYUVOverlay( p_pic->p_sys->p_overlay );
 
         p_pic->Y_PIXELS = p_pic->p_sys->p_overlay->pixels[0];
         p_pic->p[Y_PLANE].i_lines = p_pic->p_sys->p_overlay->h;
+        p_pic->p[Y_PLANE].i_visible_lines = p_pic->p_sys->p_overlay->h;
         p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[0];
 
         switch( p_vout->output.i_chroma )
         {
         case SDL_YV12_OVERLAY:
             p_pic->p[Y_PLANE].i_pixel_pitch = 1;
-            p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p[Y_PLANE].i_pitch;
+            p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w;
 
             p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[2];
             p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
+            p_pic->p[U_PLANE].i_visible_lines = p_pic->p_sys->p_overlay->h / 2;
             p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[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->p[U_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
 
             p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[1];
             p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
+            p_pic->p[V_PLANE].i_visible_lines = p_pic->p_sys->p_overlay->h / 2;
             p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1];
             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[V_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
 
             p_pic->i_planes = 3;
             break;
 
         case SDL_IYUV_OVERLAY:
             p_pic->p[Y_PLANE].i_pixel_pitch = 1;
-            p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p[Y_PLANE].i_pitch;
+            p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w;
 
             p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[1];
             p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
+            p_pic->p[U_PLANE].i_visible_lines = p_pic->p_sys->p_overlay->h / 2;
             p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1];
             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->p[U_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
 
             p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[2];
             p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
+            p_pic->p[V_PLANE].i_visible_lines = p_pic->p_sys->p_overlay->h / 2;
             p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[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[V_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
 
             p_pic->i_planes = 3;
             break;
 
         default:
             p_pic->p[Y_PLANE].i_pixel_pitch = 2;
-            p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p[Y_PLANE].i_pitch;
+            p_pic->p[U_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w * 2;
 
             p_pic->i_planes = 1;
             break;
         }
     }
 
-    return 0;
+    return VLC_SUCCESS;
 }
 
 /*****************************************************************************
  * SetPalette: sets an 8 bpp palette
  *****************************************************************************/
-static void SetPalette( vout_thread_t *p_vout, u16 *red, u16 *green, u16 *blue )
+static void SetPalette( vout_thread_t *p_vout,
+                        uint16_t *red, uint16_t *green, uint16_t *blue )
 {
     SDL_Color colors[256];
     int i;
-  
+
     /* Fill colors with color information */
     for( i = 0; i < 256; i++ )
     {