]> git.sesse.net Git - vlc/blobdiff - src/video_output/display.c
Reused vout window in vout_Request().
[vlc] / src / video_output / display.c
index eec453626ba99e8c94b5ff09d169b112613530e6..b1672e6df66f1b5fba5ae10fad304dafa76ab781 100644 (file)
@@ -58,7 +58,10 @@ static picture_t *VideoBufferNew(filter_t *filter)
            vd->fmt.i_width  == fmt->i_width  &&
            vd->fmt.i_height == fmt->i_height);
 
-    return vout_display_Get(vd);
+    picture_pool_t *pool = vout_display_Pool(vd, 3);
+    if (!pool)
+        return NULL;
+    return picture_pool_Get(pool);
 }
 static void VideoBufferDelete(filter_t *filter, picture_t *picture)
 {
@@ -68,17 +71,17 @@ static void VideoBufferDelete(filter_t *filter, picture_t *picture)
 
 static int  FilterAllocationInit(filter_t *filter, void *vd)
 {
-    filter->pf_vout_buffer_new = VideoBufferNew;
-    filter->pf_vout_buffer_del = VideoBufferDelete;
-    filter->p_owner            = vd;
+    filter->pf_video_buffer_new = VideoBufferNew;
+    filter->pf_video_buffer_del = VideoBufferDelete;
+    filter->p_owner             = vd;
 
     return VLC_SUCCESS;
 }
 static void FilterAllocationClean(filter_t *filter)
 {
-    filter->pf_vout_buffer_new = NULL;
-    filter->pf_vout_buffer_del = NULL;
-    filter->p_owner            = NULL;
+    filter->pf_video_buffer_new = NULL;
+    filter->pf_video_buffer_del = NULL;
+    filter->p_owner             = NULL;
 }
 
 /*****************************************************************************
@@ -102,7 +105,6 @@ static vout_display_t *vout_display_New(vlc_object_t *obj,
 
     /* Picture buffer does not have the concept of aspect ratio */
     video_format_Copy(&vd->fmt, fmt);
-    vd->fmt.i_aspect = 0;
     vd->fmt.i_sar_num = 0;
     vd->fmt.i_sar_den = 0;
 
@@ -112,7 +114,7 @@ static vout_display_t *vout_display_New(vlc_object_t *obj,
     vd->info.has_pictures_invalid = false;
 
     vd->cfg = cfg;
-    vd->get = NULL;
+    vd->pool = NULL;
     vd->prepare = NULL;
     vd->display = NULL;
     vd->control = NULL;
@@ -126,7 +128,6 @@ static vout_display_t *vout_display_New(vlc_object_t *obj,
     if (load_module) {
         vd->module = module_need(vd, "vout display", module, module && *module != '\0');
         if (!vd->module) {
-            vlc_object_detach(vd);
             vlc_object_release(vd);
             return NULL;
         }
@@ -141,8 +142,6 @@ static vout_display_t *vout_display_New(vlc_object_t *obj,
  */
 static void vout_display_Delete(vout_display_t *vd)
 {
-    vlc_object_detach(vd);
-
     if (vd->module)
         module_unneed(vd, vd->module);
 
@@ -209,14 +208,10 @@ void vout_display_PlacePicture(vout_display_place_t *place,
         return;
 
     /* */
-    unsigned width;
-    unsigned height;
     unsigned display_width;
     unsigned display_height;
 
     if (cfg->is_display_filled) {
-        width  = source->i_visible_width;
-        height = source->i_visible_height;
         display_width  = cfg->display.width;
         display_height = cfg->display.height;
     } else {
@@ -224,17 +219,17 @@ void vout_display_PlacePicture(vout_display_place_t *place,
 
         cfg_tmp.display.width  = 0;
         cfg_tmp.display.height = 0;
-        vout_display_GetDefaultDisplaySize(&width, &height,
+        vout_display_GetDefaultDisplaySize(&display_width, &display_height,
                                            source, &cfg_tmp);
 
-        display_width  = width;
-        display_height = height;
         if (do_clipping) {
             display_width  = __MIN(display_width,  cfg->display.width);
             display_height = __MIN(display_height, cfg->display.height);
         }
     }
 
+    const unsigned width  = source->i_visible_width;
+    const unsigned height = source->i_visible_height;
     /* Compute the height if we use the width to fill up display_width */
     const int64_t scaled_height = (int64_t)height * display_width  * cfg->display.sar.num * source->i_sar_den / width  / source->i_sar_num / cfg->display.sar.den;
     /* And the same but switching width/height */
@@ -282,7 +277,7 @@ struct vout_display_owner_sys_t {
 
     /* */
     vout_display_cfg_t cfg;
-    bool     is_on_top_initial;
+    unsigned     wm_state_initial;
     struct {
         unsigned num;
         unsigned den;
@@ -307,8 +302,8 @@ struct vout_display_owner_sys_t {
         int  den;
     } zoom;
 
-    bool ch_on_top;
-    bool is_on_top;
+    bool ch_wm_state;
+    unsigned wm_state;
 
     bool ch_sar;
     struct {
@@ -359,6 +354,8 @@ struct vout_display_owner_sys_t {
     bool display_is_fullscreen;
     bool display_is_forced;
 
+    int  fit_window;
+
 #ifdef ALLOW_DUMMY_VOUT
     vlc_mouse_t vout_mouse;
 #endif
@@ -373,12 +370,10 @@ static void VoutDisplayCreateRender(vout_display_t *vd)
     osys->filters = NULL;
 
     video_format_t v_src = vd->source;
-    v_src.i_aspect  = 0;
     v_src.i_sar_num = 0;
     v_src.i_sar_den = 0;
 
     video_format_t v_dst = vd->fmt;
-    v_dst.i_aspect  = 0;
     v_dst.i_sar_num = 0;
     v_dst.i_sar_den = 0;
 
@@ -393,7 +388,7 @@ static void VoutDisplayCreateRender(vout_display_t *vd)
     if (!convert)
         return;
 
-    msg_Err(vd, "A filter to adapt decoder to display is needed");
+    msg_Dbg(vd, "A filter to adapt decoder to display is needed");
 
     osys->filters = filter_chain_New(vd, "video filter2", false,
                                      FilterAllocationInit,
@@ -532,9 +527,6 @@ static void VoutDisplayEventMouse(vout_display_t *vd, int event, va_list args)
     if (!vd->info.has_hide_mouse)
         osys->mouse.last_moved = mdate();
 
-    /* */
-    vlc_mutex_unlock(&osys->lock);
-
     /* */
     vout_SendEventMouseVisible(osys->vout);
 #ifdef ALLOW_DUMMY_VOUT
@@ -542,6 +534,7 @@ static void VoutDisplayEventMouse(vout_display_t *vd, int event, va_list args)
 #else
     vout_SendDisplayEventMouse(osys->vout, &m);
 #endif
+    vlc_mutex_unlock(&osys->lock);
 }
 
 static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args)
@@ -582,15 +575,15 @@ static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args)
         break;
     }
 
-    case VOUT_DISPLAY_EVENT_ON_TOP: {
-        const int is_on_top = (int)va_arg(args, int);
+    case VOUT_DISPLAY_EVENT_WINDOW_STATE: {
+        const unsigned state = va_arg(args, unsigned);
 
-        msg_Dbg(vd, "VoutDisplayEvent 'on top' %d", is_on_top);
+        msg_Dbg(vd, "VoutDisplayEvent 'window state' %u", state);
 
         vlc_mutex_lock(&osys->lock);
-        if (!is_on_top != !osys->is_on_top) {
-            osys->ch_on_top = true;
-            osys->is_on_top = is_on_top;
+        if (state != osys->wm_state) {
+            osys->ch_wm_state = true;
+            osys->wm_state = state;
         }
         vlc_mutex_unlock(&osys->lock);
         break;
@@ -647,6 +640,62 @@ static void VoutDisplayDelWindow(vout_display_t *vd, vout_window_t *window)
     vout_DeleteDisplayWindow(osys->vout, vd, window);
 }
 
+static void VoutDisplayFitWindow(vout_display_t *vd, bool default_size)
+{
+    vout_display_owner_sys_t *osys = vd->owner.sys;
+    vout_display_cfg_t cfg = osys->cfg;
+
+    if (!cfg.is_display_filled)
+        return;
+
+    cfg.display.width = 0;
+    if (default_size) {
+        cfg.display.height = 0;
+    } else {
+        cfg.display.height = osys->height_saved;
+        cfg.zoom.num = 1;
+        cfg.zoom.den = 1;
+    }
+
+    unsigned display_width;
+    unsigned display_height;
+    vout_display_GetDefaultDisplaySize(&display_width, &display_height,
+                                       &vd->source, &cfg);
+
+    vlc_mutex_lock(&osys->lock);
+
+    osys->ch_display_size       = true;
+    osys->display_width         = display_width;
+    osys->display_height        = display_height;
+    osys->display_is_fullscreen = osys->cfg.is_fullscreen;
+    osys->display_is_forced     = true;
+
+    vlc_mutex_unlock(&osys->lock);
+}
+
+static void VoutDisplayCropRatio(unsigned *x, unsigned *y,
+                                 unsigned *width, unsigned *height,
+                                 const video_format_t *source,
+                                 unsigned num, unsigned den)
+{
+    unsigned scaled_width  = (uint64_t)source->i_visible_height * num * source->i_sar_den / den / source->i_sar_num;
+    unsigned scaled_height = (uint64_t)source->i_visible_width  * den * source->i_sar_num / num / source->i_sar_den;
+
+    if (scaled_width < source->i_visible_width) {
+        *x      = (source->i_visible_width - scaled_width) / 2;
+        *y      = 0;
+        *width  = scaled_width;
+        *height = source->i_visible_height;
+    } else {
+        *x      = 0;
+        *y      = (source->i_visible_height - scaled_height) / 2;
+        *width  = source->i_visible_width;
+        *height = scaled_height;
+    }
+    *x += source->i_x_offset;
+    *y += source->i_y_offset;
+}
+
 void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
 {
     vout_display_owner_sys_t *osys = vd->owner.sys;
@@ -685,9 +734,9 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
         bool is_fullscreen  = osys->is_fullscreen;
         osys->ch_fullscreen = false;
 
-        bool ch_on_top  = osys->ch_on_top;
-        bool is_on_top  = osys->is_on_top;
-        osys->ch_on_top = false;
+        bool ch_wm_state  = osys->ch_wm_state;
+        unsigned wm_state  = osys->wm_state;
+        osys->ch_wm_state = false;
 
         bool ch_display_size       = osys->ch_display_size;
         int  display_width         = osys->display_width;
@@ -711,10 +760,17 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
             !reset_pictures &&
             !osys->ch_display_filled &&
             !osys->ch_zoom &&
-            !ch_on_top &&
+            !ch_wm_state &&
             !osys->ch_sar &&
-            !osys->ch_crop)
+            !osys->ch_crop) {
+
+            if (!osys->cfg.is_fullscreen && osys->fit_window != 0) {
+                VoutDisplayFitWindow(vd, osys->fit_window == -1);
+                osys->fit_window = 0;
+                continue;
+            }
             break;
+        }
 
         /* */
         if (ch_fullscreen) {
@@ -727,6 +783,8 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
             if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_FULLSCREEN, &cfg)) {
                 msg_Err(vd, "Failed to set fullscreen");
                 is_fullscreen = osys->cfg.is_fullscreen;
+            } else if (!is_fullscreen) {
+                vout_display_Control(vd, VOUT_DISPLAY_CHANGE_DISPLAY_SIZE, &cfg, true);
             }
             osys->cfg.is_fullscreen = is_fullscreen;
 
@@ -791,19 +849,8 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
                 msg_Err(vd, "Failed to change zoom");
                 osys->zoom.num = osys->cfg.zoom.num;
                 osys->zoom.den = osys->cfg.zoom.den;
-            } else if (cfg.is_display_filled) {
-                const int display_width  = (int64_t)vd->source.i_width  * osys->zoom.num / osys->zoom.den;
-                const int display_height = (int64_t)vd->source.i_height * osys->zoom.num / osys->zoom.den;
-
-                vlc_mutex_lock(&osys->lock);
-
-                osys->ch_display_size       = true;
-                osys->display_width         = display_width;
-                osys->display_height        = display_height;
-                osys->display_is_fullscreen = osys->cfg.is_fullscreen;
-                osys->display_is_forced     = true;
-
-                vlc_mutex_unlock(&osys->lock);
+            } else {
+                osys->fit_window = -1;
             }
 
             osys->cfg.zoom.num = osys->zoom.num;
@@ -813,15 +860,15 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
             vout_SendEventZoom(osys->vout, osys->cfg.zoom.num, osys->cfg.zoom.den);
         }
         /* */
-        if (ch_on_top) {
-            if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_ON_TOP, is_on_top)) {
+        if (ch_wm_state) {
+            if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_WINDOW_STATE, wm_state)) {
                 msg_Err(vd, "Failed to set on top");
-                is_on_top = osys->is_on_top_initial;
+                wm_state = osys->wm_state;
             }
-            osys->is_on_top_initial = is_on_top;
+            osys->wm_state_initial = wm_state;
 
             /* */
-            vout_SendEventOnTop(osys->vout, osys->is_on_top_initial);
+            vout_SendEventOnTop(osys->vout, osys->wm_state_initial);
         }
         /* */
         if (osys->ch_sar) {
@@ -843,6 +890,8 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
                  */
                 msg_Err(vd, "Failed to change source AR");
                 source = vd->source;
+            } else if (!osys->fit_window) {
+                osys->fit_window = 1;
             }
             vd->source = source;
             osys->sar.num = source.i_sar_num;
@@ -864,12 +913,24 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
                              65536);
                 vout_SendEventSourceAspect(osys->vout, dar_num, dar_den);
             }
+            /* If a crop ratio is requested, recompute the parameters */
+            if (osys->crop.num > 0 && osys->crop.den > 0)
+                osys->ch_crop = true;
         }
         /* */
         if (osys->ch_crop) {
             video_format_t source = vd->source;
+
             unsigned crop_num = osys->crop.num;
             unsigned crop_den = osys->crop.den;
+            if (crop_num > 0 && crop_den > 0) {
+                video_format_t fmt = osys->source;
+                fmt.i_sar_num = source.i_sar_num;
+                fmt.i_sar_den = source.i_sar_den;
+                VoutDisplayCropRatio(&osys->crop.x, &osys->crop.y,
+                                     &osys->crop.width, &osys->crop.height,
+                                     &fmt, crop_num, crop_den);
+            }
 
             source.i_x_offset       = osys->crop.x;
             source.i_y_offset       = osys->crop.y;
@@ -895,6 +956,8 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
                 /* FIXME implement cropping in the core if not supported by the
                  * vout module (easy)
                  */
+            } else if (!osys->fit_window) {
+                osys->fit_window = 1;
             }
             vd->source = source;
             osys->crop.x      = source.i_x_offset;
@@ -980,23 +1043,26 @@ void vout_SetDisplayZoom(vout_display_t *vd, int num, int den)
 {
     vout_display_owner_sys_t *osys = vd->owner.sys;
 
-    if (osys->zoom.num != num || osys->zoom.den != den) {
+    if (osys->is_display_filled ||
+        osys->zoom.num != num || osys->zoom.den != den) {
         osys->ch_zoom = true;
         osys->zoom.num = num;
         osys->zoom.den = den;
     }
 }
-void vout_SetDisplayOnTop(vout_display_t *vd, bool is_on_top)
+
+void vout_SetWindowState(vout_display_t *vd, unsigned state)
 {
     vout_display_owner_sys_t *osys = vd->owner.sys;
 
     vlc_mutex_lock(&osys->lock);
-    if (!osys->is_on_top != !is_on_top) {
-        osys->ch_on_top = true;
-        osys->is_on_top = is_on_top;
+    if (osys->wm_state != state) {
+        osys->ch_wm_state = true;
+        osys->wm_state = state;
     }
     vlc_mutex_unlock(&osys->lock);
 }
+
 void vout_SetDisplayAspect(vout_display_t *vd, unsigned sar_num, unsigned sar_den)
 {
     vout_display_owner_sys_t *osys = vd->owner.sys;
@@ -1014,7 +1080,9 @@ void vout_SetDisplayCrop(vout_display_t *vd,
     vout_display_owner_sys_t *osys = vd->owner.sys;
 
     if (osys->crop.x != x || osys->crop.y != y ||
-        osys->crop.width  != width || osys->crop.height != height) {
+        osys->crop.width  != width || osys->crop.height != height ||
+        (crop_num > 0 && crop_den > 0 &&
+         (crop_num != osys->crop.num || crop_den != osys->crop.den))) {
 
         osys->crop.x      = x;
         osys->crop.y      = y;
@@ -1048,7 +1116,7 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
     vout_display_cfg_t *cfg = &osys->cfg;
 
     *cfg = state->cfg;
-    osys->is_on_top_initial = state->is_on_top;;
+    osys->wm_state_initial = -1;
     osys->sar_initial.num = state->sar.num;
     osys->sar_initial.den = state->sar.den;
     vout_display_GetDefaultDisplaySize(&cfg->display.width, &cfg->display.height,
@@ -1065,13 +1133,24 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
     osys->mouse.double_click_timeout = double_click_timeout;
     osys->mouse.hide_timeout = hide_timeout;
     osys->is_fullscreen  = cfg->is_fullscreen;
-    osys->width_saved    =
     osys->display_width  = cfg->display.width;
-    osys->height_saved   =
     osys->display_height = cfg->display.height;
     osys->is_display_filled = cfg->is_display_filled;
+    osys->width_saved    = cfg->display.width;
+    osys->height_saved   = cfg->display.height;
+    if (osys->is_fullscreen) {
+        vout_display_cfg_t cfg_windowed = *cfg;
+        cfg_windowed.is_fullscreen  = false;
+        cfg_windowed.display.width  = 0;
+        cfg_windowed.display.height = 0;
+        vout_display_GetDefaultDisplaySize(&osys->width_saved,
+                                           &osys->height_saved,
+                                           source_org, &cfg_windowed);
+    }
     osys->zoom.num = cfg->zoom.num;
     osys->zoom.den = cfg->zoom.den;
+    osys->wm_state = state->wm_state;
+    osys->fit_window = 0;
 
     osys->source = *source_org;
 
@@ -1121,8 +1200,8 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
     if (osys->sar.num != source_org->i_sar_num ||
         osys->sar.den != source_org->i_sar_den)
         osys->ch_sar = true;
-    if (osys->is_on_top)
-        osys->ch_on_top = true;
+    if (osys->wm_state != osys->wm_state_initial)
+        osys->ch_wm_state = true;
     if (osys->crop.x      != source_org->i_x_offset ||
         osys->crop.y      != source_org->i_y_offset ||
         osys->crop.width  != source_org->i_visible_width ||
@@ -1139,9 +1218,9 @@ void vout_DeleteDisplay(vout_display_t *vd, vout_display_state_t *state)
     if (state) {
         if (!osys->is_wrapper )
             state->cfg = osys->cfg;
-        state->is_on_top = osys->is_on_top_initial;
-        state->sar.num   = osys->sar_initial.num;
-        state->sar.den   = osys->sar_initial.den;
+        state->wm_state = osys->wm_state;
+        state->sar.num  = osys->sar_initial.num;
+        state->sar.den  = osys->sar_initial.den;
     }
 
     VoutDisplayDestroyRender(vd);
@@ -1166,17 +1245,11 @@ vout_display_t *vout_NewDisplay(vout_thread_t *vout,
                       double_click_timeout, hide_timeout, NULL);
 }
 
-static void SplitterClose(vout_display_t *vd)
-{
-    VLC_UNUSED(vd);
-    assert(0);
-}
-
-#if 0
 /*****************************************************************************
  *
  *****************************************************************************/
 struct vout_display_sys_t {
+    picture_pool_t   *pool;
     video_splitter_t *splitter;
 
     /* */
@@ -1207,7 +1280,7 @@ static void SplitterDelWindow(vout_display_t *vd, vout_window_t *window)
 }
 static void SplitterEvent(vout_display_t *vd, int event, va_list args)
 {
-    vout_display_owner_sys_t *osys = vd->owner.sys;
+    //vout_display_owner_sys_t *osys = vd->owner.sys;
 
     switch (event) {
 #if 0
@@ -1233,10 +1306,12 @@ static void SplitterEvent(vout_display_t *vd, int event, va_list args)
     }
 }
 
-static picture_t *SplitterGet(vout_display_t *vd)
+static picture_pool_t *SplitterPool(vout_display_t *vd, unsigned count)
 {
-    /* TODO pool ? */
-    return picture_NewFromFormat(&vd->fmt);
+    vout_display_sys_t *sys = vd->sys;
+    if (!sys->pool)
+        sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);
+    return sys->pool;
 }
 static void SplitterPrepare(vout_display_t *vd, picture_t *picture)
 {
@@ -1252,27 +1327,10 @@ static void SplitterPrepare(vout_display_t *vd, picture_t *picture)
     }
 
     for (int i = 0; i < sys->count; i++) {
-        /* */
-        /* FIXME now vout_FilterDisplay already return a direct buffer FIXME */
-        sys->picture[i] = vout_FilterDisplay(sys->display[i], sys->picture[i]);
-        if (!sys->picture[i])
-            continue;
-
-        /* */
-        picture_t *direct = vout_display_Get(sys->display[i]);
-        if (!direct) {
-            msg_Err(vd, "Failed to get a direct buffer");
-            picture_Release(sys->picture[i]);
-            sys->picture[i] = NULL;
-            continue;
-        }
-
-        /* FIXME not always needed (easy when there is a osys->filters) */
-        picture_Copy(direct, sys->picture[i]);
-        picture_Release(sys->picture[i]);
-        sys->picture[i] = direct;
-
-        vout_display_Prepare(sys->display[i], sys->picture[i]);
+        if (vout_IsDisplayFiltered(sys->display[i]))
+            sys->picture[i] = vout_FilterDisplay(sys->display[i], sys->picture[i]);
+        if (sys->picture[i])
+            vout_display_Prepare(sys->display[i], sys->picture[i]);
     }
 }
 static void SplitterDisplay(vout_display_t *vd, picture_t *picture)
@@ -1294,7 +1352,7 @@ static void SplitterManage(vout_display_t *vd)
     vout_display_sys_t *sys = vd->sys;
 
     for (int i = 0; i < sys->count; i++)
-        vout_ManageDisplay(sys->display[i]);
+        vout_ManageDisplay(sys->display[i], true);
 }
 
 static int SplitterPictureNew(video_splitter_t *splitter, picture_t *picture[])
@@ -1302,8 +1360,13 @@ static int SplitterPictureNew(video_splitter_t *splitter, picture_t *picture[])
     vout_display_sys_t *wsys = splitter->p_owner->wrapper->sys;
 
     for (int i = 0; i < wsys->count; i++) {
-        /* TODO pool ? */
-        picture[i] = picture_NewFromFormat(&wsys->display[i]->source);
+        if (vout_IsDisplayFiltered(wsys->display[i])) {
+            /* TODO use a pool ? */
+            picture[i] = picture_NewFromFormat(&wsys->display[i]->source);
+        } else {
+            picture_pool_t *pool = vout_display_Pool(wsys->display[i], 1);
+            picture[i] = pool ? picture_pool_Get(pool) : NULL;
+        }
         if (!picture[i]) {
             for (int j = 0; j < i; j++)
                 picture_Release(picture[j]);
@@ -1328,6 +1391,9 @@ static void SplitterClose(vout_display_t *vd)
     free(splitter->p_owner);
     video_splitter_Delete(splitter);
 
+    if (sys->pool)
+        picture_pool_Delete(sys->pool);
+
     /* */
     for (int i = 0; i < sys->count; i++)
         vout_DeleteDisplay(sys->display[i], NULL);
@@ -1365,8 +1431,9 @@ vout_display_t *vout_NewSplitter(vout_thread_t *vout,
     if (!sys->picture )
         abort();
     sys->splitter = splitter;
+    sys->pool     = NULL;
 
-    wrapper->get     = SplitterGet;
+    wrapper->pool    = SplitterPool;
     wrapper->prepare = SplitterPrepare;
     wrapper->display = SplitterDisplay;
     wrapper->control = SplitterControl;
@@ -1416,7 +1483,6 @@ vout_display_t *vout_NewSplitter(vout_thread_t *vout,
 
     return wrapper;
 }
-#endif
 
 /*****************************************************************************
  * TODO move out
@@ -1424,6 +1490,19 @@ vout_display_t *vout_NewSplitter(vout_thread_t *vout,
 #include "vout_internal.h"
 void vout_SendDisplayEventMouse(vout_thread_t *vout, const vlc_mouse_t *m)
 {
+    vlc_mouse_t tmp;
+
+    /* The check on p_spu is needed as long as ALLOW_DUMMY_VOUT is defined */
+    if (vout->p->p_spu && spu_ProcessMouse( vout->p->p_spu, m, &vout->p->display.vd->source))
+        return;
+
+    vlc_mutex_lock( &vout->p->vfilter_lock );
+    if (vout->p->vfilter_chain) {
+        if (!filter_chain_MouseFilter(vout->p->vfilter_chain, &tmp, m))
+            m = &tmp;
+    }
+    vlc_mutex_unlock( &vout->p->vfilter_lock );
+
     if (vlc_mouse_HasMoved(&vout->p->mouse, m)) {
         vout_SendEventMouseMoved(vout, m->i_x, m->i_y);
     }
@@ -1455,29 +1534,17 @@ static void DummyVoutSendDisplayEventMouse(vout_thread_t *vout, vlc_mouse_t *fal
 
     if (!vout->p) {
         p.mouse = *fallback;
+        vlc_mutex_init(&p.vfilter_lock);
+        p.vfilter_chain = NULL;
+        p.p_spu = NULL;
         vout->p = &p;
     }
     vout_SendDisplayEventMouse(vout, m);
     if (vout->p == &p) {
+        vlc_mutex_destroy(&p.vfilter_lock);
         *fallback = p.mouse;
         vout->p = NULL;
     }
 }
 #endif
-vout_window_t * vout_NewDisplayWindow(vout_thread_t *vout, vout_display_t *vd, const vout_window_cfg_t *cfg)
-{
-    VLC_UNUSED(vd);
-    vout_window_cfg_t cfg_override = *cfg;
-
-    if( !config_GetInt( vout, "embedded-video" ) )
-        cfg_override.is_standalone = true;
-
-    return vout_window_New(VLC_OBJECT(vout), NULL, &cfg_override);
-}
-void vout_DeleteDisplayWindow(vout_thread_t *vout, vout_display_t *vd, vout_window_t *window)
-{
-    VLC_UNUSED(vout);
-    VLC_UNUSED(vd);
-    vout_window_Delete(window);
-}