X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_output%2Fdisplay.c;h=5639deadce38b82d5c380ee587f4b182f25464c6;hb=26af1ac094f8abef021fb4bdb28fee39872ba345;hp=e3a3305c5bc74596607a0cf769fadb14eaf06bdd;hpb=7d6feff668bd4b361e7d504fda33c4ae3b8d98e4;p=vlc diff --git a/src/video_output/display.c b/src/video_output/display.c index e3a3305c5b..5639deadce 100644 --- a/src/video_output/display.c +++ b/src/video_output/display.c @@ -40,6 +40,10 @@ #include "event.h" +/* It must be present as long as a vout_display_t must be created using a dummy + * vout (as an opengl provider) */ +#define ALLOW_DUMMY_VOUT + static void SplitterClose(vout_display_t *vd); /***************************************************************************** @@ -54,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, 1); + if (!pool) + return NULL; + return picture_pool_Get(pool); } static void VideoBufferDelete(filter_t *filter, picture_t *picture) { @@ -64,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; } /***************************************************************************** @@ -98,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; @@ -108,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; @@ -122,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; } @@ -137,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); @@ -278,7 +281,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; @@ -303,8 +306,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 { @@ -353,8 +356,15 @@ struct vout_display_owner_sys_t { int display_width; int display_height; bool display_is_fullscreen; + bool display_is_forced; + +#ifdef ALLOW_DUMMY_VOUT + vlc_mouse_t vout_mouse; +#endif }; +static void DummyVoutSendDisplayEventMouse(vout_thread_t *, vlc_mouse_t *fallback, const vlc_mouse_t *m); + static void VoutDisplayCreateRender(vout_display_t *vd) { vout_display_owner_sys_t *osys = vd->owner.sys; @@ -362,12 +372,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; @@ -454,7 +462,7 @@ static void VoutDisplayEventMouse(vout_display_t *vd, int event, va_list args) const int x = (int)va_arg(args, int); const int y = (int)va_arg(args, int); if (x != osys->mouse.state.i_x || y != osys->mouse.state.i_y) { - msg_Dbg(vd, "VoutDisplayEvent 'mouse' @%d,%d", x, y); + //msg_Dbg(vd, "VoutDisplayEvent 'mouse' @%d,%d", x, y); m.i_x = x; m.i_y = y; @@ -526,7 +534,11 @@ static void VoutDisplayEventMouse(vout_display_t *vd, int event, va_list args) /* */ vout_SendEventMouseVisible(osys->vout); +#ifdef ALLOW_DUMMY_VOUT + DummyVoutSendDisplayEventMouse(osys->vout, &osys->vout_mouse, &m); +#else vout_SendDisplayEventMouse(osys->vout, &m); +#endif } static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args) @@ -567,6 +579,20 @@ static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args) break; } + case VOUT_DISPLAY_EVENT_WINDOW_STATE: { + const unsigned state = va_arg(args, unsigned); + + msg_Dbg(vd, "VoutDisplayEvent 'window state' %u", state); + + vlc_mutex_lock(&osys->lock); + if (state != osys->wm_state) { + osys->ch_wm_state = true; + osys->wm_state = state; + } + vlc_mutex_unlock(&osys->lock); + break; + } + case VOUT_DISPLAY_EVENT_DISPLAY_SIZE: { const int width = (int)va_arg(args, int); const int height = (int)va_arg(args, int); @@ -581,6 +607,7 @@ static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args) osys->display_width = width; osys->display_height = height; osys->display_is_fullscreen = is_fullscreen; + osys->display_is_forced = false; vlc_mutex_unlock(&osys->lock); break; @@ -617,7 +644,7 @@ static void VoutDisplayDelWindow(vout_display_t *vd, vout_window_t *window) vout_DeleteDisplayWindow(osys->vout, vd, window); } -void vout_ManageDisplay(vout_display_t *vd) +void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures) { vout_display_owner_sys_t *osys = vd->owner.sys; @@ -655,14 +682,24 @@ void vout_ManageDisplay(vout_display_t *vd) bool is_fullscreen = osys->is_fullscreen; osys->ch_fullscreen = 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; int display_height = osys->display_height; bool display_is_fullscreen = osys->display_is_fullscreen; + bool display_is_forced = osys->display_is_forced; osys->ch_display_size = false; - bool reset_pictures = osys->reset_pictures; - osys->reset_pictures = false; + bool reset_pictures; + if (allow_reset_pictures) { + reset_pictures = osys->reset_pictures; + osys->reset_pictures = false; + } else { + reset_pictures = false; + } vlc_mutex_unlock(&osys->lock); @@ -671,7 +708,7 @@ void vout_ManageDisplay(vout_display_t *vd) !reset_pictures && !osys->ch_display_filled && !osys->ch_zoom && - !osys->ch_on_top && + !ch_wm_state && !osys->ch_sar && !osys->ch_crop) break; @@ -701,7 +738,7 @@ void vout_ManageDisplay(vout_display_t *vd) cfg.display.height = display_height; if (!cfg.is_fullscreen != !display_is_fullscreen || - vout_display_Control(vd, VOUT_DISPLAY_CHANGE_DISPLAY_SIZE, &cfg)) { + vout_display_Control(vd, VOUT_DISPLAY_CHANGE_DISPLAY_SIZE, &cfg, display_is_forced)) { if (!cfg.is_fullscreen == !display_is_fullscreen) msg_Err(vd, "Failed to resize display"); @@ -755,7 +792,15 @@ void vout_ManageDisplay(vout_display_t *vd) 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; - vout_display_SendEventDisplaySize(vd, display_width, display_height, osys->cfg.is_fullscreen); + 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); } osys->cfg.zoom.num = osys->zoom.num; @@ -765,19 +810,15 @@ void vout_ManageDisplay(vout_display_t *vd) vout_SendEventZoom(osys->vout, osys->cfg.zoom.num, osys->cfg.zoom.den); } /* */ - if (osys->ch_on_top) { - bool is_on_top = osys->is_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 = - osys->is_on_top = is_on_top; - osys->ch_on_top = false; + 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) { @@ -936,21 +977,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; - if (!osys->is_on_top != !is_on_top) { - osys->ch_on_top = true; - osys->is_on_top = is_on_top; + vlc_mutex_lock(&osys->lock); + 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; @@ -980,7 +1026,13 @@ void vout_SetDisplayCrop(vout_display_t *vd, osys->ch_crop = true; } } - +vout_opengl_t *vout_GetDisplayOpengl(vout_display_t *vd) +{ + vout_opengl_t *gl; + if (vout_display_Control(vd, VOUT_DISPLAY_GET_OPENGL, &gl)) + return NULL; + return gl; +} static vout_display_t *DisplayNew(vout_thread_t *vout, const video_format_t *source_org, @@ -996,7 +1048,8 @@ 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 = state->is_on_top + ? VOUT_WINDOW_STATE_ABOVE : VOUT_WINDOW_STATE_NORMAL; osys->sar_initial.num = state->sar.num; osys->sar_initial.den = state->sar.den; vout_display_GetDefaultDisplaySize(&cfg->display.width, &cfg->display.height, @@ -1040,6 +1093,9 @@ static vout_display_t *DisplayNew(vout_thread_t *vout, osys->sar.num = osys->sar_initial.num ? osys->sar_initial.num : source.i_sar_num; osys->sar.den = osys->sar_initial.den ? osys->sar_initial.den : source.i_sar_den; +#ifdef ALLOW_DUMMY_VOUT + vlc_mouse_Init(&osys->vout_mouse); +#endif vout_display_owner_t owner; if (owner_ptr) { @@ -1066,8 +1122,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 != VOUT_WINDOW_STATE_NORMAL) + 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 || @@ -1084,7 +1140,7 @@ 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->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; } @@ -1393,12 +1449,28 @@ void vout_SendDisplayEventMouse(vout_thread_t *vout, const vlc_mouse_t *m) vout_SendEventMouseDoubleClick(vout); vout->p->mouse = *m; } +#ifdef ALLOW_DUMMY_VOUT +static void DummyVoutSendDisplayEventMouse(vout_thread_t *vout, vlc_mouse_t *fallback, const vlc_mouse_t *m) +{ + vout_thread_sys_t p; + + if (!vout->p) { + p.mouse = *fallback; + vout->p = &p; + } + vout_SendDisplayEventMouse(vout, m); + if (vout->p == &p) { + *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" ) ) + if( !var_InheritBool( vout, "embedded-video" ) ) cfg_override.is_standalone = true; return vout_window_New(VLC_OBJECT(vout), NULL, &cfg_override);