00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <vlc/vout.h>
00029 #include <vlc_osd.h>
00030
00031 #include <vlc_video.h>
00032 #include <vlc_filter.h>
00033
00034 #define STYLE_EMPTY 0
00035 #define STYLE_FILLED 1
00036
00037
00038
00039
00040 static void DrawRect( subpicture_t *, int, int, int, int, short );
00041 static void DrawTriangle( subpicture_t *, int, int, int, int, short );
00042 static int CreatePicture( spu_t *, subpicture_t *, int, int, int, int );
00043 static subpicture_t *osd_CreateWidget( spu_t *, int );
00044
00045
00046
00047
00048
00049 static void DrawRect( subpicture_t *p_subpic, int i_x1, int i_y1,
00050 int i_x2, int i_y2, short fill )
00051 {
00052 int x, y;
00053 uint8_t *p_a = p_subpic->p_region->picture.A_PIXELS;
00054 int i_pitch = p_subpic->p_region->picture.Y_PITCH;
00055
00056 if( fill == STYLE_FILLED )
00057 {
00058 for( y = i_y1; y <= i_y2; y++ )
00059 {
00060 for( x = i_x1; x <= i_x2; x++ )
00061 {
00062 p_a[ x + i_pitch * y ] = 0xff;
00063 }
00064 }
00065 }
00066 else
00067 {
00068 for( y = i_y1; y <= i_y2; y++ )
00069 {
00070 p_a[ i_x1 + i_pitch * y ] = 0xff;
00071 p_a[ i_x2 + i_pitch * y ] = 0xff;
00072 }
00073 for( x = i_x1; x <= i_x2; x++ )
00074 {
00075 p_a[ x + i_pitch * i_y1 ] = 0xff;
00076 p_a[ x + i_pitch * i_y2 ] = 0xff;
00077 }
00078 }
00079 }
00080
00081
00082
00083
00084
00085 static void DrawTriangle( subpicture_t *p_subpic, int i_x1, int i_y1,
00086 int i_x2, int i_y2, short fill )
00087 {
00088 int x, y, i_mid, h;
00089 uint8_t *p_a = p_subpic->p_region->picture.A_PIXELS;
00090 int i_pitch = p_subpic->p_region->picture.Y_PITCH;
00091
00092 i_mid = i_y1 + ( ( i_y2 - i_y1 ) >> 1 );
00093
00094 if( i_x2 >= i_x1 )
00095 {
00096 if( fill == STYLE_FILLED )
00097 {
00098 for( y = i_y1; y <= i_mid; y++ )
00099 {
00100 h = y - i_y1;
00101 for( x = i_x1; x <= i_x1 + h && x <= i_x2; x++ )
00102 {
00103 p_a[ x + i_pitch * y ] = 0xff;
00104 p_a[ x + i_pitch * ( i_y2 - h ) ] = 0xff;
00105 }
00106 }
00107 }
00108 else
00109 {
00110 for( y = i_y1; y <= i_mid; y++ )
00111 {
00112 h = y - i_y1;
00113 p_a[ i_x1 + i_pitch * y ] = 0xff;
00114 p_a[ i_x1 + h + i_pitch * y ] = 0xff;
00115 p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff;
00116 p_a[ i_x1 + h + i_pitch * ( i_y2 - h ) ] = 0xff;
00117 }
00118 }
00119 }
00120 else
00121 {
00122 if( fill == STYLE_FILLED )
00123 {
00124 for( y = i_y1; y <= i_mid; y++ )
00125 {
00126 h = y - i_y1;
00127 for( x = i_x1; x >= i_x1 - h && x >= i_x2; x-- )
00128 {
00129 p_a[ x + i_pitch * y ] = 0xff;
00130 p_a[ x + i_pitch * ( i_y2 - h ) ] = 0xff;
00131 }
00132 }
00133 }
00134 else
00135 {
00136 for( y = i_y1; y <= i_mid; y++ )
00137 {
00138 h = y - i_y1;
00139 p_a[ i_x1 + i_pitch * y ] = 0xff;
00140 p_a[ i_x1 - h + i_pitch * y ] = 0xff;
00141 p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff;
00142 p_a[ i_x1 - h + i_pitch * ( i_y2 - h ) ] = 0xff;
00143 }
00144 }
00145 }
00146 }
00147
00148
00149
00150
00151 static int CreatePicture( spu_t *p_spu, subpicture_t *p_subpic,
00152 int i_x, int i_y, int i_width, int i_height )
00153 {
00154 uint8_t *p_y, *p_u, *p_v, *p_a;
00155 video_format_t fmt;
00156 int i_pitch;
00157
00158
00159 memset( &fmt, 0, sizeof(video_format_t) );
00160 fmt.i_chroma = VLC_FOURCC('Y','U','V','A');
00161 fmt.i_aspect = 0;
00162 fmt.i_width = fmt.i_visible_width = i_width;
00163 fmt.i_height = fmt.i_visible_height = i_height;
00164 fmt.i_x_offset = fmt.i_y_offset = 0;
00165 p_subpic->p_region = p_subpic->pf_create_region( VLC_OBJECT(p_spu), &fmt );
00166 if( !p_subpic->p_region )
00167 {
00168 msg_Err( p_spu, "cannot allocate SPU region" );
00169 return VLC_EGENERIC;
00170 }
00171
00172 p_subpic->p_region->i_x = i_x;
00173 p_subpic->p_region->i_y = i_y;
00174 p_y = p_subpic->p_region->picture.Y_PIXELS;
00175 p_u = p_subpic->p_region->picture.U_PIXELS;
00176 p_v = p_subpic->p_region->picture.V_PIXELS;
00177 p_a = p_subpic->p_region->picture.A_PIXELS;
00178 i_pitch = p_subpic->p_region->picture.Y_PITCH;
00179
00180
00181 memset( p_y, 0xff, i_pitch * p_subpic->p_region->fmt.i_height );
00182 memset( p_u, 0x80, i_pitch * p_subpic->p_region->fmt.i_height );
00183 memset( p_v, 0x80, i_pitch * p_subpic->p_region->fmt.i_height );
00184 memset( p_a, 0x00, i_pitch * p_subpic->p_region->fmt.i_height );
00185
00186 return VLC_SUCCESS;
00187 }
00188
00189
00190
00191
00192 subpicture_t *osd_CreateWidget( spu_t *p_spu, int i_channel )
00193 {
00194 subpicture_t *p_subpic;
00195 mtime_t i_now = mdate();
00196
00197
00198 p_subpic = spu_CreateSubpicture( p_spu );
00199 if( p_subpic == NULL ) return NULL;
00200
00201 p_subpic->i_channel = i_channel;
00202 p_subpic->i_start = i_now;
00203 p_subpic->i_stop = i_now + 1200000;
00204 p_subpic->b_ephemer = VLC_TRUE;
00205 p_subpic->b_fade = VLC_TRUE;
00206
00207 return p_subpic;
00208 }
00209
00210
00211
00212
00213
00214 int osd_Slider( vlc_object_t *p_this, spu_t *p_spu,
00215 int i_render_width, int i_render_height,
00216 int i_channel, int i_position, short i_type )
00217 {
00218 subpicture_t *p_subpic;
00219 int i_x_margin, i_y_margin, i_x, i_y, i_width, i_height;
00220
00221 p_subpic = osd_CreateWidget( p_spu, i_channel );
00222 if( p_subpic == NULL )
00223 {
00224 return VLC_EGENERIC;
00225 }
00226
00227 i_y_margin = i_render_height / 10;
00228 i_x_margin = i_y_margin;
00229 if( i_type == OSD_HOR_SLIDER )
00230 {
00231 i_width = i_render_width - 2 * i_x_margin;
00232 i_height = i_render_height / 20;
00233 i_x = i_x_margin;
00234 i_y = i_render_height - i_y_margin - i_height;
00235 }
00236 else
00237 {
00238 i_width = i_render_width / 40;
00239 i_height = i_render_height - 2 * i_y_margin;
00240 i_x = i_render_width - i_x_margin - i_width;
00241 i_y = i_y_margin;
00242 }
00243
00244
00245 CreatePicture( p_spu, p_subpic, i_x, i_y, i_width, i_height );
00246
00247 if( i_type == OSD_HOR_SLIDER )
00248 {
00249 int i_x_pos = ( i_width - 2 ) * i_position / 100;
00250 DrawRect( p_subpic, i_x_pos - 1, 2, i_x_pos + 1,
00251 i_height - 3, STYLE_FILLED );
00252 DrawRect( p_subpic, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY );
00253 }
00254 else if( i_type == OSD_VERT_SLIDER )
00255 {
00256 int i_y_pos = i_height / 2;
00257 DrawRect( p_subpic, 2, i_height - ( i_height - 2 ) * i_position / 100,
00258 i_width - 3, i_height - 3, STYLE_FILLED );
00259 DrawRect( p_subpic, 1, i_y_pos, 1, i_y_pos, STYLE_FILLED );
00260 DrawRect( p_subpic, i_width - 2, i_y_pos,
00261 i_width - 2, i_y_pos, STYLE_FILLED );
00262 DrawRect( p_subpic, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY );
00263 }
00264
00265 spu_DisplaySubpicture( p_spu, p_subpic );
00266
00267 return VLC_SUCCESS;
00268 }
00269
00270
00271
00272
00273
00274 int osd_Icon( vlc_object_t *p_this, spu_t *p_spu,
00275 int i_render_width, int i_render_height, int i_channel, short i_type )
00276 {
00277 subpicture_t *p_subpic;
00278 int i_x_margin, i_y_margin, i_x, i_y, i_width, i_height;
00279
00280 p_subpic = osd_CreateWidget( p_spu, i_channel );
00281 if( p_subpic == NULL )
00282 {
00283 return VLC_EGENERIC;
00284 }
00285
00286 i_y_margin = i_render_height / 15;
00287 i_x_margin = i_y_margin;
00288 i_width = i_render_width / 20;
00289 i_height = i_width;
00290 i_x = i_render_width - i_x_margin - i_width;
00291 i_y = i_y_margin;
00292
00293
00294 CreatePicture( p_spu, p_subpic, i_x, i_y, i_width, i_height );
00295
00296 if( i_type == OSD_PAUSE_ICON )
00297 {
00298 int i_bar_width = i_width / 3;
00299 DrawRect( p_subpic, 0, 0, i_bar_width - 1, i_height -1, STYLE_FILLED );
00300 DrawRect( p_subpic, i_width - i_bar_width, 0,
00301 i_width - 1, i_height - 1, STYLE_FILLED );
00302 }
00303 else if( i_type == OSD_PLAY_ICON )
00304 {
00305 int i_mid = i_height >> 1;
00306 int i_delta = ( i_width - i_mid ) >> 1;
00307 int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2;
00308 DrawTriangle( p_subpic, i_delta, 0, i_width - i_delta, i_y2,
00309 STYLE_FILLED );
00310 }
00311 else if( i_type == OSD_SPEAKER_ICON || i_type == OSD_MUTE_ICON )
00312 {
00313 int i_mid = i_height >> 1;
00314 int i_delta = ( i_width - i_mid ) >> 1;
00315 int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2;
00316 DrawRect( p_subpic, i_delta, i_mid / 2, i_width - i_delta,
00317 i_height - 1 - i_mid / 2, STYLE_FILLED );
00318 DrawTriangle( p_subpic, i_width - i_delta, 0, i_delta, i_y2,
00319 STYLE_FILLED );
00320 if( i_type == OSD_MUTE_ICON )
00321 {
00322 uint8_t *p_a = p_subpic->p_region->picture.A_PIXELS;
00323 int i_pitch = p_subpic->p_region->picture.Y_PITCH;
00324 int i;
00325 for( i = 1; i < i_pitch; i++ )
00326 {
00327 int k = i + ( i_height - i - 1 ) * i_pitch;
00328 p_a[ k ] = 0xff - p_a[ k ];
00329 }
00330 }
00331 }
00332
00333 spu_DisplaySubpicture( p_spu, p_subpic );
00334
00335 return VLC_SUCCESS;
00336 }