Commit 0fddb7eb authored by Gildas Bazin's avatar Gildas Bazin

* Merged trunk changesets 9185 9204 9205 9273 to 0.8.1 branch.

parent 19db8d9d
...@@ -244,6 +244,7 @@ struct subpicture_t ...@@ -244,6 +244,7 @@ struct subpicture_t
vlc_bool_t b_ephemer; /**< If this flag is set to true vlc_bool_t b_ephemer; /**< If this flag is set to true
the subtitle will be displayed the subtitle will be displayed
untill the next one appear */ untill the next one appear */
vlc_bool_t b_fade; /**< enable fading */
/**@}*/ /**@}*/
subpicture_region_t *p_region; /**< region list composing this subtitle */ subpicture_region_t *p_region; /**< region list composing this subtitle */
......
...@@ -28,47 +28,30 @@ ...@@ -28,47 +28,30 @@
#include <vlc/vout.h> #include <vlc/vout.h>
#include <osd.h> #include <osd.h>
#include "vlc_video.h"
#include "vlc_filter.h"
#define STYLE_EMPTY 0 #define STYLE_EMPTY 0
#define STYLE_FILLED 1 #define STYLE_FILLED 1
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static void DrawRect( vout_thread_t *, subpicture_t *, int, int, int, int, static void DrawRect( subpicture_t *, int, int, int, int, short );
short ); static void DrawTriangle( subpicture_t *, int, int, int, int, short );
static void DrawTriangle( vout_thread_t *, subpicture_t *, int, int, int, int, static void CreatePicture( spu_t *, subpicture_t *, int, int, int, int );
short ); static subpicture_t *vout_CreateWidget( spu_t *, int );
static void Render ( vout_thread_t *, picture_t *, const subpicture_t * );
static void RenderI420( vout_thread_t *, picture_t *, const subpicture_t *,
int );
static void RenderYUY2( vout_thread_t *, picture_t *, const subpicture_t *,
int );
static void RenderRV32( vout_thread_t *, picture_t *, const subpicture_t *,
int );
static subpicture_t *vout_CreateWidget( vout_thread_t *, int );
static void FreeWidget( subpicture_t * );
/**
* Private data in a subpicture.
*/
struct subpicture_sys_t
{
int i_x;
int i_y;
int i_width;
int i_height;
uint8_t *p_pic;
};
/***************************************************************************** /*****************************************************************************
* Draws a rectangle at the given position in the subpic. * Draws a rectangle at the given position in the subpic.
* It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY). * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY).
*****************************************************************************/ *****************************************************************************/
static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic, static void DrawRect( subpicture_t *p_subpic, int i_x1, int i_y1,
int i_x1, int i_y1, int i_x2, int i_y2, short fill ) int i_x2, int i_y2, short fill )
{ {
int x, y; int x, y;
subpicture_sys_t *p_widget = p_subpic->p_sys; uint8_t *p_a = p_subpic->p_region->picture.A_PIXELS;
int i_pitch = p_subpic->p_region->picture.Y_PITCH;
if( fill == STYLE_FILLED ) if( fill == STYLE_FILLED )
{ {
...@@ -76,7 +59,7 @@ static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic, ...@@ -76,7 +59,7 @@ static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic,
{ {
for( x = i_x1; x <= i_x2; x++ ) for( x = i_x1; x <= i_x2; x++ )
{ {
p_widget->p_pic[ x + p_widget->i_width * y ] = 1; p_a[ x + i_pitch * y ] = 0xff;
} }
} }
} }
...@@ -84,13 +67,13 @@ static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic, ...@@ -84,13 +67,13 @@ static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic,
{ {
for( y = i_y1; y <= i_y2; y++ ) for( y = i_y1; y <= i_y2; y++ )
{ {
p_widget->p_pic[ i_x1 + p_widget->i_width * y ] = 1; p_a[ i_x1 + i_pitch * y ] = 0xff;
p_widget->p_pic[ i_x2 + p_widget->i_width * y ] = 1; p_a[ i_x2 + i_pitch * y ] = 0xff;
} }
for( x = i_x1; x <= i_x2; x++ ) for( x = i_x1; x <= i_x2; x++ )
{ {
p_widget->p_pic[ x + p_widget->i_width * i_y1 ] = 1; p_a[ x + i_pitch * i_y1 ] = 0xff;
p_widget->p_pic[ x + p_widget->i_width * i_y2 ] = 1; p_a[ x + i_pitch * i_y2 ] = 0xff;
} }
} }
} }
...@@ -99,11 +82,12 @@ static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic, ...@@ -99,11 +82,12 @@ static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic,
* Draws a triangle at the given position in the subpic. * Draws a triangle at the given position in the subpic.
* It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY). * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY).
*****************************************************************************/ *****************************************************************************/
static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic, static void DrawTriangle( subpicture_t *p_subpic, int i_x1, int i_y1,
int i_x1, int i_y1, int i_x2, int i_y2, short fill ) int i_x2, int i_y2, short fill )
{ {
int x, y, i_mid, h; int x, y, i_mid, h;
subpicture_sys_t *p_widget = p_subpic->p_sys; uint8_t *p_a = p_subpic->p_region->picture.A_PIXELS;
int i_pitch = p_subpic->p_region->picture.Y_PITCH;
i_mid = i_y1 + ( ( i_y2 - i_y1 ) >> 1 ); i_mid = i_y1 + ( ( i_y2 - i_y1 ) >> 1 );
...@@ -116,8 +100,8 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic, ...@@ -116,8 +100,8 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic,
h = y - i_y1; h = y - i_y1;
for( x = i_x1; x <= i_x1 + h && x <= i_x2; x++ ) for( x = i_x1; x <= i_x1 + h && x <= i_x2; x++ )
{ {
p_widget->p_pic[ x + p_widget->i_width * y ] = 1; p_a[ x + i_pitch * y ] = 0xff;
p_widget->p_pic[ x + p_widget->i_width * ( i_y2 - h ) ] = 1; p_a[ x + i_pitch * ( i_y2 - h ) ] = 0xff;
} }
} }
} }
...@@ -126,10 +110,10 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic, ...@@ -126,10 +110,10 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic,
for( y = i_y1; y <= i_mid; y++ ) for( y = i_y1; y <= i_mid; y++ )
{ {
h = y - i_y1; h = y - i_y1;
p_widget->p_pic[ i_x1 + p_widget->i_width * y ] = 1; p_a[ i_x1 + i_pitch * y ] = 0xff;
p_widget->p_pic[ i_x1 + h + p_widget->i_width * y ] = 1; p_a[ i_x1 + h + i_pitch * y ] = 0xff;
p_widget->p_pic[ i_x1 + p_widget->i_width * ( i_y2 - h ) ] = 1; p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff;
p_widget->p_pic[ i_x1 + h + p_widget->i_width * ( i_y2 - h ) ] = 1; p_a[ i_x1 + h + i_pitch * ( i_y2 - h ) ] = 0xff;
} }
} }
} }
...@@ -142,8 +126,8 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic, ...@@ -142,8 +126,8 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic,
h = y - i_y1; h = y - i_y1;
for( x = i_x1; x >= i_x1 - h && x >= i_x2; x-- ) for( x = i_x1; x >= i_x1 - h && x >= i_x2; x-- )
{ {
p_widget->p_pic[ x + p_widget->i_width * y ] = 1; p_a[ x + i_pitch * y ] = 0xff;
p_widget->p_pic[ x + p_widget->i_width * ( i_y2 - h ) ] = 1; p_a[ x + i_pitch * ( i_y2 - h ) ] = 0xff;
} }
} }
} }
...@@ -152,256 +136,71 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic, ...@@ -152,256 +136,71 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic,
for( y = i_y1; y <= i_mid; y++ ) for( y = i_y1; y <= i_mid; y++ )
{ {
h = y - i_y1; h = y - i_y1;
p_widget->p_pic[ i_x1 + p_widget->i_width * y ] = 1; p_a[ i_x1 + i_pitch * y ] = 0xff;
p_widget->p_pic[ i_x1 - h + p_widget->i_width * y ] = 1; p_a[ i_x1 - h + i_pitch * y ] = 0xff;
p_widget->p_pic[ i_x1 + p_widget->i_width * ( i_y2 - h ) ] = 1; p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff;
p_widget->p_pic[ i_x1 - h + p_widget->i_width * ( i_y2 - h ) ] = 1; p_a[ i_x1 - h + i_pitch * ( i_y2 - h ) ] = 0xff;
} }
} }
} }
} }
/***************************************************************************** /*****************************************************************************
* Render: place widget in picture * Create Picture: creates subpicture region and picture
*****************************************************************************
* This function merges the previously drawn widget into a picture
*****************************************************************************/ *****************************************************************************/
static void Render( vout_thread_t *p_vout, picture_t *p_pic, static void CreatePicture( spu_t *p_spu, subpicture_t *p_subpic,
const subpicture_t *p_subpic ) int i_x, int i_y, int i_width, int i_height )
{
int i_fade_alpha = 255;
mtime_t i_fade_start = ( p_subpic->i_stop + p_subpic->i_start ) / 2;
mtime_t i_now = mdate();
if( i_now >= i_fade_start )
{
i_fade_alpha = 255 * ( p_subpic->i_stop - i_now ) /
( p_subpic->i_stop - i_fade_start );
}
switch( p_vout->output.i_chroma )
{
/* I420 target, no scaling */
case VLC_FOURCC('I','4','2','0'):
case VLC_FOURCC('I','Y','U','V'):
case VLC_FOURCC('Y','V','1','2'):
RenderI420( p_vout, p_pic, p_subpic, i_fade_alpha );
break;
/* RV32 target, scaling */
case VLC_FOURCC('R','V','2','4'):
case VLC_FOURCC('R','V','3','2'):
RenderRV32( p_vout, p_pic, p_subpic, i_fade_alpha );
break;
/* NVidia or BeOS overlay, no scaling */
case VLC_FOURCC('Y','U','Y','2'):
RenderYUY2( p_vout, p_pic, p_subpic, i_fade_alpha );
break;
default:
msg_Err( p_vout, "unknown chroma, can't render SPU" );
break;
}
}
/**
* Draw a widget on a I420 (or similar) picture
*/
static void RenderI420( vout_thread_t *p_vout, picture_t *p_pic,
const subpicture_t *p_subpic, int i_fade_alpha )
{
subpicture_sys_t *p_widget = p_subpic->p_sys;
int i_plane, x, y, pen_x, pen_y;
for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
{
uint8_t *p_in = p_pic->p[ i_plane ].p_pixels;
int i_pic_pitch = p_pic->p[ i_plane ].i_pitch;
if ( i_plane == 0 )
{
pen_x = p_widget->i_x;
pen_y = p_widget->i_y;
#define alpha p_widget->p_pic[ x + y * p_widget->i_width ] * i_fade_alpha
#define pixel p_in[ ( pen_y + y ) * i_pic_pitch + pen_x + x ]
for( y = 0; y < p_widget->i_height; y++ )
{
for( x = 0; x < p_widget->i_width; x++ )
{
if( alpha == 0 ) continue;
pen_y--;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_y++; pen_x--;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_x += 2;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_y++; pen_x--;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_y--;
}
}
for( y = 0; y < p_widget->i_height; y++ )
{
for( x = 0; x < p_widget->i_width; x++ )
{
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 ) +
( 255 * alpha >> 8 );
}
}
#undef alpha
#undef pixel
}
else
{
pen_x = p_widget->i_x >> 1;
pen_y = p_widget->i_y >> 1;
#define alpha p_widget->p_pic[ x + y * p_widget->i_width ] * i_fade_alpha
#define pixel p_in[ ( pen_y + (y >> 1) ) * i_pic_pitch + pen_x + (x >> 1) ]
for( y = 0; y < p_widget->i_height; y+=2 )
{
for( x = 0; x < p_widget->i_width; x+=2 )
{
if( alpha == 0 ) continue;
pixel = ( ( pixel * ( 0xFF - alpha ) ) >> 8 ) +
( 0x80 * alpha >> 8 );
}
}
#undef alpha
#undef pixel
}
}
}
/**
* Draw a widget on a YUY2 picture
*/
static void RenderYUY2( vout_thread_t *p_vout, picture_t *p_pic,
const subpicture_t *p_subpic, int i_fade_alpha )
{ {
subpicture_sys_t *p_widget = p_subpic->p_sys; uint8_t *p_y, *p_u, *p_v, *p_a;
int x, y, pen_x, pen_y; video_format_t fmt;
uint8_t *p_in = p_pic->p[0].p_pixels; int i_pitch;
int i_pic_pitch = p_pic->p[0].i_pitch;
/* Create a new subpicture region */
pen_x = p_widget->i_x; memset( &fmt, 0, sizeof(video_format_t) );
pen_y = p_widget->i_y; fmt.i_chroma = VLC_FOURCC('Y','U','V','A');
#define alpha p_widget->p_pic[ x + y * p_widget->i_width ] * i_fade_alpha fmt.i_aspect = VOUT_ASPECT_FACTOR;
#define pixel p_in[ ( pen_y + y ) * i_pic_pitch + 2 * ( pen_x + x ) ] fmt.i_width = fmt.i_visible_width = i_width;
for( y = 0; y < p_widget->i_height; y++ ) fmt.i_height = fmt.i_visible_height = i_height;
fmt.i_x_offset = fmt.i_y_offset = 0;
p_subpic->p_region = p_subpic->pf_create_region( VLC_OBJECT(p_spu), &fmt );
if( !p_subpic->p_region )
{ {
for( x = 0; x < p_widget->i_width; x++ ) msg_Err( p_spu, "cannot allocate SPU region" );
{ return;
pen_y--;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_y++; pen_x--;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_x += 2;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_y++; pen_x--;
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 );
pen_y--;
}
} }
for( y = 0; y < p_widget->i_height; y++ )
{
for( x = 0; x < p_widget->i_width; x++ )
{
pixel = ( ( pixel * ( 255 - alpha ) ) >> 8 ) +
( 255 * alpha >> 8 );
}
}
#undef alpha
#undef pixel
}
/**
* Draw a widget on a RV32 picture
*/
static void RenderRV32( vout_thread_t *p_vout, picture_t *p_pic,
const subpicture_t *p_subpic, int i_fade_alpha )
{
subpicture_sys_t *p_widget = p_subpic->p_sys;
int x, y, pen_x, pen_y;
uint8_t *p_in = p_pic->p[0].p_pixels;
int i_pic_pitch = p_pic->p[0].i_pitch;
pen_x = p_widget->i_x;
pen_y = p_widget->i_y;
#define alpha p_widget->p_pic[ x + y * p_widget->i_width ] * i_fade_alpha p_subpic->p_region->i_x = i_x;
#define pixel( c ) p_in[ ( pen_y + y ) * i_pic_pitch + 4 * ( pen_x + x ) + c ] p_subpic->p_region->i_y = i_y;
for(y = 0; y < p_widget->i_height; y++ ) p_y = p_subpic->p_region->picture.Y_PIXELS;
{ p_u = p_subpic->p_region->picture.U_PIXELS;
for( x = 0; x < p_widget->i_width; x++ ) p_v = p_subpic->p_region->picture.V_PIXELS;
{ p_a = p_subpic->p_region->picture.A_PIXELS;
pen_y--; i_pitch = p_subpic->p_region->picture.Y_PITCH;
pixel( 0 ) = ( ( pixel( 0 ) * ( 255 - alpha ) ) >> 8 );
pixel( 1 ) = ( ( pixel( 1 ) * ( 255 - alpha ) ) >> 8 ); /* Initialize the region pixels (only the alpha will be changed later) */
pixel( 2 ) = ( ( pixel( 2 ) * ( 255 - alpha ) ) >> 8 ); memset( p_y, 0xff, i_pitch * p_subpic->p_region->fmt.i_height );
pen_y++; pen_x--; memset( p_u, 0x80, i_pitch * p_subpic->p_region->fmt.i_height );
pixel( 0 ) = ( ( pixel( 0 ) * ( 255 - alpha ) ) >> 8 ); memset( p_v, 0x80, i_pitch * p_subpic->p_region->fmt.i_height );
pixel( 1 ) = ( ( pixel( 1 ) * ( 255 - alpha ) ) >> 8 ); memset( p_a, 0x00, i_pitch * p_subpic->p_region->fmt.i_height );
pixel( 2 ) = ( ( pixel( 2 ) * ( 255 - alpha ) ) >> 8 );
pen_x += 2;
pixel( 0 ) = ( ( pixel( 0 ) * ( 255 - alpha ) ) >> 8 );
pixel( 1 ) = ( ( pixel( 1 ) * ( 255 - alpha ) ) >> 8 );
pixel( 2 ) = ( ( pixel( 2 ) * ( 255 - alpha ) ) >> 8 );
pen_y++; pen_x--;
pixel( 0 ) = ( ( pixel( 0 ) * ( 255 - alpha ) ) >> 8 );
pixel( 1 ) = ( ( pixel( 1 ) * ( 255 - alpha ) ) >> 8 );
pixel( 2 ) = ( ( pixel( 2 ) * ( 255 - alpha ) ) >> 8 );
pen_y--;
}
}
for(y = 0; y < p_widget->i_height; y++ )
{
for( x = 0; x < p_widget->i_width; x++ )
{
pixel( 0 ) = ( ( pixel( 0 ) * ( 255 - alpha ) ) >> 8 ) +
( 255 * alpha >> 8 );
pixel( 1 ) = ( ( pixel( 1 ) * ( 255 - alpha ) ) >> 8 ) +
( 255 * alpha >> 8 );
pixel( 2 ) = ( ( pixel( 2 ) * ( 255 - alpha ) ) >> 8 ) +
( 255 * alpha >> 8 );
}
}
#undef alpha
#undef pixel
} }
/***************************************************************************** /*****************************************************************************
* Creates and initializes an OSD widget. * Creates and initializes an OSD widget.
*****************************************************************************/ *****************************************************************************/
subpicture_t *vout_CreateWidget( vout_thread_t *p_vout, int i_channel ) subpicture_t *vout_CreateWidget( spu_t *p_spu, int i_channel )
{ {
subpicture_t *p_subpic; subpicture_t *p_subpic;
subpicture_sys_t *p_widget;
mtime_t i_now = mdate(); mtime_t i_now = mdate();
p_subpic = 0;
p_widget = 0;
/* Create and initialize a subpicture */ /* Create and initialize a subpicture */
p_subpic = spu_CreateSubpicture( p_vout->p_spu ); p_subpic = spu_CreateSubpicture( p_spu );
if( p_subpic == NULL ) if( p_subpic == NULL ) return NULL;
{
return NULL;
}
p_subpic->i_channel = i_channel; p_subpic->i_channel = i_channel;
p_subpic->pf_render = Render;
p_subpic->pf_destroy = FreeWidget;
p_subpic->i_start = i_now; p_subpic->i_start = i_now;
p_subpic->i_stop = i_now + 1200000; p_subpic->i_stop = i_now + 1200000;
p_subpic->b_ephemer = VLC_TRUE; p_subpic->b_ephemer = VLC_TRUE;
p_subpic->b_fade = VLC_TRUE;
p_widget = malloc( sizeof(subpicture_sys_t) );
if( p_widget == NULL )
{
FreeWidget( p_subpic );
spu_DestroySubpicture( p_vout->p_spu, p_subpic );
return NULL;
}
p_subpic->p_sys = p_widget;
return p_subpic; return p_subpic;
} }
...@@ -416,70 +215,55 @@ void vout_OSDSlider( vlc_object_t *p_caller, int i_channel, int i_position, ...@@ -416,70 +215,55 @@ void vout_OSDSlider( vlc_object_t *p_caller, int i_channel, int i_position,
vout_thread_t *p_vout = vlc_object_find( p_caller, VLC_OBJECT_VOUT, vout_thread_t *p_vout = vlc_object_find( p_caller, VLC_OBJECT_VOUT,
FIND_ANYWHERE ); FIND_ANYWHERE );
subpicture_t *p_subpic; subpicture_t *p_subpic;
subpicture_sys_t *p_widget; int i_x_margin, i_y_margin, i_x, i_y, i_width, i_height;
int i_x_margin, i_y_margin;
if( p_vout == NULL || !config_GetInt( p_caller, "osd" ) || i_position < 0 ) if( p_vout == NULL || !config_GetInt( p_caller, "osd" ) || i_position < 0 )
{ {
return; return;
} }
p_subpic = vout_CreateWidget( p_vout, i_channel ); p_subpic = vout_CreateWidget( p_vout->p_spu, i_channel );
if( p_subpic == NULL ) if( p_subpic == NULL )
{ {
return; return;
} }
p_widget = p_subpic->p_sys;
i_y_margin = p_vout->render.i_height / 10; i_y_margin = p_vout->render.i_height / 10;
i_x_margin = i_y_margin; i_x_margin = i_y_margin;
if( i_type == OSD_HOR_SLIDER ) if( i_type == OSD_HOR_SLIDER )
{ {
p_widget->i_width = p_vout->render.i_width - 2 * i_x_margin; i_width = p_vout->render.i_width - 2 * i_x_margin;
p_widget->i_height = p_vout->render.i_height / 20; i_height = p_vout->render.i_height / 20;
p_widget->i_x = i_x_margin; i_x = i_x_margin;
p_widget->i_y = p_vout->render.i_height - i_y_margin - i_y = p_vout->render.i_height - i_y_margin - i_height;
p_widget->i_height;
} }
else else
{ {
p_widget->i_width = p_vout->render.i_width / 40; i_width = p_vout->render.i_width / 40;
p_widget->i_height = p_vout->render.i_height - 2 * i_y_margin; i_height = p_vout->render.i_height - 2 * i_y_margin;
p_widget->i_x = p_vout->render.i_width - i_x_margin - i_x = p_vout->render.i_width - i_x_margin - i_width;
p_widget->i_width; i_y = i_y_margin;
p_widget->i_y = i_y_margin;
} }
p_widget->p_pic = (uint8_t *)malloc( p_widget->i_width * /* Create subpicture region and picture */
p_widget->i_height ); CreatePicture( p_vout->p_spu, p_subpic, i_x, i_y, i_width, i_height );
if( p_widget->p_pic == NULL )
{
FreeWidget( p_subpic );
spu_DestroySubpicture( p_vout->p_spu, p_subpic );
return;
}
memset( p_widget->p_pic, 0, p_widget->i_width * p_widget->i_height );
if( i_type == OSD_HOR_SLIDER ) if( i_type == OSD_HOR_SLIDER )
{ {
int i_x_pos = ( p_widget->i_width - 2 ) * i_position / 100; int i_x_pos = ( i_width - 2 ) * i_position / 100;
DrawRect( p_vout, p_subpic, i_x_pos - 1, 2, i_x_pos + 1, DrawRect( p_subpic, i_x_pos - 1, 2, i_x_pos + 1,
p_widget->i_height - 3, STYLE_FILLED ); i_height - 3, STYLE_FILLED );
DrawRect( p_vout, p_subpic, 0, 0, p_widget->i_width - 1, DrawRect( p_subpic, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY );
p_widget->i_height - 1, STYLE_EMPTY );
} }
else if( i_type == OSD_VERT_SLIDER ) else if( i_type == OSD_VERT_SLIDER )
{ {
int i_y_pos = p_widget->i_height / 2; int i_y_pos = i_height / 2;
DrawRect( p_vout, p_subpic, 2, p_widget->i_height - DrawRect( p_subpic, 2, i_height - ( i_height - 2 ) * i_position / 100,
( p_widget->i_height - 2 ) * i_position / 100, i_width - 3, i_height - 3, STYLE_FILLED );
p_widget->i_width - 3, p_widget->i_height - 3, DrawRect( p_subpic, 1, i_y_pos, 1, i_y_pos, STYLE_FILLED );
STYLE_FILLED ); DrawRect( p_subpic, i_width - 2, i_y_pos,
DrawRect( p_vout, p_subpic, 1, i_y_pos, 1, i_y_pos, STYLE_FILLED ); i_width - 2, i_y_pos, STYLE_FILLED );
DrawRect( p_vout, p_subpic, p_widget->i_width - 2, i_y_pos, DrawRect( p_subpic, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY );
p_widget->i_width - 2, i_y_pos, STYLE_FILLED );
DrawRect( p_vout, p_subpic, 0, 0, p_widget->i_width - 1,
p_widget->i_height - 1, STYLE_EMPTY );
} }
spu_DisplaySubpicture( p_vout->p_spu, p_subpic ); spu_DisplaySubpicture( p_vout->p_spu, p_subpic );
...@@ -497,72 +281,62 @@ void vout_OSDIcon( vlc_object_t *p_caller, int i_channel, short i_type ) ...@@ -497,72 +281,62 @@ void vout_OSDIcon( vlc_object_t *p_caller, int i_channel, short i_type )
vout_thread_t *p_vout = vlc_object_find( p_caller, VLC_OBJECT_VOUT, vout_thread_t *p_vout = vlc_object_find( p_caller, VLC_OBJECT_VOUT,
FIND_ANYWHERE ); FIND_ANYWHERE );
subpicture_t *p_subpic; subpicture_t *p_subpic;
subpicture_sys_t *p_widget; int i_x_margin, i_y_margin, i_x, i_y, i_width, i_height;
int i_x_margin, i_y_margin;
if( p_vout == NULL || !config_GetInt( p_caller, "osd" ) ) if( p_vout == NULL || !config_GetInt( p_caller, "osd" ) )
{ {
return; return;
} }
p_subpic = vout_CreateWidget( p_vout, i_channel ); p_subpic = vout_CreateWidget( p_vout->p_spu, i_channel );
if( p_subpic == NULL ) if( p_subpic == NULL )
{ {
return; return;
} }
p_widget = p_subpic->p_sys;
i_y_margin = p_vout->render.i_height / 15; i_y_margin = p_vout->render.i_height / 15;
i_x_margin = i_y_margin; i_x_margin = i_y_margin;
p_widget->i_width = p_vout->render.i_width / 20; i_width = p_vout->render.i_width / 20;
p_widget->i_height = p_widget->i_width; i_height = i_width;
p_widget->i_x = p_vout->render.i_width - i_x_margin - i_x = p_vout->render.i_width - i_x_margin - i_width;
p_widget->i_width; i_y = i_y_margin;
p_widget->i_y = i_y_margin;
/* Create subpicture region and picture */
p_widget->p_pic = (uint8_t *)malloc( p_widget->i_width * CreatePicture( p_vout->p_spu, p_subpic, i_x, i_y, i_width, i_height );
p_widget->i_height );
if( p_widget->p_pic == NULL )
{
FreeWidget( p_subpic );
spu_DestroySubpicture( p_vout->p_spu, p_subpic );
return;
}
memset( p_widget->p_pic, 0, p_widget->i_width * p_widget->i_height );
if( i_type == OSD_PAUSE_ICON ) if( i_type == OSD_PAUSE_ICON )
{ {
int i_bar_width = p_widget->i_width / 3; int i_bar_width = i_width / 3;
DrawRect( p_vout, p_subpic, 0, 0, i_bar_width - 1, DrawRect( p_subpic, 0, 0, i_bar_width - 1, i_height -1, STYLE_FILLED );
p_widget->i_height - 1, STYLE_FILLED ); DrawRect( p_subpic, i_width - i_bar_width, 0,
DrawRect( p_vout, p_subpic, p_widget->i_width - i_bar_width, 0, i_width - 1, i_height - 1, STYLE_FILLED );
p_widget->i_width - 1, p_widget->i_height - 1, STYLE_FILLED );
} }
else if( i_type == OSD_PLAY_ICON ) else if( i_type == OSD_PLAY_ICON )
{ {
int i_mid = p_widget->i_height >> 1; int i_mid = i_height >> 1;
int i_delta = ( p_widget->i_width - i_mid ) >> 1; int i_delta = ( i_width - i_mid ) >> 1;
int i_y2 = ( ( p_widget->i_height - 1 ) >> 1 ) * 2; int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2;
DrawTriangle( p_vout, p_subpic, i_delta, 0, DrawTriangle( p_subpic, i_delta, 0, i_width - i_delta, i_y2,
p_widget->i_width - i_delta, i_y2, STYLE_FILLED ); STYLE_FILLED );
} }
else if( i_type == OSD_SPEAKER_ICON || i_type == OSD_MUTE_ICON ) else if( i_type == OSD_SPEAKER_ICON || i_type == OSD_MUTE_ICON )
{ {
int i_mid = p_widget->i_height >> 1; int i_mid = i_height >> 1;
int i_delta = ( p_widget->i_width - i_mid ) >> 1; int i_delta = ( i_width - i_mid ) >> 1;
int i_y2 = ( ( p_widget->i_height - 1 ) >> 1 ) * 2; int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2;
DrawRect( p_vout, p_subpic, i_delta, i_mid / 2, DrawRect( p_subpic, i_delta, i_mid / 2, i_width - i_delta,
p_widget->i_width - i_delta, i_height - 1 - i_mid / 2, STYLE_FILLED );
p_widget->i_height - 1 - i_mid / 2, STYLE_FILLED ); DrawTriangle( p_subpic, i_width - i_delta, 0, i_delta, i_y2,
DrawTriangle( p_vout, p_subpic, p_widget->i_width - i_delta, 0, STYLE_FILLED );
i_delta, i_y2, STYLE_FILLED );
if( i_type == OSD_MUTE_ICON ) if( i_type == OSD_MUTE_ICON )
{ {
uint8_t *p_a = p_subpic->p_region->picture.A_PIXELS;
int i_pitch = p_subpic->p_region->picture.Y_PITCH;
int i; int i;
for( i = 1; i < p_widget->i_width; i++ ) for( i = 1; i < i_pitch; i++ )
{ {
int k = i + ( p_widget->i_height - i - 1 ) * p_widget->i_width; int k = i + ( i_height - i - 1 ) * i_pitch;
p_widget->p_pic[ k ] = 1 - p_widget->p_pic[ k ]; p_a[ k ] = 0xff - p_a[ k ];
} }
} }
} }
...@@ -572,19 +346,3 @@ void vout_OSDIcon( vlc_object_t *p_caller, int i_channel, short i_type ) ...@@ -572,19 +346,3 @@ void vout_OSDIcon( vlc_object_t *p_caller, int i_channel, short i_type )
vlc_object_release( p_vout ); vlc_object_release( p_vout );
return; return;
} }
/**
* Frees the widget.
*/
static void FreeWidget( subpicture_t *p_subpic )
{
subpicture_sys_t *p_widget = p_subpic->p_sys;
if( p_subpic->p_sys == NULL ) return;
if( p_widget->p_pic != NULL )
{
free( p_widget->p_pic );
}
free( p_widget );
}
...@@ -372,6 +372,7 @@ subpicture_t *spu_CreateSubpicture( spu_t *p_spu ) ...@@ -372,6 +372,7 @@ subpicture_t *spu_CreateSubpicture( spu_t *p_spu )
memset( p_subpic, 0, sizeof(subpicture_t) ); memset( p_subpic, 0, sizeof(subpicture_t) );
p_subpic->i_status = RESERVED_SUBPICTURE; p_subpic->i_status = RESERVED_SUBPICTURE;
p_subpic->b_absolute = VLC_TRUE; p_subpic->b_absolute = VLC_TRUE;
p_subpic->b_fade = VLC_FALSE;
p_subpic->pf_render = 0; p_subpic->pf_render = 0;
p_subpic->pf_destroy = 0; p_subpic->pf_destroy = 0;
p_subpic->p_sys = 0; p_subpic->p_sys = 0;
...@@ -538,6 +539,7 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt, ...@@ -538,6 +539,7 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,
else while( p_region && p_spu->p_blend && else while( p_region && p_spu->p_blend &&
p_spu->p_blend->pf_video_blend ) p_spu->p_blend->pf_video_blend )
{ {
int i_fade_alpha = 255;
int i_x_offset = p_region->i_x + p_subpic->i_x; int i_x_offset = p_region->i_x + p_subpic->i_x;
int i_y_offset = p_region->i_y + p_subpic->i_y; int i_y_offset = p_region->i_y + p_subpic->i_y;
...@@ -733,8 +735,21 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt, ...@@ -733,8 +735,21 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,
p_spu->p_blend->fmt_out.video.i_visible_height = p_spu->p_blend->fmt_out.video.i_visible_height =
p_fmt->i_height; p_fmt->i_height;
p_spu->p_blend->pf_video_blend( p_spu->p_blend, p_pic_dst, if( p_subpic->b_fade )
p_pic_src, &p_region->picture, i_x_offset, i_y_offset, 255 ); {
mtime_t i_fade_start = ( p_subpic->i_stop +
p_subpic->i_start ) / 2;
mtime_t i_now = mdate();
if( i_now >= i_fade_start && p_subpic->i_stop > i_fade_start )
{
i_fade_alpha = 255 * ( p_subpic->i_stop - i_now ) /
( p_subpic->i_stop - i_fade_start );
}
}
p_spu->p_blend->pf_video_blend( p_spu->p_blend, p_pic_dst,
p_pic_src, &p_region->picture, i_x_offset, i_y_offset,
i_fade_alpha );
p_region = p_region->p_next; p_region = p_region->p_next;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment