Work towards handling all planes in subtites, generalizing for CVD, and
authorRocky Bernstein <rocky@videolan.org>
Sun, 28 Dec 2003 02:01:11 +0000 (02:01 +0000)
committerRocky Bernstein <rocky@videolan.org>
Sun, 28 Dec 2003 02:01:11 +0000 (02:01 +0000)
some cleanup.

modules/codec/ogt/ogt.c
modules/codec/ogt/ogt.h
modules/codec/ogt/parse.c
modules/codec/ogt/render.c
modules/codec/ogt/render.h [new file with mode: 0644]
modules/codec/ogt/subtitle.h [new file with mode: 0644]

index 656d4f9..3c0567e 100644 (file)
@@ -2,7 +2,7 @@
  * ogt.c : Overlay Graphics Text (SVCD subtitles) decoder thread
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: ogt.c,v 1.4 2003/12/26 02:47:59 rocky Exp $
+ * $Id: ogt.c,v 1.5 2003/12/28 02:01:11 rocky Exp $
  *
  * Authors: Rocky Bernstein
  *   based on code from:
 #include <vlc/vout.h>
 #include <vlc/decoder.h>
 
+#include "subtitle.h"
 #include "ogt.h"
 
 #define DEBUG_LONGTEXT N_( \
     "This integer when viewed in binary is a debugging mask\n" \
-    "external call     1\n" \
-    "all calls         2\n" \
-    "misc              4\n" )
+    "external call          1\n" \
+    "all calls              2\n" \
+    "packet assembly info   4\n" \
+    "image bitmaps          8\n" \
+    "image transformations 16\n" \
+    "rendering information 32\n" \
+    "misc info             64\n" )
 
 
 /*****************************************************************************
index e021f7c..1e8e0da 100644 (file)
@@ -2,12 +2,9 @@
  * ogt.h : Overlay Graphics Text (SVCD subtitles) decoder thread interface
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: ogt.h,v 1.5 2003/12/27 01:49:59 rocky Exp $
+ * $Id: ogt.h,v 1.6 2003/12/28 02:01:11 rocky Exp $
  *
  * Author: Rocky Bernstein
- *   based on code from:
- *       Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
- *       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
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-#define DECODE_DBG_EXT         1 /* Calls from external routines */
-#define DECODE_DBG_CALL        2 /* all calls */
-#define DECODE_DBG_PACKET      4 /* packet assembly info */
-#define DECODE_DBG_IMAGE       8 /* image bitmaps */
-#define DECODE_DBG_TRANSFORM  16 /* bitmap transformations */
-#define DECODE_DBG_INFO       32
-
-#define DECODE_DEBUG 1
-#if DECODE_DEBUG
-#define dbg_print(mask, s, args...) \
-   if (p_sys && p_sys->i_debug & mask) \
-     msg_Dbg(p_dec, "%s: "s, __func__ , ##args)
-#else
-#define dbg_print(mask, s, args...)
-#endif
-
-#define LOG_ERR(args...)  msg_Err( p_input, args )
-#define LOG_WARN(args...) msg_Warn( p_input, args )
-
-#define GETINT16(p) ( (p[0] <<  8) +  p[1] ); p +=2;
-
-#define GETINT32(p) ( (p[0] << 24) +  (p[1] << 16) +    \
-                      (p[2] <<  8) +  (p[3]) ) ; p += 4;
-
-
-/* The number of color palette entries allowed in a subtitle. */
-#define NUM_SUBTITLE_COLORS 4 
-
-typedef enum  {
-  SUBTITLE_BLOCK_EMPTY,
-  SUBTITLE_BLOCK_PARTIAL,
-  SUBTITLE_BLOCK_COMPLETE
-} packet_state_t;
-
-/* FIXME: REMOVE THE BELOW. */
-/* Color and transparency of a pixel or a palette (CLUT) entry */
-typedef struct ogt_yuvt_val_s {
-  uint8_t y;
-  uint8_t u;
-  uint8_t v;
-  uint8_t t;
-} ogt_yuvt_t;
-
-/* The storage used by one pixel */
-#define PIXEL_SIZE 4
-
-/* Size in bytes of YUV portion above. */ 
-#define YUV_SIZE 3
-
-/* Transparency plane. NOTE: see vlc_video.h for V_PLANE */
-#define T_PLANE  V_PLANE+1
-
-struct decoder_sys_t
-{
-  int            i_debug; /* debugging mask */
-  mtime_t        i_pts;   /* Start PTS of subtitle block */
-  int            i_spu;
-  packet_state_t state;   /* data-gathering state for this subtitle */
-
-  uint16_t       i_image; /* image number in the subtitle stream; 0 is the 
-                            first one. */
-  uint8_t        i_packet;/* packet number for above image number; 0 is the 
-                            first one. */
-  block_t        *p_block;/* Bytes of the packet. */
-  
-  uint8_t buffer[65536 + 20 ]; /* we will never overflow more than 11
-                                 bytes if I'm right */
-  int     b_packetizer;
-  int     i_spu_size;    /* goal for subtitle_data_pos while gathering,
-                            size of used subtitle_data later */
-  vout_thread_t *p_vout;
-
-  /* FIXME: Remove this? */
-  uint8_t *subtitle_data;      /* buffer used to accumulate data from
-                                  successive packets in the same subtitle */
-  int subtitle_data_size;      /* size of the allocated subtitle_data */
-
-  /* Move into subpicture_sys_t? */
-  uint16_t comp_image_offset;  /* offset from subtitle_data to compressed
-                                  image data */
-  int comp_image_length;       /* size of the compressed image data */
-  int second_field_offset;      /* offset of odd raster lines */
-  int metadata_offset;          /* offset to data describing the image */
-  int metadata_length;          /* length of metadata */
-
-  int subtitle_data_pos;       /* where to write next chunk */
-
-  uint32_t i_duration;         /* how long to display the image, 0 stands
-                                  for "until next subtitle" */
-
-  uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
-                                    image when displayed */
-  uint16_t i_width, i_height;  /* dimensions in pixels of image */
-
-  ogt_yuvt_t pi_palette[NUM_SUBTITLE_COLORS];
-
-  uint8_t i_options;
-  uint8_t i_options2;
-  uint8_t i_cmd;
-  uint32_t i_cmd_arg;
-};
-
-struct subpicture_sys_t
-{
-  mtime_t i_pts;                /* presentation timestamp */
-
-  u_int8_t *p_data;             /* Image data one byte T, Y, U, V */
-
-  /* Color information */
-  vlc_bool_t b_palette;
-  
-  /* Link to our input */
-  vlc_object_t * p_input;
-  
-  /* Cropping properties */
-  vlc_mutex_t  lock;
-  vlc_bool_t   b_crop;
-  unsigned int i_x_start, i_y_start, i_x_end, i_y_end;
-};
-
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
 void E_(ParseHeader)( decoder_t *, uint8_t *, block_t *  );
 void E_(ParsePacket)( decoder_t * );
-void E_(RenderSPU)  ( vout_thread_t *, picture_t *, const subpicture_t * );
 
index da2695e..618b1ba 100644 (file)
@@ -2,7 +2,7 @@
  * parse.c: Philips OGT (SVCD subtitle) packet parser
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: parse.c,v 1.2 2003/12/27 01:49:59 rocky Exp $
+ * $Id: parse.c,v 1.3 2003/12/28 02:01:11 rocky Exp $
  *
  * Authors: Rocky Bernstein 
  *   based on code from: 
@@ -32,6 +32,8 @@
 #include <vlc/vout.h>
 #include <vlc/decoder.h>
 
+#include "subtitle.h"
+#include "render.h"
 #include "ogt.h"
 
 /* An image color is a two-bit palette entry: 0..3 */ 
@@ -105,12 +107,13 @@ void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
   p_sys->i_height = GETINT16(p);
   
   for (i=0; i<4; i++) {
-    p_sys->pi_palette[i].y = *p++;
-    p_sys->pi_palette[i].u = *p++;
-    p_sys->pi_palette[i].v = *p++;
-    /* We have just 4-bit resolution for alpha, but the value for SVCD
-     * has 8 bits so we scale down the values to the acceptable range */
-       p_sys->pi_palette[i].t = (*p++) >> 4;
+    p_sys->pi_palette[i].s.y = *p++;
+    p_sys->pi_palette[i].s.u = *p++;
+    p_sys->pi_palette[i].s.v = *p++;
+    /* Note alpha is 8 bits. DVD's use only 4 bits. Our rendering routine
+       will use an 8-bit transparancy.
+    */
+    p_sys->pi_palette[i].s.t = *p++;
   }
   p_sys->i_cmd = *p++;
       /* We do not really know this, FIXME */
@@ -135,8 +138,8 @@ void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
     
     for (i=0; i<4; i++) {
       msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
-              p_sys->pi_palette[i].t, p_sys->pi_palette[i].y, 
-              p_sys->pi_palette[i].u, p_sys->pi_palette[i].v );
+              p_sys->pi_palette[i].s.t, p_sys->pi_palette[i].s.y, 
+              p_sys->pi_palette[i].s.u, p_sys->pi_palette[i].s.v );
     }
   }
 }
@@ -174,15 +177,15 @@ E_(ParsePacket)( decoder_t *p_dec)
     /* Fill the p_spu structure */
     vlc_mutex_init( p_dec, &p_spu->p_sys->lock );
 
-    p_spu->pf_render = E_(RenderSPU);
+    p_spu->pf_render  = VCDRenderSPU;
     p_spu->pf_destroy = DestroySPU;
     p_spu->p_sys->p_data = (uint8_t*)p_spu->p_sys + sizeof( subpicture_sys_t );
-    p_spu->p_sys->b_palette = VLC_FALSE;
 
     p_spu->p_sys->i_x_end        = p_sys->i_x_start + p_sys->i_width - 1;
     p_spu->p_sys->i_y_end        = p_sys->i_y_start + p_sys->i_height - 1;
 
-    p_spu->i_x        = p_sys->i_x_start / 2;
+    /* FIXME: use aspect ratio for x? */
+    p_spu->i_x        = p_sys->i_x_start * 3 / 4; 
     p_spu->i_y        = p_sys->i_y_start;
     p_spu->i_width    = p_sys->i_width;
     p_spu->i_height   = p_sys->i_height;
@@ -190,7 +193,8 @@ E_(ParsePacket)( decoder_t *p_dec)
     p_spu->i_start    = p_sys->i_pts;
     p_spu->i_stop     = p_sys->i_pts + (p_sys->i_duration * 10);
     
-    p_spu->p_sys->b_crop = VLC_FALSE;
+    p_spu->p_sys->b_crop  = VLC_FALSE;
+    p_spu->p_sys->i_debug = p_sys->i_debug;
 
     /* Get display time now. If we do it later, we may miss the PTS. */
     p_spu->p_sys->i_pts = p_sys->i_pts;
@@ -266,7 +270,7 @@ ScaleX( decoder_t *p_dec, subpicture_t *p_spu,
   for ( i_row=0; i_row <= p_spu->i_height - 1; i_row++ ) {
 
     if (used != 0) {
-      /* Discard the remaining piece of the colum of the previous line*/
+      /* Discard the remaining piece of the column of the previous line*/
       used=0;
       p_src1 = p_src2;
       p_src2 += PIXEL_SIZE;
@@ -299,7 +303,7 @@ ScaleX( decoder_t *p_dec, subpicture_t *p_spu,
     ogt_yuvt_t *p_source = (ogt_yuvt_t *) p_spu->p_sys->p_data;
     for ( i_row=0; i_row < p_spu->i_height - 1; i_row++ ) {
       for ( i_col=0; i_col < p_spu->i_width - 1; i_col++ ) {
-       printf("%1x", p_source->t);
+       printf("%1x", p_source->s.t);
        p_source++;
       }
       printf("\n");
index 8f65d8d..0a3e294 100644 (file)
@@ -2,7 +2,7 @@
  * render.c : Philips OGT (SVCD Subtitle) renderer
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: render.c,v 1.2 2003/12/27 01:49:59 rocky Exp $
+ * $Id: render.c,v 1.3 2003/12/28 02:01:11 rocky Exp $
  *
  * Author: Rocky Bernstein 
  *   based on code from: 
 #include <vlc/vout.h>
 #include <vlc/decoder.h>
 
-#include "ogt.h"
+#include "subtitle.h"
+#include "render.h"
+
+/* We use 8 bits for an alpha value: 0..255. Note: For DVDs; 0.15. */
+#define ALPHA_BITS (8)
+#define MAX_ALPHA  ((1<<ALPHA_BITS) - 1) 
+
+/* Horrible hack to get dbg_print to do the right thing */
+#define p_dec p_vout
 
 /*****************************************************************************
  * Local prototypes
@@ -51,13 +59,13 @@ static void RenderI420( vout_thread_t *, picture_t *, const subpicture_t *,
   routine can be as fast as possible.
 
  *****************************************************************************/
-void E_(RenderSPU)( vout_thread_t *p_vout, picture_t *p_pic,
-                    const subpicture_t *p_spu )
+void VCDRenderSPU( vout_thread_t *p_vout, picture_t *p_pic,
+                  const subpicture_t *p_spu )
 {
-
-    /*
-      printf("+++%x\n", p_vout->output.i_chroma);
-    */
+    struct subpicture_sys_t *p_sys = p_spu->p_sys;
+  
+    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
+              "chroma %x", p_vout->output.i_chroma );
   
     switch( p_vout->output.i_chroma )
     {
@@ -99,82 +107,98 @@ static void RenderI420( vout_thread_t *p_vout, picture_t *p_pic,
   uint8_t *p_dest;
   uint8_t *p_destptr;
   ogt_yuvt_t *p_source;
-  
+
+  unsigned int i_plane;
   int i_x, i_y;
   uint16_t i_colprecomp, i_destalpha;
   
   /* Crop-specific */
   int i_x_start, i_y_start, i_x_end, i_y_end;
   /* int i=0; */
+
+  struct subpicture_sys_t *p_sys = p_spu->p_sys;
   
-  p_dest = p_pic->Y_PIXELS + p_spu->i_x + p_spu->i_width
-    + p_pic->Y_PITCH * ( p_spu->i_y + p_spu->i_height );
-  
-  i_x_start = p_spu->i_width - p_spu->p_sys->i_x_end;
-  i_y_start = p_pic->Y_PITCH * (p_spu->i_height - p_spu->p_sys->i_y_end );
-  i_x_end   = p_spu->i_width - p_spu->p_sys->i_x_start;
-  i_y_end   = p_pic->Y_PITCH * (p_spu->i_height - p_spu->p_sys->i_y_start );
-  
-  p_source = (ogt_yuvt_t *)p_spu->p_sys->p_data;
+  dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
+            "spu width: %d, height %d, pitch (%d, %d, %d)", 
+            p_spu->i_width,  p_spu->i_height, 
+            p_pic->Y_PITCH, p_pic->U_PITCH, p_pic->V_PITCH );
 
-  /* printf("+++spu width: %d, height %d\n", p_spu->i_width, 
-     p_spu->i_height); */
   
-  /* Draw until we reach the bottom of the subtitle */
-  for( i_y = p_spu->i_height * p_pic->Y_PITCH ;
-       i_y ;
-       i_y -= p_pic->Y_PITCH )
+  /*for ( i_plane = 0; i_plane < p_pic->i_planes ; i_plane++ )*/
+  for ( i_plane = 0; i_plane < 1 ; i_plane++ )
     {
-      /* printf("+++begin line: %d,\n", i++); */
-      /* Draw until we reach the end of the line */
-      for( i_x = p_spu->i_width ; i_x ; i_x--, p_source++ )
-        {
-         
-         if( b_crop
-             && ( i_x < i_x_start || i_x > i_x_end
-                  || i_y < i_y_start || i_y > i_y_end ) )
-            {
-             continue;
-            }
-
-         /* printf( "t: %x, y: %x, u: %x, v: %x\n", 
-            p_source->t, p_source->y, p_source->u, p_source->v ); */
-         
-         switch( p_source->t )
-            {
-           case 0x00: 
-             /* Completely transparent. Don't change underlying pixel */
-             break;
+      
+      p_dest = p_pic->p[i_plane].p_pixels + p_spu->i_x + p_spu->i_width
+       + p_pic->p[i_plane].i_pitch * ( p_spu->i_y + p_spu->i_height );
+      
+      i_x_start = p_spu->i_width - p_sys->i_x_end;
+      i_y_start = p_pic->p[i_plane].i_pitch 
+       * (p_spu->i_height - p_sys->i_y_end );
+      
+      i_x_end   = p_spu->i_width - p_sys->i_x_start;
+      i_y_end   = p_pic->p[i_plane].i_pitch 
+       * (p_spu->i_height - p_sys->i_y_start );
+      
+      p_source = (ogt_yuvt_t *)p_sys->p_data;
+      
+      /* Draw until we reach the bottom of the subtitle */
+      for( i_y = p_spu->i_height * p_pic->p[i_plane].i_pitch ;
+          i_y ;
+          i_y -= p_pic->p[i_plane].i_pitch )
+       {
+         /* printf("+++begin line: %d,\n", i++); */
+         /* Draw until we reach the end of the line */
+         for( i_x = p_spu->i_width ; i_x ; i_x--, p_source++ )
+           {
              
-           case 0x0f:
-             /* Completely opaque. Completely overwrite underlying
-                pixel with subtitle pixel. */
-
-             p_destptr = p_dest - i_x - i_y;
-
-             i_colprecomp = (uint16_t) ( p_source->y * 15 );
-             *p_destptr = i_colprecomp >> 4;
-
-             break;
+             if( b_crop
+                 && ( i_x < i_x_start || i_x > i_x_end
+                      || i_y < i_y_start || i_y > i_y_end ) )
+               {
+                 continue;
+               }
              
-           default:
-             /* Blend in underlying pixel subtitle pixel. */
-
-             /* To be able to divide by 16 (>>4) we add 1 to the alpha.
-              * This means Alpha 0 won't be completely transparent, but
-              * that's handled in a special case above anyway. */
-
-             p_destptr = p_dest - i_x - i_y;
-
-             i_colprecomp = (uint16_t) ( (p_source->y 
-                                          * (uint16_t)(p_source->t + 1) ) );
-             i_destalpha = 15 - p_source->t;
-
-             *p_destptr = ( i_colprecomp +
-                              (uint16_t)*p_destptr * i_destalpha ) >> 4;
-             break;
-            }
-        }
-    }
+             /* printf( "t: %x, y: %x, u: %x, v: %x\n", 
+                p_source->s.t, p_source->y, p_source->u, p_source->v ); */
+             
+             switch( p_source->s.t )
+               {
+               case 0x00: 
+                 /* Completely transparent. Don't change underlying pixel */
+                 break;
+                 
+               case MAX_ALPHA:
+                 /* Completely opaque. Completely overwrite underlying
+                    pixel with subtitle pixel. */
+                 
+                 p_destptr = p_dest - i_x - i_y;
+                 
+                 i_colprecomp = 
+                   (uint16_t) ( p_source->plane[i_plane] * MAX_ALPHA );
+                 *p_destptr = i_colprecomp >> ALPHA_BITS;
+                 
+                 break;
+                 
+               default:
+                 /* Blend in underlying pixel subtitle pixel. */
+                 
+                 /* To be able to ALPHA_BITS, we add 1 to the alpha.
+                  * This means Alpha 0 won't be completely transparent, but
+                  * that's handled in a special case above anyway. */
+                 
+                 p_destptr = p_dest - i_x - i_y;
+                 
+                 i_colprecomp = (uint16_t) (p_source->plane[i_plane] 
+                              * (uint16_t) (p_source->s.t+1) );
+                 i_destalpha = MAX_ALPHA - p_source->s.t;
+                 
+                 *p_destptr = ( i_colprecomp +
+                                (uint16_t)*p_destptr * i_destalpha ) 
+                   >> ALPHA_BITS;
+                 break;
+               }
+           }
+       }
+  }
 }
 
diff --git a/modules/codec/ogt/render.h b/modules/codec/ogt/render.h
new file mode 100644 (file)
index 0000000..254f074
--- /dev/null
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * render.h : Common SVCD and CVD rendering routine(s).
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: render.h,v 1.1 2003/12/28 02:01:11 rocky Exp $
+ *
+ * Author: Rocky Bernstein
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+void VCDRenderSPU  ( vout_thread_t *, picture_t *, const subpicture_t * );
+
diff --git a/modules/codec/ogt/subtitle.h b/modules/codec/ogt/subtitle.h
new file mode 100644 (file)
index 0000000..ede45c5
--- /dev/null
@@ -0,0 +1,146 @@
+/*****************************************************************************
+ * subtitle.h : Common SVCD and CVD subtitles header
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: subtitle.h,v 1.1 2003/12/28 02:01:11 rocky Exp $
+ *
+ * Author: Rocky Bernstein
+ *   based on code from:
+ *       Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
+ *       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.
+ *****************************************************************************/
+
+#define DECODE_DBG_EXT         1 /* Calls from external routines */
+#define DECODE_DBG_CALL        2 /* all calls */
+#define DECODE_DBG_PACKET      4 /* packet assembly info */
+#define DECODE_DBG_IMAGE       8 /* image bitmaps */
+#define DECODE_DBG_TRANSFORM  16 /* bitmap transformations */
+#define DECODE_DBG_RENDER     32 /* rendering information */
+#define DECODE_DBG_INFO       64
+
+#define DECODE_DEBUG 1
+#if DECODE_DEBUG
+#define dbg_print(mask, s, args...) \
+   if (p_sys && p_sys->i_debug & mask) \
+     msg_Dbg(p_dec, "%s: "s, __func__ , ##args)
+#else
+#define dbg_print(mask, s, args...)
+#endif
+
+#define LOG_ERR(args...)  msg_Err( p_input, args )
+#define LOG_WARN(args...) msg_Warn( p_input, args )
+
+#define GETINT16(p) ( (p[0] <<  8) +  p[1] ); p +=2;
+
+#define GETINT32(p) ( (p[0] << 24) +  (p[1] << 16) +    \
+                      (p[2] <<  8) +  (p[3]) ) ; p += 4;
+
+
+/* The number of color palette entries allowed in a subtitle. */
+#define NUM_SUBTITLE_COLORS 4 
+
+typedef enum  {
+  SUBTITLE_BLOCK_EMPTY,
+  SUBTITLE_BLOCK_PARTIAL,
+  SUBTITLE_BLOCK_COMPLETE
+} packet_state_t;
+
+/* Color and transparency of a pixel or a palette (CLUT) entry */
+typedef union {
+  uint8_t plane[4];
+  struct {
+    uint8_t y;
+    uint8_t u;
+    uint8_t v;
+    uint8_t t;
+  } s;
+} ogt_yuvt_t;
+
+/* The storage used by one pixel */
+#define PIXEL_SIZE 4
+
+/* Size in bytes of YUV portion above. */ 
+#define YUV_SIZE 3
+
+/* Transparency plane. NOTE: see vlc_video.h for V_PLANE */
+#define T_PLANE  V_PLANE+1
+
+struct decoder_sys_t
+{
+  int            i_debug; /* debugging mask */
+  mtime_t        i_pts;   /* Start PTS of subtitle block */
+  int            i_spu;
+  packet_state_t state;   /* data-gathering state for this subtitle */
+
+  uint16_t       i_image; /* image number in the subtitle stream; 0 is the 
+                            first one. */
+  uint8_t        i_packet;/* packet number for above image number; 0 is the 
+                            first one. */
+  block_t        *p_block;/* Bytes of the packet. */
+  
+  uint8_t buffer[65536 + 20 ]; /* we will never overflow more than 11
+                                 bytes if I'm right */
+  int     b_packetizer;
+  int     i_spu_size;    /* goal for subtitle_data_pos while gathering,
+                            size of used subtitle_data later */
+  vout_thread_t *p_vout;
+
+  /* FIXME: Remove this? */
+  uint8_t *subtitle_data;      /* buffer used to accumulate data from
+                                  successive packets in the same subtitle */
+  int subtitle_data_size;      /* size of the allocated subtitle_data */
+
+  /* Move into subpicture_sys_t? */
+  uint16_t comp_image_offset;  /* offset from subtitle_data to compressed
+                                  image data */
+  int comp_image_length;       /* size of the compressed image data */
+  int second_field_offset;      /* offset of odd raster lines */
+  int metadata_offset;          /* offset to data describing the image */
+  int metadata_length;          /* length of metadata */
+
+  int subtitle_data_pos;       /* where to write next chunk */
+
+  uint32_t i_duration;         /* how long to display the image, 0 stands
+                                  for "until next subtitle" */
+
+  uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
+                                    image when displayed */
+  uint16_t i_width, i_height;  /* dimensions in pixels of image */
+
+  ogt_yuvt_t pi_palette[NUM_SUBTITLE_COLORS];
+
+  uint8_t i_options;
+  uint8_t i_options2;
+  uint8_t i_cmd;
+  uint32_t i_cmd_arg;
+};
+
+struct subpicture_sys_t
+{
+  int     i_debug;              /* debugging mask */
+  mtime_t i_pts;                /* presentation timestamp */
+
+  u_int8_t *p_data;             /* Image data one byte T, Y, U, V */
+
+  /* Link to our input */
+  vlc_object_t * p_input;
+  
+  /* Cropping properties */
+  vlc_mutex_t  lock;
+  vlc_bool_t   b_crop;
+  unsigned int i_x_start, i_y_start, i_x_end, i_y_end;
+};