~ubuntu-branches/ubuntu/natty/vlc/natty

« back to all changes in this revision

Viewing changes to src/video_output/vout_intf.c

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2010-06-25 01:09:16 UTC
  • mfrom: (1.1.30 upstream)
  • Revision ID: james.westby@ubuntu.com-20100625010916-asxhep2mutg6g6pd
Tags: 1.1.0-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - build and install the libx264 plugin
  - add Xb-Npp header to vlc package
  - Add apport hook to include more vlc dependencies in bug reports
* Drop xulrunner patches.
* Drop 502_xulrunner_191.diff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <stdio.h>
34
34
#include <stdlib.h>                                                /* free() */
35
35
#include <sys/types.h>                                          /* opendir() */
36
 
#include <sys/stat.h>
37
36
#include <dirent.h>                                             /* opendir() */
38
37
#include <assert.h>
39
38
#include <time.h>                                           /* strftime */
43
42
#include <vlc_playlist.h>
44
43
 
45
44
#include <vlc_vout.h>
46
 
#include <vlc_window.h>
47
45
#include <vlc_image.h>
48
46
#include <vlc_osd.h>
49
 
#include <vlc_charset.h>
50
 
 
51
47
#include <vlc_strings.h>
52
48
#include <vlc_charset.h>
53
49
#include "../libvlc.h"
81
77
static int TitlePositionCallback( vlc_object_t *, char const *,
82
78
                                  vlc_value_t, vlc_value_t, void * );
83
79
 
84
 
/**
85
 
 * Creates a video output window.
86
 
 * On Unix systems, this is an X11 drawable (handle).
87
 
 * On Windows, this is a Win32 window (handle).
88
 
 * Video output plugins are supposed to called this function and display the
89
 
 * video within the resulting window, while in windowed mode.
90
 
 *
91
 
 * @param p_vout video output thread to create a window for
92
 
 * @param psz_cap VLC module capability (window system type)
93
 
 * @param pi_x_hint pointer to store the recommended horizontal position [OUT]
94
 
 * @param pi_y_hint pointer to store the recommended vertical position [OUT]
95
 
 * @param pi_width_hint pointer to store the recommended width [OUT]
96
 
 * @param pi_height_hint pointer to store the recommended height [OUT]
97
 
 *
98
 
 * @return a vout_window_t object, or NULL in case of failure.
99
 
 * The window is released with vout_ReleaseWindow().
100
 
 */
101
 
vout_window_t *vout_RequestWindow( vout_thread_t *p_vout, const char *psz_cap,
102
 
                          int *pi_x_hint, int *pi_y_hint,
103
 
                          unsigned int *pi_width_hint,
104
 
                          unsigned int *pi_height_hint )
105
 
{
106
 
    /* Get requested coordinates */
107
 
    *pi_x_hint = var_GetInteger( p_vout, "video-x" );
108
 
    *pi_y_hint = var_GetInteger( p_vout, "video-y" );
109
 
 
110
 
    *pi_width_hint = p_vout->i_window_width;
111
 
    *pi_height_hint = p_vout->i_window_height;
112
 
 
113
 
    vout_window_t *wnd = vlc_custom_create (VLC_OBJECT(p_vout), sizeof (*wnd),
114
 
                                            VLC_OBJECT_GENERIC, "window");
115
 
    if (wnd == NULL)
116
 
        return NULL;
117
 
 
118
 
    wnd->vout = p_vout;
119
 
    wnd->width = *pi_width_hint;
120
 
    wnd->height = *pi_height_hint;
121
 
    wnd->pos_x = *pi_x_hint;
122
 
    wnd->pos_y = *pi_y_hint;
123
 
    vlc_object_attach (wnd, p_vout);
124
 
 
125
 
    wnd->module = module_need (wnd, psz_cap, NULL, false);
126
 
    if (wnd->module == NULL)
127
 
    {
128
 
        msg_Dbg (wnd, "no \"%s\" window provider available", psz_cap);
129
 
        vlc_object_release (wnd);
130
 
        return NULL;
131
 
    }
132
 
    *pi_width_hint = wnd->width;
133
 
    *pi_height_hint = wnd->height;
134
 
    *pi_x_hint = wnd->pos_x;
135
 
    *pi_y_hint = wnd->pos_y;
136
 
    return wnd;
137
 
}
138
 
 
139
 
/**
140
 
 * Releases a window handle obtained with vout_RequestWindow().
141
 
 * @param p_vout video output thread that allocated the window
142
 
 *               (if this is NULL; this fnction is a no-op).
143
 
 */
144
 
void vout_ReleaseWindow( vout_window_t *wnd )
145
 
{
146
 
    if (wnd == NULL)
147
 
        return;
148
 
 
149
 
    assert (wnd->module);
150
 
    module_unneed (wnd, wnd->module);
151
 
 
152
 
    vlc_object_release (wnd);
153
 
}
154
 
 
155
 
int vout_ControlWindow( vout_window_t *wnd, int i_query, va_list args )
156
 
{
157
 
    if (wnd == NULL)
158
 
        return VLC_EGENERIC;
159
 
 
160
 
    assert (wnd->control);
161
 
    return wnd->control (wnd, i_query, args);
162
 
}
163
 
 
164
80
/*****************************************************************************
165
81
 * vout_IntfInit: called during the vout creation to initialise misc things.
166
82
 *****************************************************************************/
204
120
    { "16:9", "16:9" },
205
121
    { "16:10", "16:10" },
206
122
    { "221:100", "2.21:1" },
 
123
    { "235:100", "2.35:1" },
 
124
    { "239:100", "2.39:1" },
207
125
    { "5:4", "5:4" },
208
126
    { NULL, NULL } };
209
127
 
210
128
static void AddCustomRatios( vout_thread_t *p_vout, const char *psz_var,
211
129
                             char *psz_list )
212
130
{
213
 
    if( psz_list && *psz_list )
 
131
    assert( psz_list );
 
132
 
 
133
    char *psz_cur = psz_list;
 
134
    char *psz_next;
 
135
    while( psz_cur && *psz_cur )
214
136
    {
215
 
        char *psz_cur = psz_list;
216
 
        char *psz_next;
217
 
        while( psz_cur && *psz_cur )
 
137
        vlc_value_t val, text;
 
138
        psz_next = strchr( psz_cur, ',' );
 
139
        if( psz_next )
218
140
        {
219
 
            vlc_value_t val, text;
220
 
            psz_next = strchr( psz_cur, ',' );
221
 
            if( psz_next )
222
 
            {
223
 
                *psz_next = '\0';
224
 
                psz_next++;
225
 
            }
226
 
            val.psz_string = psz_cur;
227
 
            text.psz_string = psz_cur;
228
 
            var_Change( p_vout, psz_var, VLC_VAR_ADDCHOICE, &val, &text);
229
 
            psz_cur = psz_next;
 
141
            *psz_next = '\0';
 
142
            psz_next++;
230
143
        }
 
144
        val.psz_string = psz_cur;
 
145
        text.psz_string = psz_cur;
 
146
        var_Change( p_vout, psz_var, VLC_VAR_ADDCHOICE, &val, &text);
 
147
        psz_cur = psz_next;
231
148
    }
232
149
}
233
150
 
325
242
    var_Create( p_vout, "crop-update", VLC_VAR_VOID );
326
243
 
327
244
    /* Add custom crop ratios */
328
 
    psz_buf = config_GetPsz( p_vout, "custom-crop-ratios" );
329
 
    AddCustomRatios( p_vout, "crop", psz_buf );
330
 
    free( psz_buf );
 
245
    psz_buf = var_CreateGetNonEmptyString( p_vout, "custom-crop-ratios" );
 
246
    if( psz_buf )
 
247
    {
 
248
        AddCustomRatios( p_vout, "crop", psz_buf );
 
249
        free( psz_buf );
 
250
    }
331
251
 
332
252
    var_AddCallback( p_vout, "crop", CropCallback, NULL );
333
253
    var_Get( p_vout, "crop", &old_val );
386
306
    }
387
307
 
388
308
    /* Add custom aspect ratios */
389
 
    psz_buf = config_GetPsz( p_vout, "custom-aspect-ratios" );
390
 
    AddCustomRatios( p_vout, "aspect-ratio", psz_buf );
391
 
    free( psz_buf );
 
309
    psz_buf = var_CreateGetNonEmptyString( p_vout, "custom-aspect-ratios" );
 
310
    if( psz_buf )
 
311
    {
 
312
        AddCustomRatios( p_vout, "aspect-ratio", psz_buf );
 
313
        free( psz_buf );
 
314
    }
392
315
 
393
316
    var_AddCallback( p_vout, "aspect-ratio", AspectCallback, NULL );
394
317
    var_Get( p_vout, "aspect-ratio", &old_val );
442
365
    var_AddCallback( p_vout, "video-snapshot", SnapshotCallback, NULL );
443
366
 
444
367
    /* Mouse coordinates */
445
 
    var_Create( p_vout, "mouse-x", VLC_VAR_INTEGER );
446
 
    var_Create( p_vout, "mouse-y", VLC_VAR_INTEGER );
447
368
    var_Create( p_vout, "mouse-button-down", VLC_VAR_INTEGER );
448
 
    var_Create( p_vout, "mouse-moved", VLC_VAR_BOOL );
449
 
    var_Create( p_vout, "mouse-clicked", VLC_VAR_BOOL );
 
369
    var_Create( p_vout, "mouse-moved", VLC_VAR_COORDS );
 
370
    var_Create( p_vout, "mouse-clicked", VLC_VAR_COORDS );
 
371
    var_Create( p_vout, "mouse-object", VLC_VAR_BOOL );
450
372
 
451
373
    var_Create( p_vout, "intf-change", VLC_VAR_BOOL );
452
374
    var_SetBool( p_vout, "intf-change", true );
461
383
 */
462
384
static int VoutSnapshotPip( vout_thread_t *p_vout, picture_t *p_pic )
463
385
{
464
 
    video_format_t fmt_in = p_pic->format;
465
 
    video_format_t fmt_out;
466
 
    picture_t *p_pip;
467
 
    subpicture_t *p_subpic;
468
 
 
469
 
    /* */
470
 
    memset( &fmt_out, 0, sizeof(fmt_out) );
471
 
    fmt_out = fmt_in;
472
 
    fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
473
 
 
474
 
    /* */
475
 
    image_handler_t *p_image = image_HandlerCreate( p_vout );
476
 
    if( !p_image )
477
 
        return VLC_EGENERIC;
478
 
 
479
 
    p_pip = image_Convert( p_image, p_pic, &fmt_in, &fmt_out );
480
 
 
481
 
    image_HandlerDelete( p_image );
482
 
 
483
 
    if( !p_pip )
484
 
        return VLC_EGENERIC;
485
 
 
486
 
    p_subpic = subpicture_New();
 
386
    subpicture_t *p_subpic = subpicture_NewFromPicture( VLC_OBJECT(p_vout),
 
387
                                                        p_pic, VLC_CODEC_YUVA );
487
388
    if( !p_subpic )
488
 
    {
489
 
         picture_Release( p_pip );
490
 
         return VLC_EGENERIC;
491
 
    }
 
389
        return VLC_EGENERIC;
492
390
 
 
391
    /* FIXME DEFAULT_CHAN is not good (used by the text) but
 
392
     * hardcoded 0 doesn't seem right */
493
393
    p_subpic->i_channel = 0;
494
394
    p_subpic->i_start = mdate();
495
 
    p_subpic->i_stop = mdate() + 4000000;
 
395
    p_subpic->i_stop  = p_subpic->i_start + 4000000;
496
396
    p_subpic->b_ephemer = true;
497
397
    p_subpic->b_fade = true;
498
 
    p_subpic->i_original_picture_width = fmt_out.i_width * 4;
499
 
    p_subpic->i_original_picture_height = fmt_out.i_height * 4;
500
 
    fmt_out.i_aspect = 0;
501
 
    fmt_out.i_sar_num =
502
 
    fmt_out.i_sar_den = 0;
503
398
 
504
 
    p_subpic->p_region = subpicture_region_New( &fmt_out );
505
 
    if( p_subpic->p_region )
506
 
    {
507
 
        picture_Release( p_subpic->p_region->p_picture );
508
 
        p_subpic->p_region->p_picture = p_pip;
509
 
    }
510
 
    else
511
 
    {
512
 
        picture_Release( p_pip );
513
 
    }
 
399
    /* Reduce the picture to 1/4^2 of the screen */
 
400
    p_subpic->i_original_picture_width  *= 4;
 
401
    p_subpic->i_original_picture_height *= 4;
514
402
 
515
403
    spu_DisplaySubpicture( p_vout->p_spu, p_subpic );
516
404
    return VLC_SUCCESS;
517
405
}
518
 
/**
519
 
 * This function will return the default directory used for snapshots
520
 
 */
521
 
static char *VoutSnapshotGetDefaultDirectory( void )
522
 
{
523
 
    char *psz_path = NULL;
524
 
#if defined(__APPLE__) || defined(SYS_BEOS)
525
 
 
526
 
    if( asprintf( &psz_path, "%s/Desktop",
527
 
                  config_GetHomeDir() ) == -1 )
528
 
        psz_path = NULL;
529
 
 
530
 
#elif defined(WIN32) && !defined(UNDER_CE)
531
 
 
532
 
    /* Get the My Pictures folder path */
533
 
    char *p_mypicturesdir = NULL;
534
 
    typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
535
 
                                               LPWSTR );
536
 
    #ifndef CSIDL_FLAG_CREATE
537
 
    #   define CSIDL_FLAG_CREATE 0x8000
538
 
    #endif
539
 
    #ifndef CSIDL_MYPICTURES
540
 
    #   define CSIDL_MYPICTURES 0x27
541
 
    #endif
542
 
    #ifndef SHGFP_TYPE_CURRENT
543
 
    #   define SHGFP_TYPE_CURRENT 0
544
 
    #endif
545
 
 
546
 
    HINSTANCE shfolder_dll;
547
 
    SHGETFOLDERPATH SHGetFolderPath ;
548
 
 
549
 
    /* load the shfolder dll to retrieve SHGetFolderPath */
550
 
    if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
551
 
    {
552
 
       wchar_t wdir[PATH_MAX];
553
 
       SHGetFolderPath = (void *)GetProcAddress( shfolder_dll,
554
 
                                                  _T("SHGetFolderPathW") );
555
 
        if ((SHGetFolderPath != NULL )
556
 
         && SUCCEEDED (SHGetFolderPath (NULL,
557
 
                                       CSIDL_MYPICTURES | CSIDL_FLAG_CREATE,
558
 
                                       NULL, SHGFP_TYPE_CURRENT,
559
 
                                       wdir)))
560
 
            p_mypicturesdir = FromWide (wdir);
561
 
 
562
 
        FreeLibrary( shfolder_dll );
563
 
    }
564
 
 
565
 
    if( p_mypicturesdir == NULL )
566
 
        psz_path = strdup( config_GetHomeDir() );
567
 
    else
568
 
        psz_path = p_mypicturesdir;
569
 
 
570
 
#else
571
 
 
572
 
    /* XXX: This saves in the data directory. Shouldn't we try saving
573
 
     *      to psz_homedir/Desktop or something nicer ? */
574
 
    char *psz_datadir = config_GetUserDataDir();
575
 
    if( psz_datadir )
576
 
    {
577
 
        if( asprintf( &psz_path, "%s", psz_datadir ) == -1 )
578
 
            psz_path = NULL;
579
 
        free( psz_datadir );
580
 
    }
581
 
 
582
 
#endif
583
 
 
584
 
    return psz_path;
585
 
}
586
 
/**
587
 
 * This function will save a video snapshot to a file
588
 
 */
589
 
static int VoutWriteSnapshot( vout_thread_t *p_vout, char **ppsz_filename,
590
 
                              const block_t *p_image,
591
 
                              const char *psz_path,
592
 
                              const char *psz_format,
593
 
                              const char *psz_prefix_fmt )
594
 
{
595
 
    /* */
596
 
    char *psz_filename;
597
 
    DIR *p_path = utf8_opendir( psz_path );
598
 
    if( p_path != NULL )
599
 
    {
600
 
        /* The use specified a directory path */
601
 
        closedir( p_path );
602
 
 
603
 
        /* */
604
 
        char *psz_prefix = NULL;
605
 
        if( psz_prefix_fmt )
606
 
            psz_prefix = str_format( p_vout, psz_prefix_fmt );
607
 
        if( !psz_prefix )
608
 
        {
609
 
            psz_prefix = strdup( "vlcsnap-" );
610
 
            if( !psz_prefix )
611
 
                goto error;
612
 
        }
613
 
 
614
 
        if( var_GetBool( p_vout, "snapshot-sequential" ) )
615
 
        {
616
 
            int i_num = var_GetInteger( p_vout, "snapshot-num" );
617
 
            for( ; ; i_num++ )
618
 
            {
619
 
                struct stat st;
620
 
 
621
 
                if( asprintf( &psz_filename, "%s" DIR_SEP "%s%05d.%s",
622
 
                              psz_path, psz_prefix, i_num++, psz_format ) < 0 )
623
 
                {
624
 
                    free( psz_prefix );
625
 
                    goto error;
626
 
                }
627
 
                if( utf8_stat( psz_filename, &st ) )
628
 
                    break;
629
 
                free( psz_filename );
630
 
            }
631
 
 
632
 
            var_SetInteger( p_vout, "snapshot-num", i_num );
633
 
        }
634
 
        else
635
 
        {
636
 
            struct tm    curtime;
637
 
            time_t       lcurtime = time( NULL ) ;
638
 
 
639
 
            if( !localtime_r( &lcurtime, &curtime ) )
640
 
            {
641
 
                const unsigned int i_id = (p_image->i_pts / 100000) & 0xFFFFFF;
642
 
 
643
 
                msg_Warn( p_vout, "failed to get current time. Falling back to legacy snapshot naming" );
644
 
 
645
 
                if( asprintf( &psz_filename, "%s" DIR_SEP "%s%u.%s",
646
 
                              psz_path, psz_prefix, i_id, psz_format ) < 0 )
647
 
                    psz_filename = NULL;
648
 
            }
649
 
            else
650
 
            {
651
 
                /* suffix with the last decimal digit in 10s of seconds resolution
652
 
                 * FIXME gni ? */
653
 
                const int i_id = (p_image->i_pts / (100*1000)) & 0xFF;
654
 
                char psz_curtime[128];
655
 
 
656
 
                if( !strftime( psz_curtime, sizeof(psz_curtime), "%Y-%m-%d-%Hh%Mm%Ss", &curtime ) )
657
 
                    strcpy( psz_curtime, "error" );
658
 
 
659
 
                if( asprintf( &psz_filename, "%s" DIR_SEP "%s%s%1u.%s",
660
 
                              psz_path, psz_prefix, psz_curtime, i_id, psz_format ) < 0 )
661
 
                    psz_filename = NULL;
662
 
            }
663
 
        }
664
 
        free( psz_prefix );
665
 
    }
666
 
    else
667
 
    {
668
 
        /* The user specified a full path name (including file name) */
669
 
        psz_filename = str_format( p_vout, psz_path );
670
 
        path_sanitize( psz_filename );
671
 
    }
672
 
 
673
 
    if( !psz_filename )
674
 
        goto error;
675
 
 
676
 
    /* Save the snapshot */
677
 
    FILE *p_file = utf8_fopen( psz_filename, "wb" );
678
 
    if( !p_file )
679
 
    {
680
 
        msg_Err( p_vout, "Failed to open '%s'", psz_filename );
681
 
        free( psz_filename );
682
 
        goto error;
683
 
    }
684
 
    if( fwrite( p_image->p_buffer, p_image->i_buffer, 1, p_file ) != 1 )
685
 
    {
686
 
        msg_Err( p_vout, "Failed to write to '%s'", psz_filename );
687
 
        fclose( p_file );
688
 
        free( psz_filename );
689
 
        goto error;
690
 
    }
691
 
    fclose( p_file );
692
 
 
693
 
    /* */
694
 
    if( ppsz_filename )
695
 
        *ppsz_filename = psz_filename;
696
 
    else
697
 
        free( psz_filename );
698
 
 
699
 
    return VLC_SUCCESS;
700
 
 
701
 
error:
702
 
    msg_Err( p_vout, "could not save snapshot" );
703
 
    return VLC_EGENERIC;
704
 
}
705
406
 
706
407
/**
707
408
 * This function will display the name and a PIP of the provided snapshot
724
425
                      video_format_t *p_fmt,
725
426
                      const char *psz_format, mtime_t i_timeout )
726
427
{
727
 
    vout_thread_sys_t *p_sys = p_vout->p;
728
 
 
729
 
    vlc_mutex_lock( &p_sys->snapshot.lock );
730
 
    p_sys->snapshot.i_request++;
731
 
 
732
 
    const mtime_t i_deadline = mdate() + i_timeout;
733
 
    while( p_sys->snapshot.b_available && !p_sys->snapshot.p_picture &&
734
 
           mdate() < i_deadline )
735
 
    {
736
 
        vlc_cond_timedwait( &p_sys->snapshot.wait, &p_sys->snapshot.lock,
737
 
                            i_deadline );
738
 
    }
739
 
 
740
 
    picture_t *p_picture = p_sys->snapshot.p_picture;
741
 
    if( p_picture )
742
 
        p_sys->snapshot.p_picture = p_picture->p_next;
743
 
    else if( p_sys->snapshot.i_request > 0 )
744
 
        p_sys->snapshot.i_request--;
745
 
    vlc_mutex_unlock( &p_sys->snapshot.lock );
746
 
 
 
428
    picture_t *p_picture = vout_snapshot_Get( &p_vout->p->snapshot, i_timeout );
747
429
    if( !p_picture )
748
430
    {
749
431
        msg_Err( p_vout, "Failed to grab a snapshot" );
752
434
 
753
435
    if( pp_image )
754
436
    {
755
 
        vlc_fourcc_t i_format = VLC_FOURCC('p','n','g',' ');
 
437
        vlc_fourcc_t i_format = VLC_CODEC_PNG;
756
438
        if( psz_format && image_Type2Fourcc( psz_format ) )
757
439
            i_format = image_Type2Fourcc( psz_format );
758
440
 
799
481
 
800
482
    if( !psz_path )
801
483
    {
802
 
        psz_path = VoutSnapshotGetDefaultDirectory();
 
484
        psz_path = vout_snapshot_GetDirectory();
803
485
        if( !psz_path )
804
486
        {
805
487
            msg_Err( p_vout, "no path specified for snapshots" );
807
489
        }
808
490
    }
809
491
 
 
492
    vout_snapshot_save_cfg_t cfg;
 
493
    memset( &cfg, 0, sizeof(cfg) );
 
494
    cfg.is_sequential = var_GetBool( p_vout, "snapshot-sequential" );
 
495
    cfg.sequence = var_GetInteger( p_vout, "snapshot-num" );
 
496
    cfg.path = psz_path;
 
497
    cfg.format = psz_format;
 
498
    cfg.prefix_fmt = psz_prefix;
 
499
 
810
500
    char *psz_filename;
811
 
    if( VoutWriteSnapshot( p_vout, &psz_filename,
812
 
                           p_image,
813
 
                           psz_path, psz_format, psz_prefix ) )
 
501
    int  i_sequence;
 
502
    if (vout_snapshot_SaveImage( &psz_filename, &i_sequence,
 
503
                                 p_image, VLC_OBJECT(p_vout), &cfg ) )
814
504
        goto exit;
 
505
    if( cfg.is_sequential )
 
506
        var_SetInteger( p_vout, "snapshot-num", i_sequence + 1 );
815
507
 
816
508
    VoutOsdSnapshot( p_vout, p_picture, psz_filename );
817
509
 
818
 
    /* Generate a media player event  - Right now just trigger a global libvlc var
819
 
        CHECK: Could not find a more local object. The goal is to communicate
820
 
        vout_thread with libvlc_media_player or its input_thread */
821
 
    var_SetString( p_vout->p_libvlc, "vout-snapshottaken", psz_filename );
 
510
    /* signal creation of a new snapshot file */
 
511
    var_SetString( p_vout->p_libvlc, "snapshot-file", psz_filename );
 
512
 
822
513
    free( psz_filename );
823
514
 
824
515
exit:
835
526
 * Handle filters
836
527
 *****************************************************************************/
837
528
 
838
 
void vout_EnableFilter( vout_thread_t *p_vout, char *psz_name,
 
529
void vout_EnableFilter( vout_thread_t *p_vout, const char *psz_name,
839
530
                        bool b_add, bool b_setconfig )
840
531
{
841
532
    char *psz_parser;
842
 
    char *psz_string = config_GetPsz( p_vout, "vout-filter" );
 
533
    char *psz_string;
 
534
    const char *psz_filter_type;
 
535
 
 
536
    /* FIXME temporary hack */
 
537
    const char *psz_module_name = psz_name;
 
538
    if( !strcmp( psz_name, "magnify" ) ||
 
539
        !strcmp( psz_name, "puzzle" ) ||
 
540
        !strcmp( psz_name, "logo" ) ||
 
541
        !strcmp( psz_name, "wall" ) ||
 
542
        !strcmp( psz_name, "clone" ) )
 
543
        psz_module_name = "video_filter_wrapper";
 
544
 
 
545
    module_t *p_obj = module_find( psz_module_name );
 
546
    if( !p_obj )
 
547
    {
 
548
        msg_Err( p_vout, "Unable to find filter module \"%s\".", psz_name );
 
549
        return;
 
550
    }
 
551
 
 
552
    if( module_provides( p_obj, "video filter" ) )
 
553
    {
 
554
        psz_filter_type = "vout-filter";
 
555
    }
 
556
    else if( module_provides( p_obj, "video filter2" ) )
 
557
    {
 
558
        psz_filter_type = "video-filter";
 
559
    }
 
560
    else if( module_provides( p_obj, "sub filter" ) )
 
561
    {
 
562
        psz_filter_type = "sub-filter";
 
563
    }
 
564
    else
 
565
    {
 
566
        module_release( p_obj );
 
567
        msg_Err( p_vout, "Unknown video filter type." );
 
568
        return;
 
569
    }
 
570
    module_release( p_obj );
 
571
 
 
572
    if( !strcmp( psz_filter_type, "sub-filter") )
 
573
        psz_string = var_GetString( vout_GetSpu( p_vout ), psz_filter_type );
 
574
    else
 
575
        psz_string = var_GetString( p_vout, psz_filter_type );
843
576
 
844
577
    /* Todo : Use some generic chain manipulation functions */
845
578
    if( !psz_string ) psz_string = strdup("");
881
614
             return;
882
615
         }
883
616
    }
 
617
 
884
618
    if( b_setconfig )
885
 
        config_PutPsz( p_vout, "vout-filter", psz_string );
886
 
 
887
 
    var_SetString( p_vout, "vout-filter", psz_string );
 
619
    {
 
620
        if( !strcmp( psz_filter_type, "sub-filter") )
 
621
            config_PutPsz( vout_GetSpu( p_vout ), psz_filter_type, psz_string );
 
622
        else
 
623
            config_PutPsz( p_vout, psz_filter_type, psz_string );
 
624
    }
 
625
 
 
626
    if( !strcmp( psz_filter_type, "sub-filter") )
 
627
        var_SetString( vout_GetSpu( p_vout ), psz_filter_type, psz_string );
 
628
    else
 
629
        var_SetString( p_vout, psz_filter_type, psz_string );
 
630
 
888
631
    free( psz_string );
889
632
}
890
633
 
955
698
static int ZoomCallback( vlc_object_t *p_this, char const *psz_cmd,
956
699
                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
957
700
{
958
 
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
959
 
    (void)psz_cmd; (void)oldval; (void)newval; (void)p_data;
960
 
    InitWindowSize( p_vout, &p_vout->i_window_width,
961
 
                    &p_vout->i_window_height );
962
 
    vout_Control( p_vout, VOUT_SET_SIZE, p_vout->i_window_width,
963
 
                  p_vout->i_window_height );
964
 
    return VLC_SUCCESS;
 
701
    (void)psz_cmd; (void)oldval; (void)p_data;
 
702
 
 
703
    return var_SetFloat( p_this, "scale", newval.f_float );
965
704
}
966
705
 
967
706
static int CropCallback( vlc_object_t *p_this, char const *psz_cmd,
1132
871
             p_vout->fmt_in.i_visible_width,
1133
872
             p_vout->fmt_in.i_visible_height );
1134
873
 
1135
 
    var_SetVoid( p_vout, "crop-update" );
 
874
    var_TriggerCallback( p_vout, "crop-update" );
1136
875
 
1137
876
    return VLC_SUCCESS;
1138
877
}
1150
889
    /* Restore defaults */
1151
890
    p_vout->fmt_in.i_sar_num = p_vout->fmt_render.i_sar_num;
1152
891
    p_vout->fmt_in.i_sar_den = p_vout->fmt_render.i_sar_den;
1153
 
    p_vout->fmt_in.i_aspect = p_vout->fmt_render.i_aspect;
1154
 
    p_vout->render.i_aspect = p_vout->fmt_render.i_aspect;
 
892
    p_vout->render.i_aspect = (int64_t)p_vout->fmt_render.i_sar_num *
 
893
                                       p_vout->fmt_render.i_width *
 
894
                                       VOUT_ASPECT_FACTOR /
 
895
                                       p_vout->fmt_render.i_sar_den / p_vout->fmt_render.i_height;
1155
896
 
1156
897
    if( !psz_parser ) goto aspect_end;
1157
898
 
1166
907
    vlc_ureduce( &i_sar_num, &i_sar_den, i_sar_num, i_sar_den, 0 );
1167
908
    p_vout->fmt_in.i_sar_num = i_sar_num;
1168
909
    p_vout->fmt_in.i_sar_den = i_sar_den;
1169
 
    p_vout->fmt_in.i_aspect = i_aspect_num * VOUT_ASPECT_FACTOR / i_aspect_den;
1170
 
    p_vout->render.i_aspect = p_vout->fmt_in.i_aspect;
 
910
    p_vout->render.i_aspect = i_aspect_num * VOUT_ASPECT_FACTOR / i_aspect_den;
1171
911
 
1172
912
 aspect_end:
1173
913
    if( p_vout->p->i_par_num && p_vout->p->i_par_den )
1174
914
    {
1175
915
        p_vout->fmt_in.i_sar_num *= p_vout->p->i_par_den;
1176
916
        p_vout->fmt_in.i_sar_den *= p_vout->p->i_par_num;
1177
 
        p_vout->fmt_in.i_aspect = p_vout->fmt_in.i_aspect *
1178
 
            p_vout->p->i_par_den / p_vout->p->i_par_num;
1179
 
        p_vout->render.i_aspect = p_vout->fmt_in.i_aspect;
 
917
        p_vout->render.i_aspect = (int64_t)p_vout->fmt_in.i_sar_num *
 
918
                                           p_vout->fmt_in.i_width *
 
919
                                           VOUT_ASPECT_FACTOR /
 
920
                                           p_vout->fmt_in.i_sar_den /
 
921
                                           p_vout->fmt_in.i_height;
1180
922
    }
1181
923
 
1182
924
    p_vout->i_changes |= VOUT_ASPECT_CHANGE;
1183
925
 
1184
 
    vlc_ureduce( &i_aspect_num, &i_aspect_den,
1185
 
                 p_vout->fmt_in.i_aspect, VOUT_ASPECT_FACTOR, 0 );
1186
926
    msg_Dbg( p_vout, "new aspect-ratio %i:%i, sample aspect-ratio %i:%i",
1187
 
             i_aspect_num, i_aspect_den,
 
927
             p_vout->fmt_in.i_sar_num * p_vout->fmt_in.i_width,
 
928
             p_vout->fmt_in.i_sar_den * p_vout->fmt_in.i_height,
1188
929
             p_vout->fmt_in.i_sar_num, p_vout->fmt_in.i_sar_den );
1189
930
 
1190
931
    if( var_Get( p_vout, "crop", &val ) )
1227
968
    p_vout->b_on_top = newval.b_bool;
1228
969
    vlc_mutex_unlock( &p_vout->change_lock );
1229
970
 
1230
 
    /* Modify libvlc as well because the vout might have to be restarted */
1231
 
    var_Create( p_vout->p_libvlc, "video-on-top", VLC_VAR_BOOL );
1232
 
    var_Set( p_vout->p_libvlc, "video-on-top", newval );
1233
 
 
1234
971
    (void)psz_cmd; (void)oldval; (void)p_data;
1235
972
    return VLC_SUCCESS;
1236
973
}
1240
977
{
1241
978
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
1242
979
    vlc_value_t val;
1243
 
    (void)psz_cmd; (void)oldval; (void)p_data;
 
980
    (void)psz_cmd; (void)p_data;
1244
981
 
 
982
    if( oldval.b_bool == newval.b_bool )
 
983
        return VLC_SUCCESS; /* no-op */
1245
984
    p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
1246
985
 
1247
 
    /* Modify libvlc as well because the vout might have to be restarted */
1248
 
    var_Create( p_vout->p_libvlc, "fullscreen", VLC_VAR_BOOL );
1249
 
    var_Set( p_vout->p_libvlc, "fullscreen", newval );
1250
 
 
1251
986
    val.b_bool = true;
1252
987
    var_Set( p_vout, "intf-change", val );
1253
988
    return VLC_SUCCESS;