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
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include <vlc/vlc.h>
00032 #include <vlc/vout.h>
00033
00034 #include "vlc_filter.h"
00035 #include "filter_common.h"
00036 #include "vlc_image.h"
00037 #include "vlc_osd.h"
00038
00039 #ifdef LoadImage
00040 # undef LoadImage
00041 #endif
00042
00043
00044
00045
00046 static int Create ( vlc_object_t * );
00047 static void Destroy ( vlc_object_t * );
00048
00049 static int Init ( vout_thread_t * );
00050 static void End ( vout_thread_t * );
00051 static void Render ( vout_thread_t *, picture_t * );
00052
00053 static int SendEvents( vlc_object_t *, char const *,
00054 vlc_value_t, vlc_value_t, void * );
00055 static int MouseEvent( vlc_object_t *, char const *,
00056 vlc_value_t , vlc_value_t , void * );
00057 static int Control ( vout_thread_t *, int, va_list );
00058
00059 static int CreateFilter ( vlc_object_t * );
00060 static void DestroyFilter( vlc_object_t * );
00061
00062 static int LogoCallback( vlc_object_t *, char const *,
00063 vlc_value_t, vlc_value_t, void * );
00064
00065
00066
00067
00068 #define FILE_TEXT N_("Logo filename")
00069 #define FILE_LONGTEXT N_("Full path of the PNG file to use.")
00070 #define POSX_TEXT N_("X coordinate of the logo")
00071 #define POSX_LONGTEXT N_("You can move the logo by left-clicking on it." )
00072 #define POSY_TEXT N_("Y coordinate of the logo")
00073 #define POSY_LONGTEXT N_("You can move the logo by left-clicking on it." )
00074 #define TRANS_TEXT N_("Transparency of the logo")
00075 #define TRANS_LONGTEXT N_("You can set the logo transparency value here " \
00076 "(from 0 for full transparency to 255 for full opacity)." )
00077 #define POS_TEXT N_("Logo position")
00078 #define POS_LONGTEXT N_( \
00079 "You can enforce the logo position on the video " \
00080 "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
00081 "also use combinations of these values).")
00082
00083 static int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
00084 static char *ppsz_pos_descriptions[] =
00085 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
00086 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
00087
00088 vlc_module_begin();
00089 set_description( _("Logo video filter") );
00090 set_capability( "video filter", 0 );
00091 set_shortname( N_("Logo overlay") );
00092 set_category( CAT_VIDEO );
00093 set_subcategory( SUBCAT_VIDEO_SUBPIC );
00094 add_shortcut( "logo" );
00095 set_callbacks( Create, Destroy );
00096
00097 add_file( "logo-file", NULL, NULL, FILE_TEXT, FILE_LONGTEXT, VLC_FALSE );
00098 add_integer( "logo-x", -1, NULL, POSX_TEXT, POSX_LONGTEXT, VLC_TRUE );
00099 add_integer( "logo-y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, VLC_TRUE );
00100 add_integer_with_range( "logo-transparency", 255, 0, 255, NULL,
00101 TRANS_TEXT, TRANS_LONGTEXT, VLC_FALSE );
00102 add_integer( "logo-position", 6, NULL, POS_TEXT, POS_LONGTEXT, VLC_FALSE );
00103 change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );
00104
00105
00106 add_submodule();
00107 set_capability( "sub filter", 0 );
00108 set_callbacks( CreateFilter, DestroyFilter );
00109 set_description( _("Logo sub filter") );
00110 add_shortcut( "logo" );
00111 vlc_module_end();
00112
00113
00114
00115
00116 static picture_t *LoadImage( vlc_object_t *p_this, char *psz_filename )
00117 {
00118 picture_t *p_pic;
00119 image_handler_t *p_image;
00120 video_format_t fmt_in = {0}, fmt_out = {0};
00121
00122 fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
00123 p_image = image_HandlerCreate( p_this );
00124 p_pic = image_ReadUrl( p_image, psz_filename, &fmt_in, &fmt_out );
00125 image_HandlerDelete( p_image );
00126
00127 return p_pic;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136 struct vout_sys_t
00137 {
00138 vout_thread_t *p_vout;
00139
00140 filter_t *p_blend;
00141 picture_t *p_pic;
00142
00143 int i_width, i_height;
00144 int pos, posx, posy;
00145 char *psz_filename;
00146 int i_trans;
00147 };
00148
00149
00150
00151
00152 static int Create( vlc_object_t *p_this )
00153 {
00154 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00155 vout_sys_t *p_sys;
00156 vlc_value_t val;
00157
00158
00159 p_sys = p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
00160 if( p_sys == NULL )
00161 {
00162 msg_Err( p_vout, "out of memory" );
00163 return VLC_ENOMEM;
00164 }
00165
00166 p_vout->pf_init = Init;
00167 p_vout->pf_end = End;
00168 p_vout->pf_manage = NULL;
00169 p_vout->pf_render = Render;
00170 p_vout->pf_display = NULL;
00171 p_vout->pf_control = Control;
00172
00173 p_sys->psz_filename = var_CreateGetString( p_this , "logo-file" );
00174 if( !p_sys->psz_filename || !*p_sys->psz_filename )
00175 {
00176 msg_Err( p_this, "logo file not specified" );
00177 return 0;
00178 }
00179
00180 var_Create( p_this, "logo-position", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00181 var_Get( p_this, "logo-position", &val );
00182 p_sys->pos = val.i_int;
00183 var_Create( p_this, "logo-x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00184 var_Get( p_this, "logo-x", &val );
00185 p_sys->posx = val.i_int;
00186 var_Create( p_this, "logo-y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00187 var_Get( p_this, "logo-y", &val );
00188 p_sys->posy = val.i_int;
00189 var_Create(p_this, "logo-transparency", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT);
00190 var_Get( p_this, "logo-transparency", &val );
00191 p_sys->i_trans = __MAX( __MIN( val.i_int, 255 ), 0 );
00192
00193 p_sys->p_pic = LoadImage( p_this, p_sys->psz_filename );
00194 if( !p_sys->p_pic )
00195 {
00196 free( p_sys );
00197 return VLC_EGENERIC;
00198 }
00199
00200 p_sys->i_width = p_sys->p_pic->p[Y_PLANE].i_visible_pitch;
00201 p_sys->i_height = p_sys->p_pic->p[Y_PLANE].i_visible_lines;
00202
00203 return VLC_SUCCESS;
00204 }
00205
00206
00207
00208
00209 static int Init( vout_thread_t *p_vout )
00210 {
00211 vout_sys_t *p_sys = p_vout->p_sys;
00212 picture_t *p_pic;
00213 int i_index;
00214 video_format_t fmt = {0};
00215
00216 I_OUTPUTPICTURES = 0;
00217
00218
00219 p_vout->output.i_chroma = p_vout->render.i_chroma;
00220 p_vout->output.i_width = p_vout->render.i_width;
00221 p_vout->output.i_height = p_vout->render.i_height;
00222 p_vout->output.i_aspect = p_vout->render.i_aspect;
00223 p_vout->fmt_out = p_vout->fmt_in;
00224 fmt = p_vout->fmt_out;
00225
00226
00227 p_sys->p_blend = vlc_object_create( p_vout, sizeof(filter_t) );
00228 vlc_object_attach( p_sys->p_blend, p_vout );
00229 p_sys->p_blend->fmt_out.video.i_x_offset =
00230 p_sys->p_blend->fmt_out.video.i_y_offset = 0;
00231 p_sys->p_blend->fmt_in.video.i_x_offset =
00232 p_sys->p_blend->fmt_in.video.i_y_offset = 0;
00233 p_sys->p_blend->fmt_out.video.i_aspect = p_vout->render.i_aspect;
00234 p_sys->p_blend->fmt_out.video.i_chroma = p_vout->output.i_chroma;
00235 p_sys->p_blend->fmt_in.video.i_chroma = VLC_FOURCC('Y','U','V','A');
00236 p_sys->p_blend->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR;
00237 p_sys->p_blend->fmt_in.video.i_width =
00238 p_sys->p_blend->fmt_in.video.i_visible_width =
00239 p_sys->p_pic->p[Y_PLANE].i_visible_pitch;
00240 p_sys->p_blend->fmt_in.video.i_height =
00241 p_sys->p_blend->fmt_in.video.i_visible_height =
00242 p_sys->p_pic->p[Y_PLANE].i_visible_lines;
00243 p_sys->p_blend->fmt_out.video.i_width =
00244 p_sys->p_blend->fmt_out.video.i_visible_width =
00245 p_vout->output.i_width;
00246 p_sys->p_blend->fmt_out.video.i_height =
00247 p_sys->p_blend->fmt_out.video.i_visible_height =
00248 p_vout->output.i_height;
00249
00250 p_sys->p_blend->p_module =
00251 module_Need( p_sys->p_blend, "video blending", 0, 0 );
00252 if( !p_sys->p_blend->p_module )
00253 {
00254 msg_Err( p_vout, "can't open blending filter, aborting" );
00255 vlc_object_detach( p_sys->p_blend );
00256 vlc_object_destroy( p_sys->p_blend );
00257 return VLC_EGENERIC;
00258 }
00259
00260 if( p_sys->posx < 0 || p_sys->posy < 0 )
00261 {
00262 p_sys->posx = 0; p_sys->posy = 0;
00263
00264 if( p_sys->pos & SUBPICTURE_ALIGN_BOTTOM )
00265 {
00266 p_sys->posy = p_vout->render.i_height - p_sys->i_height;
00267 }
00268 else if ( !(p_sys->pos & SUBPICTURE_ALIGN_TOP) )
00269 {
00270 p_sys->posy = p_vout->render.i_height / 2 - p_sys->i_height / 2;
00271 }
00272
00273 if( p_sys->pos & SUBPICTURE_ALIGN_RIGHT )
00274 {
00275 p_sys->posx = p_vout->render.i_width - p_sys->i_width;
00276 }
00277 else if ( !(p_sys->pos & SUBPICTURE_ALIGN_LEFT) )
00278 {
00279 p_sys->posx = p_vout->render.i_width / 2 - p_sys->i_width / 2;
00280 }
00281 }
00282
00283
00284 msg_Dbg( p_vout, "spawning the real video output" );
00285
00286 p_sys->p_vout = vout_Create( p_vout, &fmt );
00287
00288
00289 if( p_sys->p_vout == NULL )
00290 {
00291 msg_Err( p_vout, "can't open vout, aborting" );
00292 return VLC_EGENERIC;
00293 }
00294
00295 var_AddCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout);
00296 var_AddCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout);
00297
00298 ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
00299 ADD_CALLBACKS( p_sys->p_vout, SendEvents );
00300 ADD_PARENT_CALLBACKS( SendEventsToChild );
00301
00302 return VLC_SUCCESS;
00303 }
00304
00305
00306
00307
00308 static void End( vout_thread_t *p_vout )
00309 {
00310 vout_sys_t *p_sys = p_vout->p_sys;
00311 int i_index;
00312
00313
00314 for( i_index = I_OUTPUTPICTURES ; i_index ; )
00315 {
00316 i_index--;
00317 free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
00318 }
00319
00320 var_DelCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout);
00321 var_DelCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout);
00322
00323 if( p_sys->p_vout )
00324 {
00325 DEL_CALLBACKS( p_sys->p_vout, SendEvents );
00326 vlc_object_detach( p_sys->p_vout );
00327 vout_Destroy( p_sys->p_vout );
00328 }
00329
00330 if( p_sys->p_blend->p_module )
00331 module_Unneed( p_sys->p_blend, p_sys->p_blend->p_module );
00332 vlc_object_detach( p_sys->p_blend );
00333 vlc_object_destroy( p_sys->p_blend );
00334 }
00335
00336
00337
00338
00339 static void Destroy( vlc_object_t *p_this )
00340 {
00341 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00342 vout_sys_t *p_sys = p_vout->p_sys;
00343
00344 DEL_PARENT_CALLBACKS( SendEventsToChild );
00345
00346 if( p_sys->p_pic ) p_sys->p_pic->pf_release( p_sys->p_pic );
00347 free( p_sys );
00348 }
00349
00350
00351
00352
00353 static void Render( vout_thread_t *p_vout, picture_t *p_pic )
00354 {
00355 vout_sys_t *p_sys = p_vout->p_sys;
00356 picture_t *p_outpic;
00357
00358
00359 while( !(p_outpic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 )) )
00360 {
00361 if( p_vout->b_die || p_vout->b_error ) return;
00362 msleep( VOUT_OUTMEM_SLEEP );
00363 }
00364
00365 vout_CopyPicture( p_vout, p_outpic, p_pic );
00366 vout_DatePicture( p_sys->p_vout, p_outpic, p_pic->date );
00367
00368 p_sys->p_blend->pf_video_blend( p_sys->p_blend, p_outpic, p_outpic,
00369 p_sys->p_pic, p_sys->posx, p_sys->posy,
00370 p_sys->i_trans );
00371
00372 vout_DisplayPicture( p_sys->p_vout, p_outpic );
00373 }
00374
00375
00376
00377
00378 static int SendEvents( vlc_object_t *p_this, char const *psz_var,
00379 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00380 {
00381 var_Set( (vlc_object_t *)p_data, psz_var, newval );
00382 return VLC_SUCCESS;
00383 }
00384
00385
00386
00387
00388 static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
00389 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00390 {
00391 vout_thread_t *p_vout = (vout_thread_t*)p_data;
00392 vout_sys_t *p_sys = p_vout->p_sys;
00393 vlc_value_t valb;
00394 int i_delta;
00395
00396 var_Get( p_vout->p_sys->p_vout, "mouse-button-down", &valb );
00397
00398 i_delta = newval.i_int - oldval.i_int;
00399
00400 if( (valb.i_int & 0x1) == 0 )
00401 {
00402 return VLC_SUCCESS;
00403 }
00404
00405 if( psz_var[6] == 'x' )
00406 {
00407 vlc_value_t valy;
00408 var_Get( p_vout->p_sys->p_vout, "mouse-y", &valy );
00409 if( newval.i_int >= (int)p_sys->posx &&
00410 valy.i_int >= (int)p_sys->posy &&
00411 newval.i_int <= (int)(p_sys->posx + p_sys->i_width) &&
00412 valy.i_int <= (int)(p_sys->posy + p_sys->i_height) )
00413 {
00414 p_sys->posx = __MIN( __MAX( p_sys->posx + i_delta, 0 ),
00415 p_vout->output.i_width - p_sys->i_width );
00416 }
00417 }
00418 else if( psz_var[6] == 'y' )
00419 {
00420 vlc_value_t valx;
00421 var_Get( p_vout->p_sys->p_vout, "mouse-x", &valx );
00422 if( valx.i_int >= (int)p_sys->posx &&
00423 newval.i_int >= (int)p_sys->posy &&
00424 valx.i_int <= (int)(p_sys->posx + p_sys->i_width) &&
00425 newval.i_int <= (int)(p_sys->posy + p_sys->i_height) )
00426 {
00427 p_sys->posy = __MIN( __MAX( p_sys->posy + i_delta, 0 ),
00428 p_vout->output.i_height - p_sys->i_height );
00429 }
00430 }
00431
00432 return VLC_SUCCESS;
00433 }
00434
00435
00436
00437
00438 static int Control( vout_thread_t *p_vout, int i_query, va_list args )
00439 {
00440 return vout_vaControl( p_vout->p_sys->p_vout, i_query, args );
00441 }
00442
00443
00444
00445
00446 static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
00447 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00448 {
00449 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00450 var_Set( p_vout->p_sys->p_vout, psz_var, newval );
00451 return VLC_SUCCESS;
00452 }
00453
00454
00455
00456
00457 struct filter_sys_t
00458 {
00459 picture_t *p_pic;
00460
00461 int i_width, i_height;
00462 int pos, posx, posy;
00463 char *psz_filename;
00464 int i_trans;
00465
00466 vlc_bool_t b_absolute;
00467
00468 mtime_t i_last_date;
00469
00470
00471 vlc_bool_t b_need_update;
00472 vlc_bool_t b_new_image;
00473 };
00474
00475 static subpicture_t *Filter( filter_t *, mtime_t );
00476
00477
00478
00479
00480 static int CreateFilter( vlc_object_t *p_this )
00481 {
00482 filter_t *p_filter = (filter_t *)p_this;
00483 filter_sys_t *p_sys;
00484 vlc_object_t *p_input;
00485
00486
00487 p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
00488 if( p_sys == NULL )
00489 {
00490 msg_Err( p_filter, "out of memory" );
00491 return VLC_ENOMEM;
00492 }
00493
00494
00495 p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT );
00496 if( !p_input )
00497 {
00498 free( p_sys );
00499 return VLC_ENOOBJ;
00500 }
00501
00502 p_sys->psz_filename =
00503 var_CreateGetString( p_input->p_libvlc , "logo-file" );
00504 if( !p_sys->psz_filename || !*p_sys->psz_filename )
00505 {
00506 msg_Err( p_this, "logo file not specified" );
00507 vlc_object_release( p_input );
00508 if( p_sys->psz_filename ) free( p_sys->psz_filename );
00509 free( p_sys );
00510 return VLC_EGENERIC;
00511 }
00512
00513 p_sys->posx = var_CreateGetInteger( p_input->p_libvlc , "logo-x" );
00514 p_sys->posy = var_CreateGetInteger( p_input->p_libvlc , "logo-y" );
00515 p_sys->pos = var_CreateGetInteger( p_input->p_libvlc , "logo-position" );
00516 p_sys->i_trans =
00517 var_CreateGetInteger( p_input->p_libvlc, "logo-transparency");
00518 p_sys->i_trans = __MAX( __MIN( p_sys->i_trans, 255 ), 0 );
00519
00520 var_AddCallback( p_input->p_libvlc, "logo-file", LogoCallback, p_sys );
00521 var_AddCallback( p_input->p_libvlc, "logo-x", LogoCallback, p_sys );
00522 var_AddCallback( p_input->p_libvlc, "logo-y", LogoCallback, p_sys );
00523 var_AddCallback( p_input->p_libvlc, "logo-position", LogoCallback, p_sys );
00524 var_AddCallback( p_input->p_libvlc, "logo-transparency", LogoCallback, p_sys );
00525 vlc_object_release( p_input );
00526
00527 p_sys->p_pic = LoadImage( p_this, p_sys->psz_filename );
00528 if( !p_sys->p_pic )
00529 {
00530 free( p_sys );
00531 msg_Err( p_this, "couldn't load logo file" );
00532 return VLC_EGENERIC;
00533 }
00534
00535
00536 p_filter->pf_sub_filter = Filter;
00537 p_sys->i_width = p_sys->p_pic->p[Y_PLANE].i_visible_pitch;
00538 p_sys->i_height = p_sys->p_pic->p[Y_PLANE].i_visible_lines;
00539 p_sys->b_need_update = VLC_TRUE;
00540 p_sys->b_new_image = VLC_FALSE;
00541 p_sys->i_last_date = 0;
00542
00543 return VLC_SUCCESS;
00544 }
00545
00546
00547
00548
00549 static void DestroyFilter( vlc_object_t *p_this )
00550 {
00551 filter_t *p_filter = (filter_t *)p_this;
00552 filter_sys_t *p_sys = p_filter->p_sys;
00553 vlc_object_t *p_input;
00554
00555 if( p_sys->p_pic ) p_sys->p_pic->pf_release( p_sys->p_pic );
00556 if( p_sys->psz_filename ) free( p_sys->psz_filename );
00557 free( p_sys );
00558
00559
00560 p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT );
00561 if( !p_input ) return;
00562
00563 var_Destroy( p_input->p_libvlc , "logo-file" );
00564 var_Destroy( p_input->p_libvlc , "logo-x" );
00565 var_Destroy( p_input->p_libvlc , "logo-y" );
00566 var_Destroy( p_input->p_libvlc , "logo-position" );
00567 var_Destroy( p_input->p_libvlc , "logo-transparency" );
00568 vlc_object_release( p_input );
00569 }
00570
00571
00572
00573
00574
00575
00576 static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
00577 {
00578 filter_sys_t *p_sys = p_filter->p_sys;
00579 subpicture_t *p_spu;
00580 subpicture_region_t *p_region;
00581 video_format_t fmt;
00582
00583 if( !p_sys->b_need_update && p_sys->i_last_date +5000000 > date ) return 0;
00584
00585 if( p_sys->b_new_image )
00586 {
00587 if( p_sys->p_pic ) p_sys->p_pic->pf_release( p_sys->p_pic );
00588
00589 p_sys->p_pic = LoadImage( VLC_OBJECT(p_filter), p_sys->psz_filename );
00590 if( p_sys->p_pic )
00591 {
00592 p_sys->i_width = p_sys->p_pic->p[Y_PLANE].i_visible_pitch;
00593 p_sys->i_height = p_sys->p_pic->p[Y_PLANE].i_visible_lines;
00594 }
00595
00596 p_sys->b_new_image = VLC_FALSE;
00597 }
00598
00599 p_sys->b_need_update = VLC_FALSE;
00600
00601
00602 p_spu = p_filter->pf_sub_buffer_new( p_filter );
00603 if( !p_spu ) return NULL;
00604
00605 p_spu->b_absolute = p_sys->b_absolute;
00606 p_spu->i_start = p_sys->i_last_date = date;
00607 p_spu->i_stop = 0;
00608 p_spu->b_ephemer = VLC_TRUE;
00609
00610 p_sys->b_need_update = VLC_FALSE;
00611
00612 if( !p_sys->p_pic || !p_sys->i_trans )
00613 {
00614
00615 return p_spu;
00616 }
00617
00618
00619 memset( &fmt, 0, sizeof(video_format_t) );
00620 fmt.i_chroma = VLC_FOURCC('Y','U','V','A');
00621 fmt.i_aspect = VOUT_ASPECT_FACTOR;
00622 fmt.i_sar_num = fmt.i_sar_den = 1;
00623 fmt.i_width = fmt.i_visible_width = p_sys->i_width;
00624 fmt.i_height = fmt.i_visible_height = p_sys->i_height;
00625 fmt.i_x_offset = fmt.i_y_offset = 0;
00626 p_region = p_spu->pf_create_region( VLC_OBJECT(p_filter), &fmt );
00627 if( !p_region )
00628 {
00629 msg_Err( p_filter, "cannot allocate SPU region" );
00630 p_filter->pf_sub_buffer_del( p_filter, p_spu );
00631 return NULL;
00632 }
00633
00634 vout_CopyPicture( p_filter, &p_region->picture, p_sys->p_pic );
00635
00636
00637 if( p_sys->posx < 0 || p_sys->posy < 0 )
00638 {
00639 p_spu->i_flags = p_sys->pos;
00640 p_spu->i_x = 0;
00641 p_spu->i_y = 0;
00642 p_spu->b_absolute = VLC_FALSE;
00643 }
00644 else
00645 {
00646 p_spu->i_flags = OSD_ALIGN_LEFT | OSD_ALIGN_TOP;
00647 p_spu->i_x = p_sys->posx;
00648 p_spu->i_y = p_sys->posy;
00649 p_spu->b_absolute = VLC_TRUE;
00650 }
00651
00652 p_spu->p_region = p_region;
00653 p_spu->i_alpha = p_sys->i_trans;
00654
00655 return p_spu;
00656 }
00657
00658
00659
00660
00661 static int LogoCallback( vlc_object_t *p_this, char const *psz_var,
00662 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00663 {
00664 filter_sys_t *p_sys = (filter_sys_t *)p_data;
00665
00666 if( !strncmp( psz_var, "logo-file", 6 ) )
00667 {
00668 if( p_sys->psz_filename ) free( p_sys->psz_filename );
00669 p_sys->psz_filename = strdup( newval.psz_string );
00670 p_sys->b_new_image = VLC_TRUE;
00671 }
00672 else if ( !strncmp( psz_var, "logo-x", 6 ) )
00673 {
00674 p_sys->posx = newval.i_int;
00675 }
00676 else if ( !strncmp( psz_var, "logo-y", 6 ) )
00677 {
00678 p_sys->posy = newval.i_int;
00679 }
00680 else if ( !strncmp( psz_var, "logo-position", 12 ) )
00681 {
00682 p_sys->pos = newval.i_int;
00683 }
00684 else if ( !strncmp( psz_var, "logo-transparency", 9 ) )
00685 {
00686 p_sys->i_trans = __MAX( __MIN( newval.i_int, 255 ), 0 );
00687 }
00688 p_sys->b_need_update = VLC_TRUE;
00689 return VLC_SUCCESS;
00690 }