1 /*****************************************************************************
2 * video_spu.c : DVD subpicture units functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
5 * $Id: video_spu.c,v 1.20 2001/04/06 09:15:48 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
30 #include <string.h> /* memcpy(), memset() */
38 #include "video_output.h"
39 #include "video_spu.h"
41 /* FIXME: fake palette - the real one has to be sought in the .IFO */
42 static int p_palette[4] = { 0x0000, 0xffff, 0x5555, 0x8888 };
44 /*****************************************************************************
45 * vout_RenderSPU: draw an SPU on a picture
46 *****************************************************************************
47 * This is a fast implementation of the subpicture drawing code. The data
48 * has been preprocessed once in spu_decoder.c, so we don't need to parse the
49 * RLE buffer again and again. Most sanity checks are done in spu_decoder.c
50 * so that this routine can be as fast as possible.
51 *****************************************************************************/
52 void vout_RenderSPU( vout_buffer_t *p_buffer, subpicture_t *p_spu,
53 int i_bytes_per_pixel, int i_bytes_per_line )
56 u16 *p_source = (u16 *)p_spu->p_data;
58 /* FIXME: we need a way to get 720 and 576 from the stream */
59 int i_xscale = ( p_buffer->i_pic_width << 6 ) / 720;
60 int i_yscale = ( p_buffer->i_pic_height << 6 ) / 576;
62 int i_width = p_spu->i_width * i_xscale;
63 int i_height = p_spu->i_height * i_yscale;
65 int i_x = 0, i_y = 0, i_ytmp, i_yreal, i_ynext;
67 u8 *p_dest = p_buffer->p_data
68 /* Add the picture coordinates and the SPU coordinates */
69 + ( p_buffer->i_pic_x + ((p_spu->i_x * i_xscale) >> 6))
71 + ( p_buffer->i_pic_y + ((p_spu->i_y * i_yscale) >> 6))
74 /* Draw until we reach the bottom of the subtitle */
75 for( i_y = 0 ; i_y < i_height ; /* i_y incremented below */ )
80 /* Check whether we need to draw one line or more than one */
81 if( i_ytmp + 1 >= ( i_y >> 6 ) )
83 /* Just one line : we precalculate i_y >> 6 */
84 i_yreal = i_bytes_per_line * i_ytmp;
86 /* Draw until we reach the end of the line */
87 for( i_x = 0 ; i_x < i_width ; i_x += i_len )
89 /* Get RLE information */
90 i_len = i_xscale * ( *p_source >> 2 );
91 i_color = *p_source++ & 0x3;
96 memset( p_dest + i_bytes_per_pixel * ( i_x >> 6 )
99 i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );
105 i_yreal = i_bytes_per_line * i_ytmp;
106 i_ynext = i_bytes_per_line * i_y >> 6;
108 /* Draw until we reach the end of the line */
109 for( i_x = 0 ; i_x < i_width ; i_x += i_len )
111 /* Get RLE information */
112 i_len = i_xscale * ( *p_source >> 2 );
113 i_color = *p_source++ & 0x3;
115 /* Draw as many lines as needed */
118 for( i_ytmp = i_yreal ;
120 i_ytmp += i_bytes_per_line )
122 memset( p_dest + i_bytes_per_pixel * ( i_x >> 6 )
124 p_palette[ i_color ],
125 i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );