From: Gildas Bazin Date: Wed, 10 Nov 2004 15:16:51 +0000 (+0000) Subject: * Merged trunk changesets 9185 9204 9205 9273 to 0.8.1 branch. X-Git-Tag: 0.8.1~28 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=0fddb7eb1646a7634d167c6f167131b0c65f1b13;p=vlc * Merged trunk changesets 9185 9204 9205 9273 to 0.8.1 branch. --- diff --git a/include/vlc_video.h b/include/vlc_video.h index 10a6644d39..14c497dc44 100644 --- a/include/vlc_video.h +++ b/include/vlc_video.h @@ -244,6 +244,7 @@ struct subpicture_t vlc_bool_t b_ephemer; /**< If this flag is set to true the subtitle will be displayed untill the next one appear */ + vlc_bool_t b_fade; /**< enable fading */ /**@}*/ subpicture_region_t *p_region; /**< region list composing this subtitle */ diff --git a/src/video_output/video_widgets.c b/src/video_output/video_widgets.c index d7480556aa..27f4e2f278 100644 --- a/src/video_output/video_widgets.c +++ b/src/video_output/video_widgets.c @@ -28,47 +28,30 @@ #include #include +#include "vlc_video.h" +#include "vlc_filter.h" + #define STYLE_EMPTY 0 #define STYLE_FILLED 1 /***************************************************************************** * Local prototypes *****************************************************************************/ -static void DrawRect( vout_thread_t *, subpicture_t *, int, int, int, int, - short ); -static void DrawTriangle( vout_thread_t *, subpicture_t *, int, int, int, int, - short ); -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; -}; +static void DrawRect( subpicture_t *, int, int, int, int, short ); +static void DrawTriangle( subpicture_t *, int, int, int, int, short ); +static void CreatePicture( spu_t *, subpicture_t *, int, int, int, int ); +static subpicture_t *vout_CreateWidget( spu_t *, int ); /***************************************************************************** * Draws a rectangle at the given position in the subpic. * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY). *****************************************************************************/ -static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic, - int i_x1, int i_y1, int i_x2, int i_y2, short fill ) +static void DrawRect( subpicture_t *p_subpic, int i_x1, int i_y1, + int i_x2, int i_y2, short fill ) { 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 ) { @@ -76,7 +59,7 @@ static void DrawRect( vout_thread_t *p_vout, subpicture_t *p_subpic, { 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, { for( y = i_y1; y <= i_y2; y++ ) { - p_widget->p_pic[ i_x1 + p_widget->i_width * y ] = 1; - p_widget->p_pic[ i_x2 + p_widget->i_width * y ] = 1; + p_a[ i_x1 + i_pitch * y ] = 0xff; + p_a[ i_x2 + i_pitch * y ] = 0xff; } for( x = i_x1; x <= i_x2; x++ ) { - p_widget->p_pic[ x + p_widget->i_width * i_y1 ] = 1; - p_widget->p_pic[ x + p_widget->i_width * i_y2 ] = 1; + p_a[ x + i_pitch * i_y1 ] = 0xff; + p_a[ x + i_pitch * i_y2 ] = 0xff; } } } @@ -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. * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY). *****************************************************************************/ -static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic, - int i_x1, int i_y1, int i_x2, int i_y2, short fill ) +static void DrawTriangle( subpicture_t *p_subpic, int i_x1, int i_y1, + int i_x2, int i_y2, short fill ) { 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 ); @@ -116,8 +100,8 @@ static void DrawTriangle( vout_thread_t *p_vout, subpicture_t *p_subpic, h = y - i_y1; for( x = i_x1; x <= i_x1 + h && x <= i_x2; x++ ) { - p_widget->p_pic[ x + p_widget->i_width * y ] = 1; - p_widget->p_pic[ x + p_widget->i_width * ( i_y2 - h ) ] = 1; + p_a[ x + i_pitch * y ] = 0xff; + 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, for( y = i_y1; y <= i_mid; y++ ) { h = y - i_y1; - p_widget->p_pic[ i_x1 + p_widget->i_width * y ] = 1; - p_widget->p_pic[ i_x1 + h + p_widget->i_width * y ] = 1; - p_widget->p_pic[ i_x1 + p_widget->i_width * ( i_y2 - h ) ] = 1; - p_widget->p_pic[ i_x1 + h + p_widget->i_width * ( i_y2 - h ) ] = 1; + p_a[ i_x1 + i_pitch * y ] = 0xff; + p_a[ i_x1 + h + i_pitch * y ] = 0xff; + p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff; + 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, h = y - i_y1; for( x = i_x1; x >= i_x1 - h && x >= i_x2; x-- ) { - p_widget->p_pic[ x + p_widget->i_width * y ] = 1; - p_widget->p_pic[ x + p_widget->i_width * ( i_y2 - h ) ] = 1; + p_a[ x + i_pitch * y ] = 0xff; + 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, for( y = i_y1; y <= i_mid; y++ ) { h = y - i_y1; - p_widget->p_pic[ i_x1 + p_widget->i_width * y ] = 1; - p_widget->p_pic[ i_x1 - h + p_widget->i_width * y ] = 1; - p_widget->p_pic[ i_x1 + p_widget->i_width * ( i_y2 - h ) ] = 1; - p_widget->p_pic[ i_x1 - h + p_widget->i_width * ( i_y2 - h ) ] = 1; + p_a[ i_x1 + i_pitch * y ] = 0xff; + p_a[ i_x1 - h + i_pitch * y ] = 0xff; + p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff; + p_a[ i_x1 - h + i_pitch * ( i_y2 - h ) ] = 0xff; } } } } /***************************************************************************** - * Render: place widget in picture - ***************************************************************************** - * This function merges the previously drawn widget into a picture + * Create Picture: creates subpicture region and picture *****************************************************************************/ -static void Render( vout_thread_t *p_vout, picture_t *p_pic, - const subpicture_t *p_subpic ) -{ - 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 ) +static void CreatePicture( spu_t *p_spu, subpicture_t *p_subpic, + int i_x, int i_y, int i_width, int i_height ) { - 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 -#define pixel p_in[ ( pen_y + y ) * i_pic_pitch + 2 * ( pen_x + x ) ] - for( y = 0; y < p_widget->i_height; y++ ) + uint8_t *p_y, *p_u, *p_v, *p_a; + video_format_t fmt; + int i_pitch; + + /* Create a new subpicture region */ + memset( &fmt, 0, sizeof(video_format_t) ); + fmt.i_chroma = VLC_FOURCC('Y','U','V','A'); + fmt.i_aspect = VOUT_ASPECT_FACTOR; + fmt.i_width = fmt.i_visible_width = i_width; + 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++ ) - { - 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--; - } + msg_Err( p_spu, "cannot allocate SPU region" ); + return; } - 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 -#define pixel( c ) p_in[ ( pen_y + y ) * i_pic_pitch + 4 * ( pen_x + x ) + c ] - for(y = 0; y < p_widget->i_height; y++ ) - { - for( x = 0; x < p_widget->i_width; x++ ) - { - pen_y--; - 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_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 + p_subpic->p_region->i_x = i_x; + p_subpic->p_region->i_y = i_y; + p_y = p_subpic->p_region->picture.Y_PIXELS; + p_u = p_subpic->p_region->picture.U_PIXELS; + p_v = p_subpic->p_region->picture.V_PIXELS; + p_a = p_subpic->p_region->picture.A_PIXELS; + i_pitch = p_subpic->p_region->picture.Y_PITCH; + + /* Initialize the region pixels (only the alpha will be changed later) */ + memset( p_y, 0xff, i_pitch * p_subpic->p_region->fmt.i_height ); + memset( p_u, 0x80, i_pitch * p_subpic->p_region->fmt.i_height ); + memset( p_v, 0x80, i_pitch * p_subpic->p_region->fmt.i_height ); + memset( p_a, 0x00, i_pitch * p_subpic->p_region->fmt.i_height ); } /***************************************************************************** * 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_sys_t *p_widget; mtime_t i_now = mdate(); - p_subpic = 0; - p_widget = 0; - /* Create and initialize a subpicture */ - p_subpic = spu_CreateSubpicture( p_vout->p_spu ); - if( p_subpic == NULL ) - { - return NULL; - } + p_subpic = spu_CreateSubpicture( p_spu ); + if( p_subpic == NULL ) return NULL; + 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_stop = i_now + 1200000; p_subpic->b_ephemer = 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; + p_subpic->b_fade = VLC_TRUE; return p_subpic; } @@ -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, FIND_ANYWHERE ); subpicture_t *p_subpic; - subpicture_sys_t *p_widget; - int i_x_margin, i_y_margin; + int i_x_margin, i_y_margin, i_x, i_y, i_width, i_height; if( p_vout == NULL || !config_GetInt( p_caller, "osd" ) || i_position < 0 ) { return; } - p_subpic = vout_CreateWidget( p_vout, i_channel ); + p_subpic = vout_CreateWidget( p_vout->p_spu, i_channel ); if( p_subpic == NULL ) { return; } - p_widget = p_subpic->p_sys; i_y_margin = p_vout->render.i_height / 10; i_x_margin = i_y_margin; if( i_type == OSD_HOR_SLIDER ) { - p_widget->i_width = p_vout->render.i_width - 2 * i_x_margin; - p_widget->i_height = p_vout->render.i_height / 20; - p_widget->i_x = i_x_margin; - p_widget->i_y = p_vout->render.i_height - i_y_margin - - p_widget->i_height; + i_width = p_vout->render.i_width - 2 * i_x_margin; + i_height = p_vout->render.i_height / 20; + i_x = i_x_margin; + i_y = p_vout->render.i_height - i_y_margin - i_height; } else { - p_widget->i_width = p_vout->render.i_width / 40; - p_widget->i_height = p_vout->render.i_height - 2 * i_y_margin; - p_widget->i_x = p_vout->render.i_width - i_x_margin - - p_widget->i_width; - p_widget->i_y = i_y_margin; + i_width = p_vout->render.i_width / 40; + i_height = p_vout->render.i_height - 2 * i_y_margin; + i_x = p_vout->render.i_width - i_x_margin - i_width; + i_y = i_y_margin; } - p_widget->p_pic = (uint8_t *)malloc( p_widget->i_width * - 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 ); + /* Create subpicture region and picture */ + CreatePicture( p_vout->p_spu, p_subpic, i_x, i_y, i_width, i_height ); if( i_type == OSD_HOR_SLIDER ) { - int i_x_pos = ( p_widget->i_width - 2 ) * i_position / 100; - DrawRect( p_vout, p_subpic, i_x_pos - 1, 2, i_x_pos + 1, - p_widget->i_height - 3, STYLE_FILLED ); - DrawRect( p_vout, p_subpic, 0, 0, p_widget->i_width - 1, - p_widget->i_height - 1, STYLE_EMPTY ); + int i_x_pos = ( i_width - 2 ) * i_position / 100; + DrawRect( p_subpic, i_x_pos - 1, 2, i_x_pos + 1, + i_height - 3, STYLE_FILLED ); + DrawRect( p_subpic, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY ); } else if( i_type == OSD_VERT_SLIDER ) { - int i_y_pos = p_widget->i_height / 2; - DrawRect( p_vout, p_subpic, 2, p_widget->i_height - - ( p_widget->i_height - 2 ) * i_position / 100, - p_widget->i_width - 3, p_widget->i_height - 3, - STYLE_FILLED ); - DrawRect( p_vout, p_subpic, 1, i_y_pos, 1, i_y_pos, STYLE_FILLED ); - DrawRect( p_vout, p_subpic, p_widget->i_width - 2, i_y_pos, - 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 ); + int i_y_pos = i_height / 2; + DrawRect( p_subpic, 2, i_height - ( i_height - 2 ) * i_position / 100, + i_width - 3, i_height - 3, STYLE_FILLED ); + DrawRect( p_subpic, 1, i_y_pos, 1, i_y_pos, STYLE_FILLED ); + DrawRect( p_subpic, i_width - 2, i_y_pos, + i_width - 2, i_y_pos, STYLE_FILLED ); + DrawRect( p_subpic, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY ); } 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 ) vout_thread_t *p_vout = vlc_object_find( p_caller, VLC_OBJECT_VOUT, FIND_ANYWHERE ); subpicture_t *p_subpic; - subpicture_sys_t *p_widget; - int i_x_margin, i_y_margin; + int i_x_margin, i_y_margin, i_x, i_y, i_width, i_height; if( p_vout == NULL || !config_GetInt( p_caller, "osd" ) ) { return; } - p_subpic = vout_CreateWidget( p_vout, i_channel ); + p_subpic = vout_CreateWidget( p_vout->p_spu, i_channel ); if( p_subpic == NULL ) { return; } - p_widget = p_subpic->p_sys; i_y_margin = p_vout->render.i_height / 15; i_x_margin = i_y_margin; - p_widget->i_width = p_vout->render.i_width / 20; - p_widget->i_height = p_widget->i_width; - p_widget->i_x = p_vout->render.i_width - i_x_margin - - p_widget->i_width; - p_widget->i_y = i_y_margin; - - p_widget->p_pic = (uint8_t *)malloc( p_widget->i_width * - 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 ); + i_width = p_vout->render.i_width / 20; + i_height = i_width; + i_x = p_vout->render.i_width - i_x_margin - i_width; + i_y = i_y_margin; + + /* Create subpicture region and picture */ + CreatePicture( p_vout->p_spu, p_subpic, i_x, i_y, i_width, i_height ); if( i_type == OSD_PAUSE_ICON ) { - int i_bar_width = p_widget->i_width / 3; - DrawRect( p_vout, p_subpic, 0, 0, i_bar_width - 1, - p_widget->i_height - 1, STYLE_FILLED ); - DrawRect( p_vout, p_subpic, p_widget->i_width - i_bar_width, 0, - p_widget->i_width - 1, p_widget->i_height - 1, STYLE_FILLED ); + int i_bar_width = i_width / 3; + DrawRect( p_subpic, 0, 0, i_bar_width - 1, i_height -1, STYLE_FILLED ); + DrawRect( p_subpic, i_width - i_bar_width, 0, + i_width - 1, i_height - 1, STYLE_FILLED ); } else if( i_type == OSD_PLAY_ICON ) { - int i_mid = p_widget->i_height >> 1; - int i_delta = ( p_widget->i_width - i_mid ) >> 1; - int i_y2 = ( ( p_widget->i_height - 1 ) >> 1 ) * 2; - DrawTriangle( p_vout, p_subpic, i_delta, 0, - p_widget->i_width - i_delta, i_y2, STYLE_FILLED ); + int i_mid = i_height >> 1; + int i_delta = ( i_width - i_mid ) >> 1; + int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2; + DrawTriangle( p_subpic, i_delta, 0, i_width - i_delta, i_y2, + STYLE_FILLED ); } else if( i_type == OSD_SPEAKER_ICON || i_type == OSD_MUTE_ICON ) { - int i_mid = p_widget->i_height >> 1; - int i_delta = ( p_widget->i_width - i_mid ) >> 1; - int i_y2 = ( ( p_widget->i_height - 1 ) >> 1 ) * 2; - DrawRect( p_vout, p_subpic, i_delta, i_mid / 2, - p_widget->i_width - i_delta, - p_widget->i_height - 1 - i_mid / 2, STYLE_FILLED ); - DrawTriangle( p_vout, p_subpic, p_widget->i_width - i_delta, 0, - i_delta, i_y2, STYLE_FILLED ); + int i_mid = i_height >> 1; + int i_delta = ( i_width - i_mid ) >> 1; + int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2; + DrawRect( p_subpic, i_delta, i_mid / 2, i_width - i_delta, + i_height - 1 - i_mid / 2, STYLE_FILLED ); + DrawTriangle( p_subpic, i_width - i_delta, 0, i_delta, i_y2, + STYLE_FILLED ); 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; - 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; - p_widget->p_pic[ k ] = 1 - p_widget->p_pic[ k ]; + int k = i + ( i_height - i - 1 ) * i_pitch; + 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 ) vlc_object_release( p_vout ); 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 ); -} diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c index d8ea373375..31fe32772c 100644 --- a/src/video_output/vout_subpictures.c +++ b/src/video_output/vout_subpictures.c @@ -372,6 +372,7 @@ subpicture_t *spu_CreateSubpicture( spu_t *p_spu ) memset( p_subpic, 0, sizeof(subpicture_t) ); p_subpic->i_status = RESERVED_SUBPICTURE; p_subpic->b_absolute = VLC_TRUE; + p_subpic->b_fade = VLC_FALSE; p_subpic->pf_render = 0; p_subpic->pf_destroy = 0; p_subpic->p_sys = 0; @@ -538,6 +539,7 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt, else while( p_region && p_spu->p_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_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, p_spu->p_blend->fmt_out.video.i_visible_height = p_fmt->i_height; - 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, 255 ); + if( p_subpic->b_fade ) + { + 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; }