From ed9295c250ddfb845e48f123343e7b02326e8920 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 1 Oct 2013 23:35:51 +0200 Subject: video/out: always support redrawing VO window at any point Before, a VO could easily refuse to respond to VOCTRL_REDRAW_FRAME, which means the VO wouldn't redraw OSD and window contents, and the player would appear frozen to the user. This was a bit stupid, and makes dealing with some corner cases much harder (think of --keep-open, which was hard to implement, because the VO gets into this state if there are no new video frames after a seek reset). Change this, and require VOs to always react to VOCTRL_REDRAW_FRAME. There are two aspects of this: First, behavior after a (successful) vo_reconfig() call, but before any video frame has been displayed. Second, behavior after a vo_seek_reset(). For the first issue, we define that sending VOCTRL_REDRAW_FRAME after vo_reconfig() should clear the window with black. This requires minor changes to some VOs. In particular vaapi makes this horribly complicated, because OSD rendering is bound to a video surface. We create a black dummy surface for this purpose. The second issue is much simpler and works already with most VOs: they simply redraw whatever has been uploaded previously. The exception is vdpau, which has a complicated mechanism to track and filter video frames. The state associated with this mechanism is completely cleared with vo_seek_reset(), so implementing this to work as expected is not trivial. For now, we just clear the window with black. --- video/out/vo_direct3d.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'video/out/vo_direct3d.c') diff --git a/video/out/vo_direct3d.c b/video/out/vo_direct3d.c index e265b0b38f..f16ac87703 100644 --- a/video/out/vo_direct3d.c +++ b/video/out/vo_direct3d.c @@ -130,6 +130,8 @@ typedef struct d3d_priv { struct vo *vo; + bool have_image; + D3DLOCKED_RECT locked_rect; /**< The locked offscreen surface */ RECT fs_movie_rect; /**< Rect (upscaled) of the movie when displayed in fullscreen */ @@ -842,6 +844,9 @@ static uint32_t d3d_draw_frame(d3d_priv *priv) IDirect3DDevice9_Clear(priv->d3d_device, 0, NULL, D3DCLEAR_TARGET, 0, 0, 0); + if (!priv->have_image) + return VO_TRUE; + if (priv->use_textures) { for (n = 0; n < priv->plane_count; n++) { @@ -1271,6 +1276,8 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, { d3d_priv *priv = vo->priv; + priv->have_image = false; + /* w32_common framework call. Creates window on the screen with * the given coordinates. */ @@ -1412,6 +1419,8 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) } } + priv->have_image = true; + d3d_draw_frame(priv); } @@ -1420,6 +1429,9 @@ static mp_image_t *get_screenshot(d3d_priv *priv) if (!priv->d3d_device) return NULL; + if (!priv->have_image) + return NULL; + struct mp_image buffer; if (!get_video_buffer(priv, &buffer)) return NULL; -- cgit v1.2.3