From: Laurent Aimar Date: Thu, 20 May 2010 18:50:14 +0000 (+0200) Subject: Reused vout window in vout_Request(). X-Git-Tag: 1.2.0-pre1~6576 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=c75fafe4ec348154a6e07c324dbe62c1c23a7149;p=vlc Reused vout window in vout_Request(). It basically works but they are some issues to be fixed. --- diff --git a/include/vlc_vout_wrapper.h b/include/vlc_vout_wrapper.h index 331a7fd7a9..3dcd434229 100644 --- a/include/vlc_vout_wrapper.h +++ b/include/vlc_vout_wrapper.h @@ -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; diff --git a/src/video_output/display.c b/src/video_output/display.c index 4fd32f23df..b1672e6df6 100644 --- a/src/video_output/display.c +++ b/src/video_output/display.c @@ -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); -} diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 255ec7edb4..21c4a8c12d 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -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: diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h index b6c0b78b5a..afdeec5d29 100644 --- a/src/video_output/vout_internal.h +++ b/src/video_output/vout_internal.h @@ -33,6 +33,7 @@ #include #include #include +#include #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 *); diff --git a/src/video_output/vout_wrapper.c b/src/video_output/vout_wrapper.c index 1d43e61c3a..6d6be09862 100644 --- a/src/video_output/vout_wrapper.c +++ b/src/video_output/vout_wrapper.c @@ -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)