1 /*****************************************************************************
2 * VideoEffects.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2011-2012 Felix Paul Kühne
7 * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #import "CompatibilityFixes.h"
26 #import <vlc_common.h>
27 #import <vlc_modules.h>
28 #import <vlc_charset.h>
29 #import "VideoEffects.h"
32 #pragma mark Initialization & Generic code
34 @implementation VLCVideoEffects
35 static VLCVideoEffects *_o_sharedInstance = nil;
37 + (VLCVideoEffects *)sharedInstance
39 return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
44 if (_o_sharedInstance) {
48 _o_sharedInstance = [super init];
51 return _o_sharedInstance;
54 - (IBAction)toggleWindow:(id)sender
56 if( [o_window isVisible] )
57 [o_window orderOut:sender];
59 [o_window makeKeyAndOrderFront:sender];
64 [o_window setTitle: _NS("Video Effects")];
65 [o_window setExcludedFromWindowsMenu:YES];
66 if (!OSX_SNOW_LEOPARD)
67 [o_window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
69 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"basic"]] setLabel:_NS("Basic")];
70 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"crop"]] setLabel:_NS("Crop")];
71 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"geometry"]] setLabel:_NS("Geometry")];
72 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"color"]] setLabel:_NS("Color")];
73 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"misc"]] setLabel:_NS("Miscellaneous")];
75 [o_adjust_ckb setTitle:_NS("Image Adjust")];
76 [o_adjust_hue_lbl setStringValue:_NS("Hue")];
77 [o_adjust_contrast_lbl setStringValue:_NS("Contrast")];
78 [o_adjust_brightness_lbl setStringValue:_NS("Brightness")];
79 [o_adjust_brightness_ckb setTitle:_NS("Brightness Threshold")];
80 [o_adjust_saturation_lbl setStringValue:_NS("Saturation")];
81 [o_adjust_gamma_lbl setStringValue:_NS("Gamma")];
82 [o_adjust_reset_btn setTitle: _NS("Reset")];
83 [o_sharpen_ckb setTitle:_NS("Sharpen")];
84 [o_sharpen_lbl setStringValue:_NS("Sigma")];
85 [o_banding_ckb setTitle:_NS("Banding removal")];
86 [o_banding_lbl setStringValue:_NS("Radius")];
87 [o_grain_ckb setTitle:_NS("Film Grain")];
88 [o_grain_lbl setStringValue:_NS("Variance")];
89 [o_crop_top_lbl setStringValue:_NS("Top")];
90 [o_crop_left_lbl setStringValue:_NS("Left")];
91 [o_crop_right_lbl setStringValue:_NS("Right")];
92 [o_crop_bottom_lbl setStringValue:_NS("Bottom")];
93 [o_crop_sync_top_bottom_ckb setTitle:_NS("Synchronize top and bottom")];
94 [o_crop_sync_left_right_ckb setTitle:_NS("Synchronize left and right")];
96 [o_transform_ckb setTitle:_NS("Transform")];
97 [o_transform_pop removeAllItems];
98 [o_transform_pop addItemWithTitle: _NS("Rotate by 90 degrees")];
99 [[o_transform_pop lastItem] setTag: 90];
100 [o_transform_pop addItemWithTitle: _NS("Rotate by 180 degrees")];
101 [[o_transform_pop lastItem] setTag: 180];
102 [o_transform_pop addItemWithTitle: _NS("Rotate by 270 degrees")];
103 [[o_transform_pop lastItem] setTag: 270];
104 [o_transform_pop addItemWithTitle: _NS("Flip horizontally")];
105 [[o_transform_pop lastItem] setTag: 1];
106 [o_transform_pop addItemWithTitle: _NS("Flip vertically")];
107 [[o_transform_pop lastItem] setTag: 2];
108 [o_zoom_ckb setTitle:_NS("Magnification/Zoom")];
109 [o_puzzle_ckb setTitle:_NS("Puzzle game")];
110 [o_puzzle_rows_lbl setStringValue:_NS("Rows")];
111 [o_puzzle_columns_lbl setStringValue:_NS("Columns")];
112 [o_puzzle_blackslot_ckb setTitle:_NS("Black Slot")];
114 [o_threshold_ckb setTitle:_NS("Color threshold")];
115 [o_threshold_color_lbl setStringValue:_NS("Color")];
116 [o_threshold_saturation_lbl setStringValue:_NS("Saturation")];
117 [o_threshold_similarity_lbl setStringValue:_NS("Similarity")];
118 [o_sepia_ckb setTitle:_NS("Sepia")];
119 [o_sepia_lbl setStringValue:_NS("Intensity")];
120 [o_noise_ckb setTitle:_NS("Noise")];
121 [o_gradient_ckb setTitle:_NS("Gradient")];
122 [o_gradient_mode_lbl setStringValue:_NS("Mode")];
123 [o_gradient_mode_pop removeAllItems];
124 [o_gradient_mode_pop addItemWithTitle: _NS("Gradient")];
125 [[o_gradient_mode_pop lastItem] setTag: 1];
126 [o_gradient_mode_pop addItemWithTitle: _NS("Edge")];
127 [[o_gradient_mode_pop lastItem] setTag: 2];
128 [o_gradient_mode_pop addItemWithTitle: _NS("Hough")];
129 [[o_gradient_mode_pop lastItem] setTag: 3];
130 [o_gradient_color_ckb setTitle:_NS("Color")];
131 [o_gradient_cartoon_ckb setTitle:_NS("Cartoon")];
132 [o_extract_ckb setTitle:_NS("Color extraction")];
133 [o_extract_lbl setStringValue:_NS("Color")];
134 [o_invert_ckb setTitle:_NS("Invert colors")];
135 [o_posterize_ckb setTitle:_NS("Posterize")];
136 [o_posterize_lbl setStringValue:_NS("Posterize level")];
137 [o_blur_ckb setTitle:_NS("Motion blur")];
138 [o_blur_lbl setStringValue:_NS("Factor")];
139 [o_motiondetect_ckb setTitle:_NS("Motion Detect")];
140 [o_watereffect_ckb setTitle:_NS("Water effect")];
141 [o_waves_ckb setTitle:_NS("Waves")];
142 [o_psychedelic_ckb setTitle:_NS("Psychedelic")];
143 [o_anaglyph_ckb setTitle:_NS("Anaglyph 3D")];
145 [o_addtext_ckb setTitle:_NS("Add text")];
146 [o_addtext_text_lbl setStringValue:_NS("Text")];
147 [o_addtext_pos_lbl setStringValue:_NS("Position")];
148 [o_addtext_pos_pop removeAllItems];
149 [o_addtext_pos_pop addItemWithTitle: _NS("Center")];
150 [[o_addtext_pos_pop lastItem] setTag: 0];
151 [o_addtext_pos_pop addItemWithTitle: _NS("Left")];
152 [[o_addtext_pos_pop lastItem] setTag: 1];
153 [o_addtext_pos_pop addItemWithTitle: _NS("Right")];
154 [[o_addtext_pos_pop lastItem] setTag: 2];
155 [o_addtext_pos_pop addItemWithTitle: _NS("Top")];
156 [[o_addtext_pos_pop lastItem] setTag: 4];
157 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom")];
158 [[o_addtext_pos_pop lastItem] setTag: 8];
159 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Left")];
160 [[o_addtext_pos_pop lastItem] setTag: 5];
161 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Right")];
162 [[o_addtext_pos_pop lastItem] setTag: 6];
163 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Left")];
164 [[o_addtext_pos_pop lastItem] setTag: 9];
165 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Right")];
166 [[o_addtext_pos_pop lastItem] setTag: 10];
167 [o_addlogo_ckb setTitle:_NS("Add logo")];
168 [o_addlogo_logo_lbl setStringValue:_NS("Logo")];
169 [o_addlogo_pos_lbl setStringValue:_NS("Position")];
170 [o_addlogo_pos_pop removeAllItems];
171 [o_addlogo_pos_pop addItemWithTitle: _NS("Center")];
172 [[o_addlogo_pos_pop lastItem] setTag: 0];
173 [o_addlogo_pos_pop addItemWithTitle: _NS("Left")];
174 [[o_addlogo_pos_pop lastItem] setTag: 1];
175 [o_addlogo_pos_pop addItemWithTitle: _NS("Right")];
176 [[o_addlogo_pos_pop lastItem] setTag: 2];
177 [o_addlogo_pos_pop addItemWithTitle: _NS("Top")];
178 [[o_addlogo_pos_pop lastItem] setTag: 4];
179 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom")];
180 [[o_addlogo_pos_pop lastItem] setTag: 8];
181 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Left")];
182 [[o_addlogo_pos_pop lastItem] setTag: 5];
183 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Right")];
184 [[o_addlogo_pos_pop lastItem] setTag: 6];
185 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Left")];
186 [[o_addlogo_pos_pop lastItem] setTag: 9];
187 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Right")];
188 [[o_addlogo_pos_pop lastItem] setTag: 10];
189 [o_addlogo_transparency_lbl setStringValue:_NS("Transparency")];
191 [o_tableView selectFirstTabViewItem:self];
202 /* do we have any filter enabled? if yes, show it. */
204 psz_vfilters = config_GetPsz( p_intf, "video-filter" );
206 [o_adjust_ckb setState: (NSInteger)strstr( psz_vfilters, "adjust")];
207 [o_sharpen_ckb setState: (NSInteger)strstr( psz_vfilters, "sharpen")];
208 [o_banding_ckb setState: (NSInteger)strstr( psz_vfilters, "gradfun")];
209 [o_grain_ckb setState: (NSInteger)strstr( psz_vfilters, "grain")];
210 [o_transform_ckb setState: (NSInteger)strstr( psz_vfilters, "transform")];
211 [o_zoom_ckb setState: (NSInteger)strstr( psz_vfilters, "magnify")];
212 [o_puzzle_ckb setState: (NSInteger)strstr( psz_vfilters, "puzzle")];
213 [o_threshold_ckb setState: (NSInteger)strstr( psz_vfilters, "colorthres")];
214 [o_sepia_ckb setState: (NSInteger)strstr( psz_vfilters, "sepia")];
215 [o_noise_ckb setState: (NSInteger)strstr( psz_vfilters, "noise")];
216 [o_gradient_ckb setState: (NSInteger)strstr( psz_vfilters, "gradient")];
217 [o_extract_ckb setState: (NSInteger)strstr( psz_vfilters, "extract")];
218 [o_invert_ckb setState: (NSInteger)strstr( psz_vfilters, "invert")];
219 [o_posterize_ckb setState: (NSInteger)strstr( psz_vfilters, "posterize")];
220 [o_blur_ckb setState: (NSInteger)strstr( psz_vfilters, "motionblur")];
221 [o_motiondetect_ckb setState: (NSInteger)strstr( psz_vfilters, "motiondetect")];
222 [o_watereffect_ckb setState: (NSInteger)strstr( psz_vfilters, "ripple")];
223 [o_waves_ckb setState: (NSInteger)strstr( psz_vfilters, "wave")];
224 [o_psychedelic_ckb setState: (NSInteger)strstr( psz_vfilters, "psychedelic")];
225 [o_anaglyph_ckb setState: (NSInteger)strstr( psz_vfilters, "anaglyph")];
226 free( psz_vfilters );
228 psz_vfilters = config_GetPsz( p_intf, "sub-source" );
230 [o_addtext_ckb setState: (NSInteger)strstr( psz_vfilters, "marq" )];
231 [o_addlogo_ckb setState: (NSInteger)strstr( psz_vfilters, "logo" )];
232 free( psz_vfilters );
235 /* fetch and show the various values */
236 [o_adjust_hue_sld setIntValue: config_GetInt( p_intf, "hue" )];
237 [o_adjust_contrast_sld setFloatValue: config_GetFloat( p_intf, "contrast" )];
238 [o_adjust_brightness_sld setFloatValue: config_GetFloat( p_intf, "brightness" )];
239 [o_adjust_saturation_sld setFloatValue: config_GetFloat( p_intf, "saturation" )];
240 [o_adjust_gamma_sld setFloatValue: config_GetFloat( p_intf, "gamma" )];
241 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "brightness" )]];
242 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "contrast" )]];
243 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "gamma" )]];
244 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "hue" )]];
245 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "saturation" )]];
246 b_state = [o_adjust_ckb state];
247 [o_adjust_brightness_sld setEnabled: b_state];
248 [o_adjust_brightness_ckb setEnabled: b_state];
249 [o_adjust_contrast_sld setEnabled: b_state];
250 [o_adjust_gamma_sld setEnabled: b_state];
251 [o_adjust_hue_sld setEnabled: b_state];
252 [o_adjust_saturation_sld setEnabled: b_state];
253 [o_adjust_brightness_lbl setEnabled: b_state];
254 [o_adjust_contrast_lbl setEnabled: b_state];
255 [o_adjust_gamma_lbl setEnabled: b_state];
256 [o_adjust_hue_lbl setEnabled: b_state];
257 [o_adjust_saturation_lbl setEnabled: b_state];
258 [o_adjust_reset_btn setEnabled: b_state];
259 [o_sharpen_sld setFloatValue: config_GetFloat( p_intf, "sharpen-sigma" )];
260 [o_sharpen_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "sharpen-sigma" )]];
261 [o_sharpen_sld setEnabled: [o_sharpen_ckb state]];
262 [o_sharpen_lbl setEnabled: [o_sharpen_ckb state]];
263 [o_banding_sld setIntValue: config_GetInt( p_intf, "gradfun-radius" )];
264 [o_banding_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "gradfun-radius" )]];
265 [o_banding_sld setEnabled: [o_banding_ckb state]];
266 [o_banding_lbl setEnabled: [o_banding_ckb state]];
267 [o_grain_sld setFloatValue: config_GetFloat( p_intf, "grain-variance" )];
268 [o_grain_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "grain-variance" )]];
269 [o_grain_sld setEnabled: [o_grain_ckb state]];
270 [o_grain_lbl setEnabled: [o_grain_ckb state]];
272 [o_crop_top_fld setIntValue: 0];
273 [o_crop_left_fld setIntValue: 0];
274 [o_crop_right_fld setIntValue: 0];
275 [o_crop_bottom_fld setIntValue: 0];
276 [o_crop_sync_top_bottom_ckb setState: NSOffState];
277 [o_crop_sync_left_right_ckb setState: NSOffState];
279 tmpChar = config_GetPsz( p_intf, "transform-type" );
280 tmpString = [NSString stringWithUTF8String: tmpChar];
281 if( [tmpString isEqualToString:@"hflip"] )
282 [o_transform_pop selectItemWithTag: 1];
283 else if( [tmpString isEqualToString:@"vflip"] )
284 [o_transform_pop selectItemWithTag: 2];
286 [o_transform_pop selectItemWithTag:[tmpString intValue]];
288 [o_transform_pop setEnabled: [o_transform_ckb state]];
289 [o_puzzle_rows_fld setIntValue: config_GetInt( p_intf, "puzzle-rows" )];
290 [o_puzzle_columns_fld setIntValue: config_GetInt( p_intf, "puzzle-cols" )];
291 [o_puzzle_blackslot_ckb setState: config_GetInt( p_intf, "puzzle-black-slot" )];
292 b_state = [o_puzzle_ckb state];
293 [o_puzzle_rows_fld setEnabled: b_state];
294 [o_puzzle_rows_lbl setEnabled: b_state];
295 [o_puzzle_columns_fld setEnabled: b_state];
296 [o_puzzle_columns_lbl setEnabled: b_state];
297 [o_puzzle_blackslot_ckb setEnabled: b_state];
299 [o_threshold_color_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt( p_intf, "colorthres-color" )] uppercaseString]];
300 [o_threshold_saturation_sld setIntValue: config_GetInt( p_intf, "colorthres-saturationthres" )];
301 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "colorthres-saturationthres" )]];
302 [o_threshold_similarity_sld setIntValue: config_GetInt( p_intf, "colorthres-similaritythres" )];
303 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "colorthres-similaritythres" )]];
304 b_state = [o_threshold_ckb state];
305 [o_threshold_color_fld setEnabled: b_state];
306 [o_threshold_color_lbl setEnabled: b_state];
307 [o_threshold_saturation_sld setEnabled: b_state];
308 [o_threshold_saturation_lbl setEnabled: b_state];
309 [o_threshold_similarity_sld setEnabled: b_state];
310 [o_threshold_similarity_lbl setEnabled: b_state];
311 [o_sepia_fld setIntValue: config_GetInt( p_intf, "sepia-intensity" )];
312 [o_sepia_fld setEnabled: [o_sepia_ckb state]];
313 [o_sepia_lbl setEnabled: [o_sepia_ckb state]];
314 tmpChar = config_GetPsz( p_intf, "gradient-mode" );
315 tmpString = [NSString stringWithUTF8String: tmpChar];
316 if( [tmpString isEqualToString:@"hough"] )
317 [o_gradient_mode_pop selectItemWithTag: 3];
318 else if( [tmpString isEqualToString:@"edge"] )
319 [o_gradient_mode_pop selectItemWithTag: 2];
321 [o_gradient_mode_pop selectItemWithTag: 1];
323 [o_gradient_cartoon_ckb setState: config_GetInt( p_intf, "gradient-cartoon" )];
324 [o_gradient_color_ckb setState: config_GetInt( p_intf, "gradient-type" )];
325 b_state = [o_gradient_ckb state];
326 [o_gradient_mode_pop setEnabled: b_state];
327 [o_gradient_mode_lbl setEnabled: b_state];
328 [o_gradient_cartoon_ckb setEnabled: b_state];
329 [o_gradient_color_ckb setEnabled: b_state];
330 [o_extract_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt( p_intf, "extract-component" )] uppercaseString]];
331 [o_extract_fld setEnabled: [o_extract_ckb state]];
332 [o_extract_lbl setEnabled: [o_extract_ckb state]];
333 [o_posterize_fld setIntValue: config_GetInt( p_intf, "posterize-level" )];
334 [o_posterize_fld setEnabled: [o_posterize_ckb state]];
335 [o_posterize_lbl setEnabled: [o_posterize_ckb state]];
336 [o_blur_sld setIntValue: config_GetInt( p_intf, "blur-factor" )];
337 [o_blur_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "blur-factor" )]];
338 [o_blur_sld setEnabled: [o_blur_ckb state]];
339 [o_blur_lbl setEnabled: [o_blur_ckb state]];
341 tmpChar = config_GetPsz( p_intf, "marq-marquee" );
344 [o_addtext_text_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
347 [o_addtext_pos_pop selectItemWithTag: config_GetInt( p_intf, "marq-position" )];
348 b_state = [o_addtext_ckb state];
349 [o_addtext_pos_pop setEnabled: b_state];
350 [o_addtext_pos_lbl setEnabled: b_state];
351 [o_addtext_text_lbl setEnabled: b_state];
352 [o_addtext_text_fld setEnabled: b_state];
354 tmpChar = config_GetPsz( p_intf, "logo-file" );
357 [o_addlogo_logo_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
360 [o_addlogo_pos_pop selectItemWithTag: config_GetInt( p_intf, "logo-position" )];
361 [o_addlogo_transparency_sld setIntValue: config_GetInt( p_intf, "logo-opacity" )];
362 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "logo-opacity" )]];
363 b_state = [o_addlogo_ckb state];
364 [o_addlogo_pos_pop setEnabled: b_state];
365 [o_addlogo_pos_lbl setEnabled: b_state];
366 [o_addlogo_logo_fld setEnabled: b_state];
367 [o_addlogo_logo_lbl setEnabled: b_state];
368 [o_addlogo_transparency_sld setEnabled: b_state];
369 [o_addlogo_transparency_lbl setEnabled: b_state];
372 - (void)setVideoFilter: (char *)psz_name on:(BOOL)b_on
374 char *psz_string, *psz_parser;
375 const char *psz_filter_type;
377 module_t *p_obj = module_find( psz_name );
380 msg_Err( p_intf, "Unable to find filter module \"%s\".", psz_name );
383 msg_Dbg( p_intf, "will set filter '%s'", psz_name );
385 if( module_provides( p_obj, "video splitter" ) )
387 psz_filter_type = "video-splitter";
389 else if( module_provides( p_obj, "video filter2" ) )
391 psz_filter_type = "video-filter";
393 else if( module_provides( p_obj, "sub source" ) )
395 psz_filter_type = "sub-source";
397 else if( module_provides( p_obj, "sub filter" ) )
399 psz_filter_type = "sub-filter";
403 msg_Err( p_intf, "Unknown video filter type." );
407 psz_string = config_GetPsz( p_intf, psz_filter_type );
411 psz_string = psz_name;
412 else if( (NSInteger)strstr( psz_string, psz_name ) == NO )
413 psz_string = (char *)[[NSString stringWithFormat: @"%s:%s", psz_string, psz_name] UTF8String];
418 psz_parser = strstr( psz_string, psz_name );
421 if( *( psz_parser + strlen( psz_name ) ) == ':' )
423 memmove( psz_parser, psz_parser + strlen( psz_name ) + 1,
424 strlen( psz_parser + strlen( psz_name ) + 1 ) + 1 );
431 /* Remove trailing : : */
432 if( strlen( psz_string ) > 0 &&
433 *( psz_string + strlen( psz_string ) -1 ) == ':' )
435 *( psz_string + strlen( psz_string ) -1 ) = '\0';
444 config_PutPsz( p_intf, psz_filter_type, psz_string );
446 /* Try to set on the fly */
447 if( !strcmp( psz_filter_type, "video-splitter" ) )
449 playlist_t *p_playlist = pl_Get( p_intf );
450 var_SetString( p_playlist, psz_filter_type, psz_string );
454 vout_thread_t *p_vout = getVout();
457 var_SetString( p_vout, psz_filter_type, psz_string );
458 vlc_object_release( p_vout );
463 - (void)restartFilterIfNeeded: (char *)psz_filter option: (char *)psz_name
465 vout_thread_t *p_vout = getVout();
470 vlc_object_release( p_vout );
472 vlc_object_t *p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
474 i_type = var_Type( p_filter, psz_name );
476 i_type = config_GetType( p_intf, psz_name );
478 if( !(i_type & VLC_VAR_ISCOMMAND) )
480 msg_Warn( p_intf, "Brute-restarting filter '%s', because the last changed option isn't a command", psz_name );
481 [self setVideoFilter: psz_filter on: NO];
482 [self setVideoFilter: psz_filter on: YES];
485 msg_Dbg( p_intf, "restart not needed" );
488 vlc_object_release( p_filter );
491 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter integer: (int)i_value
493 vout_thread_t *p_vout = getVout();
494 vlc_object_t *p_filter;
496 if( p_vout == NULL ) {
497 config_PutInt( p_intf , psz_name , i_value );
499 p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
502 msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
503 vlc_object_release( p_vout );
506 var_SetInteger( p_filter, psz_name, i_value );
507 config_PutInt( p_intf, psz_name, i_value );
508 vlc_object_release( p_vout );
509 vlc_object_release( p_filter );
512 [self restartFilterIfNeeded:psz_filter option: psz_name];
515 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter float: (float)f_value
517 vout_thread_t *p_vout = getVout();
518 vlc_object_t *p_filter;
520 if( p_vout == NULL ) {
521 config_PutFloat( p_intf , psz_name , f_value );
523 p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
526 msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
527 vlc_object_release( p_vout );
530 var_SetFloat( p_filter, psz_name, f_value );
531 config_PutFloat( p_intf, psz_name, f_value );
532 vlc_object_release( p_vout );
533 vlc_object_release( p_filter );
535 [self restartFilterIfNeeded:psz_filter option: psz_name];
539 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter string: (char *)psz_value
541 vout_thread_t *p_vout = getVout();
542 vlc_object_t *p_filter;
544 if( p_vout == NULL ) {
545 config_PutPsz( p_intf, psz_name, EnsureUTF8(psz_value) );
547 p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
550 msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
551 vlc_object_release( p_vout );
554 var_SetString( p_filter, psz_name, EnsureUTF8(psz_value) );
555 config_PutPsz( p_intf, psz_name, EnsureUTF8(psz_value) );
556 vlc_object_release( p_vout );
557 vlc_object_release( p_filter );
559 [self restartFilterIfNeeded:psz_filter option: psz_name];
563 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter boolean: (BOOL)b_value
565 vout_thread_t *p_vout = getVout();
566 vlc_object_t *p_filter;
568 if( p_vout == NULL ) {
569 config_PutInt( p_intf, psz_name, b_value );
571 p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
574 msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
575 vlc_object_release( p_vout );
578 var_SetBool( p_filter, psz_name, b_value );
579 config_PutInt( p_intf, psz_name, b_value );
580 vlc_object_release( p_vout );
586 - (IBAction)enableAdjust:(id)sender
588 BOOL b_state = [o_adjust_ckb state];
590 [self setVideoFilter: "adjust" on: b_state];
591 [o_adjust_brightness_sld setEnabled: b_state];
592 [o_adjust_brightness_ckb setEnabled: b_state];
593 [o_adjust_brightness_lbl setEnabled: b_state];
594 [o_adjust_contrast_sld setEnabled: b_state];
595 [o_adjust_contrast_lbl setEnabled: b_state];
596 [o_adjust_gamma_sld setEnabled: b_state];
597 [o_adjust_gamma_lbl setEnabled: b_state];
598 [o_adjust_hue_sld setEnabled: b_state];
599 [o_adjust_hue_lbl setEnabled: b_state];
600 [o_adjust_saturation_sld setEnabled: b_state];
601 [o_adjust_saturation_lbl setEnabled: b_state];
602 [o_adjust_reset_btn setEnabled: b_state];
605 - (IBAction)adjustSliderChanged:(id)sender
607 if( sender == o_adjust_brightness_sld )
608 [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: [o_adjust_brightness_sld floatValue]];
609 else if( sender == o_adjust_contrast_sld )
610 [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: [o_adjust_contrast_sld floatValue]];
611 else if( sender == o_adjust_gamma_sld )
612 [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: [o_adjust_gamma_sld floatValue]];
613 else if( sender == o_adjust_hue_sld )
614 [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: [o_adjust_hue_sld intValue]];
615 else if( sender == o_adjust_saturation_sld )
616 [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: [o_adjust_saturation_sld floatValue]];
618 if( sender == o_adjust_hue_sld )
619 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", [o_adjust_hue_sld intValue]]];
621 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
624 - (IBAction)enableAdjustBrightnessThreshold:(id)sender
626 if (sender == o_adjust_reset_btn)
628 [o_adjust_brightness_sld setFloatValue: 1.0];
629 [o_adjust_contrast_sld setFloatValue: 1.0];
630 [o_adjust_gamma_sld setFloatValue: 1.0];
631 [o_adjust_hue_sld setIntValue: 0];
632 [o_adjust_saturation_sld setFloatValue: 1.0];
633 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
634 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
635 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
636 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", 0]];
637 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
638 [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: 1.0];
639 [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: 1.0];
640 [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: 1.0];
641 [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: 0.0];
642 [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: 1.0];
645 config_PutInt( p_intf, "brightness-threshold", [o_adjust_brightness_ckb state] );
648 - (IBAction)enableSharpen:(id)sender
650 BOOL b_state = [o_sharpen_ckb state];
652 [self setVideoFilter: "sharpen" on: b_state];
653 [o_sharpen_sld setEnabled: b_state];
654 [o_sharpen_lbl setEnabled: b_state];
657 - (IBAction)sharpenSliderChanged:(id)sender
659 [self setVideoFilterProperty: "sharpen-sigma" forFilter: "sharpen" float: [sender floatValue]];
660 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
663 - (IBAction)enableBanding:(id)sender
665 BOOL b_state = [o_banding_ckb state];
667 [self setVideoFilter: "gradfun" on: b_state];
668 [o_banding_sld setEnabled: b_state];
669 [o_banding_lbl setEnabled: b_state];
672 - (IBAction)bandingSliderChanged:(id)sender
674 [self setVideoFilterProperty: "gradfun-radius" forFilter: "gradfun" integer: [sender intValue]];
675 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
678 - (IBAction)enableGrain:(id)sender
680 BOOL b_state = [o_grain_ckb state];
682 [self setVideoFilter: "grain" on: b_state];
683 [o_grain_sld setEnabled: b_state];
684 [o_grain_lbl setEnabled: b_state];
687 - (IBAction)grainSliderChanged:(id)sender
689 [self setVideoFilterProperty: "grain-variance" forFilter: "grain" float: [sender floatValue]];
690 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
697 #define updateopposite( giver, taker ) \
698 if (sender == giver) \
699 [taker setIntValue: [giver intValue]]
701 - (IBAction)cropObjectChanged:(id)sender
703 updateopposite( o_crop_top_fld, o_crop_top_stp );
704 updateopposite( o_crop_top_stp, o_crop_top_fld );
705 updateopposite( o_crop_left_fld, o_crop_left_stp );
706 updateopposite( o_crop_left_stp, o_crop_left_fld );
707 updateopposite( o_crop_right_fld, o_crop_right_stp );
708 updateopposite( o_crop_right_stp, o_crop_right_fld );
709 updateopposite( o_crop_bottom_fld, o_crop_bottom_stp );
710 updateopposite( o_crop_bottom_stp, o_crop_bottom_fld );
712 if( [o_crop_sync_top_bottom_ckb state] ) {
713 if (sender == o_crop_top_fld || sender == o_crop_top_stp ) {
714 [o_crop_bottom_fld setIntValue: [o_crop_top_fld intValue]];
715 [o_crop_bottom_stp setIntValue: [o_crop_top_fld intValue]];
719 [o_crop_top_fld setIntValue: [o_crop_bottom_fld intValue]];
720 [o_crop_top_stp setIntValue: [o_crop_bottom_fld intValue]];
723 if( [o_crop_sync_left_right_ckb state] ) {
724 if (sender == o_crop_left_fld || sender == o_crop_left_stp ) {
725 [o_crop_right_fld setIntValue: [o_crop_left_fld intValue]];
726 [o_crop_right_stp setIntValue: [o_crop_left_fld intValue]];
730 [o_crop_left_fld setIntValue: [o_crop_right_fld intValue]];
731 [o_crop_left_stp setIntValue: [o_crop_right_fld intValue]];
735 vout_thread_t *p_vout = getVout();
737 var_SetInteger( p_vout, "crop-top", [o_crop_top_fld intValue] );
738 var_SetInteger( p_vout, "crop-bottom", [o_crop_bottom_fld intValue] );
739 var_SetInteger( p_vout, "crop-left", [o_crop_left_fld intValue] );
740 var_SetInteger( p_vout, "crop-right", [o_crop_right_fld intValue] );
741 vlc_object_release( p_vout );
745 #undef updateopposite
748 #pragma mark geometry
749 - (IBAction)enableTransform:(id)sender
751 [self setVideoFilter: "transform" on: [o_transform_ckb state]];
752 [o_transform_pop setEnabled: [o_transform_ckb state]];
755 - (IBAction)transformModifierChanged:(id)sender
757 NSInteger tag = [[o_transform_pop selectedItem] tag];
758 char * psz_string = (char *)[[NSString stringWithFormat:@"%li", tag] UTF8String];
760 psz_string = (char *)"hflip";
762 psz_string = (char *)"vflip";
764 [self setVideoFilterProperty: "transform-type" forFilter: "transform" string: psz_string];
767 - (IBAction)enableZoom:(id)sender
769 [self setVideoFilter: "magnify" on: [o_zoom_ckb state]];
772 - (IBAction)enablePuzzle:(id)sender
774 BOOL b_state = [o_puzzle_ckb state];
776 [self setVideoFilter: "puzzle" on: b_state];
777 [o_puzzle_columns_fld setEnabled: b_state];
778 [o_puzzle_columns_lbl setEnabled: b_state];
779 [o_puzzle_rows_fld setEnabled: b_state];
780 [o_puzzle_rows_lbl setEnabled: b_state];
781 [o_puzzle_blackslot_ckb setEnabled: b_state];
784 - (IBAction)puzzleModifierChanged:(id)sender
786 if( sender == o_puzzle_blackslot_ckb )
787 [self setVideoFilterProperty: "puzzle-black-slot" forFilter: "puzzle" boolean: [o_puzzle_blackslot_ckb state]];
788 else if( sender == o_puzzle_columns_fld )
789 [self setVideoFilterProperty: "puzzle-cols" forFilter: "puzzle" integer: [o_puzzle_columns_fld intValue]];
791 [self setVideoFilterProperty: "puzzle-rows" forFilter: "puzzle" integer: [o_puzzle_rows_fld intValue]];
797 - (IBAction)enableThreshold:(id)sender
799 BOOL b_state = [o_threshold_ckb state];
801 [self setVideoFilter: "colorthres" on: b_state];
802 [o_threshold_color_fld setEnabled: b_state];
803 [o_threshold_color_lbl setEnabled: b_state];
804 [o_threshold_saturation_sld setEnabled: b_state];
805 [o_threshold_saturation_lbl setEnabled: b_state];
806 [o_threshold_similarity_sld setEnabled: b_state];
807 [o_threshold_similarity_lbl setEnabled: b_state];
810 - (IBAction)thresholdModifierChanged:(id)sender
812 if( sender == o_threshold_color_fld )
813 [self setVideoFilterProperty: "colorthres-color" forFilter: "colorthres" integer: [o_threshold_color_fld intValue]];
814 else if( sender == o_threshold_saturation_sld )
816 [self setVideoFilterProperty: "colorthres-saturationthres" forFilter: "colorthres" integer: [o_threshold_saturation_sld intValue]];
817 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_saturation_sld intValue]]];
821 [self setVideoFilterProperty: "colorthres-similaritythres" forFilter: "colorthres" integer: [o_threshold_similarity_sld intValue]];
822 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_similarity_sld intValue]]];
826 - (IBAction)enableSepia:(id)sender
828 BOOL b_state = [o_sepia_ckb state];
830 [self setVideoFilter: "sepia" on: b_state];
831 [o_sepia_fld setEnabled: b_state];
832 [o_sepia_lbl setEnabled: b_state];
835 - (IBAction)sepiaModifierChanged:(id)sender
837 [self setVideoFilterProperty: "sepia-intensity" forFilter: "sepia" integer: [o_sepia_fld intValue]];
840 - (IBAction)enableNoise:(id)sender
842 [self setVideoFilter: "noise" on: [o_noise_ckb state]];
845 - (IBAction)enableGradient:(id)sender
847 BOOL b_state = [o_gradient_ckb state];
849 [self setVideoFilter: "gradient" on: b_state];
850 [o_gradient_mode_pop setEnabled: b_state];
851 [o_gradient_mode_lbl setEnabled: b_state];
852 [o_gradient_color_ckb setEnabled: b_state];
853 [o_gradient_cartoon_ckb setEnabled: b_state];
856 - (IBAction)gradientModifierChanged:(id)sender
858 if( sender == o_gradient_mode_pop ) {
859 if( [[o_gradient_mode_pop selectedItem] tag] == 3 )
860 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "hough"];
861 else if( [[o_gradient_mode_pop selectedItem] tag] == 2 )
862 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "edge"];
864 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "gradient"];
866 else if( sender == o_gradient_color_ckb )
867 [self setVideoFilterProperty: "gradient-type" forFilter: "gradient" integer: [o_gradient_color_ckb state]];
869 [self setVideoFilterProperty: "gradient-cartoon" forFilter: "gradient" boolean: [o_gradient_cartoon_ckb state]];
872 - (IBAction)enableExtract:(id)sender
874 BOOL b_state = [o_extract_ckb state];
875 [self setVideoFilter: "extract" on: b_state];
876 [o_extract_fld setEnabled: b_state];
877 [o_extract_lbl setEnabled: b_state];
880 - (IBAction)extractModifierChanged:(id)sender
882 [self setVideoFilterProperty: "extract-component" forFilter: "extract" integer: [o_extract_fld intValue]];
885 - (IBAction)enableInvert:(id)sender
887 [self setVideoFilter: "invert" on: [o_invert_ckb state]];
890 - (IBAction)enablePosterize:(id)sender
892 BOOL b_state = [o_posterize_ckb state];
894 [self setVideoFilter: "posterize" on: b_state];
895 [o_posterize_fld setEnabled: b_state];
896 [o_posterize_lbl setEnabled: b_state];
899 - (IBAction)posterizeModifierChanged:(id)sender
901 [self setVideoFilterProperty: "posterize-level" forFilter: "posterize" integer: [o_posterize_fld intValue]];
904 - (IBAction)enableBlur:(id)sender
906 BOOL b_state = [o_blur_ckb state];
908 [self setVideoFilter: "motionblur" on: b_state];
909 [o_blur_sld setEnabled: b_state];
910 [o_blur_lbl setEnabled: b_state];
913 - (IBAction)blurModifierChanged:(id)sender
915 [self setVideoFilterProperty: "blur-factor" forFilter: "motionblur" integer: [sender intValue]];
916 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
919 - (IBAction)enableMotionDetect:(id)sender
921 [self setVideoFilter: "motiondetect" on: [o_motiondetect_ckb state]];
924 - (IBAction)enableWaterEffect:(id)sender
926 [self setVideoFilter: "ripple" on: [o_watereffect_ckb state]];
929 - (IBAction)enableWaves:(id)sender
931 [self setVideoFilter: "wave" on: [o_waves_ckb state]];
934 - (IBAction)enablePsychedelic:(id)sender
936 [self setVideoFilter: "psychedelic" on: [o_psychedelic_ckb state]];
940 #pragma mark Miscellaneous
941 - (IBAction)enableAddText:(id)sender
943 BOOL b_state = [o_addtext_ckb state];
945 [o_addtext_pos_pop setEnabled: b_state];
946 [o_addtext_pos_lbl setEnabled: b_state];
947 [o_addtext_text_lbl setEnabled: b_state];
948 [o_addtext_text_fld setEnabled: b_state];
949 [self setVideoFilter: "marq" on: b_state];
950 [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
951 [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
954 - (IBAction)addTextModifierChanged:(id)sender
956 if (sender == o_addtext_text_fld)
957 [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
959 [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
962 - (IBAction)enableAddLogo:(id)sender
964 BOOL b_state = [o_addlogo_ckb state];
966 [o_addlogo_pos_pop setEnabled: b_state];
967 [o_addlogo_pos_lbl setEnabled: b_state];
968 [o_addlogo_logo_fld setEnabled: b_state];
969 [o_addlogo_logo_lbl setEnabled: b_state];
970 [o_addlogo_transparency_sld setEnabled: b_state];
971 [o_addlogo_transparency_lbl setEnabled: b_state];
972 [self setVideoFilter: "logo" on: b_state];
975 - (IBAction)addLogoModifierChanged:(id)sender
977 if (sender == o_addlogo_logo_fld)
978 [self setVideoFilterProperty: "logo-file" forFilter: "logo" string: (char *)[[o_addlogo_logo_fld stringValue] UTF8String]];
979 else if (sender == o_addlogo_pos_pop)
980 [self setVideoFilterProperty: "logo-position" forFilter: "logo" integer: [[o_addlogo_pos_pop selectedItem] tag]];
983 [self setVideoFilterProperty: "logo-opacity" forFilter: "logo" integer: [o_addlogo_transparency_sld intValue]];
984 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%i", [o_addlogo_transparency_sld intValue]]];
988 - (IBAction)enableAnaglyph:(id)sender
990 [self setVideoFilter: "anaglyph" on: [o_anaglyph_ckb state]];