Start work on CVD subtitles.
authorRocky Bernstein <rocky@videolan.org>
Sun, 28 Dec 2003 04:51:52 +0000 (04:51 +0000)
committerRocky Bernstein <rocky@videolan.org>
Sun, 28 Dec 2003 04:51:52 +0000 (04:51 +0000)
modules/codec/ogt/common.c [new file with mode: 0644]
modules/codec/ogt/common.h [new file with mode: 0644]
modules/codec/ogt/cvd.c [new file with mode: 0644]
modules/codec/ogt/cvd.h [new file with mode: 0644]
modules/codec/ogt/cvd_parse.c [new file with mode: 0644]
modules/codec/ogt/ogt.c
modules/codec/ogt/ogt_parse.c [new file with mode: 0644]
modules/codec/ogt/parse.c [deleted file]
modules/codec/ogt/render.c
modules/codec/ogt/render.h

diff --git a/modules/codec/ogt/common.c b/modules/codec/ogt/common.c
new file mode 100644 (file)
index 0000000..925de46
--- /dev/null
@@ -0,0 +1,285 @@
+/*****************************************************************************
+ * Common SVCD and VCD subtitle routines.
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: common.c,v 1.1 2003/12/28 04:51:52 rocky Exp $
+ *
+ * Author: Rocky Bernstein
+ *   based on code from:
+ *       Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
+ *       Samuel Hocevar <sam@zoy.org>
+ *       Laurent Aimar <fenrir@via.ecp.fr>
+ *
+ * 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 <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/decoder.h>
+
+#include "subtitle.h"
+#include "common.h"
+
+/*****************************************************************************
+ Free Resources associated with subtitle packet.
+ *****************************************************************************/
+void VCDSubClose( vlc_object_t *p_this )
+{
+    decoder_t     *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
+
+    if( !p_sys->b_packetizer )
+    {
+        /* FIXME check if it's ok to not lock vout */
+        if( p_sys->p_vout != NULL && p_sys->p_vout->p_subpicture != NULL )
+        {
+            subpicture_t *  p_subpic;
+            int             i_subpic;
+
+            for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
+            {
+                p_subpic = &p_sys->p_vout->p_subpicture[i_subpic];
+
+                if( p_subpic != NULL &&
+                    ( ( p_subpic->i_status == RESERVED_SUBPICTURE ) ||
+                      ( p_subpic->i_status == READY_SUBPICTURE ) ) )
+                {
+                    vout_DestroySubPicture( p_sys->p_vout, p_subpic );
+                }
+            }
+        }
+    }
+
+    if( p_sys->p_block )
+    {
+        block_ChainRelease( p_sys->p_block );
+    }
+
+    free( p_sys );
+}
+
+/*****************************************************************************
+
+Initialize so the next packet will start off a new one.
+
+ *****************************************************************************/
+void 
+VCDSubInitSubtitleBlock( decoder_sys_t * p_sys ) 
+{
+  p_sys->i_spu_size = 0;
+  p_sys->state      = SUBTITLE_BLOCK_EMPTY;
+  p_sys->i_spu      = 0;
+  p_sys->p_block    = NULL;
+  p_sys->subtitle_data_pos = 0;
+
+}
+
+void 
+VCDSubInitSubtitleData(decoder_sys_t *p_sys)
+{
+  if ( p_sys->subtitle_data ) {
+    if ( p_sys->subtitle_data_size < p_sys->i_spu_size ) {
+      p_sys->subtitle_data = realloc(p_sys->subtitle_data,
+                                   p_sys->i_spu_size);
+      p_sys->subtitle_data_size = p_sys->i_spu_size;
+    }
+  } else {
+    p_sys->subtitle_data = malloc(p_sys->i_spu_size);
+    p_sys->subtitle_data_size = p_sys->i_spu_size;
+    /* FIXME: wrong place to get p_sys */
+    p_sys->i_image = 0;
+  }
+  p_sys->subtitle_data_pos = 0;
+}
+
+void 
+VCDSubAppendData ( decoder_t *p_dec, uint8_t *buffer, uint32_t buf_len )
+{
+  decoder_sys_t *p_sys = p_dec->p_sys;
+  int chunk_length = buf_len;
+
+  if ( chunk_length > p_sys->i_spu_size - p_sys->subtitle_data_pos ) {
+    msg_Warn( p_dec, "too much data (%d) expecting at most %u",
+             chunk_length, p_sys->i_spu_size - p_sys->subtitle_data_pos );
+
+    chunk_length = p_sys->i_spu_size - p_sys->subtitle_data_pos;
+  }
+
+  if ( chunk_length > 0 ) {
+    memcpy(p_sys->subtitle_data + p_sys->subtitle_data_pos,
+          buffer, chunk_length);
+    p_sys->subtitle_data_pos += chunk_length;
+    dbg_print(DECODE_DBG_PACKET, "%d bytes appended, pointer now %d",
+             chunk_length, p_sys->subtitle_data_pos);
+  }
+}
+
+
+/*****************************************************************************
+ * FindVout: Find a vout or wait for one to be created.
+ *****************************************************************************/
+vout_thread_t *VCDSubFindVout( decoder_t *p_dec )
+{
+    vout_thread_t *p_vout = NULL;
+
+    /* Find an available video output */
+    do
+    {
+        if( p_dec->b_die || p_dec->b_error )
+        {
+            break;
+        }
+
+        p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
+        if( p_vout )
+        {
+            break;
+        }
+
+        msleep( VOUT_OUTMEM_SLEEP );
+    }
+    while( 1 );
+
+    return p_vout;
+}
+
+
+/* Scales down (reduces size) of p_dest in the x direction as 
+   determined through aspect ratio x_scale by y_scale. Scaling
+   is done in place. p_spu->i_width, is updated to new width
+
+   The aspect ratio is assumed to be between 1/2 and 1.
+*/
+void
+VCDSubScaleX( decoder_t *p_dec, subpicture_t *p_spu, 
+             unsigned int i_scale_x, unsigned int i_scale_y )
+{
+  int i_row, i_col;
+
+  decoder_sys_t *p_sys = p_dec->p_sys;
+  uint8_t *p_src1 = p_spu->p_sys->p_data;
+  uint8_t *p_src2 = p_src1 + PIXEL_SIZE;
+  uint8_t *p_dst  = p_src1;
+  unsigned int i_new_width = (p_spu->i_width * i_scale_x) / i_scale_y ;
+  unsigned int used=0;  /* Number of bytes used up in p_src1. */
+
+  dbg_print( (DECODE_DBG_CALL|DECODE_DBG_TRANSFORM) , 
+            "Old width: %d, new width: %d", 
+            p_spu->i_width, i_new_width);
+  
+  for ( i_row=0; i_row <= p_spu->i_height - 1; i_row++ ) {
+
+    if (used != 0) {
+      /* Discard the remaining piece of the column of the previous line*/
+      used=0;
+      p_src1 = p_src2;
+      p_src2 += PIXEL_SIZE;
+    }
+    
+    for ( i_col=0; i_col <= p_spu->i_width - 2; i_col++ ) {
+      unsigned int i;
+      unsigned int w1= i_scale_x - used;
+      unsigned int w2= i_scale_y - w1;
+
+      used = w2;
+      for (i = 0; i < PIXEL_SIZE; i++ ) {
+       *p_dst = ( (*p_src1 * w1) + (*p_src2 * w2) ) / i_scale_y;
+       p_src1++; p_src2++; p_dst++;
+      }
+
+      if (i_scale_x == used) {
+       /* End of last pixel was end of p_src2. */
+       p_src1 = p_src2;
+       p_src2 += PIXEL_SIZE;
+       i_col++;
+       used = 0;
+      }
+    }
+  }
+  p_spu->i_width = i_new_width;
+
+  if ( p_sys && p_sys->i_debug & DECODE_DBG_TRANSFORM )
+  { 
+    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->s.t);
+       p_source++;
+      }
+      printf("\n");
+    }
+  }
+
+}
+
+/*****************************************************************************
+ * DestroySPU: subpicture destructor
+ *****************************************************************************/
+void VCDSubDestroySPU( subpicture_t *p_spu )
+{
+    if( p_spu->p_sys->p_input )
+    {
+        /* Detach from our input thread */
+        vlc_object_release( p_spu->p_sys->p_input );
+    }
+
+    vlc_mutex_destroy( &p_spu->p_sys->lock );
+    free( p_spu->p_sys );
+}
+
+/*****************************************************************************
+  This callback is called from the input thread when we need cropping
+ *****************************************************************************/
+int VCDSubCropCallback( vlc_object_t *p_object, char const *psz_var,
+                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    VCDSubUpdateSPU( (subpicture_t *)p_data, p_object );
+
+    return VLC_SUCCESS;
+}
+
+
+/*****************************************************************************
+  update subpicture settings
+ *****************************************************************************
+  This function is called from CropCallback and at initialization time, to
+  retrieve crop information from the input.
+ *****************************************************************************/
+void VCDSubUpdateSPU( subpicture_t *p_spu, vlc_object_t *p_object )
+{
+    vlc_value_t val;
+
+    p_spu->p_sys->b_crop = val.b_bool;
+    if( !p_spu->p_sys->b_crop )
+    {
+        return;
+    }
+
+    var_Get( p_object, "x-start", &val );
+    p_spu->p_sys->i_x_start = val.i_int;
+    var_Get( p_object, "y-start", &val );
+    p_spu->p_sys->i_y_start = val.i_int;
+    var_Get( p_object, "x-end", &val );
+    p_spu->p_sys->i_x_end = val.i_int;
+    var_Get( p_object, "y-end", &val );
+    p_spu->p_sys->i_y_end = val.i_int;
+
+}
+
diff --git a/modules/codec/ogt/common.h b/modules/codec/ogt/common.h
new file mode 100644 (file)
index 0000000..41e03e1
--- /dev/null
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Header for Common SVCD and VCD subtitle routines.
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: common.h,v 1.1 2003/12/28 04:51:52 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.
+ *****************************************************************************/
+
+void           VCDSubClose  ( vlc_object_t * );
+void           VCDSubInitSubtitleBlock( decoder_sys_t * p_sys );
+void           VCDSubInitSubtitleData(decoder_sys_t *p_sys);
+void           VCDSubAppendData( decoder_t *p_dec, uint8_t *buffer, 
+                                uint32_t buf_len );
+vout_thread_t *VCDSubFindVout( decoder_t *p_dec );
+
+void           VCDSubScaleX( decoder_t *p_dec, subpicture_t *p_spu, 
+                            unsigned int i_scale_x, unsigned int i_scale_y );
+void           VCDSubDestroySPU( subpicture_t *p_spu );
+int            VCDSubCropCallback( vlc_object_t *p_object, char const *psz_var,
+                                  vlc_value_t oldval, vlc_value_t newval, 
+                                  void *p_data );
+void           VCDSubUpdateSPU( subpicture_t *p_spu, vlc_object_t *p_object );
+
+
diff --git a/modules/codec/ogt/cvd.c b/modules/codec/ogt/cvd.c
new file mode 100644 (file)
index 0000000..e48d813
--- /dev/null
@@ -0,0 +1,307 @@
+/*****************************************************************************
+ * cvd.c : CVD Subtitle decoder thread
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: cvd.c,v 1.1 2003/12/28 04:51:52 rocky Exp $
+ *
+ * Authors: Rocky Bernstein
+ *   based on code from:
+ *       Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
+ *       Samuel Hocevar <sam@zoy.org>
+ *       Laurent Aimar <fenrir@via.ecp.fr>
+ *
+ * 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 <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/decoder.h>
+
+#include "subtitle.h"
+#include "cvd.h"
+#include "common.h"
+
+#define DEBUG_LONGTEXT N_( \
+    "This integer when viewed in binary is a debugging mask\n" \
+    "external call          1\n" \
+    "all calls              2\n" \
+    "packet assembly info   4\n" \
+    "image bitmaps          8\n" \
+    "image transformations 16\n" \
+    "misc info             32\n" )
+
+/*****************************************************************************
+ * Module descriptor.
+ *****************************************************************************/
+static int  DecoderOpen   ( vlc_object_t * );
+static int  PacketizerOpen( vlc_object_t * );
+
+vlc_module_begin();
+    set_description( _("CVD subtitle decoder") );
+    set_capability( "decoder", 50 );
+    set_callbacks( DecoderOpen, VCDSubClose );
+
+    add_integer ( MODULE_STRING "-debug", 0, NULL,
+                  N_("set debug mask for additional debugging."),
+                  N_(DEBUG_LONGTEXT), VLC_TRUE );
+
+    add_submodule();
+    set_description( _("Chaoji VCD subtitle packetizer") );
+    set_capability( "packetizer", 50 );
+    set_callbacks( PacketizerOpen, VCDSubClose );
+vlc_module_end();
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+
+static block_t *Reassemble( decoder_t *, block_t ** );
+static void     Decode   ( decoder_t *, block_t ** );
+static block_t *Packetize( decoder_t *, block_t ** );
+
+
+/*****************************************************************************
+ * DecoderOpen
+ *****************************************************************************
+ * Tries to launch a decoder and return score so that the interface is able
+ * to chose.
+ *****************************************************************************/
+static int
+DecoderOpen( vlc_object_t *p_this )
+{
+    decoder_t     *p_dec = (decoder_t*)p_this;
+    decoder_sys_t *p_sys;
+
+    if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'c','v','d',' ' ) )
+    {
+        return VLC_EGENERIC;
+    }
+
+
+    p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
+
+    p_sys->i_debug       = config_GetInt( p_this, MODULE_STRING "-debug" );
+    p_sys->b_packetizer  = VLC_FALSE;
+    p_sys->p_vout        = NULL;
+    p_sys->i_image       = -1;
+    p_sys->subtitle_data = NULL;
+
+    VCDSubInitSubtitleBlock( p_sys );
+
+    es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'c','v','d',' ' ) );
+
+
+    p_dec->pf_decode_sub = Decode;
+    p_dec->pf_packetize  = Packetize;
+
+    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * PacketizerOpen
+ *****************************************************************************
+ * Tries to launch a decoder and return score so that the interface is able
+ * to chose.
+ *****************************************************************************/
+static int PacketizerOpen( vlc_object_t *p_this )
+{
+    decoder_t *p_dec = (decoder_t*)p_this;
+
+    if( DecoderOpen( p_this ) )
+    {
+        return VLC_EGENERIC;
+    }
+    p_dec->p_sys->b_packetizer = VLC_TRUE;
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Decode:
+ *****************************************************************************/
+static void
+Decode ( decoder_t *p_dec, block_t **pp_block )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t       *p_spu = Reassemble( p_dec, pp_block );
+
+    dbg_print( (DECODE_DBG_CALL) , "");
+
+    if( p_spu )
+    {
+        p_sys->i_spu = block_ChainExtract( p_spu, p_sys->buffer, 65536 );
+        p_sys->i_pts = p_spu->i_pts;
+        block_ChainRelease( p_spu );
+
+        if( ( p_sys->p_vout = VCDSubFindVout( p_dec ) ) )
+        {
+            /* Parse and decode */
+            E_(ParsePacket)( p_dec );
+
+            vlc_object_release( p_sys->p_vout );
+        }
+
+        VCDSubInitSubtitleBlock ( p_sys );
+    }
+
+}
+
+/*****************************************************************************
+ * Packetize:
+ *****************************************************************************/
+static block_t *
+Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t       *p_spu = Reassemble( p_dec, pp_block );
+
+    if( p_spu )
+    {
+        p_spu->i_dts = p_spu->i_pts;
+        p_spu->i_length = 0;
+
+        VCDSubInitSubtitleBlock( p_sys );
+
+        return block_ChainGather( p_spu );
+    }
+    return NULL;
+}
+
+/* following functions are local */
+
+#define SPU_HEADER_LEN 5
+
+/*****************************************************************************
+ Reassemble:
+
+ The data for single screen subtitle may come in one of many
+ non-contiguous packets of a stream. This routine is called when the
+ next packet in the stream comes in. The job of this routine is to
+ parse the header, if this is the beginning, and combine the packets
+ into one complete subtitle unit.
+
+ If everything is complete, we will return a block. Otherwise return
+ NULL.
+
+
+ The format of the beginning of the subtitle packet that is used here.
+
+   size    description
+   -------------------------------------------
+   byte    subtitle channel (0..7) in bits 0-3
+   byte    subtitle packet number of this subtitle image 0-N,
+           if the subtitle packet is complete, the top bit of the byte is 1.
+   uint16  subtitle image number
+
+ *****************************************************************************/
+static block_t *
+Reassemble( decoder_t *p_dec, block_t **pp_block )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    block_t *p_block;
+    uint8_t *p_buffer;
+    uint16_t i_expected_image;
+    uint8_t  i_packet, i_expected_packet;
+
+    if( pp_block == NULL || *pp_block == NULL )
+    {
+        return NULL;
+    }
+    p_block = *pp_block;
+    *pp_block = NULL;
+
+    if( p_block->i_buffer < SPU_HEADER_LEN )
+    {
+      msg_Dbg( p_dec, "invalid packet header (size %d < %d)" ,
+               p_block->i_buffer, SPU_HEADER_LEN );
+      block_Release( p_block );
+      return NULL;
+    }
+
+    p_buffer = p_block->p_buffer;
+
+    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_PACKET), 
+              "header: 0x%02x 0x%02x 0x%02x 0x%02x, size: %i",
+              p_buffer[1], p_buffer[2], p_buffer[3], p_buffer[4],
+              p_block->i_buffer);
+
+    if( config_GetInt( p_dec, "spu-channel" ) != p_buffer[1] )
+      return NULL;
+
+    if ( p_sys->state == SUBTITLE_BLOCK_EMPTY ) {
+      i_expected_image  = p_sys->i_image+1;
+      i_expected_packet = 0;
+    } else {
+      i_expected_image  = p_sys->i_image;
+      i_expected_packet = p_sys->i_packet+1;
+    }
+
+    p_buffer += 2;
+
+    if ( *p_buffer & 0x80 ) {
+      p_sys->state = SUBTITLE_BLOCK_COMPLETE;
+      i_packet     = ( *p_buffer++ & 0x7F );
+    } else {
+      p_sys->state = SUBTITLE_BLOCK_PARTIAL;
+      i_packet     = *p_buffer++;
+    }
+
+    p_sys->i_image = GETINT16(p_buffer);
+
+    if ( p_sys->i_image != i_expected_image ) {
+      msg_Warn( p_dec, "expecting subtitle image %u but found %u",
+                i_expected_image, p_sys->i_image );
+    }
+
+    if ( i_packet != i_expected_packet ) {
+      msg_Warn( p_dec, "expecting subtitle image packet %u but found %u",
+                i_expected_packet, i_packet);
+    }
+
+    p_sys->i_packet = i_packet;
+
+    if ( p_sys->i_packet == 0 ) {
+      /* First packet in the subtitle block */
+      E_(ParseHeader)( p_dec, p_buffer, p_block );
+      VCDSubInitSubtitleData(p_sys);
+    }
+
+    /* FIXME - remove append_data and use chainappend */
+    VCDSubAppendData( p_dec, p_buffer, p_block->i_buffer - 5 );
+
+    block_ChainAppend( &p_sys->p_block, p_block );
+
+    p_sys->i_spu += p_block->i_buffer - SPU_HEADER_LEN;
+
+    if (p_sys->state == SUBTITLE_BLOCK_COMPLETE)
+    {
+      if( p_sys->i_spu != p_sys->i_spu_size )
+        {
+          msg_Warn( p_dec, "SPU packets size=%d should be %d",
+                   p_sys->i_spu, p_sys->i_spu_size );
+        }
+
+      dbg_print( (DECODE_DBG_PACKET),
+                 "subtitle packet complete, size=%d", p_sys->i_spu );
+
+      return p_sys->p_block;
+    }
+    return NULL;
+}
diff --git a/modules/codec/ogt/cvd.h b/modules/codec/ogt/cvd.h
new file mode 100644 (file)
index 0000000..6b9f0ba
--- /dev/null
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * cvd.h : CVD subtitles decoder thread interface
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: cvd.h,v 1.1 2003/12/28 04:51:52 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 E_(ParseHeader)( decoder_t *, uint8_t *, block_t *  );
+void E_(ParsePacket)( decoder_t * );
+
diff --git a/modules/codec/ogt/cvd_parse.c b/modules/codec/ogt/cvd_parse.c
new file mode 100644 (file)
index 0000000..ed427b8
--- /dev/null
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ * parse.c: Philips OGT (SVCD subtitle) packet parser
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: cvd_parse.c,v 1.1 2003/12/28 04:51:52 rocky Exp $
+ *
+ * Authors: Rocky Bernstein 
+ *   based on code from: 
+ *       Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
+ *       Sam Hocevar <sam@zoy.org>
+ *       Laurent Aimar <fenrir@via.ecp.fr>
+ *
+ * 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 <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/decoder.h>
+
+#include "subtitle.h"
+#include "render.h"
+#include "cvd.h"
+
+/* An image color is a two-bit palette entry: 0..3 */ 
+typedef uint8_t ogt_color_t;
+
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
+static int  ParseImage         ( decoder_t *, subpicture_t * );
+
+/*
+ * We do not have information on the subtitle format used on CVD's
+ * except the submux sample code and a couple of samples of dubious
+ * origin. Thus, this is the result of reading some code whose
+ * correctness is not known and some experimentation.
+ * 
+ * CVD subtitles present several differences compared to SVCD OGT
+ * subtitles.  Firstly, the image comes first and the metadata is at
+ * the end.  So that the metadata can be found easily, the subtitle
+ * begins with two two-byte (everything is big-endian again) that
+ * describe, the total size of the subtitle data and the offset to the
+ * metadata (size of the image data plus the four bytes at the
+ * beginning.
+ *
+ * Image data comes interlaced and uses RLE.  Coding is based in
+ * four-bit nibbles that are further subdivided in a two-bit repeat
+ * count and a two-bit color number so that up to three pixels can be
+ * describe with a total of four bits.  The function of a 0 repeat
+ * count is unknown.  It might be used for RLE extension.  There is a
+ * special case, though.  When the full nibble is zero, the rest of
+ * the line is filled with the color value in the next nibble.  It is
+ * unknown what happens if the color value is greater than three.  The
+ * rest seems to use a 4-entries palette.  It is not impossible that
+ * the fill-line complete case above is not as described and the zero
+ * repeat count means fill line.  The sample code never produces this,
+ * so it may be untested.
+ *
+ * The metadata section does not follow a fixed pattern, every
+ * metadata item consists of a tag byte followed by parameters. In all
+ * cases known, the block (including the tag byte) is exactly four
+ * bytes in length.  Read the code for the rest.
+ */
+
+/* FIXME: do we really need p_buffer and p? 
+   Can't all of thes _offset's and _lengths's get removed? 
+*/
+void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
+{
+  decoder_sys_t *p_sys = p_dec->p_sys;
+
+  dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
+
+  /* To be finished...*/
+  return;
+}
+
+
+/*****************************************************************************
+ * ParsePacket: parse an SPU packet and send it to the video output
+ *****************************************************************************
+ * This function parses the SPU packet and, if valid, sends it to the
+ * video output.
+ *****************************************************************************/
+void 
+E_(ParsePacket)( decoder_t *p_dec)
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
+
+    /* To be completed... */
+    return;
+
+}
+
+/* Advance pointer to image pointer, update internal i_remaining counter
+   and check that we haven't goine too far  in the image data. */
+#define advance_color_pointer_byte                                     \
+  p++;                                                                 \
+  i_remaining=4;                                                       \
+  if (p >= maxp) {                                                     \
+    msg_Warn( p_dec,                                                   \
+             "broken subtitle - tried to access beyond end "           \
+             "in image extraction");                                   \
+    return VLC_EGENERIC;                                               \
+  }                                                                    \
+
+#define advance_color_pointer                                          \
+  i_remaining--;                                                       \
+  if ( i_remaining == 0 ) {                                            \
+    advance_color_pointer_byte;                                                \
+  }                                                                    
+
+/* Get the next field - either a palette index or a RLE count for
+   color 0.  To do this we use byte image pointer p, and i_remaining
+   which indicates where we are in the byte.
+*/
+static inline ogt_color_t 
+ExtractField(uint8_t *p, unsigned int i_remaining) 
+{
+  return ( ( *p >> 2*(i_remaining-1) ) & 0x3 );
+}
+
+/*****************************************************************************
+ * ParseImage: parse the image part of the subtitle
+ *****************************************************************************
+ This part parses the subtitle graphical data and stores it in a more
+ convenient structure for later rendering. 
+
+ The image is encoded using two bits per pixel that select a palette
+ entry except that value 0 starts a limited run-length encoding for
+ color 0.  When 0 is seen, the next two bits encode one less than the
+ number of pixels, so we can encode run lengths from 1 to 4. These get
+ filled with the color in palette entry 0.
+
+ The encoding of each line is padded to a whole number of bytes.  The
+ first field is padded to an even byte length and the complete subtitle
+ is padded to a 4-byte multiple that always include one zero byte at
+ the end.
+
+ However we'll transform this so that that the RLE is expanded and
+ interlacing will also be removed. On output each pixel entry will by 
+ an 8-bit alpha, y, u, and v entry.
+
+ *****************************************************************************/
+static int 
+ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    dbg_print( (DECODE_DBG_CALL) , "");
+    /* To be finished...*/
+    return VLC_EGENERIC;
+
+}
+
index 3c0567e..abd119a 100644 (file)
@@ -2,7 +2,7 @@
  * ogt.c : Overlay Graphics Text (SVCD subtitles) decoder thread
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: ogt.c,v 1.5 2003/12/28 02:01:11 rocky Exp $
+ * $Id: ogt.c,v 1.6 2003/12/28 04:51:52 rocky Exp $
  *
  * Authors: Rocky Bernstein
  *   based on code from:
@@ -34,6 +34,7 @@
 
 #include "subtitle.h"
 #include "ogt.h"
+#include "common.h"
 
 #define DEBUG_LONGTEXT N_( \
     "This integer when viewed in binary is a debugging mask\n" \
 static int  DecoderOpen   ( vlc_object_t * );
 static int  PacketizerOpen( vlc_object_t * );
 
-static void Close  ( vlc_object_t * );
-
 vlc_module_begin();
     set_description( _("Philips OGT (SVCD subtitle) decoder") );
     set_capability( "decoder", 50 );
-    set_callbacks( DecoderOpen, Close );
+    set_callbacks( DecoderOpen, VCDSubClose );
 
     add_integer ( MODULE_STRING "-debug", 0, NULL,
                   N_("set debug mask for additional debugging."),
@@ -66,17 +65,14 @@ vlc_module_begin();
     add_submodule();
     set_description( _("Philips OGT (SVCD subtitle) packetizer") );
     set_capability( "packetizer", 50 );
-    set_callbacks( PacketizerOpen, Close );
+    set_callbacks( PacketizerOpen, VCDSubClose );
 vlc_module_end();
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static void     InitSubtitleBlock( decoder_sys_t * p_sys );
-static vout_thread_t *FindVout( decoder_t *);
 
 static block_t *Reassemble( decoder_t *, block_t ** );
-
 static void     Decode   ( decoder_t *, block_t ** );
 static block_t *Packetize( decoder_t *, block_t ** );
 
@@ -107,7 +103,7 @@ DecoderOpen( vlc_object_t *p_this )
     p_sys->i_image       = -1;
     p_sys->subtitle_data = NULL;
 
-    InitSubtitleBlock( p_sys );
+    VCDSubInitSubtitleBlock( p_sys );
 
     es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'o','g','t',' ' ) );
 
@@ -139,46 +135,6 @@ static int PacketizerOpen( vlc_object_t *p_this )
     return VLC_SUCCESS;
 }
 
-/*****************************************************************************
- * Close:
- *****************************************************************************/
-static void Close( vlc_object_t *p_this )
-{
-    decoder_t     *p_dec = (decoder_t*)p_this;
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
-
-    if( !p_sys->b_packetizer )
-    {
-        /* FIXME check if it's ok to not lock vout */
-        if( p_sys->p_vout != NULL && p_sys->p_vout->p_subpicture != NULL )
-        {
-            subpicture_t *  p_subpic;
-            int             i_subpic;
-
-            for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
-            {
-                p_subpic = &p_sys->p_vout->p_subpicture[i_subpic];
-
-                if( p_subpic != NULL &&
-                    ( ( p_subpic->i_status == RESERVED_SUBPICTURE ) ||
-                      ( p_subpic->i_status == READY_SUBPICTURE ) ) )
-                {
-                    vout_DestroySubPicture( p_sys->p_vout, p_subpic );
-                }
-            }
-        }
-    }
-
-    if( p_sys->p_block )
-    {
-        block_ChainRelease( p_sys->p_block );
-    }
-
-    free( p_sys );
-}
-
 /*****************************************************************************
  * Decode:
  *****************************************************************************/
@@ -196,7 +152,7 @@ Decode ( decoder_t *p_dec, block_t **pp_block )
         p_sys->i_pts = p_spu->i_pts;
         block_ChainRelease( p_spu );
 
-        if( ( p_sys->p_vout = FindVout( p_dec ) ) )
+        if( ( p_sys->p_vout = VCDSubFindVout( p_dec ) ) )
         {
             /* Parse and decode */
             E_(ParsePacket)( p_dec );
@@ -204,7 +160,7 @@ Decode ( decoder_t *p_dec, block_t **pp_block )
             vlc_object_release( p_sys->p_vout );
         }
 
-        InitSubtitleBlock ( p_sys );
+        VCDSubInitSubtitleBlock ( p_sys );
     }
 
 }
@@ -223,72 +179,13 @@ Packetize( decoder_t *p_dec, block_t **pp_block )
         p_spu->i_dts = p_spu->i_pts;
         p_spu->i_length = 0;
 
-        InitSubtitleBlock( p_sys );
+        VCDSubInitSubtitleBlock( p_sys );
 
         return block_ChainGather( p_spu );
     }
     return NULL;
 }
 
-/* following functions are local */
-
-static void 
-InitSubtitleData(decoder_sys_t *p_sys)
-{
-  if ( p_sys->subtitle_data ) {
-    if ( p_sys->subtitle_data_size < p_sys->i_spu_size ) {
-      p_sys->subtitle_data = realloc(p_sys->subtitle_data,
-                                   p_sys->i_spu_size);
-      p_sys->subtitle_data_size = p_sys->i_spu_size;
-    }
-  } else {
-    p_sys->subtitle_data = malloc(p_sys->i_spu_size);
-    p_sys->subtitle_data_size = p_sys->i_spu_size;
-    /* FIXME: wrong place to get p_sys */
-    p_sys->i_image = 0;
-  }
-  p_sys->subtitle_data_pos = 0;
-}
-
-static void 
-AppendData ( decoder_t *p_dec, uint8_t *buffer, uint32_t buf_len )
-{
-  decoder_sys_t *p_sys = p_dec->p_sys;
-  int chunk_length = buf_len;
-
-  if ( chunk_length > p_sys->i_spu_size - p_sys->subtitle_data_pos ) {
-    msg_Warn( p_dec, "too much data (%d) expecting at most %u",
-             chunk_length, p_sys->i_spu_size - p_sys->subtitle_data_pos );
-
-    chunk_length = p_sys->i_spu_size - p_sys->subtitle_data_pos;
-  }
-
-  if ( chunk_length > 0 ) {
-    memcpy(p_sys->subtitle_data + p_sys->subtitle_data_pos,
-          buffer, chunk_length);
-    p_sys->subtitle_data_pos += chunk_length;
-    dbg_print(DECODE_DBG_PACKET, "%d bytes appended, pointer now %d",
-             chunk_length, p_sys->subtitle_data_pos);
-  }
-}
-
-/*****************************************************************************
- InitSubtitleBlock:
-
-Initialize so the next packet will start off a new one.
-
- *****************************************************************************/
-static void 
-InitSubtitleBlock( decoder_sys_t * p_sys ) 
-{
-  p_sys->i_spu_size = 0;
-  p_sys->state      = SUBTITLE_BLOCK_EMPTY;
-  p_sys->i_spu      = 0;
-  p_sys->p_block    = NULL;
-  p_sys->subtitle_data_pos = 0;
-
-}
-
 #define SPU_HEADER_LEN 5
 
 /*****************************************************************************
@@ -383,11 +280,11 @@ Reassemble( decoder_t *p_dec, block_t **pp_block )
     if ( p_sys->i_packet == 0 ) {
       /* First packet in the subtitle block */
       E_(ParseHeader)( p_dec, p_buffer, p_block );
-      InitSubtitleData(p_sys);
+      VCDSubInitSubtitleData(p_sys);
     }
 
     /* FIXME - remove append_data and use chainappend */
-    AppendData( p_dec, p_buffer, p_block->i_buffer - 5 );
+    VCDSubAppendData( p_dec, p_buffer, p_block->i_buffer - 5 );
 
     block_ChainAppend( &p_sys->p_block, p_block );
 
@@ -408,32 +305,3 @@ Reassemble( decoder_t *p_dec, block_t **pp_block )
     }
     return NULL;
 }
-
-/*****************************************************************************
- * FindVout: Find a vout or wait for one to be created.
- *****************************************************************************/
-static vout_thread_t *FindVout( decoder_t *p_dec )
-{
-    vout_thread_t *p_vout = NULL;
-
-    /* Find an available video output */
-    do
-    {
-        if( p_dec->b_die || p_dec->b_error )
-        {
-            break;
-        }
-
-        p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
-        if( p_vout )
-        {
-            break;
-        }
-
-        msleep( VOUT_OUTMEM_SLEEP );
-    }
-    while( 1 );
-
-    return p_vout;
-}
-
diff --git a/modules/codec/ogt/ogt_parse.c b/modules/codec/ogt/ogt_parse.c
new file mode 100644 (file)
index 0000000..b3375a7
--- /dev/null
@@ -0,0 +1,368 @@
+/*****************************************************************************
+ * Philips OGT (SVCD subtitle) packet parser
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: ogt_parse.c,v 1.1 2003/12/28 04:51:52 rocky Exp $
+ *
+ * Author: Rocky Bernstein 
+ *   based on code from: 
+ *       Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
+ *       Sam Hocevar <sam@zoy.org>
+ *       Laurent Aimar <fenrir@via.ecp.fr>
+ *
+ * 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 <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/decoder.h>
+
+#include "subtitle.h"
+#include "common.h"
+#include "render.h"
+#include "ogt.h"
+
+/* An image color is a two-bit palette entry: 0..3 */ 
+typedef uint8_t ogt_color_t;
+
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
+static int  ParseImage         ( decoder_t *, subpicture_t * );
+
+/*
+  The format is roughly as follows (everything is big-endian):
+   size     description
+   -------------------------------------------
+   byte     subtitle channel (0..7) in bits 0-3 
+   byte     subtitle packet number of this subtitle image 0-N,
+            if the subtitle packet is complete, the top bit of the byte is 1.
+   u_int16  subtitle image number
+   u_int16  length in bytes of the rest
+   byte     option flags, unknown meaning except bit 3 (0x08) indicates
+           presence of the duration field
+   byte     unknown 
+   u_int32  duration in 1/90000ths of a second (optional), start time
+           is as indicated by the PTS in the PES header
+   u_int32  xpos
+   u_int32  ypos
+   u_int32  width (must be even)
+   u_int32  height (must be even)
+   byte[16] palette, 4 palette entries, each contains values for
+           Y, U, V and transparency, 0 standing for transparent
+   byte     command,
+           cmd>>6==1 indicates shift
+           (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
+   u_int32  shift duration in 1/90000ths of a second
+   u_int16  offset of odd-numbered scanlines - subtitle images are 
+            given in interlace order
+   byte[]   limited RLE image data in interlace order (0,2,4... 1,3,5) with
+            2-bits per palette number
+*/
+
+/* FIXME: do we really need p_buffer and p? 
+   Can't all of thes _offset's and _lengths's get removed? 
+*/
+void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
+{
+  decoder_sys_t *p_sys = p_dec->p_sys;
+  u_int8_t *p = p_buffer;
+  int i;
+  
+  p_sys->i_pts    = p_block->i_pts;
+  p_sys->i_spu_size = GETINT16(p);
+  p_sys->i_options  = *p++;
+  p_sys->i_options2 = *p++;
+  
+  if ( p_sys->i_options & 0x08 ) {
+    p_sys->i_duration = GETINT32(p);
+  } else {
+    /* 0 means display until next subtitle comes in. */
+    p_sys->i_duration = 0;
+  }
+  p_sys->i_x_start= GETINT16(p);
+  p_sys->i_y_start= GETINT16(p);
+  p_sys->i_width  = GETINT16(p);
+  p_sys->i_height = GETINT16(p);
+  
+  for (i=0; i<4; i++) {
+    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 */
+  if ( p_sys->i_cmd ) {
+    p_sys->i_cmd_arg = GETINT32(p);
+  }
+
+  /* Actually, this is measured against a different origin, so we have to
+     adjust it */
+  p_sys->second_field_offset = GETINT16(p);
+  p_sys->comp_image_offset = p - p_buffer;
+  p_sys->comp_image_length = p_sys->i_spu_size - p_sys->comp_image_offset;
+  p_sys->metadata_length   = p_sys->comp_image_offset;
+
+  if (p_sys && p_sys->i_debug & DECODE_DBG_PACKET) {
+    msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
+            "spu size: %d, duration: %u (d:%d p:%d)",
+            p_sys->i_x_start, p_sys->i_y_start, 
+            p_sys->i_width, p_sys->i_height, 
+            p_sys->i_spu_size, p_sys->i_duration,
+            p_sys->comp_image_length, p_sys->comp_image_offset);
+    
+    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].s.t, p_sys->pi_palette[i].s.y, 
+              p_sys->pi_palette[i].s.u, p_sys->pi_palette[i].s.v );
+    }
+  }
+}
+
+
+/*****************************************************************************
+ * ParsePacket: parse an SPU packet and send it to the video output
+ *****************************************************************************
+ * This function parses the SPU packet and, if valid, sends it to the
+ * video output.
+ *****************************************************************************/
+void 
+E_(ParsePacket)( decoder_t *p_dec)
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    subpicture_t  *p_spu;
+
+    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
+    
+    /* Allocate the subpicture internal data. */
+    p_spu = vout_CreateSubPicture( p_sys->p_vout, MEMORY_SUBPICTURE );
+    if( p_spu == NULL )
+    {
+        return;
+    }
+
+    /* In ParseImage we expand the run-length encoded color 0's; also
+       we expand pixels and remove the color palette. This should
+       facilitate scaling and antialiasing and speed up rendering.
+    */
+    p_spu->p_sys = malloc( sizeof( subpicture_sys_t ) 
+                          + PIXEL_SIZE * (p_sys->i_width * p_sys->i_height) );
+
+    /* Fill the p_spu structure */
+    vlc_mutex_init( p_dec, &p_spu->p_sys->lock );
+
+    p_spu->pf_render  = VCDSubRender;
+    p_spu->pf_destroy = VCDSubDestroySPU;
+    p_spu->p_sys->p_data = (uint8_t*)p_spu->p_sys + sizeof( subpicture_sys_t );
+
+    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;
+
+    /* 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;
+
+    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->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;
+
+    /* Attach to our input thread */
+    p_spu->p_sys->p_input = vlc_object_find( p_dec,
+                                             VLC_OBJECT_INPUT, FIND_PARENT );
+
+    /* We try to display it */
+    if( ParseImage( p_dec, p_spu ) )
+    {
+        /* There was a parse error, delete the subpicture */
+        vout_DestroySubPicture( p_sys->p_vout, p_spu );
+        return;
+    }
+
+    /* SPU is finished - we can ask the video output to display it */
+    vout_DisplaySubPicture( p_sys->p_vout, p_spu );
+
+}
+
+/* Advance pointer to image pointer, update internal i_remaining counter
+   and check that we haven't goine too far  in the image data. */
+#define advance_color_pointer_byte                                     \
+  p++;                                                                 \
+  i_remaining=4;                                                       \
+  if (p >= maxp) {                                                     \
+    msg_Warn( p_dec,                                                   \
+             "broken subtitle - tried to access beyond end "           \
+             "in image extraction");                                   \
+    return VLC_EGENERIC;                                               \
+  }                                                                    \
+
+#define advance_color_pointer                                          \
+  i_remaining--;                                                       \
+  if ( i_remaining == 0 ) {                                            \
+    advance_color_pointer_byte;                                                \
+  }                                                                    
+
+/* Get the next field - either a palette index or a RLE count for
+   color 0.  To do this we use byte image pointer p, and i_remaining
+   which indicates where we are in the byte.
+*/
+static inline ogt_color_t 
+ExtractField(uint8_t *p, unsigned int i_remaining) 
+{
+  return ( ( *p >> 2*(i_remaining-1) ) & 0x3 );
+}
+
+/*****************************************************************************
+ * ParseImage: parse the image part of the subtitle
+ *****************************************************************************
+ This part parses the subtitle graphical data and stores it in a more
+ convenient structure for later rendering. 
+
+ The image is encoded using two bits per pixel that select a palette
+ entry except that value 0 starts a limited run-length encoding for
+ color 0.  When 0 is seen, the next two bits encode one less than the
+ number of pixels, so we can encode run lengths from 1 to 4. These get
+ filled with the color in palette entry 0.
+
+ The encoding of each line is padded to a whole number of bytes.  The
+ first field is padded to an even byte length and the complete subtitle
+ is padded to a 4-byte multiple that always include one zero byte at
+ the end.
+
+ However we'll transform this so that that the RLE is expanded and
+ interlacing will also be removed. On output each pixel entry will by 
+ an 8-bit alpha, y, u, and v entry.
+
+ *****************************************************************************/
+static int 
+ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    unsigned int i_field;  /* The subtitles are interlaced, are we on an
+                             even or odd scanline?  */
+
+    unsigned int i_row;    /* scanline row number */
+    unsigned int i_column; /* scanline column number */
+
+    unsigned int i_width  = p_sys->i_width;
+    unsigned int i_height = p_sys->i_height;
+
+    uint8_t *p_dest = (uint8_t *)p_spu->p_sys->p_data;
+
+    uint8_t i_remaining;           /* number of 2-bit pixels remaining 
+                                     in byte of *p */
+    uint8_t i_pending_zero = 0;    /* number of pixels to fill with 
+                                     color zero 0..4 */
+    ogt_color_t i_color;           /* current pixel color: 0..3 */
+    uint8_t *p = p_sys->subtitle_data  + p_sys->comp_image_offset;
+    uint8_t *maxp = p + p_sys->comp_image_length;
+
+    dbg_print( (DECODE_DBG_CALL) , "width x height: %dx%d ",
+              i_width, i_height);
+
+    if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)    
+      printf("\n");
+
+    for ( i_field=0; i_field < 2; i_field++ ) {
+      i_remaining = 4;
+      for ( i_row=i_field; i_row < i_height; i_row += 2 ) {
+       for ( i_column=0; i_column<i_width; i_column++ ) {
+
+         if ( i_pending_zero ) {
+           i_pending_zero--;
+           i_color = 0;
+         } else {
+           i_color = ExtractField( p, i_remaining);
+           advance_color_pointer;
+           if ( i_color == 0 ) {
+             i_pending_zero = ExtractField( p, i_remaining );
+             advance_color_pointer;
+             /* Fall through with i_color == 0 to output the first cell */
+           }
+         }
+
+         /* Color is 0-3. */
+         p_dest[i_row*i_width+i_column] = i_color;
+
+         if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)       
+           printf("%1d", i_color);
+
+       }
+
+       if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) 
+         printf("\n");
+
+       if ( i_remaining != 4 ) {
+         /* Lines are padded to complete bytes, ignore padding */
+         advance_color_pointer_byte;
+       }
+      }
+      p = p_sys->subtitle_data + p_sys->comp_image_offset 
+       + p_sys->second_field_offset;
+    }
+
+    /* Dump out image not interlaced... */
+    if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) {
+      uint8_t *p = p_dest;
+      printf("-------------------------------------\n++");
+      for ( i_row=0; i_row < i_height; i_row ++ ) {
+       for ( i_column=0; i_column<i_width; i_column++ ) {
+         printf("%1d", *p++ & 0x03);
+       }
+       printf("\n++");
+      }
+      printf("\n-------------------------------------\n");
+    }
+
+    /* Remove color palette by expanding pixel entries to contain the
+       palette values. We work from the free space at the end to the
+       beginning so we can expand inline.
+    */
+    {
+      int n = (i_height * i_width) - 1;
+      uint8_t    *p_from = p_dest;
+      ogt_yuvt_t *p_to   = (ogt_yuvt_t *) p_dest;
+      
+      for ( ; n >= 0 ; n-- ) {
+       p_to[n] = p_sys->pi_palette[p_from[n]];
+      }
+    }
+
+    /* The video is automatically scaled. However subtitle bitmaps
+       assume a 1:1 aspect ratio. So we need to scale to compensate for
+       or undo the effects of video output scaling. 
+    */
+    /* FIXME do the right scaling depending on vout. It may not be 4:3 */
+    VCDSubScaleX( p_dec, p_spu, 3, 4 );
+
+    return VLC_SUCCESS;
+}
+
diff --git a/modules/codec/ogt/parse.c b/modules/codec/ogt/parse.c
deleted file mode 100644 (file)
index 618b1ba..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/*****************************************************************************
- * parse.c: Philips OGT (SVCD subtitle) packet parser
- *****************************************************************************
- * Copyright (C) 2003 VideoLAN
- * $Id: parse.c,v 1.3 2003/12/28 02:01:11 rocky Exp $
- *
- * Authors: Rocky Bernstein 
- *   based on code from: 
- *       Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
- *       Sam Hocevar <sam@zoy.org>
- *       Laurent Aimar <fenrir@via.ecp.fr>
- *
- * 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 <vlc/vlc.h>
-#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 */ 
-typedef uint8_t ogt_color_t;
-
-/*****************************************************************************
- * Local prototypes.
- *****************************************************************************/
-static int  ParseImage         ( decoder_t *, subpicture_t * );
-
-static void DestroySPU       ( subpicture_t * );
-
-static void UpdateSPU        ( subpicture_t *, vlc_object_t * );
-static int  CropCallback     ( vlc_object_t *, char const *,
-                               vlc_value_t, vlc_value_t, void * );
-
-/*
-  The format is roughly as follows (everything is big-endian):
-   size     description
-   -------------------------------------------
-   byte     subtitle channel (0..7) in bits 0-3 
-   byte     subtitle packet number of this subtitle image 0-N,
-            if the subtitle packet is complete, the top bit of the byte is 1.
-   u_int16  subtitle image number
-   u_int16  length in bytes of the rest
-   byte     option flags, unknown meaning except bit 3 (0x08) indicates
-           presence of the duration field
-   byte     unknown 
-   u_int32  duration in 1/90000ths of a second (optional), start time
-           is as indicated by the PTS in the PES header
-   u_int32  xpos
-   u_int32  ypos
-   u_int32  width (must be even)
-   u_int32  height (must be even)
-   byte[16] palette, 4 palette entries, each contains values for
-           Y, U, V and transparency, 0 standing for transparent
-   byte     command,
-           cmd>>6==1 indicates shift
-           (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
-   u_int32  shift duration in 1/90000ths of a second
-   u_int16  offset of odd-numbered scanlines - subtitle images are 
-            given in interlace order
-   byte[]   limited RLE image data in interlace order (0,2,4... 1,3,5) with
-            2-bits per palette number
-*/
-
-/* FIXME: do we really need p_buffer and p? 
-   Can't all of thes _offset's and _lengths's get removed? 
-*/
-void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
-{
-  decoder_sys_t *p_sys = p_dec->p_sys;
-  u_int8_t *p = p_buffer;
-  int i;
-  
-  p_sys->i_pts    = p_block->i_pts;
-  p_sys->i_spu_size = GETINT16(p);
-  p_sys->i_options  = *p++;
-  p_sys->i_options2 = *p++;
-  
-  if ( p_sys->i_options & 0x08 ) {
-    p_sys->i_duration = GETINT32(p);
-  } else {
-    /* 0 means display until next subtitle comes in. */
-    p_sys->i_duration = 0;
-  }
-  p_sys->i_x_start= GETINT16(p);
-  p_sys->i_y_start= GETINT16(p);
-  p_sys->i_width  = GETINT16(p);
-  p_sys->i_height = GETINT16(p);
-  
-  for (i=0; i<4; i++) {
-    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 */
-  if ( p_sys->i_cmd ) {
-    p_sys->i_cmd_arg = GETINT32(p);
-  }
-
-  /* Actually, this is measured against a different origin, so we have to
-     adjust it */
-  p_sys->second_field_offset = GETINT16(p);
-  p_sys->comp_image_offset = p - p_buffer;
-  p_sys->comp_image_length = p_sys->i_spu_size - p_sys->comp_image_offset;
-  p_sys->metadata_length   = p_sys->comp_image_offset;
-
-  if (p_sys && p_sys->i_debug & DECODE_DBG_PACKET) {
-    msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
-            "spu size: %d, duration: %u (d:%d p:%d)",
-            p_sys->i_x_start, p_sys->i_y_start, 
-            p_sys->i_width, p_sys->i_height, 
-            p_sys->i_spu_size, p_sys->i_duration,
-            p_sys->comp_image_length, p_sys->comp_image_offset);
-    
-    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].s.t, p_sys->pi_palette[i].s.y, 
-              p_sys->pi_palette[i].s.u, p_sys->pi_palette[i].s.v );
-    }
-  }
-}
-
-
-/*****************************************************************************
- * ParsePacket: parse an SPU packet and send it to the video output
- *****************************************************************************
- * This function parses the SPU packet and, if valid, sends it to the
- * video output.
- *****************************************************************************/
-void 
-E_(ParsePacket)( decoder_t *p_dec)
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    subpicture_t  *p_spu;
-
-    dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
-    
-    /* Allocate the subpicture internal data. */
-    p_spu = vout_CreateSubPicture( p_sys->p_vout, MEMORY_SUBPICTURE );
-    if( p_spu == NULL )
-    {
-        return;
-    }
-
-    /* In ParseImage we expand the run-length encoded color 0's; also
-       we expand pixels and remove the color palette. This should
-       facilitate scaling and antialiasing and speed up rendering.
-    */
-    p_spu->p_sys = malloc( sizeof( subpicture_sys_t ) 
-                          + PIXEL_SIZE * (p_sys->i_width * p_sys->i_height) );
-
-    /* Fill the p_spu structure */
-    vlc_mutex_init( p_dec, &p_spu->p_sys->lock );
-
-    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->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;
-
-    /* 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;
-
-    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->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;
-
-    /* Attach to our input thread */
-    p_spu->p_sys->p_input = vlc_object_find( p_dec,
-                                             VLC_OBJECT_INPUT, FIND_PARENT );
-
-    /* We try to display it */
-    if( ParseImage( p_dec, p_spu ) )
-    {
-        /* There was a parse error, delete the subpicture */
-        vout_DestroySubPicture( p_sys->p_vout, p_spu );
-        return;
-    }
-
-    /* SPU is finished - we can ask the video output to display it */
-    vout_DisplaySubPicture( p_sys->p_vout, p_spu );
-
-}
-
-/* Advance pointer to image pointer, update internal i_remaining counter
-   and check that we haven't goine too far  in the image data. */
-#define advance_color_pointer_byte                                     \
-  p++;                                                                 \
-  i_remaining=4;                                                       \
-  if (p >= maxp) {                                                     \
-    msg_Warn( p_dec,                                                   \
-             "broken subtitle - tried to access beyond end "           \
-             "in image extraction");                                   \
-    return VLC_EGENERIC;                                               \
-  }                                                                    \
-
-#define advance_color_pointer                                          \
-  i_remaining--;                                                       \
-  if ( i_remaining == 0 ) {                                            \
-    advance_color_pointer_byte;                                                \
-  }                                                                    
-
-/* Get the next field - either a palette index or a RLE count for
-   color 0.  To do this we use byte image pointer p, and i_remaining
-   which indicates where we are in the byte.
-*/
-static inline ogt_color_t 
-ExtractField(uint8_t *p, unsigned int i_remaining) 
-{
-  return ( ( *p >> 2*(i_remaining-1) ) & 0x3 );
-}
-
-/* Scales down (reduces size) of p_dest in the x direction as 
-   determined through aspect ratio x_scale by y_scale. Scaling
-   is done in place. p_spu->i_width, is updated to new width
-
-   The aspect ratio is assumed to be between 1/2 and 1.
-*/
-static void
-ScaleX( decoder_t *p_dec, subpicture_t *p_spu, 
-       unsigned int i_scale_x, unsigned int i_scale_y )
-{
-  int i_row, i_col;
-
-  decoder_sys_t *p_sys = p_dec->p_sys;
-  uint8_t *p_src1 = p_spu->p_sys->p_data;
-  uint8_t *p_src2 = p_src1 + PIXEL_SIZE;
-  uint8_t *p_dst  = p_src1;
-  unsigned int i_new_width = (p_spu->i_width * i_scale_x) / i_scale_y ;
-  unsigned int used=0;  /* Number of bytes used up in p_src1. */
-
-  dbg_print( (DECODE_DBG_CALL|DECODE_DBG_TRANSFORM) , 
-            "Old width: %d, new width: %d", 
-            p_spu->i_width, i_new_width);
-  
-  for ( i_row=0; i_row <= p_spu->i_height - 1; i_row++ ) {
-
-    if (used != 0) {
-      /* Discard the remaining piece of the column of the previous line*/
-      used=0;
-      p_src1 = p_src2;
-      p_src2 += PIXEL_SIZE;
-    }
-    
-    for ( i_col=0; i_col <= p_spu->i_width - 2; i_col++ ) {
-      unsigned int i;
-      unsigned int w1= i_scale_x - used;
-      unsigned int w2= i_scale_y - w1;
-
-      used = w2;
-      for (i = 0; i < PIXEL_SIZE; i++ ) {
-       *p_dst = ( (*p_src1 * w1) + (*p_src2 * w2) ) / i_scale_y;
-       p_src1++; p_src2++; p_dst++;
-      }
-
-      if (i_scale_x == used) {
-       /* End of last pixel was end of p_src2. */
-       p_src1 = p_src2;
-       p_src2 += PIXEL_SIZE;
-       i_col++;
-       used = 0;
-      }
-    }
-  }
-  p_spu->i_width = i_new_width;
-
-  if ( p_sys && p_sys->i_debug & DECODE_DBG_TRANSFORM )
-  { 
-    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->s.t);
-       p_source++;
-      }
-      printf("\n");
-    }
-  }
-
-}
-
-/*****************************************************************************
- * ParseImage: parse the image part of the subtitle
- *****************************************************************************
- This part parses the subtitle graphical data and stores it in a more
- convenient structure for later rendering. 
-
- The image is encoded using two bits per pixel that select a palette
- entry except that value 0 starts a limited run-length encoding for
- color 0.  When 0 is seen, the next two bits encode one less than the
- number of pixels, so we can encode run lengths from 1 to 4. These get
- filled with the color in palette entry 0.
-
- The encoding of each line is padded to a whole number of bytes.  The
- first field is padded to an even byte length and the complete subtitle
- is padded to a 4-byte multiple that always include one zero byte at
- the end.
-
- However we'll transform this so that that the RLE is expanded and
- interlacing will also be removed. On output each pixel entry will by 
- an 8-bit alpha, y, u, and v entry.
-
- *****************************************************************************/
-static int 
-ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-
-    unsigned int i_field;  /* The subtitles are interlaced, are we on an
-                             even or odd scanline?  */
-
-    unsigned int i_row;    /* scanline row number */
-    unsigned int i_column; /* scanline column number */
-
-    unsigned int i_width  = p_sys->i_width;
-    unsigned int i_height = p_sys->i_height;
-
-    uint8_t *p_dest = (uint8_t *)p_spu->p_sys->p_data;
-
-    uint8_t i_remaining;           /* number of 2-bit pixels remaining 
-                                     in byte of *p */
-    uint8_t i_pending_zero = 0;    /* number of pixels to fill with 
-                                     color zero 0..4 */
-    ogt_color_t i_color;           /* current pixel color: 0..3 */
-    uint8_t *p = p_sys->subtitle_data  + p_sys->comp_image_offset;
-    uint8_t *maxp = p + p_sys->comp_image_length;
-
-    dbg_print( (DECODE_DBG_CALL) , "width x height: %dx%d ",
-              i_width, i_height);
-
-    if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)    
-      printf("\n");
-
-    for ( i_field=0; i_field < 2; i_field++ ) {
-      i_remaining = 4;
-      for ( i_row=i_field; i_row < i_height; i_row += 2 ) {
-       for ( i_column=0; i_column<i_width; i_column++ ) {
-
-         if ( i_pending_zero ) {
-           i_pending_zero--;
-           i_color = 0;
-         } else {
-           i_color = ExtractField( p, i_remaining);
-           advance_color_pointer;
-           if ( i_color == 0 ) {
-             i_pending_zero = ExtractField( p, i_remaining );
-             advance_color_pointer;
-             /* Fall through with i_color == 0 to output the first cell */
-           }
-         }
-
-         /* Color is 0-3. */
-         p_dest[i_row*i_width+i_column] = i_color;
-
-         if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)       
-           printf("%1d", i_color);
-
-       }
-
-       if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) 
-         printf("\n");
-
-       if ( i_remaining != 4 ) {
-         /* Lines are padded to complete bytes, ignore padding */
-         advance_color_pointer_byte;
-       }
-      }
-      p = p_sys->subtitle_data + p_sys->comp_image_offset 
-       + p_sys->second_field_offset;
-    }
-
-    /* Dump out image not interlaced... */
-    if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) {
-      uint8_t *p = p_dest;
-      printf("-------------------------------------\n++");
-      for ( i_row=0; i_row < i_height; i_row ++ ) {
-       for ( i_column=0; i_column<i_width; i_column++ ) {
-         printf("%1d", *p++ & 0x03);
-       }
-       printf("\n++");
-      }
-      printf("\n-------------------------------------\n");
-    }
-
-    /* Remove color palette by expanding pixel entries to contain the
-       palette values. We work from the free space at the end to the
-       beginning so we can expand inline.
-    */
-    {
-      int n = (i_height * i_width) - 1;
-      uint8_t    *p_from = p_dest;
-      ogt_yuvt_t *p_to   = (ogt_yuvt_t *) p_dest;
-      
-      for ( ; n >= 0 ; n-- ) {
-       p_to[n] = p_sys->pi_palette[p_from[n]];
-      }
-    }
-
-    /* The video is automatically scaled. However subtitle bitmaps
-       assume a 1:1 aspect ratio. So we need to scale to compensate for
-       or undo the effects of video output scaling. 
-    */
-    /* FIXME do the right scaling depending on vout. It may not be 4:3 */
-    ScaleX( p_dec, p_spu, 3, 4 );
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * DestroySPU: subpicture destructor
- *****************************************************************************/
-static void DestroySPU( subpicture_t *p_spu )
-{
-    if( p_spu->p_sys->p_input )
-    {
-        /* Detach from our input thread */
-        var_DelCallback( p_spu->p_sys->p_input, "highlight",
-                         CropCallback, p_spu );
-        vlc_object_release( p_spu->p_sys->p_input );
-    }
-
-    vlc_mutex_destroy( &p_spu->p_sys->lock );
-    free( p_spu->p_sys );
-}
-
-/*****************************************************************************
- * UpdateSPU: update subpicture settings
- *****************************************************************************
- * This function is called from CropCallback and at initialization time, to
- * retrieve crop information from the input.
- *****************************************************************************/
-static void UpdateSPU( subpicture_t *p_spu, vlc_object_t *p_object )
-{
-    vlc_value_t val;
-
-    if( var_Get( p_object, "highlight", &val ) )
-    {
-        return;
-    }
-
-    p_spu->p_sys->b_crop = val.b_bool;
-    if( !p_spu->p_sys->b_crop )
-    {
-        return;
-    }
-
-    var_Get( p_object, "x-start", &val );
-    p_spu->p_sys->i_x_start = val.i_int;
-    var_Get( p_object, "y-start", &val );
-    p_spu->p_sys->i_y_start = val.i_int;
-    var_Get( p_object, "x-end", &val );
-    p_spu->p_sys->i_x_end = val.i_int;
-    var_Get( p_object, "y-end", &val );
-    p_spu->p_sys->i_y_end = val.i_int;
-
-}
-
-/*****************************************************************************
- * CropCallback: called when the highlight properties are changed
- *****************************************************************************
- * This callback is called from the input thread when we need cropping
- *****************************************************************************/
-static int CropCallback( vlc_object_t *p_object, char const *psz_var,
-                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    UpdateSPU( (subpicture_t *)p_data, p_object );
-
-    return VLC_SUCCESS;
-}
-
index 0a3e294..3390275 100644 (file)
@@ -2,7 +2,7 @@
  * render.c : Philips OGT (SVCD Subtitle) renderer
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: render.c,v 1.3 2003/12/28 02:01:11 rocky Exp $
+ * $Id: render.c,v 1.4 2003/12/28 04:51:52 rocky Exp $
  *
  * Author: Rocky Bernstein 
  *   based on code from: 
@@ -59,7 +59,7 @@ static void RenderI420( vout_thread_t *, picture_t *, const subpicture_t *,
   routine can be as fast as possible.
 
  *****************************************************************************/
-void VCDRenderSPU( vout_thread_t *p_vout, picture_t *p_pic,
+void VCDSubRender( vout_thread_t *p_vout, picture_t *p_pic,
                   const subpicture_t *p_spu )
 {
     struct subpicture_sys_t *p_sys = p_spu->p_sys;
index 254f074..bf052c4 100644 (file)
@@ -2,7 +2,7 @@
  * 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 $
+ * $Id: render.h,v 1.2 2003/12/28 04:51:52 rocky Exp $
  *
  * Author: Rocky Bernstein
  *
@@ -24,5 +24,5 @@
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-void VCDRenderSPU  ( vout_thread_t *, picture_t *, const subpicture_t * );
+void VCDSubRender  ( vout_thread_t *, picture_t *, const subpicture_t * );