~ubuntu-branches/ubuntu/vivid/vlc/vivid

« back to all changes in this revision

Viewing changes to src/video_output/display.c

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2012-02-13 01:34:02 UTC
  • mfrom: (1.1.44)
  • Revision ID: package-import@ubuntu.com-20120213013402-7utx6r7s9dg3r0pf
Tags: 2.0.0~unix-0ubuntu1
* New upstream release (Closes: #499381, #573064, #624027, LP: #455825,
  #573775, #695882, #705151, #708448, #738381, #743581, #747757, #817924,
  #931083).
* Remove dropped mozilla-plugin-vlc, vlc-plugin-ggi, and vlc-plugin-svgalib.
  The Mozilla browser plug-in is now provided by a separate source tarball.
* Add new plugins to and remove dropped plugins from vlc-nox.
* Add new and remove dropped build dependencies:
  + libbluray-dev (for Blu-ray support)
  + libresid-builder-dev
  + libsamplerate0-dev
  + libsidplay2-dev
  + lbspeexdsp-dev
  + libxcb-composite0-dev
  - libgtk2.0-dev
  - xulrunner-dev
* vlc-plugin-fluidsynth depends on fluid-soundfont-gm or
  musescore-soundfont-gm for having a sound font for playing MIDI files.
* Drop all patches (they were either backported or accepted by upstream).
* Update symbols for libvlc5.
* Install plugins.dat instead of running vlc-cache-gen in postinst.
* Update minimum version of build dependencies.
* Change Build-Dependency from libupnp3-dev to unversioned libupnp-dev.
  (Closes: #656831)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * display.c: "vout display" managment
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2009 Laurent Aimar
5
 
 * $Id: 858fefb1a4aab69cf47d27860f36559838a3a2a5 $
 
5
 * $Id: 50599d0db1783e62a3592ba99424a84a3457da1c $
6
6
 *
7
7
 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
8
8
 *
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
 
9
 * This program is free software; you can redistribute it and/or modify it
 
10
 * under the terms of the GNU Lesser General Public License as published by
 
11
 * the Free Software Foundation; either version 2.1 of the License, or
12
12
 * (at your option) any later version.
13
13
 *
14
14
 * This program is distributed in the hope that it will be useful,
15
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.
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
17
 * GNU Lesser General Public License for more details.
18
18
 *
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.
 
19
 * You should have received a copy of the GNU Lesser General Public License
 
20
 * along with this program; if not, write to the Free Software Foundation,
 
21
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
22
 *****************************************************************************/
23
23
 
24
24
/*****************************************************************************
33
33
#include <vlc_video_splitter.h>
34
34
#include <vlc_vout_display.h>
35
35
#include <vlc_vout.h>
 
36
#include <vlc_block.h>
 
37
#include <vlc_modules.h>
36
38
 
37
39
#include <libvlc.h>
38
40
 
58
60
           vd->fmt.i_width  == fmt->i_width  &&
59
61
           vd->fmt.i_height == fmt->i_height);
60
62
 
61
 
    picture_pool_t *pool = vout_display_Pool(vd, 1);
 
63
    picture_pool_t *pool = vout_display_Pool(vd, 3);
62
64
    if (!pool)
63
65
        return NULL;
64
66
    return picture_pool_Get(pool);
98
100
                                        vout_display_owner_t *owner)
99
101
{
100
102
    /* */
101
 
    vout_display_t *vd = vlc_object_create(obj, sizeof(*vd));
 
103
    vout_display_t *vd = vlc_custom_create(obj, sizeof(*vd), "vout display" );
102
104
 
103
105
    /* */
104
106
    video_format_Copy(&vd->source, fmt);
112
114
    vd->info.has_double_click = false;
113
115
    vd->info.has_hide_mouse = false;
114
116
    vd->info.has_pictures_invalid = false;
 
117
    vd->info.has_event_thread = false;
 
118
    vd->info.subpicture_chromas = NULL;
115
119
 
116
120
    vd->cfg = cfg;
117
121
    vd->pool = NULL;
123
127
 
124
128
    vd->owner = *owner;
125
129
 
126
 
    vlc_object_attach(vd, obj);
127
 
 
128
130
    if (load_module) {
129
131
        vd->module = module_need(vd, "vout display", module, module && *module != '\0');
130
132
        if (!vd->module) {
162
164
 
163
165
    return result;
164
166
}
 
167
 
165
168
static void vout_display_Manage(vout_display_t *vd)
166
169
{
167
170
    if (vd->manage)
284
287
    } sar_initial;
285
288
 
286
289
    /* */
287
 
    int  width_saved;
288
 
    int  height_saved;
 
290
    unsigned width_saved;
 
291
    unsigned height_saved;
289
292
 
290
293
    struct {
291
294
        unsigned num;
313
316
 
314
317
    bool ch_crop;
315
318
    struct {
316
 
        unsigned x;
317
 
        unsigned y;
318
 
        unsigned width;
319
 
        unsigned height;
 
319
        int      left;
 
320
        int      top;
 
321
        int      right;
 
322
        int      bottom;
320
323
        unsigned num;
321
324
        unsigned den;
322
325
    } crop;
356
359
 
357
360
    int  fit_window;
358
361
 
 
362
    struct {
 
363
        vlc_thread_t thread;
 
364
        block_fifo_t *fifo;
 
365
    } event;
 
366
 
359
367
#ifdef ALLOW_DUMMY_VOUT
360
368
    vlc_mouse_t vout_mouse;
361
369
#endif
521
529
        osys->mouse.last_moved = mdate();
522
530
 
523
531
    /* */
524
 
    vlc_mutex_unlock(&osys->lock);
525
 
 
526
 
    /* */
527
532
    vout_SendEventMouseVisible(osys->vout);
528
533
#ifdef ALLOW_DUMMY_VOUT
529
534
    DummyVoutSendDisplayEventMouse(osys->vout, &osys->vout_mouse, &m);
530
535
#else
531
536
    vout_SendDisplayEventMouse(osys->vout, &m);
532
537
#endif
 
538
    vlc_mutex_unlock(&osys->lock);
 
539
}
 
540
 
 
541
VLC_NORETURN
 
542
static void *VoutDisplayEventKeyDispatch(void *data)
 
543
{
 
544
    vout_display_owner_sys_t *osys = data;
 
545
 
 
546
    for (;;) {
 
547
        block_t *event = block_FifoGet(osys->event.fifo);
 
548
 
 
549
        int cancel = vlc_savecancel();
 
550
 
 
551
        int key;
 
552
        memcpy(&key, event->p_buffer, sizeof(key));
 
553
        vout_SendEventKey(osys->vout, key);
 
554
        block_Release(event);
 
555
 
 
556
        vlc_restorecancel(cancel);
 
557
    }
 
558
}
 
559
 
 
560
static void VoutDisplayEventKey(vout_display_t *vd, int key)
 
561
{
 
562
    vout_display_owner_sys_t *osys = vd->owner.sys;
 
563
 
 
564
    if (!osys->event.fifo) {
 
565
        osys->event.fifo = block_FifoNew();
 
566
        if (!osys->event.fifo)
 
567
            return;
 
568
        if (vlc_clone(&osys->event.thread, VoutDisplayEventKeyDispatch,
 
569
                      osys, VLC_THREAD_PRIORITY_LOW)) {
 
570
            block_FifoRelease(osys->event.fifo);
 
571
            osys->event.fifo = NULL;
 
572
            return;
 
573
        }
 
574
    }
 
575
    block_t *event = block_Alloc(sizeof(key));
 
576
    if (event) {
 
577
        memcpy(event->p_buffer, &key, sizeof(key));
 
578
        block_FifoPut(osys->event.fifo, event);
 
579
    }
533
580
}
534
581
 
535
582
static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args)
545
592
    case VOUT_DISPLAY_EVENT_KEY: {
546
593
        const int key = (int)va_arg(args, int);
547
594
        msg_Dbg(vd, "VoutDisplayEvent 'key' 0x%2.2x", key);
548
 
        vout_SendEventKey(osys->vout, key);
 
595
        if (vd->info.has_event_thread)
 
596
            vout_SendEventKey(osys->vout, key);
 
597
        else
 
598
            VoutDisplayEventKey(vd, key);
549
599
        break;
550
600
    }
551
601
    case VOUT_DISPLAY_EVENT_MOUSE_STATE:
633
683
        if (!var_InheritBool(osys->vout, "embedded-video"))
634
684
            cfg_override.is_standalone = true;
635
685
 
636
 
        return vout_window_New(VLC_OBJECT(osys->vout), NULL, &cfg_override);
 
686
        return vout_window_New(VLC_OBJECT(osys->vout), "$window", &cfg_override);
637
687
    }
638
688
#endif
639
689
    return vout_NewDisplayWindow(osys->vout, vd, cfg);
685
735
    vlc_mutex_unlock(&osys->lock);
686
736
}
687
737
 
 
738
static void VoutDisplayCropRatio(int *left, int *top, int *right, int *bottom,
 
739
                                 const video_format_t *source,
 
740
                                 unsigned num, unsigned den)
 
741
{
 
742
    unsigned scaled_width  = (uint64_t)source->i_visible_height * num * source->i_sar_den / den / source->i_sar_num;
 
743
    unsigned scaled_height = (uint64_t)source->i_visible_width  * den * source->i_sar_num / num / source->i_sar_den;
 
744
 
 
745
    if (scaled_width < source->i_visible_width) {
 
746
        *left   = (source->i_visible_width - scaled_width) / 2;
 
747
        *top    = 0;
 
748
        *right  = *left + scaled_width;
 
749
        *bottom = *top  + source->i_visible_height;
 
750
    } else {
 
751
        *left   = 0;
 
752
        *top    = (source->i_visible_height - scaled_height) / 2;
 
753
        *right  = *left + source->i_visible_width;
 
754
        *bottom = *top  + scaled_height;
 
755
    }
 
756
}
 
757
 
688
758
void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
689
759
{
690
760
    vout_display_owner_sys_t *osys = vd->owner.sys;
708
778
 
709
779
    if (hide_mouse) {
710
780
        if (!vd->info.has_hide_mouse) {
711
 
            msg_Dbg(vd, "auto hidding mouse");
 
781
            msg_Dbg(vd, "auto hiding mouse cursor");
712
782
            vout_display_Control(vd, VOUT_DISPLAY_HIDE_MOUSE);
713
783
        }
714
784
        vout_SendEventMouseHidden(osys->vout);
772
842
            if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_FULLSCREEN, &cfg)) {
773
843
                msg_Err(vd, "Failed to set fullscreen");
774
844
                is_fullscreen = osys->cfg.is_fullscreen;
 
845
            } else if (!is_fullscreen) {
 
846
                vout_display_Control(vd, VOUT_DISPLAY_CHANGE_DISPLAY_SIZE, &cfg, true);
775
847
            }
776
848
            osys->cfg.is_fullscreen = is_fullscreen;
777
849
 
900
972
                             65536);
901
973
                vout_SendEventSourceAspect(osys->vout, dar_num, dar_den);
902
974
            }
 
975
            /* If a crop ratio is requested, recompute the parameters */
 
976
            if (osys->crop.num > 0 && osys->crop.den > 0)
 
977
                osys->ch_crop = true;
903
978
        }
904
979
        /* */
905
980
        if (osys->ch_crop) {
906
981
            video_format_t source = vd->source;
 
982
 
907
983
            unsigned crop_num = osys->crop.num;
908
984
            unsigned crop_den = osys->crop.den;
909
 
 
910
 
            source.i_x_offset       = osys->crop.x;
911
 
            source.i_y_offset       = osys->crop.y;
912
 
            source.i_visible_width  = osys->crop.width;
913
 
            source.i_visible_height = osys->crop.height;
914
 
 
915
 
            /* */
916
 
            const bool is_valid = source.i_x_offset < source.i_width &&
917
 
                                  source.i_y_offset < source.i_height &&
918
 
                                  source.i_x_offset + source.i_visible_width  <= source.i_width &&
919
 
                                  source.i_y_offset + source.i_visible_height <= source.i_height &&
920
 
                                  source.i_visible_width > 0 && source.i_visible_height > 0;
921
 
 
922
 
            if (!is_valid || vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_CROP, &source)) {
923
 
                if (is_valid)
924
 
                    msg_Err(vd, "Failed to change source crop TODO implement crop at core");
925
 
                else
926
 
                    msg_Err(vd, "Invalid crop requested");
 
985
            if (crop_num > 0 && crop_den > 0) {
 
986
                video_format_t fmt = osys->source;
 
987
                fmt.i_sar_num = source.i_sar_num;
 
988
                fmt.i_sar_den = source.i_sar_den;
 
989
                VoutDisplayCropRatio(&osys->crop.left,  &osys->crop.top,
 
990
                                     &osys->crop.right, &osys->crop.bottom,
 
991
                                     &fmt, crop_num, crop_den);
 
992
            }
 
993
            const int right_max  = osys->source.i_x_offset + osys->source.i_visible_width;
 
994
            const int bottom_max = osys->source.i_y_offset + osys->source.i_visible_height;
 
995
            int left   = VLC_CLIP((int)osys->source.i_x_offset + osys->crop.left,
 
996
                                0, right_max - 1);
 
997
            int top    = VLC_CLIP((int)osys->source.i_y_offset + osys->crop.top,
 
998
                                0, bottom_max - 1);
 
999
            int right, bottom;
 
1000
            if (osys->crop.right <= 0)
 
1001
                right = (int)(osys->source.i_x_offset + osys->source.i_visible_width) + osys->crop.right;
 
1002
            else
 
1003
                right = (int)osys->source.i_x_offset + osys->crop.right;
 
1004
            right = VLC_CLIP(right, left + 1, right_max);
 
1005
            if (osys->crop.bottom <= 0)
 
1006
                bottom = (int)(osys->source.i_y_offset + osys->source.i_visible_height) + osys->crop.bottom;
 
1007
            else
 
1008
                bottom = (int)osys->source.i_y_offset + osys->crop.bottom;
 
1009
            bottom = VLC_CLIP(bottom, top + 1, bottom_max);
 
1010
 
 
1011
            source.i_x_offset       = left;
 
1012
            source.i_y_offset       = top;
 
1013
            source.i_visible_width  = right - left;
 
1014
            source.i_visible_height = bottom - top;
 
1015
            video_format_Print(VLC_OBJECT(vd), "SOURCE ", &osys->source);
 
1016
            video_format_Print(VLC_OBJECT(vd), "CROPPED", &source);
 
1017
            if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_CROP, &source)) {
 
1018
                msg_Err(vd, "Failed to change source crop TODO implement crop at core");
927
1019
 
928
1020
                source = vd->source;
929
1021
                crop_num = osys->crop_saved.num;
935
1027
                osys->fit_window = 1;
936
1028
            }
937
1029
            vd->source = source;
938
 
            osys->crop.x      = source.i_x_offset;
939
 
            osys->crop.y      = source.i_y_offset;
940
 
            osys->crop.width  = source.i_visible_width;
941
 
            osys->crop.height = source.i_visible_height;
 
1030
            osys->crop.left   = source.i_x_offset - osys->source.i_x_offset;
 
1031
            osys->crop.top    = source.i_y_offset - osys->source.i_y_offset;
 
1032
            /* FIXME for right/bottom we should keep the 'type' border vs window */
 
1033
            osys->crop.right  = (source.i_x_offset + source.i_visible_width) -
 
1034
                                (osys->source.i_x_offset + osys->source.i_visible_width);
 
1035
            osys->crop.bottom = (source.i_y_offset + source.i_visible_height) -
 
1036
                                (osys->source.i_y_offset + osys->source.i_visible_height);
942
1037
            osys->crop.num    = crop_num;
943
1038
            osys->crop.den    = crop_den;
944
1039
            osys->ch_crop = false;
945
1040
 
946
 
            /* TODO fix when a ratio is used (complicated). */
947
 
            const unsigned left   = osys->crop.x - osys->source.i_x_offset;
948
 
            const unsigned top    = osys->crop.y - osys->source.i_y_offset;
949
 
            const unsigned right  = osys->source.i_visible_width  - (osys->crop.width  + osys->crop.x);
950
 
            const unsigned bottom = osys->source.i_visible_height - (osys->crop.height + osys->crop.y);
951
1041
            vout_SendEventSourceCrop(osys->vout,
952
1042
                                     osys->crop.num, osys->crop.den,
953
 
                                     left, top, right, bottom);
 
1043
                                     osys->crop.left, osys->crop.top,
 
1044
                                     -osys->crop.right, -osys->crop.bottom);
954
1045
        }
955
1046
 
956
1047
        /* */
996
1087
    return filter_chain_VideoFilter(osys->filters, picture);
997
1088
}
998
1089
 
 
1090
void vout_UpdateDisplaySourceProperties(vout_display_t *vd, const video_format_t *source)
 
1091
{
 
1092
    vout_display_owner_sys_t *osys = vd->owner.sys;
 
1093
 
 
1094
    if (source->i_sar_num * osys->source.i_sar_den !=
 
1095
        source->i_sar_den * osys->source.i_sar_num) {
 
1096
 
 
1097
        osys->source.i_sar_num = source->i_sar_num;
 
1098
        osys->source.i_sar_den = source->i_sar_den;
 
1099
        vlc_ureduce(&osys->source.i_sar_num, &osys->source.i_sar_den,
 
1100
                    osys->source.i_sar_num, osys->source.i_sar_den, 0);
 
1101
 
 
1102
        /* FIXME it will override any AR that the user would have forced */
 
1103
        osys->ch_sar = true;
 
1104
        osys->sar.num = osys->source.i_sar_num;
 
1105
        osys->sar.den = osys->source.i_sar_den;
 
1106
    }
 
1107
    if (source->i_x_offset       != osys->source.i_x_offset ||
 
1108
        source->i_y_offset       != osys->source.i_y_offset ||
 
1109
        source->i_visible_width  != osys->source.i_visible_width ||
 
1110
        source->i_visible_height != osys->source.i_visible_height) {
 
1111
 
 
1112
        video_format_CopyCrop(&osys->source, source);
 
1113
 
 
1114
        /* Force the vout to reapply the current user crop settings over the new decoder
 
1115
         * crop settings. */
 
1116
        osys->ch_crop = true;
 
1117
    }
 
1118
}
 
1119
 
999
1120
void vout_SetDisplayFullscreen(vout_display_t *vd, bool is_fullscreen)
1000
1121
{
1001
1122
    vout_display_owner_sys_t *osys = vd->owner.sys;
1042
1163
    vlc_mutex_unlock(&osys->lock);
1043
1164
}
1044
1165
 
1045
 
void vout_SetDisplayAspect(vout_display_t *vd, unsigned sar_num, unsigned sar_den)
 
1166
void vout_SetDisplayAspect(vout_display_t *vd, unsigned dar_num, unsigned dar_den)
1046
1167
{
1047
1168
    vout_display_owner_sys_t *osys = vd->owner.sys;
1048
1169
 
 
1170
    unsigned sar_num, sar_den;
 
1171
    if (dar_num > 0 && dar_den > 0) {
 
1172
        sar_num = dar_num * osys->source.i_visible_height;
 
1173
        sar_den = dar_den * osys->source.i_visible_width;
 
1174
        vlc_ureduce(&sar_num, &sar_den, sar_num, sar_den, 0);
 
1175
    } else {
 
1176
        sar_num = 0;
 
1177
        sar_den = 0;
 
1178
    }
 
1179
 
1049
1180
    if (osys->sar.num != sar_num || osys->sar.den != sar_den) {
1050
1181
        osys->ch_sar = true;
1051
1182
        osys->sar.num = sar_num;
1054
1185
}
1055
1186
void vout_SetDisplayCrop(vout_display_t *vd,
1056
1187
                         unsigned crop_num, unsigned crop_den,
1057
 
                         unsigned x, unsigned y, unsigned width, unsigned height)
 
1188
                         unsigned left, unsigned top, int right, int bottom)
1058
1189
{
1059
1190
    vout_display_owner_sys_t *osys = vd->owner.sys;
1060
1191
 
1061
 
    if (osys->crop.x != x || osys->crop.y != y ||
1062
 
        osys->crop.width  != width || osys->crop.height != height) {
 
1192
    if (osys->crop.left  != (int)left  || osys->crop.top != (int)top ||
 
1193
        osys->crop.right != right || osys->crop.bottom != bottom ||
 
1194
        (crop_num > 0 && crop_den > 0 &&
 
1195
         (crop_num != osys->crop.num || crop_den != osys->crop.den))) {
1063
1196
 
1064
 
        osys->crop.x      = x;
1065
 
        osys->crop.y      = y;
1066
 
        osys->crop.width  = width;
1067
 
        osys->crop.height = height;
 
1197
        osys->crop.left   = left;
 
1198
        osys->crop.top    = top;
 
1199
        osys->crop.right  = right;
 
1200
        osys->crop.bottom = bottom;
1068
1201
        osys->crop.num    = crop_num;
1069
1202
        osys->crop.den    = crop_den;
1070
1203
 
1071
1204
        osys->ch_crop = true;
1072
1205
    }
1073
1206
}
1074
 
vout_opengl_t *vout_GetDisplayOpengl(vout_display_t *vd)
 
1207
 
 
1208
struct vlc_gl_t *vout_GetDisplayOpengl(vout_display_t *vd)
1075
1209
{
1076
 
    vout_opengl_t *gl;
 
1210
    struct vlc_gl_t *gl;
1077
1211
    if (vout_display_Control(vd, VOUT_DISPLAY_GET_OPENGL, &gl))
1078
1212
        return NULL;
1079
1213
    return gl;
1093
1227
    vout_display_cfg_t *cfg = &osys->cfg;
1094
1228
 
1095
1229
    *cfg = state->cfg;
1096
 
    osys->wm_state_initial = VOUT_WINDOW_STATE_NORMAL;
 
1230
    osys->wm_state_initial = -1;
1097
1231
    osys->sar_initial.num = state->sar.num;
1098
1232
    osys->sar_initial.den = state->sar.den;
1099
1233
    vout_display_GetDefaultDisplaySize(&cfg->display.width, &cfg->display.height,
1110
1244
    osys->mouse.double_click_timeout = double_click_timeout;
1111
1245
    osys->mouse.hide_timeout = hide_timeout;
1112
1246
    osys->is_fullscreen  = cfg->is_fullscreen;
1113
 
    osys->width_saved    =
1114
1247
    osys->display_width  = cfg->display.width;
1115
 
    osys->height_saved   =
1116
1248
    osys->display_height = cfg->display.height;
1117
1249
    osys->is_display_filled = cfg->is_display_filled;
 
1250
    osys->width_saved    = cfg->display.width;
 
1251
    osys->height_saved   = cfg->display.height;
 
1252
    if (osys->is_fullscreen) {
 
1253
        vout_display_cfg_t cfg_windowed = *cfg;
 
1254
        cfg_windowed.is_fullscreen  = false;
 
1255
        cfg_windowed.display.width  = 0;
 
1256
        cfg_windowed.display.height = 0;
 
1257
        vout_display_GetDefaultDisplaySize(&osys->width_saved,
 
1258
                                           &osys->height_saved,
 
1259
                                           source_org, &cfg_windowed);
 
1260
    }
1118
1261
    osys->zoom.num = cfg->zoom.num;
1119
1262
    osys->zoom.den = cfg->zoom.den;
1120
 
    osys->wm_state = state->is_on_top ? VOUT_WINDOW_STATE_ABOVE
1121
 
                                      : VOUT_WINDOW_STATE_NORMAL;
 
1263
    osys->wm_state = state->wm_state;
1122
1264
    osys->fit_window = 0;
 
1265
    osys->event.fifo = NULL;
1123
1266
 
1124
1267
    osys->source = *source_org;
1125
 
 
1126
 
    video_format_t source = *source_org;
1127
 
 
1128
 
    source.i_x_offset =
1129
 
    osys->crop.x  = 0;
1130
 
    source.i_y_offset =
1131
 
    osys->crop.y  = 0;
1132
 
    source.i_visible_width  =
1133
 
    osys->crop.width    = source.i_width;
1134
 
    source.i_visible_height =
1135
 
    osys->crop.height   = source.i_height;
 
1268
    osys->crop.left   = 0;
 
1269
    osys->crop.top    = 0;
 
1270
    osys->crop.right  = 0;
 
1271
    osys->crop.bottom = 0;
1136
1272
    osys->crop_saved.num = 0;
1137
1273
    osys->crop_saved.den = 0;
1138
1274
    osys->crop.num = 0;
1139
1275
    osys->crop.den = 0;
1140
1276
 
1141
 
    osys->sar.num = osys->sar_initial.num ? osys->sar_initial.num : source.i_sar_num;
1142
 
    osys->sar.den = osys->sar_initial.den ? osys->sar_initial.den : source.i_sar_den;
 
1277
    osys->sar.num = osys->sar_initial.num ? osys->sar_initial.num : source_org->i_sar_num;
 
1278
    osys->sar.den = osys->sar_initial.den ? osys->sar_initial.den : source_org->i_sar_den;
1143
1279
#ifdef ALLOW_DUMMY_VOUT
1144
1280
    vlc_mouse_Init(&osys->vout_mouse);
1145
1281
#endif
1155
1291
    owner.sys = osys;
1156
1292
 
1157
1293
    /* */
 
1294
    video_format_t source = *source_org;
 
1295
 
 
1296
    source.i_x_offset = 0;
 
1297
    source.i_y_offset = 0;
 
1298
    source.i_visible_width  = source.i_width;
 
1299
    source.i_visible_height = source.i_height;
 
1300
 
1158
1301
    vout_display_t *p_display = vout_display_New(VLC_OBJECT(vout),
1159
1302
                                                 module, !is_wrapper,
1160
1303
                                                 &source, cfg, &owner);
1166
1309
    VoutDisplayCreateRender(p_display);
1167
1310
 
1168
1311
    /* Setup delayed request */
1169
 
    if (osys->sar.num != source_org->i_sar_num ||
1170
 
        osys->sar.den != source_org->i_sar_den)
 
1312
    if (osys->sar.num != source.i_sar_num ||
 
1313
        osys->sar.den != source.i_sar_den)
1171
1314
        osys->ch_sar = true;
1172
1315
    if (osys->wm_state != osys->wm_state_initial)
1173
1316
        osys->ch_wm_state = true;
1174
 
    if (osys->crop.x      != source_org->i_x_offset ||
1175
 
        osys->crop.y      != source_org->i_y_offset ||
1176
 
        osys->crop.width  != source_org->i_visible_width ||
1177
 
        osys->crop.height != source_org->i_visible_height)
 
1317
    if (source.i_x_offset       != source_org->i_x_offset ||
 
1318
        source.i_y_offset       != source_org->i_y_offset ||
 
1319
        source.i_visible_width  != source_org->i_visible_width ||
 
1320
        source.i_visible_height != source_org->i_visible_height)
1178
1321
        osys->ch_crop = true;
1179
1322
 
1180
1323
    return p_display;
1187
1330
    if (state) {
1188
1331
        if (!osys->is_wrapper )
1189
1332
            state->cfg = osys->cfg;
1190
 
        state->is_on_top = (osys->wm_state & VOUT_WINDOW_STATE_ABOVE) != 0;
1191
 
        state->sar.num   = osys->sar_initial.num;
1192
 
        state->sar.den   = osys->sar_initial.den;
 
1333
        state->wm_state = osys->wm_state;
 
1334
        state->sar.num  = osys->sar_initial.num;
 
1335
        state->sar.den  = osys->sar_initial.den;
1193
1336
    }
1194
1337
 
1195
1338
    VoutDisplayDestroyRender(vd);
1196
1339
    if (osys->is_wrapper)
1197
1340
        SplitterClose(vd);
1198
1341
    vout_display_Delete(vd);
 
1342
    if (osys->event.fifo) {
 
1343
        vlc_cancel(osys->event.thread);
 
1344
        vlc_join(osys->event.thread, NULL);
 
1345
        block_FifoRelease(osys->event.fifo);
 
1346
    }
1199
1347
    vlc_mutex_destroy(&osys->lock);
1200
1348
    free(osys);
1201
1349
}
1214
1362
                      double_click_timeout, hide_timeout, NULL);
1215
1363
}
1216
1364
 
1217
 
static void SplitterClose(vout_display_t *vd)
1218
 
{
1219
 
    VLC_UNUSED(vd);
1220
 
    assert(0);
1221
 
}
1222
 
 
1223
 
#if 0
1224
1365
/*****************************************************************************
1225
1366
 *
1226
1367
 *****************************************************************************/
1227
1368
struct vout_display_sys_t {
 
1369
    picture_pool_t   *pool;
1228
1370
    video_splitter_t *splitter;
1229
1371
 
1230
1372
    /* */
1255
1397
}
1256
1398
static void SplitterEvent(vout_display_t *vd, int event, va_list args)
1257
1399
{
1258
 
    vout_display_owner_sys_t *osys = vd->owner.sys;
 
1400
    //vout_display_owner_sys_t *osys = vd->owner.sys;
1259
1401
 
1260
1402
    switch (event) {
1261
1403
#if 0
1281
1423
    }
1282
1424
}
1283
1425
 
1284
 
static picture_t *SplitterGet(vout_display_t *vd)
 
1426
static picture_pool_t *SplitterPool(vout_display_t *vd, unsigned count)
1285
1427
{
1286
 
    /* TODO pool ? */
1287
 
    return picture_NewFromFormat(&vd->fmt);
 
1428
    vout_display_sys_t *sys = vd->sys;
 
1429
    if (!sys->pool)
 
1430
        sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);
 
1431
    return sys->pool;
1288
1432
}
1289
 
static void SplitterPrepare(vout_display_t *vd, picture_t *picture)
 
1433
static void SplitterPrepare(vout_display_t *vd,
 
1434
                            picture_t *picture,
 
1435
                            subpicture_t *subpicture)
1290
1436
{
1291
1437
    vout_display_sys_t *sys = vd->sys;
1292
1438
 
1293
1439
    picture_Hold(picture);
 
1440
    assert(!subpicture);
1294
1441
 
1295
1442
    if (video_splitter_Filter(sys->splitter, sys->picture, picture)) {
1296
1443
        for (int i = 0; i < sys->count; i++)
1300
1447
    }
1301
1448
 
1302
1449
    for (int i = 0; i < sys->count; i++) {
1303
 
        /* */
1304
 
        /* FIXME now vout_FilterDisplay already return a direct buffer FIXME */
1305
 
        sys->picture[i] = vout_FilterDisplay(sys->display[i], sys->picture[i]);
1306
 
        if (!sys->picture[i])
1307
 
            continue;
1308
 
 
1309
 
        /* */
1310
 
        picture_t *direct = vout_display_Get(sys->display[i]);
1311
 
        if (!direct) {
1312
 
            msg_Err(vd, "Failed to get a direct buffer");
1313
 
            picture_Release(sys->picture[i]);
1314
 
            sys->picture[i] = NULL;
1315
 
            continue;
1316
 
        }
1317
 
 
1318
 
        /* FIXME not always needed (easy when there is a osys->filters) */
1319
 
        picture_Copy(direct, sys->picture[i]);
1320
 
        picture_Release(sys->picture[i]);
1321
 
        sys->picture[i] = direct;
1322
 
 
1323
 
        vout_display_Prepare(sys->display[i], sys->picture[i]);
 
1450
        if (vout_IsDisplayFiltered(sys->display[i]))
 
1451
            sys->picture[i] = vout_FilterDisplay(sys->display[i], sys->picture[i]);
 
1452
        if (sys->picture[i])
 
1453
            vout_display_Prepare(sys->display[i], sys->picture[i], NULL);
1324
1454
    }
1325
1455
}
1326
 
static void SplitterDisplay(vout_display_t *vd, picture_t *picture)
 
1456
static void SplitterDisplay(vout_display_t *vd,
 
1457
                            picture_t *picture,
 
1458
                            subpicture_t *subpicture)
1327
1459
{
1328
1460
    vout_display_sys_t *sys = vd->sys;
1329
1461
 
 
1462
    assert(!subpicture);
1330
1463
    for (int i = 0; i < sys->count; i++) {
1331
1464
        if (sys->picture[i])
1332
 
            vout_display_Display(sys->display[i], sys->picture[i]);
 
1465
            vout_display_Display(sys->display[i], sys->picture[i], NULL);
1333
1466
    }
1334
1467
    picture_Release(picture);
1335
1468
}
1336
1469
static int SplitterControl(vout_display_t *vd, int query, va_list args)
1337
1470
{
 
1471
    (void)vd; (void)query; (void)args;
1338
1472
    return VLC_EGENERIC;
1339
1473
}
1340
1474
static void SplitterManage(vout_display_t *vd)
1342
1476
    vout_display_sys_t *sys = vd->sys;
1343
1477
 
1344
1478
    for (int i = 0; i < sys->count; i++)
1345
 
        vout_ManageDisplay(sys->display[i]);
 
1479
        vout_ManageDisplay(sys->display[i], true);
1346
1480
}
1347
1481
 
1348
1482
static int SplitterPictureNew(video_splitter_t *splitter, picture_t *picture[])
1350
1484
    vout_display_sys_t *wsys = splitter->p_owner->wrapper->sys;
1351
1485
 
1352
1486
    for (int i = 0; i < wsys->count; i++) {
1353
 
        /* TODO pool ? */
1354
 
        picture[i] = picture_NewFromFormat(&wsys->display[i]->source);
 
1487
        if (vout_IsDisplayFiltered(wsys->display[i])) {
 
1488
            /* TODO use a pool ? */
 
1489
            picture[i] = picture_NewFromFormat(&wsys->display[i]->source);
 
1490
        } else {
 
1491
            picture_pool_t *pool = vout_display_Pool(wsys->display[i], 1);
 
1492
            picture[i] = pool ? picture_pool_Get(pool) : NULL;
 
1493
        }
1355
1494
        if (!picture[i]) {
1356
1495
            for (int j = 0; j < i; j++)
1357
1496
                picture_Release(picture[j]);
1376
1515
    free(splitter->p_owner);
1377
1516
    video_splitter_Delete(splitter);
1378
1517
 
 
1518
    if (sys->pool)
 
1519
        picture_pool_Delete(sys->pool);
 
1520
 
1379
1521
    /* */
1380
1522
    for (int i = 0; i < sys->count; i++)
1381
1523
        vout_DeleteDisplay(sys->display[i], NULL);
1413
1555
    if (!sys->picture )
1414
1556
        abort();
1415
1557
    sys->splitter = splitter;
 
1558
    sys->pool     = NULL;
1416
1559
 
1417
 
    wrapper->get     = SplitterGet;
 
1560
    wrapper->pool    = SplitterPool;
1418
1561
    wrapper->prepare = SplitterPrepare;
1419
1562
    wrapper->display = SplitterDisplay;
1420
1563
    wrapper->control = SplitterControl;
1464
1607
 
1465
1608
    return wrapper;
1466
1609
}
1467
 
#endif
1468
1610
 
1469
1611
/*****************************************************************************
1470
1612
 * TODO move out
1472
1614
#include "vout_internal.h"
1473
1615
void vout_SendDisplayEventMouse(vout_thread_t *vout, const vlc_mouse_t *m)
1474
1616
{
 
1617
    vlc_mouse_t tmp1, tmp2;
 
1618
 
 
1619
    /* The check on spu is needed as long as ALLOW_DUMMY_VOUT is defined */
 
1620
    if (vout->p->spu && spu_ProcessMouse( vout->p->spu, m, &vout->p->display.vd->source))
 
1621
        return;
 
1622
 
 
1623
    vlc_mutex_lock( &vout->p->filter.lock );
 
1624
    if (vout->p->filter.chain_static && vout->p->filter.chain_interactive) {
 
1625
        if (!filter_chain_MouseFilter(vout->p->filter.chain_interactive, &tmp1, m))
 
1626
            m = &tmp1;
 
1627
        if (!filter_chain_MouseFilter(vout->p->filter.chain_static,      &tmp2, m))
 
1628
            m = &tmp2;
 
1629
    }
 
1630
    vlc_mutex_unlock( &vout->p->filter.lock );
 
1631
 
1475
1632
    if (vlc_mouse_HasMoved(&vout->p->mouse, m)) {
1476
1633
        vout_SendEventMouseMoved(vout, m->i_x, m->i_y);
1477
1634
    }
1478
1635
    if (vlc_mouse_HasButton(&vout->p->mouse, m)) {
1479
 
        static const int buttons[] = {
1480
 
            MOUSE_BUTTON_LEFT,
1481
 
            MOUSE_BUTTON_CENTER,
1482
 
            MOUSE_BUTTON_RIGHT,
1483
 
            MOUSE_BUTTON_WHEEL_UP,
1484
 
            MOUSE_BUTTON_WHEEL_DOWN,
1485
 
            -1
1486
 
        };
1487
 
        for (int i = 0; buttons[i] >= 0; i++) {
1488
 
            const int button = buttons[i];
 
1636
        for (unsigned button = 0; button < MOUSE_BUTTON_MAX; button++) {
1489
1637
            if (vlc_mouse_HasPressed(&vout->p->mouse, m, button))
1490
1638
                vout_SendEventMousePressed(vout, button);
1491
1639
            else if (vlc_mouse_HasReleased(&vout->p->mouse, m, button))
1503
1651
 
1504
1652
    if (!vout->p) {
1505
1653
        p.mouse = *fallback;
 
1654
        vlc_mutex_init(&p.filter.lock);
 
1655
        p.filter.chain_static = NULL;
 
1656
        p.filter.chain_interactive = NULL;
 
1657
        p.spu = NULL;
1506
1658
        vout->p = &p;
1507
1659
    }
1508
1660
    vout_SendDisplayEventMouse(vout, m);
1509
1661
    if (vout->p == &p) {
 
1662
        vlc_mutex_destroy(&p.filter.lock);
1510
1663
        *fallback = p.mouse;
1511
1664
        vout->p = NULL;
1512
1665
    }
1513
1666
}
1514
1667
#endif
1515
 
vout_window_t * vout_NewDisplayWindow(vout_thread_t *vout, vout_display_t *vd, const vout_window_cfg_t *cfg)
1516
 
{
1517
 
    VLC_UNUSED(vd);
1518
 
    vout_window_cfg_t cfg_override = *cfg;
1519
 
 
1520
 
    if( !var_InheritBool( vout, "embedded-video" ) )
1521
 
        cfg_override.is_standalone = true;
1522
 
 
1523
 
    return vout_window_New(VLC_OBJECT(vout), NULL, &cfg_override);
1524
 
}
1525
 
void vout_DeleteDisplayWindow(vout_thread_t *vout, vout_display_t *vd, vout_window_t *window)
1526
 
{
1527
 
    VLC_UNUSED(vout);
1528
 
    VLC_UNUSED(vd);
1529
 
    vout_window_Delete(window);
1530
 
}
1531
1668