vout_intf.c 24 KB
Newer Older
gbazin's avatar
gbazin committed
1
2
3
/*****************************************************************************
 * vout_intf.c : video output interface
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2000-2007 VLC authors and VideoLAN
gbazin's avatar
gbazin committed
5
6
7
 *
 * Authors: Gildas Bazin <gbazin@videolan.org>
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
8
9
10
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
gbazin's avatar
gbazin committed
11
12
13
14
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
15
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
gbazin's avatar
gbazin committed
17
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
18
19
20
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
gbazin's avatar
gbazin committed
21
22
23
24
25
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
26

27
28
29
30
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

31
#include <vlc_common.h>
32
33

#include <stdio.h>
gbazin's avatar
gbazin committed
34
#include <stdlib.h>                                                /* free() */
35
#include <assert.h>
gbazin's avatar
gbazin committed
36

37
#include <vlc_block.h>
38
#include <vlc_modules.h>
gbazin's avatar
gbazin committed
39

zorglub's avatar
zorglub committed
40
#include <vlc_vout.h>
41
#include <vlc_vout_osd.h>
zorglub's avatar
zorglub committed
42
43
#include <vlc_strings.h>
#include <vlc_charset.h>
44
#include "vout_internal.h"
45

gbazin's avatar
gbazin committed
46
47
48
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
49
/* Object variables callbacks */
50
51
static int CropCallback( vlc_object_t *, char const *,
                         vlc_value_t, vlc_value_t, void * );
52
53
static int CropBorderCallback( vlc_object_t *, char const *,
                               vlc_value_t, vlc_value_t, void * );
54
55
static int AspectCallback( vlc_object_t *, char const *,
                           vlc_value_t, vlc_value_t, void * );
56
57
58
59
60
61
static int AutoScaleCallback( vlc_object_t *, char const *,
                              vlc_value_t, vlc_value_t, void * );
static int ScaleCallback( vlc_object_t *, char const *,
                          vlc_value_t, vlc_value_t, void * );
static int ZoomCallback( vlc_object_t *, char const *,
                         vlc_value_t, vlc_value_t, void * );
62
63
static int OnTopCallback( vlc_object_t *, char const *,
                          vlc_value_t, vlc_value_t, void * );
64
65
static int FullscreenCallback( vlc_object_t *, char const *,
                               vlc_value_t, vlc_value_t, void * );
66
67
static int SnapshotCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
68
69
static int VideoFilterCallback( vlc_object_t *, char const *,
                                vlc_value_t, vlc_value_t, void * );
70
static int SubSourceCallback( vlc_object_t *, char const *,
71
                              vlc_value_t, vlc_value_t, void * );
72
73
static int SubFilterCallback( vlc_object_t *, char const *,
                              vlc_value_t, vlc_value_t, void * );
Laurent Aimar's avatar
Laurent Aimar committed
74
75
static int SubMarginCallback( vlc_object_t *, char const *,
                              vlc_value_t, vlc_value_t, void * );
76
77
78
79

/*****************************************************************************
 * vout_IntfInit: called during the vout creation to initialise misc things.
 *****************************************************************************/
80
81
82
static const struct
{
    double f_value;
83
    char psz_label[13];
84
85
86
87
88
} p_zoom_values[] = {
    { 0.25, N_("1:4 Quarter") },
    { 0.5, N_("1:2 Half") },
    { 1, N_("1:1 Original") },
    { 2, N_("2:1 Double") },
89
};
90
91
92

static const struct
{
93
94
    char psz_value[8];
    char psz_label[8];
95
96
97
} p_crop_values[] = {
    { "", N_("Default") },
    { "16:10", "16:10" },
98
    { "16:9", "16:9" },
99
    { "185:100", "1.85:1" },
100
101
102
    { "221:100", "2.21:1" },
    { "235:100", "2.35:1" },
    { "239:100", "2.39:1" },
103
104
105
106
    { "5:3", "5:3" },
    { "4:3", "4:3" },
    { "5:4", "5:4" },
    { "1:1", "1:1" },
107
};
108
109
110

static const struct
{
111
112
    char psz_value[8];
    char psz_label[8];
113
114
115
116
117
118
119
} p_aspect_ratio_values[] = {
    { "", N_("Default") },
    { "1:1", "1:1" },
    { "4:3", "4:3" },
    { "16:9", "16:9" },
    { "16:10", "16:10" },
    { "221:100", "2.21:1" },
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
120
121
    { "235:100", "2.35:1" },
    { "239:100", "2.39:1" },
122
    { "5:4", "5:4" },
123
};
124
125
126
127

static void AddCustomRatios( vout_thread_t *p_vout, const char *psz_var,
                             char *psz_list )
{
128
129
130
131
132
    assert( psz_list );

    char *psz_cur = psz_list;
    char *psz_next;
    while( psz_cur && *psz_cur )
133
    {
134
135
136
        vlc_value_t val, text;
        psz_next = strchr( psz_cur, ',' );
        if( psz_next )
137
        {
138
139
            *psz_next = '\0';
            psz_next++;
140
        }
141
142
143
144
        val.psz_string = psz_cur;
        text.psz_string = psz_cur;
        var_Change( p_vout, psz_var, VLC_VAR_ADDCHOICE, &val, &text);
        psz_cur = psz_next;
145
146
147
    }
}

148
149
150
void vout_IntfInit( vout_thread_t *p_vout )
{
    vlc_value_t val, text, old_val;
151
    char *psz_buf;
152
153

    /* Create a few object variables we'll need later on */
154
155
156
    var_Create( p_vout, "snapshot-num", VLC_VAR_INTEGER );
    var_SetInteger( p_vout, "snapshot-num", 1 );

157
158
    var_Create( p_vout, "width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
    var_Create( p_vout, "height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
159
    var_Create( p_vout, "align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
160

161
162
163
    var_Create( p_vout, "video-x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
    var_Create( p_vout, "video-y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );

164
165
    var_Create( p_vout, "mouse-hide-timeout",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
166

167
168
169
170
171
    /* Add variables to manage scaling video */
    var_Create( p_vout, "autoscale", VLC_VAR_BOOL | VLC_VAR_DOINHERIT
                | VLC_VAR_ISCOMMAND );
    text.psz_string = _("Autoscale video");
    var_Change( p_vout, "autoscale", VLC_VAR_SETTEXT, &text, NULL );
172
    var_AddCallback( p_vout, "autoscale", AutoScaleCallback, NULL );
173
174
175
176
177

    var_Create( p_vout, "scale", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT
                | VLC_VAR_ISCOMMAND );
    text.psz_string = _("Scale factor");
    var_Change( p_vout, "scale", VLC_VAR_SETTEXT, &text, NULL );
178
    var_AddCallback( p_vout, "scale", ScaleCallback, NULL );
179

180
    /* Zoom object var */
181
182
183
184
185
    var_Create( p_vout, "zoom", VLC_VAR_FLOAT | VLC_VAR_ISCOMMAND |
                VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT );

    text.psz_string = _("Zoom");
    var_Change( p_vout, "zoom", VLC_VAR_SETTEXT, &text, NULL );
186
    old_val.f_float = var_GetFloat( p_vout, "zoom" );
187

188
    for( size_t i = 0; i < ARRAY_SIZE(p_zoom_values); i++ )
189
    {
190
        val.f_float = p_zoom_values[i].f_value;
191
192
193
194
195
        text.psz_string = vlc_gettext( p_zoom_values[i].psz_label );
        /* FIXME: This DELCHOICE hack corrupts the the "zoom" variable value
         * for a short time window. Same for "crop" and "aspect-ratio". */
        if( old_val.f_float == val.f_float )
            var_Change( p_vout, "zoom", VLC_VAR_DELCHOICE, &old_val, NULL );
196
        var_Change( p_vout, "zoom", VLC_VAR_ADDCHOICE, &val, &text );
197
198
        if( old_val.f_float == val.f_float )
            var_Change( p_vout, "zoom", VLC_VAR_SETVALUE, &old_val, NULL );
199
200
201
    }

    var_AddCallback( p_vout, "zoom", ZoomCallback, NULL );
202

203
    /* Crop offset vars */
204
205
206
207
    var_Create( p_vout, "crop-left", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
    var_Create( p_vout, "crop-top", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
    var_Create( p_vout, "crop-right", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
    var_Create( p_vout, "crop-bottom", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
208

209
210
211
212
    var_AddCallback( p_vout, "crop-left", CropBorderCallback, NULL );
    var_AddCallback( p_vout, "crop-top", CropBorderCallback, NULL );
    var_AddCallback( p_vout, "crop-right", CropBorderCallback, NULL );
    var_AddCallback( p_vout, "crop-bottom", CropBorderCallback, NULL );
213

214
    /* Crop object var */
215
    var_Create( p_vout, "crop", VLC_VAR_STRING | VLC_VAR_ISCOMMAND |
216
217
218
219
220
                VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT );

    text.psz_string = _("Crop");
    var_Change( p_vout, "crop", VLC_VAR_SETTEXT, &text, NULL );

221
    val.psz_string = (char*)"";
222
223
    var_Change( p_vout, "crop", VLC_VAR_DELCHOICE, &val, 0 );

224
    for( size_t i = 0; i < ARRAY_SIZE(p_crop_values); i++ )
225
    {
226
227
228
        val.psz_string = (char*)p_crop_values[i].psz_value;
        text.psz_string = _( p_crop_values[i].psz_label );
        var_Change( p_vout, "crop", VLC_VAR_ADDCHOICE, &val, &text );
229
    }
230
231

    /* Add custom crop ratios */
232
233
234
235
236
237
    psz_buf = var_CreateGetNonEmptyString( p_vout, "custom-crop-ratios" );
    if( psz_buf )
    {
        AddCustomRatios( p_vout, "crop", psz_buf );
        free( psz_buf );
    }
238

239
    var_AddCallback( p_vout, "crop", CropCallback, NULL );
240
241

    /* Monitor pixel aspect-ratio */
242
    var_Create( p_vout, "monitor-par", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
243
244

    /* Aspect-ratio object var */
245
    var_Create( p_vout, "aspect-ratio", VLC_VAR_STRING | VLC_VAR_ISCOMMAND |
246
247
                VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT );

Christoph Miebach's avatar
Christoph Miebach committed
248
    text.psz_string = _("Aspect ratio");
249
250
    var_Change( p_vout, "aspect-ratio", VLC_VAR_SETTEXT, &text, NULL );

251
    val.psz_string = (char*)"";
252
253
    var_Change( p_vout, "aspect-ratio", VLC_VAR_DELCHOICE, &val, 0 );

254
    for( size_t i = 0; i < ARRAY_SIZE(p_aspect_ratio_values); i++ )
255
    {
256
257
258
        val.psz_string = (char*)p_aspect_ratio_values[i].psz_value;
        text.psz_string = _( p_aspect_ratio_values[i].psz_label );
        var_Change( p_vout, "aspect-ratio", VLC_VAR_ADDCHOICE, &val, &text );
259
    }
260
261

    /* Add custom aspect ratios */
262
263
264
265
266
267
    psz_buf = var_CreateGetNonEmptyString( p_vout, "custom-aspect-ratios" );
    if( psz_buf )
    {
        AddCustomRatios( p_vout, "aspect-ratio", psz_buf );
        free( psz_buf );
    }
268

269
    var_AddCallback( p_vout, "aspect-ratio", AspectCallback, NULL );
270

271
    /* Add a variable to indicate if the window should be on top of others */
272
273
    var_Create( p_vout, "video-on-top", VLC_VAR_BOOL | VLC_VAR_DOINHERIT
                | VLC_VAR_ISCOMMAND );
274
275
276
    text.psz_string = _("Always on top");
    var_Change( p_vout, "video-on-top", VLC_VAR_SETTEXT, &text, NULL );
    var_AddCallback( p_vout, "video-on-top", OnTopCallback, NULL );
277

278
279
280
    /* Add a variable to indicate whether we want window decoration or not */
    var_Create( p_vout, "video-deco", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );

281
    /* Add a fullscreen variable */
282
283
    var_Create( p_vout, "fullscreen",
                VLC_VAR_BOOL | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );
284
285
    text.psz_string = _("Fullscreen");
    var_Change( p_vout, "fullscreen", VLC_VAR_SETTEXT, &text, NULL );
286
    var_AddCallback( p_vout, "fullscreen", FullscreenCallback, NULL );
287

288
289
290
291
292
293
    /* Add a snapshot variable */
    var_Create( p_vout, "video-snapshot", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
    text.psz_string = _("Snapshot");
    var_Change( p_vout, "video-snapshot", VLC_VAR_SETTEXT, &text, NULL );
    var_AddCallback( p_vout, "video-snapshot", SnapshotCallback, NULL );

294
295
296
297
298
    /* Add a video-filter variable */
    var_Create( p_vout, "video-filter",
                VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );
    var_AddCallback( p_vout, "video-filter", VideoFilterCallback, NULL );

299
300
    /* Add a sub-source variable */
    var_Create( p_vout, "sub-source",
301
                VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );
302
    var_AddCallback( p_vout, "sub-source", SubSourceCallback, NULL );
303

304
305
306
307
308
    /* Add a sub-filter variable */
    var_Create( p_vout, "sub-filter",
                VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );
    var_AddCallback( p_vout, "sub-filter", SubFilterCallback, NULL );

Laurent Aimar's avatar
Laurent Aimar committed
309
310
311
312
313
    /* Add sub-margin variable */
    var_Create( p_vout, "sub-margin",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );
    var_AddCallback( p_vout, "sub-margin", SubMarginCallback, NULL );

314
315
    /* Mouse coordinates */
    var_Create( p_vout, "mouse-button-down", VLC_VAR_INTEGER );
316
317
    var_Create( p_vout, "mouse-moved", VLC_VAR_COORDS );
    var_Create( p_vout, "mouse-clicked", VLC_VAR_COORDS );
318
    var_Create( p_vout, "mouse-object", VLC_VAR_BOOL );
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

    vout_IntfReinit( p_vout );
}

void vout_IntfReinit( vout_thread_t *p_vout )
{
    var_TriggerCallback( p_vout, "zoom" );
    var_TriggerCallback( p_vout, "crop" );
    var_TriggerCallback( p_vout, "aspect-ratio" );

    var_TriggerCallback( p_vout, "video-on-top" );

    var_TriggerCallback( p_vout, "video-filter" );
    var_TriggerCallback( p_vout, "sub-source" );
    var_TriggerCallback( p_vout, "sub-filter" );
    var_TriggerCallback( p_vout, "sub-margin" );
335
336
}

337
338
339
/*****************************************************************************
 * vout_Snapshot: generates a snapshot.
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
340
341
342
343
/**
 * This function will inject a subpicture into the vout with the provided
 * picture
 */
344
static int VoutSnapshotPip( vout_thread_t *p_vout, picture_t *p_pic )
Laurent Aimar's avatar
Laurent Aimar committed
345
{
346
347
    subpicture_t *p_subpic = subpicture_NewFromPicture( VLC_OBJECT(p_vout),
                                                        p_pic, VLC_CODEC_YUVA );
348
    if( !p_subpic )
349
        return VLC_EGENERIC;
Laurent Aimar's avatar
Laurent Aimar committed
350

Laurent Aimar's avatar
Laurent Aimar committed
351
    /* FIXME SPU_DEFAULT_CHANNEL is not good (used by the text) but
352
     * hardcoded 0 doesn't seem right */
Laurent Aimar's avatar
Laurent Aimar committed
353
354
    p_subpic->i_channel = 0;
    p_subpic->i_start = mdate();
355
    p_subpic->i_stop  = p_subpic->i_start + 4000000;
Laurent Aimar's avatar
Laurent Aimar committed
356
357
    p_subpic->b_ephemer = true;
    p_subpic->b_fade = true;
358
359
360
361

    /* Reduce the picture to 1/4^2 of the screen */
    p_subpic->i_original_picture_width  *= 4;
    p_subpic->i_original_picture_height *= 4;
Laurent Aimar's avatar
Laurent Aimar committed
362

363
    vout_PutSubpicture( p_vout, p_subpic );
Laurent Aimar's avatar
Laurent Aimar committed
364
365
    return VLC_SUCCESS;
}
Laurent Aimar's avatar
Laurent Aimar committed
366
367
368
369
370
371
372

/**
 * This function will display the name and a PIP of the provided snapshot
 */
static void VoutOsdSnapshot( vout_thread_t *p_vout, picture_t *p_pic, const char *psz_filename )
{
    msg_Dbg( p_vout, "snapshot taken (%s)", psz_filename );
373
    vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", psz_filename );
374

375
    if( var_InheritBool( p_vout, "snapshot-preview" ) )
376
    {
377
        if( VoutSnapshotPip( p_vout, p_pic ) )
Laurent Aimar's avatar
Laurent Aimar committed
378
            msg_Warn( p_vout, "Failed to display snapshot" );
379
    }
380
}
381

Laurent Aimar's avatar
Laurent Aimar committed
382
383
384
/**
 * This function will handle a snapshot request
 */
385
386
static void VoutSaveSnapshot( vout_thread_t *p_vout )
{
387
388
389
    char *psz_path = var_InheritString( p_vout, "snapshot-path" );
    char *psz_format = var_InheritString( p_vout, "snapshot-format" );
    char *psz_prefix = var_InheritString( p_vout, "snapshot-prefix" );
390

Laurent Aimar's avatar
Laurent Aimar committed
391
392
393
394
395
396
397
    /* */
    picture_t *p_picture;
    block_t *p_image;
    video_format_t fmt;

    /* 500ms timeout
     * XXX it will cause trouble with low fps video (< 2fps) */
398
    if( vout_GetSnapshot( p_vout, &p_image, &p_picture, &fmt, psz_format, 500*1000 ) )
399
    {
Laurent Aimar's avatar
Laurent Aimar committed
400
401
402
403
404
        p_picture = NULL;
        p_image = NULL;
        goto exit;
    }

405
    if( !psz_path )
Laurent Aimar's avatar
Laurent Aimar committed
406
    {
407
        psz_path = vout_snapshot_GetDirectory();
Laurent Aimar's avatar
Laurent Aimar committed
408
409
        if( !psz_path )
        {
410
411
            msg_Err( p_vout, "no path specified for snapshots" );
            goto exit;
Laurent Aimar's avatar
Laurent Aimar committed
412
        }
413
    }
Laurent Aimar's avatar
Laurent Aimar committed
414

415
416
    vout_snapshot_save_cfg_t cfg;
    memset( &cfg, 0, sizeof(cfg) );
417
    cfg.is_sequential = var_InheritBool( p_vout, "snapshot-sequential" );
418
419
420
421
422
    cfg.sequence = var_GetInteger( p_vout, "snapshot-num" );
    cfg.path = psz_path;
    cfg.format = psz_format;
    cfg.prefix_fmt = psz_prefix;

423
    char *psz_filename;
424
425
426
    int  i_sequence;
    if (vout_snapshot_SaveImage( &psz_filename, &i_sequence,
                                 p_image, VLC_OBJECT(p_vout), &cfg ) )
427
        goto exit;
428
429
    if( cfg.is_sequential )
        var_SetInteger( p_vout, "snapshot-num", i_sequence + 1 );
Laurent Aimar's avatar
Laurent Aimar committed
430

431
    VoutOsdSnapshot( p_vout, p_picture, psz_filename );
Laurent Aimar's avatar
Laurent Aimar committed
432

433
434
435
    /* signal creation of a new snapshot file */
    var_SetString( p_vout->p_libvlc, "snapshot-file", psz_filename );

436
    free( psz_filename );
Laurent Aimar's avatar
Laurent Aimar committed
437
438
439
440
441
442
443
444
445

exit:
    if( p_image )
        block_Release( p_image );
    if( p_picture )
        picture_Release( p_picture );
    free( psz_prefix );
    free( psz_format );
    free( psz_path );
446
447
}

448
449
450
451
/*****************************************************************************
 * Handle filters
 *****************************************************************************/

452
void vout_EnableFilter( vout_thread_t *p_vout, const char *psz_name,
453
                        bool b_add, bool b_setconfig )
454
455
{
    char *psz_parser;
456
457
458
    char *psz_string;
    const char *psz_filter_type;

459
    module_t *p_obj = module_find( psz_name );
460
461
462
463
464
465
    if( !p_obj )
    {
        msg_Err( p_vout, "Unable to find filter module \"%s\".", psz_name );
        return;
    }

466
    if( module_provides( p_obj, "video filter2" ) )
467
468
469
    {
        psz_filter_type = "video-filter";
    }
470
    else if( module_provides( p_obj, "sub source" ) )
471
    {
472
        psz_filter_type = "sub-source";
473
    }
474
475
476
477
    else if( module_provides( p_obj, "sub filter" ) )
    {
        psz_filter_type = "sub-filter";
    }
478
479
480
481
482
483
    else
    {
        msg_Err( p_vout, "Unknown video filter type." );
        return;
    }

484
    psz_string = var_GetString( p_vout, psz_filter_type );
485
486
487
488
489
490
491
492
493
494

    /* Todo : Use some generic chain manipulation functions */
    if( !psz_string ) psz_string = strdup("");

    psz_parser = strstr( psz_string, psz_name );
    if( b_add )
    {
        if( !psz_parser )
        {
            psz_parser = psz_string;
495
496
497
498
499
500
            if( asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
                          psz_string, psz_name ) == -1 )
            {
                free( psz_parser );
                return;
            }
501
502
503
            free( psz_parser );
        }
        else
ivoire's avatar
ivoire committed
504
505
        {
            free( psz_string );
506
            return;
ivoire's avatar
ivoire committed
507
        }
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
    }
    else
    {
        if( psz_parser )
        {
            memmove( psz_parser, psz_parser + strlen(psz_name) +
                            (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
                            strlen(psz_parser + strlen(psz_name)) + 1 );

            /* Remove trailing : : */
            if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
            {
                *(psz_string+strlen(psz_string ) -1 ) = '\0';
            }
         }
         else
         {
             free( psz_string );
             return;
         }
    }
529

530
    if( b_setconfig )
531
    {
532
        config_PutPsz( p_vout, psz_filter_type, psz_string );
533
534
    }

535
    var_SetString( p_vout, psz_filter_type, psz_string );
536
537
538
539

    free( psz_string );
}

540
541
542
/*****************************************************************************
 * Object variables callbacks
 *****************************************************************************/
543
544
static int CropCallback( vlc_object_t *object, char const *cmd,
                         vlc_value_t oldval, vlc_value_t newval, void *data )
545
{
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
    vout_thread_t *vout = (vout_thread_t *)object;
    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data);
    unsigned num, den;
    unsigned y, x;
    unsigned width, height;
    unsigned left, top, right, bottom;

    if (sscanf(newval.psz_string, "%u:%u", &num, &den) == 2) {
        vout_ControlChangeCropRatio(vout, num, den);
    } else if (sscanf(newval.psz_string, "%ux%u+%u+%u",
                      &width, &height, &x, &y) == 4) {
        vout_ControlChangeCropWindow(vout, x, y, width, height);
    } else if (sscanf(newval.psz_string, "%u+%u+%u+%u",
                    &left, &top, &right, &bottom) == 4) {
        vout_ControlChangeCropBorder(vout, left, top, right, bottom);
    } else if (*newval.psz_string == '\0') {
        vout_ControlChangeCropRatio(vout, 0, 0);
    } else {
        msg_Err(object, "Unknown crop format (%s)", newval.psz_string);
565
566
567
568
    }
    return VLC_SUCCESS;
}

569
570
static int CropBorderCallback(vlc_object_t *object, char const *cmd,
                              vlc_value_t oldval, vlc_value_t newval, void *data)
571
{
572
573
574
575
576
577
578
579
580
581
    vout_thread_t *vout = (vout_thread_t *)object;
    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data); VLC_UNUSED(newval);

    vout_ControlChangeCropBorder(vout,
                                 var_GetInteger(object, "crop-left"),
                                 var_GetInteger(object, "crop-top"),
                                 var_GetInteger(object, "crop-right"),
                                 var_GetInteger(object, "crop-bottom"));
    return VLC_SUCCESS;
}
582

583
584
585
586
587
588
589
590
591
592
593
594
595
static int AspectCallback( vlc_object_t *object, char const *cmd,
                         vlc_value_t oldval, vlc_value_t newval, void *data )
{
    vout_thread_t *vout = (vout_thread_t *)object;
    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data);
    unsigned num, den;

    if (sscanf(newval.psz_string, "%u:%u", &num, &den) == 2 &&
        (num > 0) == (den > 0))
        vout_ControlChangeSampleAspectRatio(vout, num, den);
    else if (*newval.psz_string == '\0')
        vout_ControlChangeSampleAspectRatio(vout, 0, 0);
    return VLC_SUCCESS;
596
597
}

598
599
static int AutoScaleCallback( vlc_object_t *obj, char const *name,
                              vlc_value_t prev, vlc_value_t cur, void *data )
600
{
601
602
603
604
605
606
    vout_thread_t *p_vout = (vout_thread_t *)obj;

    (void) name; (void) prev; (void) data;
    vout_ControlChangeDisplayFilled( p_vout, cur.b_bool );
    return VLC_SUCCESS;
}
607

608
609
610
611
static int ScaleCallback( vlc_object_t *obj, char const *name,
                          vlc_value_t prev, vlc_value_t cur, void *data )
{
    vout_thread_t *p_vout = (vout_thread_t *)obj;
612

613
614
    (void) name; (void) prev; (void) data;
    vout_ControlChangeZoom( p_vout, 1000 * cur.f_float, 1000 );
615
    return VLC_SUCCESS;
616
617
}

618
619
620
621
622
623
624
static int ZoomCallback( vlc_object_t *obj, char const *name,
                         vlc_value_t prev, vlc_value_t cur, void *data )
{
    (void) name; (void) prev; (void) data;
    return var_SetFloat( obj, "scale", cur.f_float );
}

625
626
627
628
static int OnTopCallback( vlc_object_t *p_this, char const *psz_cmd,
                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
629
    (void)psz_cmd; (void)oldval; (void)p_data;
630
631

    vout_ControlChangeOnTop( p_vout, newval.b_bool );
632
633
    return VLC_SUCCESS;
}
634
635
636
637
638

static int FullscreenCallback( vlc_object_t *p_this, char const *psz_cmd,
                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
639
    (void)psz_cmd; (void)p_data;
640

641
642
    if( oldval.b_bool != newval.b_bool )
        vout_ControlChangeFullscreen( p_vout, newval.b_bool );
643
644
    return VLC_SUCCESS;
}
645
646
647
648

static int SnapshotCallback( vlc_object_t *p_this, char const *psz_cmd,
                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
649
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
650
651
    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
    VLC_UNUSED(newval); VLC_UNUSED(p_data);
652
653

    VoutSaveSnapshot( p_vout );
654
655
    return VLC_SUCCESS;
}
656

657
658
659
660
661
662
663
664
665
666
static int VideoFilterCallback( vlc_object_t *p_this, char const *psz_cmd,
                                vlc_value_t oldval, vlc_value_t newval, void *p_data)
{
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);

    vout_ControlChangeFilters( p_vout, newval.psz_string );
    return VLC_SUCCESS;
}

667
static int SubSourceCallback( vlc_object_t *p_this, char const *psz_cmd,
668
669
670
671
672
                              vlc_value_t oldval, vlc_value_t newval, void *p_data)
{
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);

673
    vout_ControlChangeSubSources( p_vout, newval.psz_string );
674
675
676
    return VLC_SUCCESS;
}

677
678
679
680
681
682
683
684
685
686
static int SubFilterCallback( vlc_object_t *p_this, char const *psz_cmd,
                              vlc_value_t oldval, vlc_value_t newval, void *p_data)
{
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);

    vout_ControlChangeSubFilters( p_vout, newval.psz_string );
    return VLC_SUCCESS;
}

Laurent Aimar's avatar
Laurent Aimar committed
687
688
689
690
691
692
693
694
695
696
static int SubMarginCallback( vlc_object_t *p_this, char const *psz_cmd,
                              vlc_value_t oldval, vlc_value_t newval, void *p_data)
{
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);

    vout_ControlChangeSubMargin( p_vout, newval.i_int );
    return VLC_SUCCESS;
}