summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
Diffstat (limited to 'video/out')
-rw-r--r--video/out/cocoa_common.h2
-rw-r--r--video/out/cocoa_common.m36
-rw-r--r--video/out/gl_video.c91
-rw-r--r--video/out/vo.c75
-rw-r--r--video/out/vo.h8
-rw-r--r--video/out/vo_lavc.c70
-rw-r--r--video/out/vo_sdl.c6
-rw-r--r--video/out/vo_xv.c6
-rw-r--r--video/out/w32_common.c33
-rw-r--r--video/out/w32_common.h1
-rw-r--r--video/out/wayland_common.c4
-rw-r--r--video/out/x11_common.c19
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;
}