Commit c75fafe4 authored by Laurent Aimar's avatar Laurent Aimar

Reused vout window in vout_Request().

It basically works but they are some issues to be fixed.
parent e5d23eb8
...@@ -59,8 +59,7 @@ static inline void vout_display_Display(vout_display_t *vd, picture_t *picture) ...@@ -59,8 +59,7 @@ static inline void vout_display_Display(vout_display_t *vd, picture_t *picture)
*/ */
typedef struct { typedef struct {
vout_display_cfg_t cfg; vout_display_cfg_t cfg;
unsigned wm_state;
bool is_on_top;
struct { struct {
int num; int num;
int den; int den;
......
...@@ -783,6 +783,8 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures) ...@@ -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)) { if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_FULLSCREEN, &cfg)) {
msg_Err(vd, "Failed to set fullscreen"); msg_Err(vd, "Failed to set fullscreen");
is_fullscreen = osys->cfg.is_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; osys->cfg.is_fullscreen = is_fullscreen;
...@@ -1114,7 +1116,7 @@ static vout_display_t *DisplayNew(vout_thread_t *vout, ...@@ -1114,7 +1116,7 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
vout_display_cfg_t *cfg = &osys->cfg; vout_display_cfg_t *cfg = &osys->cfg;
*cfg = state->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.num = state->sar.num;
osys->sar_initial.den = state->sar.den; osys->sar_initial.den = state->sar.den;
vout_display_GetDefaultDisplaySize(&cfg->display.width, &cfg->display.height, vout_display_GetDefaultDisplaySize(&cfg->display.width, &cfg->display.height,
...@@ -1131,15 +1133,23 @@ static vout_display_t *DisplayNew(vout_thread_t *vout, ...@@ -1131,15 +1133,23 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
osys->mouse.double_click_timeout = double_click_timeout; osys->mouse.double_click_timeout = double_click_timeout;
osys->mouse.hide_timeout = hide_timeout; osys->mouse.hide_timeout = hide_timeout;
osys->is_fullscreen = cfg->is_fullscreen; osys->is_fullscreen = cfg->is_fullscreen;
osys->width_saved =
osys->display_width = cfg->display.width; osys->display_width = cfg->display.width;
osys->height_saved =
osys->display_height = cfg->display.height; osys->display_height = cfg->display.height;
osys->is_display_filled = cfg->is_display_filled; 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.num = cfg->zoom.num;
osys->zoom.den = cfg->zoom.den; osys->zoom.den = cfg->zoom.den;
osys->wm_state = state->is_on_top ? VOUT_WINDOW_STATE_ABOVE osys->wm_state = state->wm_state;
: VOUT_WINDOW_STATE_NORMAL;
osys->fit_window = 0; osys->fit_window = 0;
osys->source = *source_org; osys->source = *source_org;
...@@ -1208,9 +1218,9 @@ void vout_DeleteDisplay(vout_display_t *vd, vout_display_state_t *state) ...@@ -1208,9 +1218,9 @@ void vout_DeleteDisplay(vout_display_t *vd, vout_display_state_t *state)
if (state) { if (state) {
if (!osys->is_wrapper ) if (!osys->is_wrapper )
state->cfg = osys->cfg; state->cfg = osys->cfg;
state->is_on_top = (osys->wm_state & VOUT_WINDOW_STATE_ABOVE) != 0; state->wm_state = osys->wm_state;
state->sar.num = osys->sar_initial.num; state->sar.num = osys->sar_initial.num;
state->sar.den = osys->sar_initial.den; state->sar.den = osys->sar_initial.den;
} }
VoutDisplayDestroyRender(vd); VoutDisplayDestroyRender(vd);
...@@ -1537,20 +1547,4 @@ static void DummyVoutSendDisplayEventMouse(vout_thread_t *vout, vlc_mouse_t *fal ...@@ -1537,20 +1547,4 @@ static void DummyVoutSendDisplayEventMouse(vout_thread_t *vout, vlc_mouse_t *fal
} }
} }
#endif #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);
}
...@@ -427,6 +427,89 @@ void vout_ControlChangeSubFilters(vout_thread_t *vout, const char *filters) ...@@ -427,6 +427,89 @@ void vout_ControlChangeSubFilters(vout_thread_t *vout, const char *filters)
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) static picture_t *VoutVideoFilterNewPicture(filter_t *filter)
{ {
...@@ -845,7 +928,7 @@ static void ThreadExecuteCropRatio(vout_thread_t *vout, ...@@ -845,7 +928,7 @@ static void ThreadExecuteCropRatio(vout_thread_t *vout,
source->i_visible_height); 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); vlc_mouse_Init(&vout->p->mouse);
vout->p->decoder_fifo = picture_fifo_New(); vout->p->decoder_fifo = picture_fifo_New();
...@@ -857,7 +940,18 @@ static int ThreadStart(vout_thread_t *vout) ...@@ -857,7 +940,18 @@ static int ThreadStart(vout_thread_t *vout)
filter_chain_New( vout, "video filter2", false, filter_chain_New( vout, "video filter2", false,
VoutVideoFilterAllocationSetup, NULL, vout); 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; return VLC_EGENERIC;
if (vout_InitWrapper(vout)) if (vout_InitWrapper(vout))
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -877,7 +971,7 @@ static int ThreadStart(vout_thread_t *vout) ...@@ -877,7 +971,7 @@ static int ThreadStart(vout_thread_t *vout)
return VLC_SUCCESS; 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 */ /* Destroy the video filters2 */
filter_chain_Delete(vout->p->vfilter_chain); filter_chain_Delete(vout->p->vfilter_chain);
...@@ -888,7 +982,7 @@ static void ThreadStop(vout_thread_t *vout) ...@@ -888,7 +982,7 @@ static void ThreadStop(vout_thread_t *vout)
ThreadFlush(vout, true, INT64_MAX); ThreadFlush(vout, true, INT64_MAX);
vout_EndWrapper(vout); vout_EndWrapper(vout);
} }
vout_CloseWrapper(vout); vout_CloseWrapper(vout, state);
} }
if (vout->p->decoder_fifo) if (vout->p->decoder_fifo)
...@@ -898,16 +992,22 @@ static void ThreadStop(vout_thread_t *vout) ...@@ -898,16 +992,22 @@ static void ThreadStop(vout_thread_t *vout)
static void ThreadInit(vout_thread_t *vout) static void ThreadInit(vout_thread_t *vout)
{ {
vout->p->dead = false; vout->p->window.is_unused = true;
vout->p->is_late_dropped = var_InheritBool(vout, "drop-late-frames"); vout->p->window.object = NULL;
vout->p->pause.is_on = false; vout->p->dead = false;
vout->p->pause.date = VLC_TS_INVALID; 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 */ vout_chrono_Init(&vout->p->render, 5, 10000); /* Arbitrary initial time */
} }
static void ThreadClean(vout_thread_t *vout) 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_chrono_Clean(&vout->p->render);
vout->p->dead = true; vout->p->dead = true;
vout_control_Dead(&vout->p->control); vout_control_Dead(&vout->p->control);
...@@ -918,17 +1018,29 @@ static int ThreadReinit(vout_thread_t *vout, ...@@ -918,17 +1018,29 @@ static int ThreadReinit(vout_thread_t *vout,
{ {
video_format_t original; video_format_t original;
if (VoutValidateFormat(&original, fmt)) { if (VoutValidateFormat(&original, fmt)) {
ThreadStop(vout); ThreadStop(vout, NULL);
ThreadClean(vout); ThreadClean(vout);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if (video_format_IsSimilar(&original, &vout->p->original)) if (video_format_IsSimilar(&original, &vout->p->original))
return VLC_SUCCESS; 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; vout->p->original = original;
if (ThreadStart(vout)) { if (ThreadStart(vout, &state)) {
ThreadClean(vout); ThreadClean(vout);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -964,14 +1076,14 @@ static void *Thread(void *object) ...@@ -964,14 +1076,14 @@ static void *Thread(void *object)
switch(cmd.type) { switch(cmd.type) {
case VOUT_CONTROL_INIT: case VOUT_CONTROL_INIT:
ThreadInit(vout); ThreadInit(vout);
if (ThreadStart(vout)) { if (ThreadStart(vout, NULL)) {
ThreadStop(vout); ThreadStop(vout, NULL);
ThreadClean(vout); ThreadClean(vout);
return NULL; return NULL;
} }
break; break;
case VOUT_CONTROL_CLEAN: case VOUT_CONTROL_CLEAN:
ThreadStop(vout); ThreadStop(vout, NULL);
ThreadClean(vout); ThreadClean(vout);
return NULL; return NULL;
case VOUT_CONTROL_REINIT: case VOUT_CONTROL_REINIT:
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <vlc_picture_fifo.h> #include <vlc_picture_fifo.h>
#include <vlc_picture_pool.h> #include <vlc_picture_pool.h>
#include <vlc_vout_display.h> #include <vlc_vout_display.h>
#include <vlc_vout_wrapper.h>
#include "vout_control.h" #include "vout_control.h"
#include "control.h" #include "control.h"
#include "snapshot.h" #include "snapshot.h"
...@@ -61,6 +62,13 @@ struct vout_thread_sys_t ...@@ -61,6 +62,13 @@ struct vout_thread_sys_t
unsigned int i_par_num; unsigned int i_par_num;
unsigned int i_par_den; unsigned int i_par_den;
/* Video output window */
struct {
bool is_unused;
vout_window_cfg_t cfg;
vout_window_t *object;
} window;
/* Thread & synchronization */ /* Thread & synchronization */
vlc_thread_t thread; vlc_thread_t thread;
bool dead; bool dead;
...@@ -135,8 +143,8 @@ void vout_ControlChangeSubFilters(vout_thread_t *, const char *); ...@@ -135,8 +143,8 @@ void vout_ControlChangeSubFilters(vout_thread_t *, const char *);
void vout_IntfInit( vout_thread_t * ); void vout_IntfInit( vout_thread_t * );
/* */ /* */
int vout_OpenWrapper (vout_thread_t *, const char *); int vout_OpenWrapper (vout_thread_t *, const char *, const vout_display_state_t *);
void vout_CloseWrapper(vout_thread_t *); void vout_CloseWrapper(vout_thread_t *, vout_display_state_t *);
int vout_InitWrapper(vout_thread_t *); int vout_InitWrapper(vout_thread_t *);
void vout_EndWrapper(vout_thread_t *); void vout_EndWrapper(vout_thread_t *);
void vout_ManageWrapper(vout_thread_t *); void vout_ManageWrapper(vout_thread_t *);
......
...@@ -47,8 +47,6 @@ ...@@ -47,8 +47,6 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static void VoutGetDisplayCfg(vout_thread_t *,
vout_display_cfg_t *, const char *title);
#ifdef WIN32 #ifdef WIN32
static int Forward(vlc_object_t *, char const *, static int Forward(vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void *); vlc_value_t, vlc_value_t, void *);
...@@ -57,7 +55,8 @@ static int Forward(vlc_object_t *, char const *, ...@@ -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; vout_thread_sys_t *sys = vout->p;
msg_Dbg(vout, "Opening vout display wrapper"); msg_Dbg(vout, "Opening vout display wrapper");
...@@ -72,21 +71,15 @@ int vout_OpenWrapper(vout_thread_t *vout, const char *name) ...@@ -72,21 +71,15 @@ int vout_OpenWrapper(vout_thread_t *vout, const char *name)
source.i_x_offset = 0; source.i_x_offset = 0;
source.i_y_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 double_click_timeout = 300000;
const mtime_t hide_timeout = var_CreateGetInteger(vout, "mouse-hide-timeout") * 1000; 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); double_click_timeout, hide_timeout);
/* If we need to video filter and it fails, then try a splitter /* If we need to video filter and it fails, then try a splitter
* XXX it is a hack for now FIXME */ * XXX it is a hack for now FIXME */
if (name && !sys->display.vd) 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); double_click_timeout, hide_timeout);
if (!sys->display.vd) { if (!sys->display.vd) {
free(sys->display.title); free(sys->display.title);
...@@ -110,7 +103,7 @@ int vout_OpenWrapper(vout_thread_t *vout, const char *name) ...@@ -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; vout_thread_sys_t *sys = vout->p;
...@@ -120,7 +113,7 @@ void vout_CloseWrapper(vout_thread_t *vout) ...@@ -120,7 +113,7 @@ void vout_CloseWrapper(vout_thread_t *vout)
#endif #endif
sys->decoder_pool = NULL; /* FIXME remove */ sys->decoder_pool = NULL; /* FIXME remove */
vout_DeleteDisplay(sys->display.vd, NULL); vout_DeleteDisplay(sys->display.vd, state);
free(sys->display.title); free(sys->display.title);
} }
...@@ -222,36 +215,6 @@ void vout_DisplayWrapper(vout_thread_t *vout, picture_t *picture) ...@@ -222,36 +215,6 @@ void vout_DisplayWrapper(vout_thread_t *vout, picture_t *picture)
sys->display.filtered = NULL; 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 #ifdef WIN32
static int Forward(vlc_object_t *object, char const *var, static int Forward(vlc_object_t *object, char const *var,
vlc_value_t oldval, vlc_value_t newval, void *data) vlc_value_t oldval, vlc_value_t newval, void *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment