[vlc-devel] commit: Fixed segfault with some dvd subttile streams. (Laurent Aimar )
git version control
git at videolan.org
Sun Apr 12 16:39:51 CEST 2009
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Sun Apr 12 16:38:34 2009 +0200| [3d9eb4d80736a1bdb3bcb0c382bd14e55199aa63] | committer: Laurent Aimar
Fixed segfault with some dvd subttile streams.
It happens when RLE offsets overlap (en general, because both fields
share the same data).
Its is probably present in 0.9.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3d9eb4d80736a1bdb3bcb0c382bd14e55199aa63
---
modules/codec/spudec/parse.c | 76 +++++++++++++++++++++++++++--------------
modules/codec/spudec/spudec.h | 19 ----------
2 files changed, 50 insertions(+), 45 deletions(-)
diff --git a/modules/codec/spudec/parse.c b/modules/codec/spudec/parse.c
index f4a7252..84db8df 100644
--- a/modules/codec/spudec/parse.c
+++ b/modules/codec/spudec/parse.c
@@ -48,6 +48,25 @@ typedef struct
int i_y;
} spu_properties_t;
+typedef struct
+{
+ mtime_t i_pts; /* presentation timestamp */
+
+ int pi_offset[2]; /* byte offsets to data */
+ uint16_t *p_data;
+
+ /* Color information */
+ bool b_palette;
+ uint8_t pi_alpha[4];
+ uint8_t pi_yuv[4][3];
+
+ /* Auto crop fullscreen subtitles */
+ bool b_auto_crop;
+ int i_y_top_offset;
+ int i_y_bottom_offset;
+
+} subpicture_data_t;
+
static int ParseControlSeq( decoder_t *, subpicture_t *, subpicture_data_t *,
spu_properties_t * );
static int ParseRLE ( decoder_t *, subpicture_data_t *,
@@ -80,32 +99,28 @@ static inline unsigned int AddNibble( unsigned int i_code,
subpicture_t * ParsePacket( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- subpicture_data_t *p_spu_data;
subpicture_t *p_spu;
+ subpicture_data_t spu_data;
spu_properties_t spu_properties;
/* Allocate the subpicture internal data. */
p_spu = decoder_NewSubpicture( p_dec );
if( !p_spu ) return NULL;
- /* Rationale for the "p_spudec->i_rle_size * 4": we are going to
- * expand the RLE stuff so that we won't need to read nibbles later
- * on. This will speed things up a lot. Plus, we'll only need to do
- * this stupid interlacing stuff once. */
- p_spu_data = malloc( sizeof(subpicture_data_t) + 4 * p_sys->i_rle_size );
- p_spu_data->p_data = (uint8_t *)p_spu_data + sizeof(subpicture_data_t);
- p_spu_data->b_palette = false;
- p_spu_data->b_auto_crop = false;
- p_spu_data->i_y_top_offset = 0;
- p_spu_data->i_y_bottom_offset = 0;
-
- p_spu_data->pi_alpha[0] = 0x00;
- p_spu_data->pi_alpha[1] = 0x0f;
- p_spu_data->pi_alpha[2] = 0x0f;
- p_spu_data->pi_alpha[3] = 0x0f;
+ /* */
+ spu_data.p_data = NULL;
+ spu_data.b_palette = false;
+ spu_data.b_auto_crop = false;
+ spu_data.i_y_top_offset = 0;
+ spu_data.i_y_bottom_offset = 0;
+
+ spu_data.pi_alpha[0] = 0x00;
+ spu_data.pi_alpha[1] = 0x0f;
+ spu_data.pi_alpha[2] = 0x0f;
+ spu_data.pi_alpha[3] = 0x0f;
/* Get display time now. If we do it later, we may miss the PTS. */
- p_spu_data->i_pts = p_sys->i_pts;
+ spu_data.i_pts = p_sys->i_pts;
p_spu->i_original_picture_width =
p_dec->fmt_in.subs.spu.i_original_frame_width;
@@ -115,31 +130,40 @@ subpicture_t * ParsePacket( decoder_t *p_dec )
memset( &spu_properties, 0, sizeof(spu_properties) );
/* Getting the control part */
- if( ParseControlSeq( p_dec, p_spu, p_spu_data, &spu_properties ) )
+ if( ParseControlSeq( p_dec, p_spu, &spu_data, &spu_properties ) )
{
/* There was a parse error, delete the subpicture */
decoder_DeleteSubpicture( p_dec, p_spu );
- free( p_spu_data );
return NULL;
}
+ /* we are going to expand the RLE stuff so that we won't need to read
+ * nibbles later on. This will speed things up a lot. Plus, we'll only
+ * need to do this stupid interlacing stuff once.
+ *
+ * Rationale for the "p_spudec->i_rle_size * 4*sizeof(*spu_data.p_data)":
+ * one byte gaves two nibbles and may be used twice (once per field)
+ * generating 4 codes.
+ */
+ spu_data.p_data = malloc( sizeof(*spu_data.p_data) * 2 * 2 * p_sys->i_rle_size );
+
/* We try to display it */
- if( ParseRLE( p_dec, p_spu_data, &spu_properties ) )
+ if( ParseRLE( p_dec, &spu_data, &spu_properties ) )
{
/* There was a parse error, delete the subpicture */
decoder_DeleteSubpicture( p_dec, p_spu );
- free( p_spu_data );
+ free( spu_data.p_data );
return NULL;
}
#ifdef DEBUG_SPUDEC
msg_Dbg( p_dec, "total size: 0x%x, RLE offsets: 0x%x 0x%x",
p_sys->i_spu_size,
- p_spu_data->pi_offset[0], p_spu_data->pi_offset[1] );
+ spu_data.pi_offset[0], spu_data.pi_offset[1] );
#endif
- Render( p_dec, p_spu, p_spu_data, &spu_properties );
- free( p_spu_data );
+ Render( p_dec, p_spu, &spu_data, &spu_properties );
+ free( spu_data.p_data );
return p_spu;
}
@@ -412,7 +436,7 @@ static int ParseRLE( decoder_t *p_dec,
unsigned int i_height = p_spu_properties->i_height;
unsigned int i_x, i_y;
- uint16_t *p_dest = (uint16_t *)p_spu_data->p_data;
+ uint16_t *p_dest = p_spu_data->p_data;
/* The subtitles are interlaced, we need two offsets */
unsigned int i_id = 0; /* Start on the even SPU layer */
@@ -656,7 +680,7 @@ static void Render( decoder_t *p_dec, subpicture_t *p_spu,
{
uint8_t *p_p;
int i_x, i_y, i_len, i_color, i_pitch;
- uint16_t *p_source = (uint16_t *)p_spu_data->p_data;
+ const uint16_t *p_source = p_spu_data->p_data;
video_format_t fmt;
video_palette_t palette;
diff --git a/modules/codec/spudec/spudec.h b/modules/codec/spudec/spudec.h
index da5789e..9e5b5fb 100644
--- a/modules/codec/spudec/spudec.h
+++ b/modules/codec/spudec/spudec.h
@@ -38,25 +38,6 @@ struct decoder_sys_t
uint8_t buffer[65536];
};
-typedef struct subpicture_data_t
-{
- mtime_t i_pts; /* presentation timestamp */
-
- int pi_offset[2]; /* byte offsets to data */
- void *p_data;
-
- /* Color information */
- bool b_palette;
- uint8_t pi_alpha[4];
- uint8_t pi_yuv[4][3];
-
- /* Auto crop fullscreen subtitles */
- bool b_auto_crop;
- int i_y_top_offset;
- int i_y_bottom_offset;
-
-} subpicture_data_t;
-
/*****************************************************************************
* Amount of bytes we GetChunk() in one go
*****************************************************************************/
More information about the vlc-devel
mailing list