]> git.sesse.net Git - vlc/commitdiff
Reused vout window in vout_Request().
authorLaurent Aimar <fenrir@videolan.org>
Thu, 20 May 2010 18:50:14 +0000 (20:50 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Thu, 20 May 2010 21:51:26 +0000 (23:51 +0200)
It basically works but they are some issues to be fixed.

include/vlc_vout_wrapper.h
src/video_output/display.c
src/video_output/video_output.c
src/video_output/vout_internal.h
src/video_output/vout_wrapper.c

index 331a7fd7a928ace4fc0aeba4c30e70b6a67d4c1d..3dcd434229d2b3d1cc630171a60c4c7d957bbe28 100644 (file)
@@ -59,8 +59,7 @@ static inline void vout_display_Display(vout_display_t *vd, picture_t *picture)
  */
 typedef struct {
     vout_display_cfg_t cfg;
-
-    bool is_on_top;
+    unsigned wm_state;
     struct {
         int num;
         int den;
index 4fd32f23df0169e1c85f3915e5ffb84b8d5f0435..b1672e6df66f1b5fba5ae10fad304dafa76ab781 100644 (file)
@@ -783,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;
 
@@ -1114,7 +1116,7 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
     vout_display_cfg_t *cfg = &osys->cfg;
 
     *cfg = state->cfg;
-    osys->wm_state_initial = VOUT_WINDOW_STATE_NORMAL;
+    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,
@@ -1131,15 +1133,23 @@ 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->is_on_top ? VOUT_WINDOW_STATE_ABOVE
-                                      : VOUT_WINDOW_STATE_NORMAL;
+    osys->wm_state = state->wm_state;
     osys->fit_window = 0;
 
     osys->source = *source_org;
@@ -1208,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->wm_state & VOUT_WINDOW_STATE_ABOVE) != 0;
-        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);
@@ -1537,20 +1547,4 @@ static void DummyVoutSendDisplayEventMouse(vout_thread_t *vout, vlc_mouse_t *fal
     }
 }
 #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( !var_InheritBool( 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);
-}
 
index 255ec7edb45ce2ee37d267998249b7d8a37cbc30..21c4a8c12de934979b0fc033961717b0e38ee35c 100644 (file)
@@ -427,6 +427,89 @@ void vout_ControlChangeSubFilters(vout_thread_t *vout, const char *filters)
                             filters);
 }
 
+/* */
+static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, const char *title)
+{
+    /* Load configuration */
+    cfg->is_fullscreen = var_CreateGetBool(vout, "fullscreen");
+    cfg->display.title = title;
+    const int display_width = var_CreateGetInteger(vout, "width");
+    const int display_height = var_CreateGetInteger(vout, "height");
+    cfg->display.width   = display_width > 0  ? display_width  : 0;
+    cfg->display.height  = display_height > 0 ? display_height : 0;
+    cfg->is_display_filled  = var_CreateGetBool(vout, "autoscale");
+    cfg->display.sar.num = 1; /* TODO monitor AR */
+    cfg->display.sar.den = 1;
+    unsigned zoom_den = 1000;
+    unsigned zoom_num = zoom_den * var_CreateGetFloat(vout, "scale");
+    vlc_ureduce(&zoom_num, &zoom_den, zoom_num, zoom_den, 0);
+    cfg->zoom.num = zoom_num;
+    cfg->zoom.den = zoom_den;
+    cfg->align.vertical = VOUT_DISPLAY_ALIGN_CENTER;
+    cfg->align.horizontal = VOUT_DISPLAY_ALIGN_CENTER;
+    const int align_mask = var_CreateGetInteger(vout, "align");
+    if (align_mask & 0x1)
+        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_LEFT;
+    else if (align_mask & 0x2)
+        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_RIGHT;
+    if (align_mask & 0x4)
+        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_TOP;
+    else if (align_mask & 0x8)
+        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_BOTTOM;
+}
+
+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 (!var_InheritBool( vout, "embedded-video"))
+        cfg_override.is_standalone = true;
+
+    if (vout->p->window.is_unused && vout->p->window.object) {
+        assert(!vout->p->splitter_name);
+        if (!cfg_override.is_standalone == !vout->p->window.cfg.is_standalone &&
+            cfg_override.type           == vout->p->window.cfg.type) {
+            /* Reuse the stored window */
+            msg_Dbg(vout, "Reusing previous vout window");
+            vout_window_t *window = vout->p->window.object;
+            if (cfg_override.width  != vout->p->window.cfg.width ||
+                cfg_override.height != vout->p->window.cfg.height)
+                vout_window_SetSize(window,
+                                    cfg_override.width, cfg_override.height);
+            vout->p->window.is_unused = false;
+            vout->p->window.cfg       = cfg_override;
+            return window;
+        }
+
+        vout_window_Delete(vout->p->window.object);
+        vout->p->window.is_unused = true;
+        vout->p->window.object    = NULL;
+    }
+
+    vout_window_t *window = vout_window_New(VLC_OBJECT(vout), NULL,
+                                            &cfg_override);
+    if (!window)
+        return NULL;
+    if (!vout->p->splitter_name) {
+        vout->p->window.is_unused = false;
+        vout->p->window.cfg       = cfg_override;
+        vout->p->window.object    = window;
+    }
+    return window;
+}
+
+void vout_DeleteDisplayWindow(vout_thread_t *vout, vout_display_t *vd,
+                              vout_window_t *window)
+{
+    VLC_UNUSED(vd);
+    if (!vout->p->window.is_unused && vout->p->window.object == window)
+        vout->p->window.is_unused = true;
+    else
+        vout_window_Delete(window);
+}
+
 /* */
 static picture_t *VoutVideoFilterNewPicture(filter_t *filter)
 {
@@ -845,7 +928,7 @@ static void ThreadExecuteCropRatio(vout_thread_t *vout,
                             source->i_visible_height);
 }
 
-static int ThreadStart(vout_thread_t *vout)
+static int ThreadStart(vout_thread_t *vout, const vout_display_state_t *state)
 {
     vlc_mouse_Init(&vout->p->mouse);
     vout->p->decoder_fifo = picture_fifo_New();
@@ -857,7 +940,18 @@ static int ThreadStart(vout_thread_t *vout)
         filter_chain_New( vout, "video filter2", false,
                           VoutVideoFilterAllocationSetup, NULL, vout);
 
-    if (vout_OpenWrapper(vout, vout->p->splitter_name))
+    vout_display_state_t state_default;
+    if (!state) {
+        VoutGetDisplayCfg(vout, &state_default.cfg, vout->p->display.title);
+        state_default.wm_state = var_CreateGetBool(vout, "video-on-top") ? VOUT_WINDOW_STATE_ABOVE :
+                                                                           VOUT_WINDOW_STATE_NORMAL;
+        state_default.sar.num = 0;
+        state_default.sar.den = 0;
+
+        state = &state_default;
+    }
+
+    if (vout_OpenWrapper(vout, vout->p->splitter_name, state))
         return VLC_EGENERIC;
     if (vout_InitWrapper(vout))
         return VLC_EGENERIC;
@@ -877,7 +971,7 @@ static int ThreadStart(vout_thread_t *vout)
     return VLC_SUCCESS;
 }
 
-static void ThreadStop(vout_thread_t *vout)
+static void ThreadStop(vout_thread_t *vout, vout_display_state_t *state)
 {
     /* Destroy the video filters2 */
     filter_chain_Delete(vout->p->vfilter_chain);
@@ -888,7 +982,7 @@ static void ThreadStop(vout_thread_t *vout)
             ThreadFlush(vout, true, INT64_MAX);
             vout_EndWrapper(vout);
         }
-        vout_CloseWrapper(vout);
+        vout_CloseWrapper(vout, state);
     }
 
     if (vout->p->decoder_fifo)
@@ -898,16 +992,22 @@ static void ThreadStop(vout_thread_t *vout)
 
 static void ThreadInit(vout_thread_t *vout)
 {
-    vout->p->dead            = false;
-    vout->p->is_late_dropped = var_InheritBool(vout, "drop-late-frames");
-    vout->p->pause.is_on     = false;
-    vout->p->pause.date      = VLC_TS_INVALID;
+    vout->p->window.is_unused = true;
+    vout->p->window.object    = NULL;
+    vout->p->dead             = false;
+    vout->p->is_late_dropped  = var_InheritBool(vout, "drop-late-frames");
+    vout->p->pause.is_on      = false;
+    vout->p->pause.date       = VLC_TS_INVALID;
 
     vout_chrono_Init(&vout->p->render, 5, 10000); /* Arbitrary initial time */
 }
 
 static void ThreadClean(vout_thread_t *vout)
 {
+    if (vout->p->window.object) {
+        assert(vout->p->window.is_unused);
+        vout_window_Delete(vout->p->window.object);
+    }
     vout_chrono_Clean(&vout->p->render);
     vout->p->dead = true;
     vout_control_Dead(&vout->p->control);
@@ -918,17 +1018,29 @@ static int ThreadReinit(vout_thread_t *vout,
 {
     video_format_t original;
     if (VoutValidateFormat(&original, fmt)) {
-        ThreadStop(vout);
+        ThreadStop(vout, NULL);
         ThreadClean(vout);
         return VLC_EGENERIC;
     }
     if (video_format_IsSimilar(&original, &vout->p->original))
         return VLC_SUCCESS;
 
-    ThreadStop(vout);
+    vout_display_state_t state;
+    memset(&state, 0, sizeof(state));
+
+    ThreadStop(vout, &state);
+
+    if (!state.cfg.is_fullscreen) {
+        state.cfg.display.width  = 0;
+        state.cfg.display.height = 0;
+    }
+    state.sar.num = 0;
+    state.sar.den = 0;
+    /* FIXME current vout "variables" are not in sync here anymore
+     * and I am not sure what to do */
 
     vout->p->original = original;
-    if (ThreadStart(vout)) {
+    if (ThreadStart(vout, &state)) {
         ThreadClean(vout);
         return VLC_EGENERIC;
     }
@@ -964,14 +1076,14 @@ static void *Thread(void *object)
             switch(cmd.type) {
             case VOUT_CONTROL_INIT:
                 ThreadInit(vout);
-                if (ThreadStart(vout)) {
-                    ThreadStop(vout);
+                if (ThreadStart(vout, NULL)) {
+                    ThreadStop(vout, NULL);
                     ThreadClean(vout);
                     return NULL;
                 }
                 break;
             case VOUT_CONTROL_CLEAN:
-                ThreadStop(vout);
+                ThreadStop(vout, NULL);
                 ThreadClean(vout);
                 return NULL;
             case VOUT_CONTROL_REINIT:
index b6c0b78b5aeb9721fd859141d89805a5cc43c161..afdeec5d294fb0477ac3cd42639fb7f30926e6de 100644 (file)
@@ -33,6 +33,7 @@
 #include <vlc_picture_fifo.h>
 #include <vlc_picture_pool.h>
 #include <vlc_vout_display.h>
+#include <vlc_vout_wrapper.h>
 #include "vout_control.h"
 #include "control.h"
 #include "snapshot.h"
@@ -61,6 +62,13 @@ struct vout_thread_sys_t
     unsigned int    i_par_num;
     unsigned int    i_par_den;
 
+    /* Video output window */
+    struct {
+        bool              is_unused;
+        vout_window_cfg_t cfg;
+        vout_window_t     *object;
+    } window;
+
     /* Thread & synchronization */
     vlc_thread_t    thread;
     bool            dead;
@@ -135,8 +143,8 @@ void vout_ControlChangeSubFilters(vout_thread_t *, const char *);
 void vout_IntfInit( vout_thread_t * );
 
 /* */
-int  vout_OpenWrapper (vout_thread_t *, const char *);
-void vout_CloseWrapper(vout_thread_t *);
+int  vout_OpenWrapper (vout_thread_t *, const char *, const vout_display_state_t *);
+void vout_CloseWrapper(vout_thread_t *, vout_display_state_t *);
 int  vout_InitWrapper(vout_thread_t *);
 void vout_EndWrapper(vout_thread_t *);
 void vout_ManageWrapper(vout_thread_t *);
index 1d43e61c3acc662328a7448b93a41e7e4b4fb7d7..6d6be09862d9f7ef50e351d8c729b84468104ff5 100644 (file)
@@ -47,8 +47,6 @@
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static void VoutGetDisplayCfg(vout_thread_t *,
-                              vout_display_cfg_t *, const char *title);
 #ifdef WIN32
 static int  Forward(vlc_object_t *, char const *,
                     vlc_value_t, vlc_value_t, void *);
@@ -57,7 +55,8 @@ static int  Forward(vlc_object_t *, char const *,
 /*****************************************************************************
  *
  *****************************************************************************/
-int vout_OpenWrapper(vout_thread_t *vout, const char *name)
+int vout_OpenWrapper(vout_thread_t *vout,
+                     const char *name, const vout_display_state_t *state)
 {
     vout_thread_sys_t *sys = vout->p;
     msg_Dbg(vout, "Opening vout display wrapper");
@@ -72,21 +71,15 @@ int vout_OpenWrapper(vout_thread_t *vout, const char *name)
     source.i_x_offset       = 0;
     source.i_y_offset       = 0;
 
-    vout_display_state_t state;
-    VoutGetDisplayCfg(vout, &state.cfg, sys->display.title);
-    state.is_on_top = var_CreateGetBool(vout, "video-on-top");
-    state.sar.num = 0;
-    state.sar.den = 0;
-
     const mtime_t double_click_timeout = 300000;
     const mtime_t hide_timeout = var_CreateGetInteger(vout, "mouse-hide-timeout") * 1000;
 
-    sys->display.vd = vout_NewDisplay(vout, &source, &state, name ? name : "$vout",
+    sys->display.vd = vout_NewDisplay(vout, &source, state, name ? name : "$vout",
                                       double_click_timeout, hide_timeout);
     /* If we need to video filter and it fails, then try a splitter
      * XXX it is a hack for now FIXME */
     if (name && !sys->display.vd)
-        sys->display.vd = vout_NewSplitter(vout, &source, &state, "$vout", name,
+        sys->display.vd = vout_NewSplitter(vout, &source, state, "$vout", name,
                                            double_click_timeout, hide_timeout);
     if (!sys->display.vd) {
         free(sys->display.title);
@@ -110,7 +103,7 @@ int vout_OpenWrapper(vout_thread_t *vout, const char *name)
 /*****************************************************************************
  *
  *****************************************************************************/
-void vout_CloseWrapper(vout_thread_t *vout)
+void vout_CloseWrapper(vout_thread_t *vout, vout_display_state_t *state)
 {
     vout_thread_sys_t *sys = vout->p;
 
@@ -120,7 +113,7 @@ void vout_CloseWrapper(vout_thread_t *vout)
 #endif
     sys->decoder_pool = NULL; /* FIXME remove */
 
-    vout_DeleteDisplay(sys->display.vd, NULL);
+    vout_DeleteDisplay(sys->display.vd, state);
     free(sys->display.title);
 }
 
@@ -222,36 +215,6 @@ void vout_DisplayWrapper(vout_thread_t *vout, picture_t *picture)
      sys->display.filtered = NULL;
 }
 
-static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, const char *title)
-{
-    /* Load configuration */
-    cfg->is_fullscreen = var_CreateGetBool(vout, "fullscreen");
-    cfg->display.title = title;
-    const int display_width = var_CreateGetInteger(vout, "width");
-    const int display_height = var_CreateGetInteger(vout, "height");
-    cfg->display.width   = display_width > 0  ? display_width  : 0;
-    cfg->display.height  = display_height > 0 ? display_height : 0;
-    cfg->is_display_filled  = var_CreateGetBool(vout, "autoscale");
-    cfg->display.sar.num = 1; /* TODO monitor AR */
-    cfg->display.sar.den = 1;
-    unsigned zoom_den = 1000;
-    unsigned zoom_num = zoom_den * var_CreateGetFloat(vout, "scale");
-    vlc_ureduce(&zoom_num, &zoom_den, zoom_num, zoom_den, 0);
-    cfg->zoom.num = zoom_num;
-    cfg->zoom.den = zoom_den;
-    cfg->align.vertical = VOUT_DISPLAY_ALIGN_CENTER;
-    cfg->align.horizontal = VOUT_DISPLAY_ALIGN_CENTER;
-    const int align_mask = var_CreateGetInteger(vout, "align");
-    if (align_mask & 0x1)
-        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_LEFT;
-    else if (align_mask & 0x2)
-        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_RIGHT;
-    if (align_mask & 0x4)
-        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_TOP;
-    else if (align_mask & 0x8)
-        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_BOTTOM;
-}
-
 #ifdef WIN32
 static int Forward(vlc_object_t *object, char const *var,
                    vlc_value_t oldval, vlc_value_t newval, void *data)