]> git.sesse.net Git - vlc/commitdiff
* Added SPU cropping.
authorSam Hocevar <sam@videolan.org>
Thu, 10 May 2001 06:47:31 +0000 (06:47 +0000)
committerSam Hocevar <sam@videolan.org>
Thu, 10 May 2001 06:47:31 +0000 (06:47 +0000)
  * Gnome interface segfault fix.
  * BeOS interface segfault fix by AnEvilYak (what's you real name btw?).

  Note: if you want to have a look at the currently buggy YUV subpictures,
        uncomment line 1999 of src/video_output/video_output.c. Don't report
        bugs about this, I _know_ it's a quick hack.

ChangeLog
plugins/beos/intf_beos.cpp
plugins/gnome/gnome_callbacks.c
plugins/gnome/intf_gnome.c
plugins/gnome/intf_gnome.h
src/spu_decoder/spu_decoder.c
src/spu_decoder/spu_decoder.h

index f40bc557e2e01e7078462e7dd3a27b1093430b22..a84ac3ccf130328d4d487d33976dd2f2d4529dbf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
 #===================#
 
 HEAD
+  * Added SPU cropping.
+  * Gnome interface segfault fix.
+  * BeOS interface segfault fix by AnEvilYak (what's you real name btw?).
   * Fixed an aspect ratio issue in the SPU decoder, and optimized the
     SPU renderer.
   * Speed optimization in the handling of the unusual ephemer DVD subtitles.
index 003b21a39daf3b3dfba92f0803884296ee7135ba..ccaaf680404392d72cc501e6e2c829a396dbfef0 100644 (file)
@@ -2,7 +2,7 @@
  * intf_beos.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: intf_beos.cpp,v 1.28 2001/05/07 04:42:42 sam Exp $
+ * $Id: intf_beos.cpp,v 1.29 2001/05/10 06:47:31 sam Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -272,15 +272,13 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
         break;
 
     case OPEN_DVD:
-        const char **ppsz_device;
+        const char *psz_device;
         char psz_method[ B_FILE_NAME_LENGTH + 4 ];
-
-        if( p_message->FindString("device", ppsz_device) != B_ERROR )
+        if( p_message->FindString("device", &psz_device) != B_ERROR )
         {
             snprintf( psz_method, B_FILE_NAME_LENGTH + 4,
-                      "dvd:%s", *ppsz_device );
-            psz_method[ B_FILE_NAME_LENGTH + 4 - 1 ] = '\0';
-
+                      "dvd:%s", psz_device );
+            psz_method[ strlen(psz_method) ] = '\0';
             intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_method );
         }
         break;
index d2f4cc2b1ae4c217f53b5df96c4479a914854cf7..1d61cb49c116a2592ae4eceb57cca996eeb17725 100644 (file)
@@ -2,7 +2,7 @@
  * gnome_callbacks.c : Callbacks for the Gnome plugin.
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: gnome_callbacks.c,v 1.27 2001/05/07 03:14:09 stef Exp $
+ * $Id: gnome_callbacks.c,v 1.28 2001/05/10 06:47:31 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Stéphane Borel <stef@via.ecp.fr>
@@ -182,7 +182,8 @@ on_button_title_prev_clicked           (GtkButton       *button,
     p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
     i_id = p_intf->p_input->stream.p_selected_area->i_id - 1;
 
-    if( i_id >= 0 )
+    /* Disallow area 0 since it is used for video_ts.vob */
+    if( i_id > 0 )
     {
         p_area = p_intf->p_input->stream.pp_areas[i_id];
         p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
@@ -990,14 +991,10 @@ on_popup_navigation_toggle             (GtkCheckMenuItem     *menuitem,
         !p_intf->p_sys->b_title_update &&
         !p_intf->p_sys->b_chapter_update )
     {
-        input_area_t *  p_area;
-        gint            i_title;
-        gint            i_chapter;
-
-        i_title   = (gint)(user_data) / 100;
-        i_chapter = (gint)(user_data) - ( 100 * i_title );
-        p_area = p_intf->p_input->stream.p_selected_area;
+        input_area_t   *p_area = p_intf->p_input->stream.p_selected_area;
 
+        gint i_title   = DATA2TITLE( user_data );
+        gint i_chapter = DATA2CHAPTER( user_data );
 
         if( p_area != p_intf->p_input->stream.pp_areas[i_title] )
         {
index 5572afd378ab22663b243436978defd2ec6b4e09..401e4aced925067a67d34995d47c9439198d5b24 100644 (file)
@@ -2,7 +2,7 @@
  * intf_gnome.c: Gnome interface
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_gnome.c,v 1.37 2001/05/07 03:14:09 stef Exp $
+ * $Id: intf_gnome.c,v 1.38 2001/05/10 06:47:31 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Stéphane Borel <stef@via.ecp.fr>
@@ -439,7 +439,7 @@ static gint GnomeRadioMenu( intf_thread_t * p_intf,
             }
 
             snprintf( psz_name, GNOME_MENU_LABEL_SIZE,
-                      "%d - %d", i_item + 1, i_item + 10);
+                      "Chapters %d to %d", i_item + 1, i_item + 10);
             psz_name[ GNOME_MENU_LABEL_SIZE - 1 ] = '\0';
             p_item_group = gtk_menu_item_new_with_label( psz_name );
             gtk_widget_show( p_item_group );
@@ -782,7 +782,7 @@ static gint GnomeTitleMenu( gpointer       p_data,
                 gtk_signal_connect( GTK_OBJECT( p_item ),
                            "toggled",
                            GTK_SIGNAL_FUNC( pf_toggle ),
-                           (gpointer)( ( i_title * 100 ) + ( i_chapter + 1) ) );
+                           (gpointer)POS2DATA( i_title, i_chapter + 1) );
 
                 if( i_chapter_nb > 20 )
                 {
index 12257e870aa902a685ec184f9ec6abc04b2f8877..027ba476d21d3563b6957bc8842e6bc8915858ce 100644 (file)
@@ -2,7 +2,7 @@
  * intf_gnome.h: private Gnome interface description
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_gnome.h,v 1.10 2001/05/06 18:32:30 stef Exp $
+ * $Id: intf_gnome.h,v 1.11 2001/05/10 06:47:31 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
  *****************************************************************************/
 #define GNOME_MENU_LABEL_SIZE 64
 
+/*****************************************************************************
+ * Convert user_data structures to title and chapter information
+ *****************************************************************************/
+#define DATA2TITLE( user_data )    ( (gint)(user_data) >> 16 )
+#define DATA2CHAPTER( user_data )  ( (gint)(user_data) & 0xffff )
+#define POS2DATA( title, chapter ) ( ((title) << 16) | ((chapter) & 0xffff) )
+
 /*****************************************************************************
  * Inline function to retrieve the interface structure
  *****************************************************************************/
@@ -49,9 +56,6 @@ static __inline__ intf_thread_t * GetIntf( GtkWidget *item, char * psz_parent )
                                  "p_intf" ) );
 }
 
-
-
-
 /*****************************************************************************
  * intf_sys_t: description and status of Gnome interface
  *****************************************************************************/
@@ -105,3 +109,4 @@ typedef struct intf_sys_s
     void             ( *pf_gdk_callback ) ( void );
 
 } intf_sys_t;
+
index 95dee601dc2edaeb28c745ee6434e42576ef213c..c186d29b9212ece1c8d42750a918967f17fb459d 100644 (file)
@@ -2,7 +2,7 @@
  * spu_decoder.c : spu decoder thread
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: spu_decoder.c,v 1.43 2001/05/08 20:38:25 sam Exp $
+ * $Id: spu_decoder.c,v 1.44 2001/05/10 06:47:31 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -60,7 +60,7 @@ static void EndThread   ( spudec_thread_t * );
 static int  SyncPacket           ( spudec_thread_t * );
 static void ParsePacket          ( spudec_thread_t * );
 static int  ParseControlSequences( spudec_thread_t *, subpicture_t * );
-static int  ParseRLE             ( u8 *,              subpicture_t * );
+static int  ParseRLE             ( spudec_thread_t *, subpicture_t *, u8 * );
 
 /*****************************************************************************
  * spudec_CreateThread: create a spu decoder thread
@@ -250,7 +250,8 @@ static int SyncPacket( spudec_thread_t *p_spudec )
     p_spudec->i_rle_size = ShowBits( &p_spudec->bit_stream, 16 ) - 4;
 
     /* If the values we got are a bit strange, skip packet */
-    if( p_spudec->i_rle_size >= p_spudec->i_spu_size )
+    if( !p_spudec->i_spu_size
+         || ( p_spudec->i_rle_size >= p_spudec->i_spu_size ) )
     {
         return( 1 );
     }
@@ -324,7 +325,9 @@ static void ParsePacket( spudec_thread_t *p_spudec )
         return;
     }
 
-    if( ParseRLE( p_src, p_spu ) )
+    p_spudec->i_skipped_top = p_spudec->i_skipped_bottom = 0;
+
+    if( ParseRLE( p_spudec, p_spu, p_src ) )
     {
         /* There was a parse error, delete the subpicture */
         free( p_src );
@@ -334,7 +337,18 @@ static void ParsePacket( spudec_thread_t *p_spudec )
 
     intf_WarnMsg( 3, "spudec: valid subtitle, size: %ix%i, position: %i,%i",
                   p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y );
-                     
+
+    /* Crop if necessary */
+    if( p_spudec->i_skipped_top || p_spudec->i_skipped_bottom )
+    {
+        p_spu->i_y += p_spudec->i_skipped_top;
+        p_spu->i_height -= p_spudec->i_skipped_top
+                            + p_spudec->i_skipped_bottom;
+
+        intf_WarnMsg( 3, "spudec: cropped to: %ix%i, position: %i,%i",
+                      p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y );
+    }
+
     intf_WarnMsg( 3, "spudec: total size: 0x%x, RLE offsets: 0x%x 0x%x",
                   p_spudec->i_spu_size,
                   p_spu->type.spu.i_offset[0], p_spu->type.spu.i_offset[1] );
@@ -366,6 +380,9 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
     u8  i_command;
     int i_date;
 
+    /* XXX: temporary variables */
+    boolean_t b_force_display = 0;
+
     /* Initialize the structure */
     p_spu->i_start = p_spu->i_stop = 0;
     p_spu->b_ephemer = 0;
@@ -392,9 +409,7 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
                 case SPU_CMD_FORCE_DISPLAY:
 
                     /* 00 (force displaying) */
-                    intf_ErrMsg( "spudec: \"force display\" command" );
-                    intf_ErrMsg( "spudec: send mail to <sam@zoy.org> if you "
-                                         "want to help debugging this" );
+                    b_force_display = 1;
  
                     break;
  
@@ -527,6 +542,13 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
             break;
     }
 
+    if( b_force_display )
+    {
+        intf_ErrMsg( "spudec: \"force display\" command" );
+        intf_ErrMsg( "spudec: send mail to <sam@zoy.org> if you "
+                     "want to help debugging this" );
+    }
+
     /* Successfully parsed ! */
     return( 0 );
 }
@@ -538,7 +560,8 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
  * convenient structure for later decoding. For more information on the
  * subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html
  *****************************************************************************/
-static int ParseRLE( u8 *p_src, subpicture_t * p_spu )
+static int ParseRLE( spudec_thread_t *p_spudec,
+                     subpicture_t * p_spu, u8 * p_src )
 {
     unsigned int i_code;
 
@@ -553,6 +576,12 @@ static int ParseRLE( u8 *p_src, subpicture_t * p_spu )
     unsigned int  pi_table[ 2 ];
     unsigned int *pi_offset;
 
+    boolean_t b_empty_top = 1,
+              b_empty_bottom = 0;
+
+    /* XXX: temporary variables */
+    boolean_t b_padding_bytes = 0;
+
     pi_table[ 0 ] = p_spu->type.spu.i_offset[ 0 ] << 1;
     pi_table[ 1 ] = p_spu->type.spu.i_offset[ 1 ] << 1;
 
@@ -604,8 +633,33 @@ static int ParseRLE( u8 *p_src, subpicture_t * p_spu )
                 return( 1 );
             }
 
-            /* We got a valid code, store it */
-            *p_dest++ = i_code;
+            if( i_code == (i_width << 2) )
+            {
+                if( b_empty_top )
+                {
+                    /* This is a blank top line, we skip it */
+                    p_spudec->i_skipped_top++;
+                }
+                else
+                {
+                    /* We can't be sure the current lines will be skipped,
+                     * so we store the code just in case. */
+                    *p_dest++ = i_code;
+
+                    b_empty_bottom = 1;
+                    p_spudec->i_skipped_bottom++;
+                }
+            }
+            else
+            {
+                /* We got a valid code, store it */
+                *p_dest++ = i_code;
+
+                /* Valid code means no blank line */
+                b_empty_top = 0;
+                b_empty_bottom = 0;
+                p_spudec->i_skipped_bottom = 0;
+            }
         }
 
         /* Check that we didn't go too far */
@@ -629,10 +683,18 @@ static int ParseRLE( u8 *p_src, subpicture_t * p_spu )
     /* FIXME: we shouldn't need these padding bytes */
     while( i_y < i_height )
     {
+        b_padding_bytes = 1;
         *p_dest++ = i_width << 2;
         i_y++;
     }
 
+    if( b_padding_bytes )
+    {
+        intf_ErrMsg( "spudec: padding bytes found in RLE sequence" );
+        intf_ErrMsg( "spudec: send mail to <sam@zoy.org> if you "
+                     "want to help debugging this" );
+    }
+
     return( 0 );
 }
 
index a7277d0e23caacc5cfd7d3426c5d302133aa9d16..e04b512a6242be4dd554763f009a1b687c276c7f 100644 (file)
@@ -2,7 +2,7 @@
  * spu_decoder.h : sub picture unit decoder thread interface
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: spu_decoder.h,v 1.8 2001/05/07 04:42:42 sam Exp $
+ * $Id: spu_decoder.h,v 1.9 2001/05/10 06:47:31 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -48,9 +48,13 @@ typedef struct spudec_thread_s
      * Private properties
      */
     mtime_t             i_pts;                     /* presentation timestamp */
+
+ //   subpicture_t *      p_spu;
     int                 i_spu_size;            /* size of current SPU packet */
+
     int                 i_rle_size;                  /* size of the RLE part */
-    subpicture_t *      p_spu;
+    int                 i_skipped_top;                  /* skipped RLE lines */
+    int                 i_skipped_bottom;
 
 } spudec_thread_t;