* thread, and destroy a previously oppened video output thread.
*****************************************************************************
* Copyright (C) 2000 VideoLAN
- * $Id: video_output.c,v 1.127 2001/05/08 00:43:57 sam Exp $
+ * $Id: video_output.c,v 1.128 2001/05/08 20:38:25 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
static void SetBufferPicture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderPictureInfo ( vout_thread_t *p_vout, picture_t *p_pic );
-static void RenderSubPicture ( vout_thread_t *p_vout,
+static void RenderSubPicture ( vout_thread_t *p_vout, picture_t *p_pic,
subpicture_t *p_subpic );
-static void RenderInterface ( vout_thread_t *p_vout );
static int RenderIdle ( vout_thread_t *p_vout );
-static int RenderSplash ( vout_thread_t *p_vout );
static void RenderInfo ( vout_thread_t *p_vout );
static int Manage ( vout_thread_t *p_vout );
static int Align ( vout_thread_t *p_vout, int *pi_x,
RenderPictureInfo( p_vout, p_pic );
RenderInfo( p_vout );
}
+ }
+ if( b_display ) /* XXX: quick HACK */
+ {
if( p_subpic )
{
- RenderSubPicture( p_vout, p_subpic );
+ RenderSubPicture( p_vout, p_pic, p_subpic );
}
}
-
- /* Render interface and subpicture */
- if( b_display && p_vout->b_interface && p_vout->b_need_render )
- {
- RenderInterface( p_vout );
- }
-
}
else if( p_vout->b_active && p_vout->b_need_render
&& p_vout->init_display_date == 0)
if( b_display )
{
p_vout->last_idle_date = current_date;
- if( p_vout->b_interface )
- {
- RenderInterface( p_vout );
- }
}
}
*/
if( p_vout->init_display_date > 0 && p_vout->b_need_render )
{
- if( p_vout->b_active &&
- mdate()-p_vout->init_display_date < 5000000)
- {
- /* there is something to display ! */
- b_display = 1;
- RenderSplash( p_vout );
-
- } else {
- /* no splash screen ! */
- p_vout->init_display_date=0;
- }
+ p_vout->init_display_date = 0;
}
#endif
}
-/*****************************************************************************
- * RenderSplash: render splash picture
- *****************************************************************************
- * This function will print something on the screen. It will return 0 if
- * nothing has been rendered, or 1 if something has been changed on the screen.
- * Note that if you absolutely want something to be printed, you will have
- * to force it by setting the last idle date to 0.
- * Unlike other rendering functions, this one calls the SetBufferPicture
- * function when needed.
- *****************************************************************************/
-int RenderSplash( vout_thread_t *p_vout )
-{
- int i_x = 0, i_y = 0; /* text position */
- int i_width, i_height; /* text size */
- char *psz_text = "VideoLAN Client (" VERSION ")"; /* text to display */
-
- memset( p_vout->p_buffer[ p_vout->i_buffer_index ].p_data,
- p_vout->i_bytes_per_line * p_vout->i_height, 12);
-
- // SetBufferPicture( p_vout, NULL );
- vout_TextSize( p_vout->p_large_font, WIDE_TEXT | OUTLINED_TEXT, psz_text,
- &i_width, &i_height );
- if( !Align( p_vout, &i_x, &i_y, i_width, i_height, CENTER_RALIGN, CENTER_RALIGN ) )
- {
- vout_Print( p_vout->p_large_font,
- p_vout->p_buffer[ p_vout->i_buffer_index ].p_data +
- i_x * p_vout->i_bytes_per_pixel + (i_y - 16 ) * p_vout->i_bytes_per_line,
- p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
- p_vout->i_white_pixel, p_vout->i_gray_pixel, 0,
- WIDE_TEXT | OUTLINED_TEXT, psz_text, 100);
- SetBufferArea( p_vout, i_x, i_y, i_width, i_height);
- }
- return( 1 );
-}
-
-
/*****************************************************************************
* RenderIdle: render idle picture
*****************************************************************************
*****************************************************************************
* This function renders a sub picture unit.
*****************************************************************************/
-static void RenderSubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
+static void RenderSubPicture( vout_thread_t *p_vout, picture_t *p_pic,
+ subpicture_t *p_subpic )
{
p_vout_font_t p_font; /* text font */
int i_width, i_height; /* subpicture dimensions */
switch( p_subpic->i_type )
{
case DVD_SUBPICTURE: /* DVD subpicture unit */
- vout_RenderSPU( &p_vout->p_buffer[ p_vout->i_buffer_index ],
- p_subpic, p_vout->i_bytes_per_pixel,
- p_vout->i_bytes_per_line );
+ vout_RenderRGBSPU( p_pic, p_subpic,
+ &p_vout->p_buffer[ p_vout->i_buffer_index ],
+ p_vout->i_bytes_per_pixel,
+ p_vout->i_bytes_per_line );
+ /* vout_RenderYUVSPU( p_pic, p_subpic ); */
break;
case TEXT_SUBPICTURE: /* single line text */
}
}
-/*****************************************************************************
- * RenderInterface: render the interface
- *****************************************************************************
- * This function renders the interface, if any.
- *****************************************************************************/
-static void RenderInterface( vout_thread_t *p_vout )
-{
- int i_height, i_text_height; /* total and text height */
- int i_width_1, i_width_2; /* text width */
- int i_byte; /* byte index */
- const char *psz_text_1 = "[1-9] Channel [i]nfo [c]olor [g/G]amma";
- const char *psz_text_2 = "[+/-] Volume [m]ute [s]caling [Q]uit";
-
- /* Get text size */
- vout_TextSize( p_vout->p_large_font, OUTLINED_TEXT, psz_text_1, &i_width_1, &i_height );
- vout_TextSize( p_vout->p_large_font, OUTLINED_TEXT, psz_text_2, &i_width_2, &i_text_height );
- i_height += i_text_height;
-
- /* Render background */
- for( i_byte = (p_vout->i_height - i_height) * p_vout->i_bytes_per_line;
- i_byte < p_vout->i_height * p_vout->i_bytes_per_line;
- i_byte++ )
- {
- /* XXX?? noooo ! */
- p_vout->p_buffer[ p_vout->i_buffer_index ].p_data[ i_byte ] = p_vout->i_blue_pixel;
- }
-
- /* Render text, if not larger than screen */
- if( i_width_1 < p_vout->i_width )
- {
- vout_Print( p_vout->p_large_font, p_vout->p_buffer[ p_vout->i_buffer_index ].p_data +
- (p_vout->i_height - i_height) * p_vout->i_bytes_per_line,
- p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
- p_vout->i_white_pixel, p_vout->i_black_pixel, 0,
- OUTLINED_TEXT, psz_text_1, 100 );
- }
- if( i_width_2 < p_vout->i_width )
- {
- vout_Print( p_vout->p_large_font, p_vout->p_buffer[ p_vout->i_buffer_index ].p_data +
- (p_vout->i_height - i_height + i_text_height) * p_vout->i_bytes_per_line,
- p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
- p_vout->i_white_pixel, p_vout->i_black_pixel, 0,
- OUTLINED_TEXT, psz_text_2, 100 );
- }
-
- /* Activate modified area */
- SetBufferArea( p_vout, 0, p_vout->i_height - i_height, p_vout->i_width, i_height );
-}
-
/*****************************************************************************
* Manage: manage thread
*****************************************************************************
* video_spu.c : DVD subpicture units functions
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_spu.c,v 1.20 2001/04/06 09:15:48 sam Exp $
+ * $Id: video_spu.c,v 1.21 2001/05/08 20:38:25 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
static int p_palette[4] = { 0x0000, 0xffff, 0x5555, 0x8888 };
/*****************************************************************************
- * vout_RenderSPU: draw an SPU on a picture
+ * vout_RenderRGBSPU: draw an SPU on a picture
*****************************************************************************
* This is a fast implementation of the subpicture drawing code. The data
* has been preprocessed once in spu_decoder.c, so we don't need to parse the
* RLE buffer again and again. Most sanity checks are done in spu_decoder.c
* so that this routine can be as fast as possible.
*****************************************************************************/
-void vout_RenderSPU( vout_buffer_t *p_buffer, subpicture_t *p_spu,
- int i_bytes_per_pixel, int i_bytes_per_line )
+void vout_RenderRGBSPU( picture_t *p_pic, const subpicture_t *p_spu,
+ vout_buffer_t *p_buffer,
+ int i_bytes_per_pixel, int i_bytes_per_line )
{
int i_len, i_color;
u16 *p_source = (u16 *)p_spu->p_data;
- /* FIXME: we need a way to get 720 and 576 from the stream */
- int i_xscale = ( p_buffer->i_pic_width << 6 ) / 720;
- int i_yscale = ( p_buffer->i_pic_height << 6 ) / 576;
+ int i_xscale = ( p_buffer->i_pic_width << 6 ) / p_pic->i_width;
+ int i_yscale = ( p_buffer->i_pic_height << 6 ) / p_pic->i_height;
int i_width = p_spu->i_width * i_xscale;
int i_height = p_spu->i_height * i_yscale;
- int i_x = 0, i_y = 0, i_ytmp, i_yreal, i_ynext;
+ int i_x, i_y, i_ytmp, i_yreal, i_ynext;
- u8 *p_dest = p_buffer->p_data
+ u8 *p_dest = p_buffer->p_data + ( i_width >> 6 ) * i_bytes_per_pixel
/* Add the picture coordinates and the SPU coordinates */
+ ( p_buffer->i_pic_x + ((p_spu->i_x * i_xscale) >> 6))
* i_bytes_per_pixel
* i_bytes_per_line;
/* Draw until we reach the bottom of the subtitle */
- for( i_y = 0 ; i_y < i_height ; /* i_y incremented below */ )
+ i_y = 0;
+
+ while( i_y < i_height )
{
i_ytmp = i_y >> 6;
i_y += i_yscale;
i_yreal = i_bytes_per_line * i_ytmp;
/* Draw until we reach the end of the line */
- for( i_x = 0 ; i_x < i_width ; i_x += i_len )
+ i_x = i_width;
+
+ while( i_x )
{
- /* Get RLE information */
- i_len = i_xscale * ( *p_source >> 2 );
- i_color = *p_source++ & 0x3;
+ /* Get the RLE part */
+ i_color = *p_source & 0x3;
/* Draw the line */
if( i_color )
{
- memset( p_dest + i_bytes_per_pixel * ( i_x >> 6 )
+ i_len = i_xscale * ( *p_source++ >> 2 );
+
+ memset( p_dest - i_bytes_per_pixel * ( i_x >> 6 )
+ i_yreal,
p_palette[ i_color ],
i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );
+
+ i_x -= i_len;
+ continue;
}
+
+ i_x -= i_xscale * ( *p_source++ >> 2 );
}
}
else
i_ynext = i_bytes_per_line * i_y >> 6;
/* Draw until we reach the end of the line */
- for( i_x = 0 ; i_x < i_width ; i_x += i_len )
+ i_x = i_width;
+
+ while( i_x )
{
- /* Get RLE information */
- i_len = i_xscale * ( *p_source >> 2 );
- i_color = *p_source++ & 0x3;
+ /* Get the RLE part */
+ i_color = *p_source & 0x3;
/* Draw as many lines as needed */
if( i_color )
{
+ i_len = i_xscale * ( *p_source++ >> 2 );
+
for( i_ytmp = i_yreal ;
i_ytmp < i_ynext ;
i_ytmp += i_bytes_per_line )
{
- memset( p_dest + i_bytes_per_pixel * ( i_x >> 6 )
+ memset( p_dest - i_bytes_per_pixel * ( i_x >> 6 )
+ i_ytmp,
p_palette[ i_color ],
i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );
}
+
+ i_x -= i_len;
+ continue;
}
+
+ i_x -= i_xscale * ( *p_source++ >> 2 );
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ * vout_RenderYUVSPU: draw an SPU on an YUV overlay
+ *****************************************************************************
+ * This is a fast implementation of the subpicture drawing code. The data
+ * has been preprocessed once in spu_decoder.c, so we don't need to parse the
+ * RLE buffer again and again. Most sanity checks are done in spu_decoder.c
+ * so that this routine can be as fast as possible.
+ *****************************************************************************/
+void vout_RenderYUVSPU( picture_t *p_pic, const subpicture_t *p_spu )
+{
+ int i_len, i_color;
+ u16 *p_source = (u16 *)p_spu->p_data;
+
+ int i_x, i_y;
+
+ u8 *p_dest = p_pic->p_y + p_spu->i_x + p_spu->i_width
+ + p_pic->i_width * ( p_spu->i_y + p_spu->i_height );
+
+ /* Draw until we reach the bottom of the subtitle */
+ i_y = p_spu->i_height * p_pic->i_width;
+
+ while( i_y )
+ {
+ /* Draw until we reach the end of the line */
+ i_x = p_spu->i_width;
+
+ while( i_x )
+ {
+ /* Draw the line if needed */
+ i_color = *p_source & 0x3;
+
+ if( i_color )
+ {
+ i_len = *p_source++ >> 2;
+ memset( p_dest - i_x - i_y, p_palette[ i_color ], i_len );
+ i_x -= i_len;
+ continue;
}
+
+ i_x -= *p_source++ >> 2;
}
+
+ i_y -= p_pic->i_width;
}
}