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 #include <math.h>
00031
00032 #include <vlc/vlc.h>
00033 #include <vlc/vout.h>
00034
00035 #ifdef HAVE_LIMITS_H
00036 # include <limits.h>
00037 #endif
00038
00039 #include "vlc_filter.h"
00040 #include "vlc_image.h"
00041
00042 #include "mosaic.h"
00043
00044 #define BLANK_DELAY I64C(1000000)
00045
00046
00047
00048
00049 static int CreateFilter ( vlc_object_t * );
00050 static void DestroyFilter ( vlc_object_t * );
00051
00052 static subpicture_t *Filter( filter_t *, mtime_t );
00053
00054 static int MosaicCallback( vlc_object_t *, char const *, vlc_value_t,
00055 vlc_value_t, void * );
00056
00057
00058
00059
00060 struct filter_sys_t
00061 {
00062 vlc_mutex_t lock;
00063 vlc_mutex_t *p_lock;
00064
00065 image_handler_t *p_image;
00066 picture_t *p_pic;
00067
00068 int i_position;
00069 vlc_bool_t b_ar;
00070 vlc_bool_t b_keep;
00071 int i_width, i_height;
00072 int i_cols, i_rows;
00073 int i_align;
00074 int i_xoffset, i_yoffset;
00075 int i_vborder, i_hborder;
00076 int i_alpha;
00077
00078 char **ppsz_order;
00079 int i_order_length;
00080
00081 mtime_t i_delay;
00082 };
00083
00084
00085
00086
00087 #define ALPHA_TEXT N_("Alpha blending")
00088 #define ALPHA_LONGTEXT N_("Alpha blending (0 -> 255). Default is 255")
00089
00090 #define HEIGHT_TEXT N_("Height in pixels")
00091 #define WIDTH_TEXT N_("Width in pixels")
00092 #define XOFFSET_TEXT N_("Top left corner x coordinate")
00093 #define YOFFSET_TEXT N_("Top left corner y coordinate")
00094 #define VBORDER_TEXT N_("Vertical border width in pixels")
00095 #define HBORDER_TEXT N_("Horizontal border width in pixels")
00096 #define ALIGN_TEXT N_("Mosaic alignment")
00097
00098 #define POS_TEXT N_("Positioning method")
00099 #define POS_LONGTEXT N_("Positioning method. auto: automatically choose " \
00100 "the best number of rows and columns. fixed: use the user-defined " \
00101 "number of rows and columns.")
00102 #define ROWS_TEXT N_("Number of rows")
00103 #define COLS_TEXT N_("Number of columns")
00104 #define AR_TEXT N_("Keep aspect ratio when resizing")
00105 #define KEEP_TEXT N_("Keep original size")
00106
00107 #define ORDER_TEXT N_("Order as a comma separated list of picture-id(s)")
00108
00109 #define DELAY_TEXT N_("Delay")
00110 #define DELAY_LONGTEXT N_("Pictures coming from the picture video outputs " \
00111 "will be delayed accordingly (in milliseconds). For high " \
00112 "values you will need to raise file-caching and others.")
00113
00114 static int pi_pos_values[] = { 0, 1 };
00115 static char * ppsz_pos_descriptions[] =
00116 { N_("auto"), N_("fixed") };
00117
00118 static int pi_align_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
00119 static char *ppsz_align_descriptions[] =
00120 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
00121 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
00122
00123
00124 vlc_module_begin();
00125 set_description( N_("Mosaic video sub filter") );
00126 set_shortname( N_("Mosaic") );
00127 set_category( CAT_VIDEO );
00128 set_subcategory( SUBCAT_VIDEO_SUBPIC);
00129 set_capability( "sub filter", 0 );
00130 set_callbacks( CreateFilter, DestroyFilter );
00131
00132 add_integer( "mosaic-alpha", 255, NULL, ALPHA_TEXT, ALPHA_LONGTEXT, VLC_FALSE );
00133 add_integer( "mosaic-height", 100, NULL, HEIGHT_TEXT, HEIGHT_TEXT, VLC_FALSE );
00134 add_integer( "mosaic-width", 100, NULL, WIDTH_TEXT, WIDTH_TEXT, VLC_FALSE );
00135 add_integer( "mosaic-align", 5, NULL, ALIGN_TEXT, ALIGN_TEXT, VLC_TRUE);
00136 change_integer_list( pi_align_values, ppsz_align_descriptions, 0 );
00137 add_integer( "mosaic-xoffset", 0, NULL, XOFFSET_TEXT, XOFFSET_TEXT, VLC_TRUE );
00138 add_integer( "mosaic-yoffset", 0, NULL, YOFFSET_TEXT, YOFFSET_TEXT, VLC_TRUE );
00139 add_integer( "mosaic-vborder", 0, NULL, VBORDER_TEXT, VBORDER_TEXT, VLC_TRUE );
00140 add_integer( "mosaic-hborder", 0, NULL, HBORDER_TEXT, HBORDER_TEXT, VLC_TRUE );
00141
00142 add_integer( "mosaic-position", 0, NULL, POS_TEXT, POS_LONGTEXT, VLC_FALSE );
00143 change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );
00144 add_integer( "mosaic-rows", 2, NULL, ROWS_TEXT, ROWS_TEXT, VLC_FALSE );
00145 add_integer( "mosaic-cols", 2, NULL, COLS_TEXT, COLS_TEXT, VLC_FALSE );
00146 add_bool( "mosaic-keep-aspect-ratio", 0, NULL, AR_TEXT, AR_TEXT, VLC_FALSE );
00147 add_bool( "mosaic-keep-picture", 0, NULL, KEEP_TEXT, KEEP_TEXT, VLC_FALSE );
00148 add_string( "mosaic-order", "", NULL, ORDER_TEXT, ORDER_TEXT, VLC_FALSE );
00149
00150 add_integer( "mosaic-delay", 0, NULL, DELAY_TEXT, DELAY_LONGTEXT,
00151 VLC_FALSE );
00152
00153 var_Create( p_module->p_libvlc, "mosaic-lock", VLC_VAR_MUTEX );
00154 vlc_module_end();
00155
00156
00157
00158
00159
00160 static int CreateFilter( vlc_object_t *p_this )
00161 {
00162 filter_t *p_filter = (filter_t *)p_this;
00163 filter_sys_t *p_sys;
00164 libvlc_t *p_libvlc = p_filter->p_libvlc;
00165 char *psz_order;
00166 int i_index;
00167 vlc_value_t val;
00168
00169
00170 vlc_thread_set_priority( p_this, VLC_THREAD_PRIORITY_OUTPUT );
00171
00172
00173 p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
00174 if( p_sys == NULL )
00175 {
00176 msg_Err( p_filter, "out of memory" );
00177 return VLC_ENOMEM;
00178 }
00179
00180 p_filter->pf_sub_filter = Filter;
00181 p_sys->p_pic = NULL;
00182
00183 vlc_mutex_init( p_filter, &p_sys->lock );
00184 vlc_mutex_lock( &p_sys->lock );
00185
00186 var_Get( p_libvlc, "mosaic-lock", &val );
00187 p_sys->p_lock = val.p_address;
00188
00189 #define GET_VAR( name, min, max ) \
00190 p_sys->i_##name = __MIN( max, __MAX( min, \
00191 var_CreateGetInteger( p_filter, "mosaic-" #name ) ) ); \
00192 var_Destroy( p_filter, "mosaic-" #name ); \
00193 var_Create( p_libvlc, "mosaic-" #name, VLC_VAR_INTEGER ); \
00194 var_SetInteger( p_libvlc, "mosaic-" #name, p_sys->i_##name ); \
00195 var_AddCallback( p_libvlc, "mosaic-" #name, MosaicCallback, p_sys );
00196
00197 GET_VAR( width, 0, INT_MAX );
00198 GET_VAR( height, 0, INT_MAX );
00199 GET_VAR( xoffset, 0, INT_MAX );
00200 GET_VAR( yoffset, 0, INT_MAX );
00201
00202 p_sys->i_align = __MIN( 10, __MAX( 0, var_CreateGetInteger( p_filter, "mosaic-align" ) ) );
00203 if( p_sys->i_align == 3 || p_sys->i_align == 7 )
00204 p_sys->i_align = 5;
00205 var_Destroy( p_filter, "mosaic-align" );
00206 var_Create( p_libvlc, "mosaic-align", VLC_VAR_INTEGER );
00207 var_SetInteger( p_libvlc, "mosaic-align", p_sys->i_align );
00208 var_AddCallback( p_libvlc, "mosaic-align", MosaicCallback, p_sys );
00209
00210 GET_VAR( vborder, 0, INT_MAX );
00211 GET_VAR( hborder, 0, INT_MAX );
00212 GET_VAR( rows, 1, INT_MAX );
00213 GET_VAR( cols, 1, INT_MAX );
00214 GET_VAR( alpha, 0, 255 );
00215 GET_VAR( position, 0, 1 );
00216 GET_VAR( delay, 100, INT_MAX );
00217 p_sys->i_delay *= 1000;
00218
00219 p_sys->b_ar = var_CreateGetBool( p_filter, "mosaic-keep-aspect-ratio" );
00220 var_Destroy( p_filter, "mosaic-keep-aspect-ratio" );
00221 var_Create( p_libvlc, "mosaic-keep-aspect-ratio", VLC_VAR_INTEGER );
00222 var_SetBool( p_libvlc, "mosaic-keep-aspect-ratio", p_sys->b_ar );
00223 var_AddCallback( p_libvlc, "mosaic-keep-aspect-ratio", MosaicCallback,
00224 p_sys );
00225
00226 p_sys->b_keep = var_CreateGetBool( p_filter, "mosaic-keep-picture" );
00227 if ( !p_sys->b_keep )
00228 {
00229 p_sys->p_image = image_HandlerCreate( p_filter );
00230 }
00231
00232 p_sys->i_order_length = 0;
00233 p_sys->ppsz_order = NULL;
00234 psz_order = var_CreateGetString( p_filter, "mosaic-order" );
00235
00236 if( psz_order[0] != 0 )
00237 {
00238 char *psz_end = NULL;
00239 i_index = 0;
00240 do
00241 {
00242 psz_end = strchr( psz_order, ',' );
00243 i_index++;
00244 p_sys->ppsz_order = realloc( p_sys->ppsz_order,
00245 i_index * sizeof(char *) );
00246 p_sys->ppsz_order[i_index - 1] = strndup( psz_order,
00247 psz_end - psz_order );
00248 psz_order = psz_end+1;
00249 } while( NULL != psz_end );
00250 p_sys->i_order_length = i_index;
00251 }
00252
00253 vlc_mutex_unlock( &p_sys->lock );
00254
00255 return VLC_SUCCESS;
00256 }
00257
00258
00259
00260
00261 static void DestroyFilter( vlc_object_t *p_this )
00262 {
00263 filter_t *p_filter = (filter_t*)p_this;
00264 filter_sys_t *p_sys = p_filter->p_sys;
00265 libvlc_t *p_libvlc = p_filter->p_libvlc;
00266 int i_index;
00267
00268 vlc_mutex_lock( &p_sys->lock );
00269
00270 if( !p_sys->b_keep )
00271 {
00272 image_HandlerDelete( p_sys->p_image );
00273 }
00274
00275 if( p_sys->i_order_length )
00276 {
00277 for( i_index = 0; i_index < p_sys->i_order_length; i_index++ )
00278 {
00279 free( p_sys->ppsz_order[i_index] );
00280 }
00281 free( p_sys->ppsz_order );
00282 }
00283
00284 var_Destroy( p_libvlc, "mosaic-alpha" );
00285 var_Destroy( p_libvlc, "mosaic-height" );
00286 var_Destroy( p_libvlc, "mosaic-align" );
00287 var_Destroy( p_libvlc, "mosaic-width" );
00288 var_Destroy( p_libvlc, "mosaic-xoffset" );
00289 var_Destroy( p_libvlc, "mosaic-yoffset" );
00290 var_Destroy( p_libvlc, "mosaic-vborder" );
00291 var_Destroy( p_libvlc, "mosaic-hborder" );
00292 var_Destroy( p_libvlc, "mosaic-position" );
00293 var_Destroy( p_libvlc, "mosaic-rows" );
00294 var_Destroy( p_libvlc, "mosaic-cols" );
00295 var_Destroy( p_libvlc, "mosaic-keep-aspect-ratio" );
00296
00297 if( p_sys->p_pic ) p_sys->p_pic->pf_release( p_sys->p_pic );
00298 vlc_mutex_unlock( &p_sys->lock );
00299 vlc_mutex_destroy( &p_sys->lock );
00300 free( p_sys );
00301 }
00302
00303
00304
00305
00306 static void MosaicReleasePicture( picture_t *p_picture )
00307 {
00308 picture_t *p_original_pic = (picture_t *)p_picture->p_sys;
00309
00310 p_original_pic->pf_release( p_original_pic );
00311 }
00312
00313
00314
00315
00316 static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
00317 {
00318 filter_sys_t *p_sys = p_filter->p_sys;
00319 bridge_t *p_bridge;
00320
00321 subpicture_t *p_spu;
00322
00323 int i_index, i_real_index, i_row, i_col;
00324 int i_greatest_real_index_used = p_sys->i_order_length - 1;
00325
00326 subpicture_region_t *p_region;
00327 subpicture_region_t *p_region_prev = NULL;
00328
00329
00330 p_spu = p_filter->pf_sub_buffer_new( p_filter );
00331 if( !p_spu )
00332 {
00333 return NULL;
00334 }
00335
00336
00337 p_spu->i_channel = 0;
00338 p_spu->i_start = date;
00339 p_spu->i_stop = 0;
00340 p_spu->b_ephemer = VLC_TRUE;
00341 p_spu->i_alpha = p_sys->i_alpha;
00342 p_spu->i_flags = p_sys->i_align;
00343 p_spu->b_absolute = VLC_FALSE;
00344
00345 vlc_mutex_lock( &p_sys->lock );
00346 vlc_mutex_lock( p_sys->p_lock );
00347
00348 p_bridge = GetBridge( p_filter );
00349 if ( p_bridge == NULL )
00350 {
00351 vlc_mutex_unlock( p_sys->p_lock );
00352 vlc_mutex_unlock( &p_sys->lock );
00353 return p_spu;
00354 }
00355
00356 if ( p_sys->i_position == 0 )
00357 {
00358 int i_numpics = p_sys->i_order_length;
00359 for ( i_index = 0; i_index < p_bridge->i_es_num; i_index++ )
00360 {
00361 bridged_es_t *p_es = p_bridge->pp_es[i_index];
00362 if ( !p_es->b_empty )
00363 {
00364 i_numpics ++;
00365 if( p_sys->i_order_length && p_es->psz_id != 0 )
00366 {
00367
00368
00369 int i;
00370 for( i = 0; i < p_sys->i_order_length ; i++ )
00371 {
00372 if( !strcmp( p_sys->ppsz_order[i], p_es->psz_id ) )
00373 {
00374 i_numpics--;
00375 break;
00376 }
00377 }
00378
00379 }
00380 }
00381 }
00382 p_sys->i_rows = ((int)ceil(sqrt( (float)i_numpics )));
00383 p_sys->i_cols = ( i_numpics % p_sys->i_rows == 0 ?
00384 i_numpics / p_sys->i_rows :
00385 i_numpics / p_sys->i_rows + 1 );
00386 }
00387
00388 i_real_index = 0;
00389
00390 for ( i_index = 0; i_index < p_bridge->i_es_num; i_index++ )
00391 {
00392 bridged_es_t *p_es = p_bridge->pp_es[i_index];
00393 video_format_t fmt_in = {0}, fmt_out = {0};
00394 picture_t *p_converted;
00395
00396 if ( p_es->b_empty )
00397 continue;
00398
00399 while ( p_es->p_picture != NULL
00400 && p_es->p_picture->date + p_sys->i_delay < date )
00401 {
00402 if ( p_es->p_picture->p_next != NULL )
00403 {
00404 picture_t *p_next = p_es->p_picture->p_next;
00405 p_es->p_picture->pf_release( p_es->p_picture );
00406 p_es->p_picture = p_next;
00407 }
00408 else if ( p_es->p_picture->date + p_sys->i_delay + BLANK_DELAY <
00409 date )
00410 {
00411
00412 p_es->p_picture->pf_release( p_es->p_picture );
00413 p_es->p_picture = NULL;
00414 p_es->pp_last = &p_es->p_picture;
00415 break;
00416 }
00417 else
00418 {
00419 msg_Dbg( p_filter, "too late picture for %s (" I64Fd ")",
00420 p_es->psz_id,
00421 date - p_es->p_picture->date - p_sys->i_delay );
00422 break;
00423 }
00424 }
00425
00426 if ( p_es->p_picture == NULL )
00427 continue;
00428
00429 if ( p_sys->i_order_length == 0 )
00430 {
00431 i_real_index++;
00432 }
00433 else
00434 {
00435 int i;
00436 for ( i = 0; i <= p_sys->i_order_length; i++ )
00437 {
00438 if ( i == p_sys->i_order_length ) break;
00439 if ( strcmp( p_es->psz_id, p_sys->ppsz_order[i] ) == 0 )
00440 {
00441 i_real_index = i;
00442 break;
00443 }
00444 }
00445 if ( i == p_sys->i_order_length )
00446 i_real_index = ++i_greatest_real_index_used;
00447 }
00448 i_row = ( i_real_index / p_sys->i_cols ) % p_sys->i_rows;
00449 i_col = i_real_index % p_sys->i_cols ;
00450
00451 if ( !p_sys->b_keep )
00452 {
00453
00454 fmt_in.i_chroma = p_es->p_picture->format.i_chroma;
00455 fmt_in.i_height = p_es->p_picture->format.i_height;
00456 fmt_in.i_width = p_es->p_picture->format.i_width;
00457
00458 fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
00459 fmt_out.i_width = fmt_in.i_width *
00460 ( ( p_sys->i_width - ( p_sys->i_cols - 1 ) * p_sys->i_vborder )
00461 / p_sys->i_cols ) / fmt_in.i_width;
00462 fmt_out.i_height = fmt_in.i_height *
00463 ( ( p_sys->i_height - ( p_sys->i_rows - 1 ) * p_sys->i_hborder )
00464 / p_sys->i_rows ) / fmt_in.i_height;
00465 if( p_sys->b_ar )
00466 {
00467 if( (float)fmt_out.i_width / (float)fmt_out.i_height
00468 > (float)fmt_in.i_width / (float)fmt_in.i_height )
00469 {
00470 fmt_out.i_width = ( fmt_out.i_height * fmt_in.i_width )
00471 / fmt_in.i_height;
00472 }
00473 else
00474 {
00475 fmt_out.i_height = ( fmt_out.i_width * fmt_in.i_height )
00476 / fmt_in.i_width;
00477 }
00478 }
00479
00480 fmt_out.i_visible_width = fmt_out.i_width;
00481 fmt_out.i_visible_height = fmt_out.i_height;
00482
00483 p_converted = image_Convert( p_sys->p_image, p_es->p_picture,
00484 &fmt_in, &fmt_out );
00485 if( !p_converted )
00486 {
00487 msg_Warn( p_filter,
00488 "image resizing and chroma conversion failed" );
00489 continue;
00490 }
00491 }
00492 else
00493 {
00494 p_converted = p_es->p_picture;
00495 p_converted->i_refcount++;
00496 fmt_in.i_width = fmt_out.i_width = p_converted->format.i_width;
00497 fmt_in.i_height = fmt_out.i_height = p_converted->format.i_height;
00498 fmt_in.i_chroma = fmt_out.i_chroma = p_converted->format.i_chroma;
00499 fmt_out.i_visible_width = fmt_out.i_width;
00500 fmt_out.i_visible_height = fmt_out.i_height;
00501 }
00502
00503 p_region = p_spu->pf_make_region( VLC_OBJECT(p_filter), &fmt_out,
00504 p_converted );
00505 if( !p_region )
00506 {
00507 msg_Err( p_filter, "cannot allocate SPU region" );
00508 p_filter->pf_sub_buffer_del( p_filter, p_spu );
00509 vlc_mutex_unlock( &p_sys->lock );
00510 vlc_mutex_unlock( p_sys->p_lock );
00511 return p_spu;
00512 }
00513
00514
00515
00516
00517 if( !p_sys->b_keep )
00518 {
00519 free( p_converted );
00520 }
00521 else
00522 {
00523
00524 p_region->picture.p_sys = (picture_sys_t *)p_converted;
00525 p_region->picture.pf_release = MosaicReleasePicture;
00526 }
00527
00528 if( p_sys->b_ar || p_sys->b_keep )
00529 {
00530
00531 p_region->i_x = p_sys->i_xoffset
00532 + i_col * ( p_sys->i_width / p_sys->i_cols )
00533 + ( i_col * p_sys->i_vborder ) / p_sys->i_cols
00534 + ( ( ( p_sys->i_width
00535 - ( p_sys->i_cols - 1 ) * p_sys->i_vborder )
00536 / p_sys->i_cols ) - fmt_out.i_width ) / 2;
00537 p_region->i_y = p_sys->i_yoffset
00538 + i_row * ( p_sys->i_height / p_sys->i_rows )
00539 + ( i_row * p_sys->i_hborder ) / p_sys->i_rows
00540 + ( ( ( p_sys->i_height
00541 - ( p_sys->i_rows - 1 ) * p_sys->i_hborder )
00542 / p_sys->i_rows ) - fmt_out.i_height ) / 2;
00543 }
00544 else
00545 {
00546
00547
00548 p_region->i_x = p_sys->i_xoffset
00549 + i_col * ( p_sys->i_width / p_sys->i_cols )
00550 + ( i_col * p_sys->i_vborder ) / p_sys->i_cols;
00551 p_region->i_y = p_sys->i_yoffset
00552 + i_row * ( p_sys->i_height / p_sys->i_rows )
00553 + ( i_row * p_sys->i_hborder ) / p_sys->i_rows;
00554 }
00555
00556 if( p_region_prev == NULL )
00557 {
00558 p_spu->p_region = p_region;
00559 }
00560 else
00561 {
00562 p_region_prev->p_next = p_region;
00563 }
00564
00565 p_region_prev = p_region;
00566 }
00567
00568 vlc_mutex_unlock( p_sys->p_lock );
00569 vlc_mutex_unlock( &p_sys->lock );
00570
00571 return p_spu;
00572 }
00573
00574
00575
00576
00577 static int MosaicCallback( vlc_object_t *p_this, char const *psz_var,
00578 vlc_value_t oldval, vlc_value_t newval,
00579 void *p_data )
00580 {
00581 filter_sys_t *p_sys = (filter_sys_t *) p_data;
00582 if( !strcmp( psz_var, "mosaic-alpha" ) )
00583 {
00584 vlc_mutex_lock( &p_sys->lock );
00585 msg_Dbg( p_this, "Changing alpha from %d/255 to %d/255",
00586 p_sys->i_alpha, newval.i_int);
00587 p_sys->i_alpha = __MIN( __MAX( newval.i_int, 0 ), 255 );
00588 vlc_mutex_unlock( &p_sys->lock );
00589 }
00590 else if( !strcmp( psz_var, "mosaic-height" ) )
00591 {
00592 vlc_mutex_lock( &p_sys->lock );
00593 msg_Dbg( p_this, "Changing height from %dpx to %dpx",
00594 p_sys->i_height, newval.i_int );
00595 p_sys->i_height = __MAX( newval.i_int, 0 );
00596 vlc_mutex_unlock( &p_sys->lock );
00597 }
00598 else if( !strcmp( psz_var, "mosaic-width" ) )
00599 {
00600 vlc_mutex_lock( &p_sys->lock );
00601 msg_Dbg( p_this, "Changing width from %dpx to %dpx",
00602 p_sys->i_width, newval.i_int );
00603 p_sys->i_width = __MAX( newval.i_int, 0 );
00604 vlc_mutex_unlock( &p_sys->lock );
00605 }
00606 else if( !strcmp( psz_var, "mosaic-xoffset" ) )
00607 {
00608 vlc_mutex_lock( &p_sys->lock );
00609 msg_Dbg( p_this, "Changing x offset from %dpx to %dpx",
00610 p_sys->i_xoffset, newval.i_int );
00611 p_sys->i_xoffset = __MAX( newval.i_int, 0 );
00612 vlc_mutex_unlock( &p_sys->lock );
00613 }
00614 else if( !strcmp( psz_var, "mosaic-yoffset" ) )
00615 {
00616 vlc_mutex_lock( &p_sys->lock );
00617 msg_Dbg( p_this, "Changing y offset from %dpx to %dpx",
00618 p_sys->i_yoffset, newval.i_int );
00619 p_sys->i_yoffset = __MAX( newval.i_int, 0 );
00620 vlc_mutex_unlock( &p_sys->lock );
00621 }
00622 else if( !strcmp( psz_var, "mosaic-align" ) )
00623 {
00624 int i_old = 0, i_new = 0;
00625 vlc_mutex_lock( &p_sys->lock );
00626 newval.i_int = __MIN( __MAX( newval.i_int, 0 ), 10 );
00627 if( newval.i_int == 3 || newval.i_int == 7 )
00628 newval.i_int = 5;
00629 while( pi_align_values[i_old] != p_sys->i_align ) i_old++;
00630 while( pi_align_values[i_new] != newval.i_int ) i_new++;
00631 msg_Dbg( p_this, "Changing alignment from %d (%s) to %d (%s)",
00632 p_sys->i_align, ppsz_align_descriptions[i_old],
00633 newval.i_int, ppsz_align_descriptions[i_new] );
00634 p_sys->i_align = newval.i_int;
00635 vlc_mutex_unlock( &p_sys->lock );
00636 }
00637 else if( !strcmp( psz_var, "mosaic-vborder" ) )
00638 {
00639 vlc_mutex_lock( &p_sys->lock );
00640 msg_Dbg( p_this, "Changing vertical border from %dpx to %dpx",
00641 p_sys->i_vborder, newval.i_int );
00642 p_sys->i_vborder = __MAX( newval.i_int, 0 );
00643 vlc_mutex_unlock( &p_sys->lock );
00644 }
00645 else if( !strcmp( psz_var, "mosaic-hborder" ) )
00646 {
00647 vlc_mutex_lock( &p_sys->lock );
00648 msg_Dbg( p_this, "Changing horizontal border from %dpx to %dpx",
00649 p_sys->i_vborder, newval.i_int );
00650 p_sys->i_hborder = __MAX( newval.i_int, 0 );
00651 vlc_mutex_unlock( &p_sys->lock );
00652 }
00653 else if( !strcmp( psz_var, "mosaic-position" ) )
00654 {
00655 if( newval.i_int > 1 || newval.i_int < 0 )
00656 {
00657 msg_Err( p_this, "Position is either 0 (auto) or 1 (fixed)" );
00658 }
00659 else
00660 {
00661 vlc_mutex_lock( &p_sys->lock );
00662 msg_Dbg( p_this, "Changing position method from %d (%s) to %d (%s)",
00663 p_sys->i_position, ppsz_pos_descriptions[p_sys->i_position],
00664 newval.i_int, ppsz_pos_descriptions[newval.i_int]);
00665 p_sys->i_position = newval.i_int;
00666 vlc_mutex_unlock( &p_sys->lock );
00667 }
00668 }
00669 else if( !strcmp( psz_var, "mosaic-rows" ) )
00670 {
00671 vlc_mutex_lock( &p_sys->lock );
00672 msg_Dbg( p_this, "Changing number of rows from %d to %d",
00673 p_sys->i_rows, newval.i_int );
00674 p_sys->i_rows = __MAX( newval.i_int, 1 );
00675 vlc_mutex_unlock( &p_sys->lock );
00676 }
00677 else if( !strcmp( psz_var, "mosaic-cols" ) )
00678 {
00679 vlc_mutex_lock( &p_sys->lock );
00680 msg_Dbg( p_this, "Changing number of columns from %d to %d",
00681 p_sys->i_cols, newval.i_int );
00682 p_sys->i_cols = __MAX( newval.i_int, 1 );
00683 vlc_mutex_unlock( &p_sys->lock );
00684 }
00685 else if( !strcmp( psz_var, "mosaic-keep-aspect-ratio" ) )
00686 {
00687 vlc_mutex_lock( &p_sys->lock );
00688 if( newval.i_int )
00689 {
00690 msg_Dbg( p_this, "Keep aspect ratio" );
00691 p_sys->b_ar = 1;
00692 }
00693 else
00694 {
00695 msg_Dbg( p_this, "Don't keep aspect ratio" );
00696 p_sys->b_ar = 0;
00697 }
00698 vlc_mutex_unlock( &p_sys->lock );
00699 }
00700 return VLC_SUCCESS;
00701 }