diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/cocoa_common.h | 2 | ||||
-rw-r--r-- | video/out/cocoa_common.m | 36 | ||||
-rw-r--r-- | video/out/gl_video.c | 91 | ||||
-rw-r--r-- | video/out/vo.c | 75 | ||||
-rw-r--r-- | video/out/vo.h | 8 | ||||
-rw-r--r-- | video/out/vo_lavc.c | 70 | ||||
-rw-r--r-- | video/out/vo_sdl.c | 6 | ||||
-rw-r--r-- | video/out/vo_xv.c | 6 | ||||
-rw-r--r-- | video/out/w32_common.c | 33 | ||||
-rw-r--r-- | video/out/w32_common.h | 1 | ||||
-rw-r--r-- | video/out/wayland_common.c | 4 | ||||
-rw-r--r-- | video/out/x11_common.c | 19 |
12 files changed, 220 insertions, 131 deletions
diff --git a/video/out/cocoa_common.h b/video/out/cocoa_common.h index f6af87f3b7..081c43d2ce 100644 --- a/video/out/cocoa_common.h +++ b/video/out/cocoa_common.h @@ -39,8 +39,6 @@ void vo_cocoa_swap_buffers(struct vo *vo); int vo_cocoa_check_events(struct vo *vo); void vo_cocoa_fullscreen(struct vo *vo); void vo_cocoa_ontop(struct vo *vo); -void vo_cocoa_pause(struct vo *vo); -void vo_cocoa_resume(struct vo *vo); int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg); void vo_cocoa_register_resize_callback(struct vo *vo, diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index b561ca892b..b5de22f951 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -149,7 +149,6 @@ static void disable_power_management(struct vo *vo) int vo_cocoa_init(struct vo *vo) { vo->cocoa = vo_cocoa_init_state(vo); - disable_power_management(vo); return 1; } @@ -185,16 +184,6 @@ void vo_cocoa_uninit(struct vo *vo) }); } -void vo_cocoa_pause(struct vo *vo) -{ - enable_power_management(vo); -} - -void vo_cocoa_resume(struct vo *vo) -{ - disable_power_management(vo); -} - void vo_cocoa_register_resize_callback(struct vo *vo, void (*cb)(struct vo *vo, int w, int h)) { @@ -266,7 +255,8 @@ static void vo_set_level(struct vo *vo, int ontop) s->window_level = NSNormalWindowLevel; } - [s->window setLevel:s->window_level]; + [[s->view window] setLevel:s->window_level]; + [s->window setLevel:s->window_level]; } void vo_cocoa_ontop(struct vo *vo) @@ -386,6 +376,12 @@ static int create_gl_context(struct vo *vo, int gl3profile) return 0; } +static void cocoa_set_window_title(struct vo *vo, const char *title) +{ + struct vo_cocoa_state *s = vo->cocoa; + [s->window setTitle: [NSString stringWithUTF8String:title]]; +} + static void update_window(struct vo *vo) { struct vo_cocoa_state *s = vo->cocoa; @@ -401,8 +397,7 @@ static void update_window(struct vo *vo) } } - [s->window setTitle: - [NSString stringWithUTF8String:vo_get_window_title(vo)]]; + cocoa_set_window_title(vo, vo_get_window_title(vo)); resize_window(vo); } @@ -555,11 +550,15 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg) vo_cocoa_set_cursor_visibility(vo, visible); return VO_TRUE; } - case VOCTRL_PAUSE: - vo_cocoa_pause(vo); + case VOCTRL_UPDATE_WINDOW_TITLE: { + cocoa_set_window_title(vo, (const char *) arg); + return VO_TRUE; + } + case VOCTRL_RESTORE_SCREENSAVER: + enable_power_management(vo); return VO_TRUE; - case VOCTRL_RESUME: - vo_cocoa_resume(vo); + case VOCTRL_KILL_SCREENSAVER: + disable_power_management(vo); return VO_TRUE; } return VO_NOTIMPL; @@ -635,7 +634,6 @@ int vo_cocoa_cgl_color_size(struct vo *vo) popts |= NSApplicationPresentationAutoHideDock; NSDictionary *fsopts = @{ - NSFullScreenModeWindowLevel : @(NSFloatingWindowLevel), NSFullScreenModeAllScreens : @NO, NSFullScreenModeApplicationPresentationOptions : @(popts) }; diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 7c6ecd426e..4d780f41d8 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -132,7 +132,7 @@ struct fbotex { GLuint fbo; GLuint texture; int tex_w, tex_h; // size of .texture - int vp_w, vp_h; // viewport of fbo / used part of the texture + int vp_x, vp_y, vp_w, vp_h; // viewport of fbo / used part of the texture }; struct gl_video { @@ -397,10 +397,12 @@ static bool fbotex_init(struct gl_video *p, struct fbotex *fbo, int w, int h, assert(!fbo->fbo); assert(!fbo->texture); - tex_size(p, w, h, &fbo->tex_w, &fbo->tex_h); + *fbo = (struct fbotex) { + .vp_w = w, + .vp_h = h, + }; - fbo->vp_w = w; - fbo->vp_h = h; + tex_size(p, w, h, &fbo->tex_w, &fbo->tex_h); mp_msg(MSGT_VO, MSGL_V, "[gl] Create FBO: %dx%d\n", fbo->tex_w, fbo->tex_h); @@ -505,7 +507,7 @@ static void update_uniforms(struct gl_video *p, GLuint program) gl->Uniform1i(gl->GetUniformLocation(program, textures_n), n); gl->Uniform2f(gl->GetUniformLocation(program, textures_size_n), - p->image.planes[n].w, p->image.planes[n].h); + p->image.planes[n].tex_w, p->image.planes[n].tex_h); } gl->Uniform2f(gl->GetUniformLocation(program, "dither_size"), @@ -1055,7 +1057,7 @@ static void reinit_rendering(struct gl_video *p) update_all_uniforms(p); if (p->indirect_program && !p->indirect_fbo.fbo) - fbotex_init(p, &p->indirect_fbo, p->texture_w, p->texture_h, + fbotex_init(p, &p->indirect_fbo, p->image_w, p->image_h, p->opts.fbo_format); recreate_osd(p); @@ -1214,17 +1216,17 @@ static void change_dither_trafo(struct gl_video *p) gl->UseProgram(0); } -static void render_to_fbo(struct gl_video *p, struct fbotex *fbo, int w, int h, - int tex_w, int tex_h) +static void render_to_fbo(struct gl_video *p, struct fbotex *fbo, + int x, int y, int w, int h, int tex_w, int tex_h) { GL *gl = p->gl; - gl->Viewport(0, 0, fbo->vp_w, fbo->vp_h); + gl->Viewport(fbo->vp_x, fbo->vp_y, fbo->vp_w, fbo->vp_h); gl->BindFramebuffer(GL_FRAMEBUFFER, fbo->fbo); struct vertex vb[VERTICES_PER_QUAD]; write_quad(vb, -1, -1, 1, 1, - 0, 0, w, h, + x, y, x + w, y + h, tex_w, tex_h, NULL, false); draw_triangles(p, vb, VERTICES_PER_QUAD); @@ -1234,7 +1236,8 @@ static void render_to_fbo(struct gl_video *p, struct fbotex *fbo, int w, int h, } -static void handle_pass(struct gl_video *p, struct fbotex **source, +// *chain contains the source, and is overwritten with a copy of the result +static void handle_pass(struct gl_video *p, struct fbotex *chain, struct fbotex *fbo, GLuint program) { GL *gl = p->gl; @@ -1242,11 +1245,12 @@ static void handle_pass(struct gl_video *p, struct fbotex **source, if (!program) return; - gl->BindTexture(GL_TEXTURE_2D, (*source)->texture); + gl->BindTexture(GL_TEXTURE_2D, chain->texture); gl->UseProgram(program); - render_to_fbo(p, fbo, (*source)->vp_w, (*source)->vp_h, - (*source)->tex_w, (*source)->tex_h); - *source = fbo; + render_to_fbo(p, fbo, chain->vp_x, chain->vp_y, + chain->vp_w, chain->vp_h, + chain->tex_w, chain->tex_h); + *chain = *fbo; } void gl_video_render_frame(struct gl_video *p) @@ -1271,24 +1275,34 @@ void gl_video_render_frame(struct gl_video *p) set_image_textures(p, vimg); - struct fbotex dummy = { - .vp_w = p->image_w, .vp_h = p->image_h, - .tex_w = p->texture_w, .tex_h = p->texture_h, + struct fbotex chain = { + .vp_w = p->image_w, + .vp_h = p->image_h, + .tex_w = p->texture_w, + .tex_h = p->texture_h, .texture = vimg->planes[0].gl_texture, }; - struct fbotex *source = &dummy; - handle_pass(p, &source, &p->indirect_fbo, p->indirect_program); - handle_pass(p, &source, &p->scale_sep_fbo, p->scale_sep_program); + handle_pass(p, &chain, &p->indirect_fbo, p->indirect_program); + + // Clip to visible height so that separate scaling scales the visible part + // only (and the target FBO texture can have a bounded size). + // Don't clamp width; too hard to get correct final scaling on l/r borders. + chain.vp_y = p->src_rect.y0, + chain.vp_h = p->src_rect.y1 - p->src_rect.y0, - gl->BindTexture(GL_TEXTURE_2D, source->texture); + handle_pass(p, &chain, &p->scale_sep_fbo, p->scale_sep_program); + + gl->BindTexture(GL_TEXTURE_2D, chain.texture); gl->UseProgram(p->final_program); - float final_texw = p->image_w * source->tex_w / (float)source->vp_w; - float final_texh = p->image_h * source->tex_h / (float)source->vp_h; + struct mp_rect src = {p->src_rect.x0, chain.vp_y, + p->src_rect.x1, chain.vp_y + chain.vp_h}; + int src_texw = chain.tex_w; + int src_texh = chain.tex_h; if (p->opts.stereo_mode) { - int w = p->src_rect.x1 - p->src_rect.x0; + int w = src.x1 - src.x0; int imgw = p->image_w; glEnable3DLeft(gl, p->opts.stereo_mode); @@ -1296,9 +1310,9 @@ void gl_video_render_frame(struct gl_video *p) write_quad(vb, p->dst_rect.x0, p->dst_rect.y0, p->dst_rect.x1, p->dst_rect.y1, - p->src_rect.x0 / 2, p->src_rect.y0, - p->src_rect.x0 / 2 + w / 2, p->src_rect.y1, - final_texw, final_texh, + src.x0 / 2, src.y0, + src.x0 / 2 + w / 2, src.y1, + src_texw, src_texh, NULL, is_flipped); draw_triangles(p, vb, VERTICES_PER_QUAD); @@ -1307,9 +1321,9 @@ void gl_video_render_frame(struct gl_video *p) write_quad(vb, p->dst_rect.x0, p->dst_rect.y0, p->dst_rect.x1, p->dst_rect.y1, - p->src_rect.x0 / 2 + imgw / 2, p->src_rect.y0, - p->src_rect.x0 / 2 + imgw / 2 + w / 2, p->src_rect.y1, - final_texw, final_texh, + src.x0 / 2 + imgw / 2, src.y0, + src.x0 / 2 + imgw / 2 + w / 2, src.y1, + src_texw, src_texh, NULL, is_flipped); draw_triangles(p, vb, VERTICES_PER_QUAD); @@ -1318,9 +1332,9 @@ void gl_video_render_frame(struct gl_video *p) write_quad(vb, p->dst_rect.x0, p->dst_rect.y0, p->dst_rect.x1, p->dst_rect.y1, - p->src_rect.x0, p->src_rect.y0, - p->src_rect.x1, p->src_rect.y1, - final_texw, final_texh, + src.x0, src.y0, + src.x1, src.y1, + src_texw, src_texh, NULL, is_flipped); draw_triangles(p, vb, VERTICES_PER_QUAD); } @@ -1408,11 +1422,6 @@ static bool get_image(struct gl_video *p, struct mp_image *mpi) if (!p->opts.pbo) return false; - // We don't support alpha planes. (Disabling PBOs with normal draw calls is - // an undesired, but harmless side-effect.) - if (mpi->num_planes != p->plane_count) - return false; - struct video_image *vimg = &p->image; for (int n = 0; n < p->plane_count; n++) { @@ -1441,7 +1450,7 @@ void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi) GL *gl = p->gl; int n; - assert(mpi->num_planes >= p->plane_count); + assert(mpi->num_planes == p->plane_count); struct video_image *vimg = &p->image; @@ -1788,7 +1797,7 @@ static bool init_format(int fmt, struct gl_video *init) plane_format[0] = byte_formats[1]; } - // XYZ (same roganization as RGB packed, but requires conversion matrix) + // XYZ (same organization as RGB packed, but requires conversion matrix) if (!supported && fmt == IMGFMT_XYZ12) { supported = true; plane_format[0] = IMGFMT_RGB48; diff --git a/video/out/vo.c b/video/out/vo.c index bf4f1660e1..c621f37472 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -26,6 +26,8 @@ #include <unistd.h> +#include <libavutil/common.h> + #include "talloc.h" #include "config.h" @@ -466,25 +468,53 @@ static void print_video_rect(struct vo *vo, struct mp_rect src, dst.x0, dst.y0, vo->dwidth - dst.x1, vo->dheight - dst.y1); } +// Clamp [start, end) to range [0, size) with various fallbacks. +static void clamp_size(int size, int *start, int *end) +{ + *start = FFMAX(0, *start); + *end = FFMIN(size, *end); + if (*start >= *end) { + *start = 0; + *end = 1; + } +} + +// Round source to a multiple of 2, this is at least needed for vo_direct3d +// and ATI cards. +#define VID_SRC_ROUND_UP(x) (((x) + 1) & ~1) + static void src_dst_split_scaling(int src_size, int dst_size, - int scaled_src_size, int *src_start, - int *src_end, int *dst_start, int *dst_end) + int scaled_src_size, + int *src_start, int *src_end, + int *dst_start, int *dst_end, + int *osd_margin_a, int *osd_margin_b) { - if (scaled_src_size > dst_size) { - int border = src_size * (scaled_src_size - dst_size) / scaled_src_size; - // round to a multiple of 2, this is at least needed for vo_direct3d - // and ATI cards - border = (border / 2 + 1) & ~1; - *src_start = border; - *src_end = src_size - border; + *src_start = 0; + *src_end = src_size; + *dst_start = (dst_size - scaled_src_size) / 2; + *dst_end = *dst_start + scaled_src_size; + + // Distance of screen frame to video + *osd_margin_a = *dst_start; + *osd_margin_b = dst_size - *dst_end; + + // Clip to screen + int s_src = *src_end - *src_start; + int s_dst = *dst_end - *dst_start; + if (*dst_start < 0) { + int border = -(*dst_start) * s_src / s_dst; + *src_start += VID_SRC_ROUND_UP(border); *dst_start = 0; - *dst_end = dst_size; - } else { - *src_start = 0; - *src_end = src_size; - *dst_start = (dst_size - scaled_src_size) / 2; - *dst_end = *dst_start + scaled_src_size; } + if (*dst_end > dst_size) { + int border = (*dst_end - dst_size) * s_src / s_dst; + *src_end -= VID_SRC_ROUND_UP(border); + *dst_end = dst_size; + } + + // For sanity: avoid bothering VOs with corner cases + clamp_size(src_size, src_start, src_end); + clamp_size(dst_size, dst_start, dst_end); } // Calculate the appropriate source and destination rectangle to @@ -495,6 +525,7 @@ static void src_dst_split_scaling(int src_size, int dst_size, void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src, struct mp_rect *out_dst, struct mp_osd_res *out_osd) { + struct mp_vo_opts *opts = vo->opts; int src_w = vo->aspdat.orgw; int src_h = vo->aspdat.orgh; struct mp_rect dst = {0, 0, vo->dwidth, vo->dheight}; @@ -505,19 +536,15 @@ void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src, .display_par = vo->aspdat.monitor_par, .video_par = vo->aspdat.par, }; - if (vo->opts->keepaspect) { + if (opts->keepaspect) { int scaled_width, scaled_height; aspect_calc_panscan(vo, &scaled_width, &scaled_height); - int border_w = vo->dwidth - scaled_width; - int border_h = vo->dheight - scaled_height; - osd.ml = border_w / 2; - osd.mt = border_h / 2; - osd.mr = border_w - osd.ml; - osd.mb = border_h - osd.mt; src_dst_split_scaling(src_w, vo->dwidth, scaled_width, - &src.x0, &src.x1, &dst.x0, &dst.x1); + &src.x0, &src.x1, &dst.x0, &dst.x1, + &osd.ml, &osd.mr); src_dst_split_scaling(src_h, vo->dheight, scaled_height, - &src.y0, &src.y1, &dst.y0, &dst.y1); + &src.y0, &src.y1, &dst.y0, &dst.y1, + &osd.mt, &osd.mb); } *out_src = src; diff --git a/video/out/vo.h b/video/out/vo.h index 3dcc58b6c3..df16a01d0e 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -60,9 +60,13 @@ enum mp_voctrl { VOCTRL_ONTOP, VOCTRL_BORDER, + VOCTRL_UPDATE_WINDOW_TITLE, // char* VOCTRL_SET_CURSOR_VISIBILITY, // bool + VOCTRL_KILL_SCREENSAVER, + VOCTRL_RESTORE_SCREENSAVER, + VOCTRL_SET_DEINTERLACE, VOCTRL_GET_DEINTERLACE, @@ -107,8 +111,8 @@ struct voctrl_screenshot_args { bool has_osd; }; -#define VO_TRUE 1 -#define VO_FALSE 0 +#define VO_TRUE true +#define VO_FALSE false #define VO_ERROR -1 #define VO_NOTAVAIL -2 #define VO_NOTIMPL -3 diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c index 5140720f92..ca3f1c5a5f 100644 --- a/video/out/vo_lavc.c +++ b/video/out/vo_lavc.c @@ -48,6 +48,8 @@ struct priv { double lastpts; int64_t lastipts; int64_t lastframeipts; + int64_t lastencodedipts; + int64_t mindeltapts; double expected_next_pts; mp_image_t *lastimg; int lastimg_wants_osd; @@ -64,7 +66,7 @@ static int preinit(struct vo *vo, const char *arg) struct priv *vc; if (!encode_lavc_available(vo->encode_lavc_ctx)) { mp_msg(MSGT_ENCODE, MSGL_ERR, - "vo-lavc: the option -o (output file) must be specified\n"); + "vo-lavc: the option --o (output file) must be specified\n"); return -1; } vo->priv = talloc_zero(vo, struct priv); @@ -136,6 +138,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, vc->lastipts = MP_NOPTS_VALUE; vc->lastframeipts = MP_NOPTS_VALUE; + vc->lastencodedipts = MP_NOPTS_VALUE; if (pix_fmt == PIX_FMT_NONE) goto error; /* imgfmt2pixfmt already prints something */ @@ -207,7 +210,7 @@ static void write_packet(struct vo *vo, int size, AVPacket *packet) vc->stream->codec->time_base, vc->stream->time_base); } else { - mp_msg(MSGT_ENCODE, MSGL_WARN, "vo-lavc: codec did not provide pts\n"); + mp_msg(MSGT_ENCODE, MSGL_V, "vo-lavc: codec did not provide pts\n"); packet->pts = av_rescale_q(vc->lastipts, vc->worst_time_base, vc->stream->time_base); } @@ -317,6 +320,11 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) vc->worst_time_base = vc->stream->time_base; vc->worst_time_base_is_stream = 1; } + if (ectx->options->maxfps) + vc->mindeltapts = ceil(vc->worst_time_base.den / + (vc->worst_time_base.num * ectx->options->maxfps)); + else + vc->mindeltapts = 0; // NOTE: we use the following "axiom" of av_rescale_q: // if time base A is worse than time base B, then @@ -387,11 +395,15 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) } // never-drop mode - if (ectx->options->neverdrop && frameipts <= vc->lastipts) { - mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: -oneverdrop increased pts by %d\n", - (int) (vc->lastipts - frameipts + 1)); - frameipts = vc->lastipts + 1; - vc->lastpts = frameipts * timeunit - encode_lavc_getoffset(ectx, vc->stream); + if (ectx->options->neverdrop) { + int64_t step = vc->mindeltapts ? vc->mindeltapts : 1; + if (frameipts < vc->lastipts + step) { + mp_msg(MSGT_ENCODE, MSGL_INFO, + "vo-lavc: --oneverdrop increased pts by %d\n", + (int) (vc->lastipts - frameipts + step)); + frameipts = vc->lastipts + step; + vc->lastpts = frameipts * timeunit - encode_lavc_getoffset(ectx, vc->stream); + } } if (vc->lastipts != MP_NOPTS_VALUE) { @@ -402,26 +414,36 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) int64_t thisduration = vc->harddup ? 1 : (frameipts - vc->lastipts); AVPacket packet; - avcodec_get_frame_defaults(frame); - - // this is a nop, unless the worst time base is the STREAM time base - frame->pts = av_rescale_q(vc->lastipts, vc->worst_time_base, - avc->time_base); - - for (i = 0; i < 4; i++) { - frame->data[i] = vc->lastimg->planes[i]; - frame->linesize[i] = vc->lastimg->stride[i]; + // we will ONLY encode this frame if it can be encoded at at least + // vc->mindeltapts after the last encoded frame! + int64_t skipframes = + vc->lastencodedipts + vc->mindeltapts - vc->lastipts; + if (skipframes < 0) + skipframes = 0; + + if (thisduration > skipframes) { + avcodec_get_frame_defaults(frame); + + // this is a nop, unless the worst time base is the STREAM time base + frame->pts = av_rescale_q(vc->lastipts + skipframes, + vc->worst_time_base, avc->time_base); + + for (i = 0; i < 4; i++) { + frame->data[i] = vc->lastimg->planes[i]; + frame->linesize[i] = vc->lastimg->stride[i]; + } + frame->quality = avc->global_quality; + + av_init_packet(&packet); + packet.data = vc->buffer; + packet.size = vc->buffer_size; + size = encode_video(vo, frame, &packet); + write_packet(vo, size, &packet); + ++vc->lastdisplaycount; + vc->lastencodedipts = vc->lastipts + skipframes; } - frame->quality = avc->global_quality; - - av_init_packet(&packet); - packet.data = vc->buffer; - packet.size = vc->buffer_size; - size = encode_video(vo, frame, &packet); - write_packet(vo, size, &packet); vc->lastipts += thisduration; - ++vc->lastdisplaycount; } avcodec_free_frame(&frame); diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index dd825c30d8..66013e01f2 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -939,6 +939,8 @@ static int get_eq(struct vo *vo, const char *name, int *value) static int control(struct vo *vo, uint32_t request, void *data) { + struct priv *vc = vo->priv; + switch (request) { case VOCTRL_CHECK_EVENTS: check_events(vo); @@ -976,6 +978,10 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_SET_CURSOR_VISIBILITY: SDL_ShowCursor(*(bool *)data); return true; + case VOCTRL_UPDATE_WINDOW_TITLE: + if (vc->window) + SDL_SetWindowTitle(vc->window, vo_get_window_title(vo)); + return true; } return VO_NOTIMPL; } diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index 0f02310473..fd8901da80 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -477,6 +477,8 @@ static void resize(struct vo *vo) vo_x11_clear_background(vo, &ctx->dst_rect); xv_draw_colorkey(vo, &ctx->dst_rect); read_xv_csp(vo); + + vo->want_redraw = true; } /* @@ -945,10 +947,8 @@ static int control(struct vo *vo, uint32_t request, void *data) } int events = 0; int r = vo_x11_control(vo, &events, request, data); - if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) { + if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) resize(vo); - vo->want_redraw = true; - } return r; } diff --git a/video/out/w32_common.c b/video/out/w32_common.c index 42a158a42f..7d60435c5b 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -174,10 +174,13 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, break; case WM_SYSCOMMAND: switch (wParam) { - case SC_SCREENSAVE: - case SC_MONITORPOWER: + case SC_SCREENSAVE: + case SC_MONITORPOWER: + if (w32->disable_screensaver) { mp_msg(MSGT_VO, MSGL_V, "vo: win32: killing screensaver\n"); return 0; + } + break; } break; case WM_KEYDOWN: @@ -404,10 +407,6 @@ static int reinit_window_state(struct vo *vo) if (vo->opts->WinID >= 0) return 1; - wchar_t *title = mp_from_utf8(NULL, vo_get_window_title(vo)); - SetWindowTextW(w32->window, title); - talloc_free(title); - bool toggle_fs = w32->current_fs != vo->opts->fs; w32->current_fs = vo->opts->fs; @@ -567,12 +566,10 @@ int vo_w32_config(struct vo *vo, uint32_t width, uint32_t height, */ int vo_w32_init(struct vo *vo) { - struct vo_w32_state *w32 = vo->w32; - if (w32 && w32->window) - return 1; + assert(!vo->w32); - if (!w32) - w32 = vo->w32 = talloc_zero(vo, struct vo_w32_state); + struct vo_w32_state *w32 = talloc_zero(vo, struct vo_w32_state); + vo->w32 = w32; HINSTANCE hInstance = GetModuleHandleW(NULL); @@ -672,6 +669,7 @@ static void vo_w32_ontop(struct vo *vo) int vo_w32_control(struct vo *vo, int *events, int request, void *arg) { + struct vo_w32_state *w32 = vo->w32; switch (request) { case VOCTRL_CHECK_EVENTS: *events |= vo_w32_check_events(vo); @@ -696,6 +694,19 @@ int vo_w32_control(struct vo *vo, int *events, int request, void *arg) } else { while (ShowCursor(0) >= 0) { } } + return VO_TRUE; + case VOCTRL_KILL_SCREENSAVER: + w32->disable_screensaver = true; + return VO_TRUE; + case VOCTRL_RESTORE_SCREENSAVER: + w32->disable_screensaver = false; + return VO_TRUE; + case VOCTRL_UPDATE_WINDOW_TITLE: { + wchar_t *title = mp_from_utf8(NULL, (char *)arg); + SetWindowTextW(w32->window, title); + talloc_free(title); + return VO_TRUE; + } } return VO_NOTIMPL; } diff --git a/video/out/w32_common.h b/video/out/w32_common.h index 1bbf27730f..3db34a8472 100644 --- a/video/out/w32_common.h +++ b/video/out/w32_common.h @@ -44,6 +44,7 @@ struct vo_w32_state { uint32_t o_dwidth; uint32_t o_dheight; + bool disable_screensaver; int event_flags; int mon_cnt; int mon_id; diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 332cf68e32..a627100477 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -865,6 +865,9 @@ int vo_wayland_control (struct vo *vo, int *events, int request, void *arg) } wl->display->cursor.visible = *(bool *)arg; return VO_TRUE; + case VOCTRL_UPDATE_WINDOW_TITLE: + wl_shell_surface_set_title(wl->window->shell_surface, (char *) arg); + return VO_TRUE; } return VO_NOTIMPL; } @@ -880,6 +883,5 @@ bool vo_wayland_config (struct vo *vo, uint32_t d_width, if ((VOFLAG_FULLSCREEN & flags) && w->type != TYPE_FULLSCREEN) vo_wayland_fullscreen(vo); - wl_shell_surface_set_title(w->shell_surface, vo_get_window_title(vo)); return true; } diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 5eb6031d66..9d2db30924 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -496,9 +496,6 @@ int vo_x11_init(struct vo *vo) fstype_dump(x11->fs_type); - if (opts->stop_screensaver) - saver_off(x11); - vo->event_fd = ConnectionNumber(x11->display); return 1; @@ -918,6 +915,9 @@ static void vo_x11_update_window_title(struct vo *vo) { struct vo_x11_state *x11 = vo->x11; + if (!x11->window) + return; + const char *title = vo_get_window_title(vo); vo_x11_set_property_string(vo, XA_WM_NAME, title); vo_x11_set_property_string(vo, XA_WM_ICON_NAME, title); @@ -973,6 +973,8 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y, XNClientWindow, x11->window, XNFocusWindow, x11->window, NULL); + + vo_x11_update_window_title(vo); } static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h) @@ -1025,7 +1027,6 @@ void vo_x11_config_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y, if (flags & VOFLAG_HIDDEN) return; - vo_x11_update_window_title(vo); if (opts->ontop) vo_x11_setlayer(vo, x11->window, opts->ontop); @@ -1371,6 +1372,7 @@ static void vo_x11_border(struct vo *vo) int vo_x11_control(struct vo *vo, int *events, int request, void *arg) { + struct vo_x11_state *x11 = vo->x11; switch (request) { case VOCTRL_CHECK_EVENTS: *events |= vo_x11_check_events(vo); @@ -1392,6 +1394,15 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg) case VOCTRL_SET_CURSOR_VISIBILITY: vo_set_cursor_hidden(vo, !(*(bool *)arg)); return VO_TRUE; + case VOCTRL_KILL_SCREENSAVER: + saver_off(x11); + return VO_TRUE; + case VOCTRL_RESTORE_SCREENSAVER: + saver_on(x11); + return VO_TRUE; + case VOCTRL_UPDATE_WINDOW_TITLE: + vo_x11_update_window_title(vo); + return VO_TRUE; } return VO_NOTIMPL; } |