summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-01-15 00:29:51 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-01-15 00:29:51 +0200
commit02bc48b67dd88c974c8f9298a0c50cbfcd51af41 (patch)
tree9e826e3d0494ce20cc115d85866f3e7472e21d60
parentc1b80dcbbb34d63df65c0f52c0bede66dfa225e8 (diff)
parent38a76f7fdf5c03bc49072b693d7c53b343f2994a (diff)
downloadmpv-02bc48b67dd88c974c8f9298a0c50cbfcd51af41.tar.bz2
mpv-02bc48b67dd88c974c8f9298a0c50cbfcd51af41.tar.xz
Merge branch 'pause'
-rw-r--r--command.c58
-rw-r--r--command.h2
-rw-r--r--libmpcodecs/dec_video.c9
-rw-r--r--libmpcodecs/dec_video.h1
-rw-r--r--libmpcodecs/vf.h1
-rw-r--r--libmpcodecs/vf_expand.c6
-rw-r--r--libmpcodecs/vf_tfields.c9
-rw-r--r--libmpcodecs/vf_vo.c3
-rw-r--r--libmpcodecs/vf_yadif.c7
-rw-r--r--libvo/video_out.h2
-rw-r--r--libvo/vo_gl.c6
-rw-r--r--libvo/vo_xv.c571
-rw-r--r--mencoder.c1
-rw-r--r--mp_core.h29
-rw-r--r--mplayer.c406
15 files changed, 619 insertions, 492 deletions
diff --git a/command.c b/command.c
index 9d4c38726b..6487a8b346 100644
--- a/command.c
+++ b/command.c
@@ -2,6 +2,7 @@
#include <inttypes.h>
#include <unistd.h>
#include <string.h>
+#include <stdbool.h>
#include "config.h"
#include "command.h"
@@ -559,10 +560,31 @@ static int mp_property_metadata(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED;
}
-static int mp_property_pause(m_option_t * prop, int action, void *arg,
- MPContext * mpctx)
+static int mp_property_pause(m_option_t *prop, int action, void *arg,
+ void *ctx)
{
- return m_property_flag_ro(prop, action, arg, mpctx->osd_function == OSD_PAUSE);
+ MPContext *mpctx = ctx;
+
+ switch (action) {
+ case M_PROPERTY_SET:
+ if (!arg)
+ return M_PROPERTY_ERROR;
+ if (mpctx->paused == (bool)*(int *) arg)
+ return M_PROPERTY_OK;
+ case M_PROPERTY_STEP_UP:
+ case M_PROPERTY_STEP_DOWN:
+ if (mpctx->paused) {
+ unpause_player(mpctx);
+ mpctx->osd_function = OSD_PLAY;
+ }
+ else {
+ pause_player(mpctx);
+ mpctx->osd_function = OSD_PAUSE;
+ }
+ return M_PROPERTY_OK;
+ default:
+ return m_property_flag(prop, action, arg, &mpctx->paused);
+ }
}
@@ -2212,6 +2234,7 @@ static struct {
{ "loop", MP_CMD_LOOP, 0, 0, -1, MSGTR_LoopStatus },
{ "chapter", MP_CMD_SEEK_CHAPTER, 0, 0, -1, NULL },
{ "angle", MP_CMD_SWITCH_ANGLE, 0, 0, -1, NULL },
+ { "pause", MP_CMD_PAUSE, 0, 0, -1, NULL },
// audio
{ "volume", MP_CMD_VOLUME, 0, OSD_VOLUME, -1, MSGTR_Volume },
{ "mute", MP_CMD_MUTE, 1, 0, -1, MSGTR_MuteStatus },
@@ -2348,12 +2371,11 @@ static const struct {
};
#endif
-int run_command(MPContext *mpctx, mp_cmd_t *cmd)
+void run_command(MPContext *mpctx, mp_cmd_t *cmd)
{
struct MPOpts *opts = &mpctx->opts;
sh_audio_t * const sh_audio = mpctx->sh_audio;
sh_video_t * const sh_video = mpctx->sh_video;
- int brk_cmd = 0;
if (!set_property_command(mpctx, cmd))
switch (cmd->id) {
case MP_CMD_SEEK:{
@@ -2378,7 +2400,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
mpctx->rel_seek_secs += v;
mpctx->osd_function = (v > 0) ? OSD_FFW : OSD_REW;
}
- brk_cmd = 1;
}
break;
@@ -2503,9 +2524,7 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
} break;
case MP_CMD_FRAME_STEP:
- case MP_CMD_PAUSE:
- cmd->pausing = 1;
- brk_cmd = 1;
+ add_step_frame(mpctx);
break;
case MP_CMD_FILE_FILTER:
@@ -2544,7 +2563,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
mpctx->stop_play = (n > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY;
if (mpctx->stop_play)
mpctx->play_tree_step = n;
- brk_cmd = 1;
}
}
break;
@@ -2561,7 +2579,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
play_tree_iter_free(i);
} else
mpctx->stop_play = (n > 0) ? PT_UP_NEXT : PT_UP_PREV;
- brk_cmd = 1;
}
break;
@@ -2575,7 +2592,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
else if (v < 0 && mpctx->playtree_iter->file > 1)
mpctx->stop_play = PT_PREV_SRC;
}
- brk_cmd = 1;
break;
case MP_CMD_SUB_STEP:
@@ -2658,7 +2674,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
pt_iter_goto_head(mpctx->playtree_iter);
mpctx->stop_play = PT_NEXT_SRC;
}
- brk_cmd = 1;
}
break;
@@ -2682,7 +2697,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
mpctx->stop_play = PT_NEXT_SRC;
}
}
- brk_cmd = 1;
}
break;
@@ -2692,7 +2706,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
(mpctx->playtree_iter, 0, 1) != PLAY_TREE_ITER_END)
/* NOP */ ;
mpctx->stop_play = PT_STOP;
- brk_cmd = 1;
break;
#ifdef CONFIG_RADIO
@@ -3215,18 +3228,13 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
switch (cmd->pausing) {
case 1: // "pausing"
- mpctx->osd_function = OSD_PAUSE;
+ pause_player(mpctx);
break;
case 3: // "pausing_toggle"
- mpctx->was_paused = !mpctx->was_paused;
- if (mpctx->was_paused)
- mpctx->osd_function = OSD_PAUSE;
- else if (mpctx->osd_function == OSD_PAUSE)
- mpctx->osd_function = OSD_PLAY;
+ if (mpctx->paused)
+ unpause_player(mpctx);
+ else
+ pause_player(mpctx);
break;
- case 2: // "pausing_keep"
- if (mpctx->was_paused)
- mpctx->osd_function = OSD_PAUSE;
}
- return brk_cmd;
}
diff --git a/command.h b/command.h
index f87c5a00ca..ee8c451a7c 100644
--- a/command.h
+++ b/command.h
@@ -4,7 +4,7 @@
struct MPContext;
struct mp_cmd;
-int run_command(struct MPContext *mpctx, struct mp_cmd *cmd);
+void run_command(struct MPContext *mpctx, struct mp_cmd *cmd);
char *property_expand_string(struct MPContext *mpctx, char *str);
void property_print_help(void);
diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c
index 291859abb2..8cdc3e7b1d 100644
--- a/libmpcodecs/dec_video.c
+++ b/libmpcodecs/dec_video.c
@@ -6,6 +6,7 @@
#include <malloc.h>
#endif
#include <stdlib.h>
+#include <stdbool.h>
#include <unistd.h>
#include "mp_msg.h"
@@ -138,6 +139,14 @@ int set_rectangle(sh_video_t *sh_video, int param, int value)
return 0;
}
+int redraw_osd(struct sh_video *sh_video, struct osd_state *osd)
+{
+ struct vf_instance *vf = sh_video->vfilter;
+ if (vf->control(vf, VFCTRL_REDRAW_OSD, osd) == true)
+ return 0;
+ return -1;
+}
+
void resync_video_stream(sh_video_t *sh_video)
{
const struct vd_functions *vd = sh_video->vd_driver;
diff --git a/libmpcodecs/dec_video.h b/libmpcodecs/dec_video.h
index 42aa56ecb5..463304bde5 100644
--- a/libmpcodecs/dec_video.h
+++ b/libmpcodecs/dec_video.h
@@ -21,6 +21,7 @@ void set_video_quality(sh_video_t *sh_video, int quality);
int get_video_colors(sh_video_t *sh_video, const char *item, int *value);
int set_video_colors(sh_video_t *sh_video, const char *item, int value);
int set_rectangle(sh_video_t *sh_video, int param, int value);
+int redraw_osd(struct sh_video *sh_video, struct osd_state *osd);
void resync_video_stream(sh_video_t *sh_video);
int get_current_video_decoder_lag(sh_video_t *sh_video);
diff --git a/libmpcodecs/vf.h b/libmpcodecs/vf.h
index 504c616a73..24d86214d6 100644
--- a/libmpcodecs/vf.h
+++ b/libmpcodecs/vf.h
@@ -91,6 +91,7 @@ typedef struct vf_seteq_s
/* Hack to make the OSD state object available to vf_expand which accesses
* the OSD state outside of normal OSD draw time. */
#define VFCTRL_SET_OSD_OBJ 20
+#define VFCTRL_REDRAW_OSD 21 /* Change user-visible OSD immediately */
#include "vfcap.h"
diff --git a/libmpcodecs/vf_expand.c b/libmpcodecs/vf_expand.c
index cdde44f82b..dec0c524b6 100644
--- a/libmpcodecs/vf_expand.c
+++ b/libmpcodecs/vf_expand.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include "config.h"
#include "mp_msg.h"
@@ -419,6 +420,11 @@ static int control(struct vf_instance* vf, int request, void* data){
break;
case VFCTRL_DRAW_OSD:
if(vf->priv->osd_enabled) return CONTROL_TRUE;
+ break;
+ case VFCTRL_REDRAW_OSD:
+ if (vf->priv->osd_enabled)
+ return false;
+ break;
}
#endif
return vf_next_control(vf,request,data);
diff --git a/libmpcodecs/vf_tfields.c b/libmpcodecs/vf_tfields.c
index 0d88119371..347cd4bb9e 100644
--- a/libmpcodecs/vf_tfields.c
+++ b/libmpcodecs/vf_tfields.c
@@ -310,9 +310,10 @@ static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts)
return continue_buffered_image(vf);
}
+extern const int under_mencoder;
+
static int continue_buffered_image(struct vf_instance *vf)
{
- struct MPOpts *opts = vf->opts;
int i=vf->priv->buffered_i;
double pts = vf->priv->buffered_pts;
mp_image_t *mpi = vf->priv->buffered_mpi;
@@ -363,7 +364,7 @@ static int continue_buffered_image(struct vf_instance *vf)
dmpi->stride[2] = 2*mpi->stride[2];
}
ret |= vf_next_put_image(vf, dmpi, pts);
- if (opts->correct_pts)
+ if (!under_mencoder)
break;
else
if (!i) vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL);
@@ -393,7 +394,7 @@ static int continue_buffered_image(struct vf_instance *vf)
mpi->chroma_width, mpi->chroma_height, (i^!tff));
}
ret |= vf_next_put_image(vf, dmpi, pts);
- if (opts->correct_pts)
+ if (!under_mencoder)
break;
else
if (!i) vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL);
@@ -419,7 +420,7 @@ static int continue_buffered_image(struct vf_instance *vf)
dmpi->stride[2], mpi->stride[2]*2, (i^!tff));
}
ret |= vf_next_put_image(vf, dmpi, pts);
- if (opts->correct_pts)
+ if (!under_mencoder)
break;
else
if (!i) vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL);
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index 4f47bc1847..85088487ed 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include "config.h"
#include "mp_msg.h"
@@ -88,6 +89,8 @@ static int control(struct vf_instance* vf, int request, void* data)
if(!video_out->config_ok) return CONTROL_FALSE; // vo not configured?
vo_draw_osd(video_out, data);
return CONTROL_TRUE;
+ case VFCTRL_REDRAW_OSD:
+ return vo_control(video_out, VOCTRL_REDRAW_OSD, data) == true;
case VFCTRL_FLIP_PAGE:
{
if(!video_out->config_ok) return CONTROL_FALSE; // vo not configured?
diff --git a/libmpcodecs/vf_yadif.c b/libmpcodecs/vf_yadif.c
index fd46f241cd..2c80a2ec5b 100644
--- a/libmpcodecs/vf_yadif.c
+++ b/libmpcodecs/vf_yadif.c
@@ -416,9 +416,10 @@ static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){
return continue_buffered_image(vf);
}
+extern const int under_mencoder;
+
static int continue_buffered_image(struct vf_instance *vf)
{
- struct MPOpts *opts = vf->opts;
mp_image_t *mpi = vf->priv->buffered_mpi;
int tff = vf->priv->buffered_tff;
double pts = vf->priv->buffered_pts;
@@ -435,10 +436,10 @@ static int continue_buffered_image(struct vf_instance *vf)
mpi->width,mpi->height);
vf_clone_mpi_attributes(dmpi, mpi);
filter(vf->priv, dmpi->planes, dmpi->stride, mpi->w, mpi->h, i ^ tff ^ 1, tff);
- if (opts->correct_pts && i < (vf->priv->mode & 1))
+ if (i < (vf->priv->mode & 1) && !under_mencoder)
vf_queue_frame(vf, continue_buffered_image);
ret |= vf_next_put_image(vf, dmpi, pts /*FIXME*/);
- if (opts->correct_pts)
+ if (!under_mencoder)
break;
if(i<(vf->priv->mode&1))
vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL);
diff --git a/libvo/video_out.h b/libvo/video_out.h
index 465697927f..e0bc79976e 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -87,6 +87,8 @@ typedef struct {
} mp_colorkey_t;
#define VOCTRL_XOVERLAY_SET_WIN 23
+#define VOCTRL_REDRAW_OSD 24
+
typedef struct {
int x,y;
int w,h;
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 4178daff9c..340b32b5a5 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -1147,6 +1147,12 @@ static int control(uint32_t request, void *data)
case VOCTRL_UPDATE_SCREENINFO:
update_xinerama_info();
return VO_TRUE;
+ case VOCTRL_REDRAW_OSD:
+ if (vo_doublebuffering)
+ do_render();
+ draw_osd();
+ flip_page();
+ return VO_TRUE;
}
return VO_NOTIMPL;
}
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index f95ea82b53..9c4dd391df 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -20,6 +20,7 @@ Buffer allocation:
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
+#include <stdbool.h>
#include "config.h"
#include "options.h"
@@ -76,8 +77,13 @@ struct xvctx {
int current_buf;
int current_ip_buf;
int num_buffers;
+ int total_buffers;
+ int have_visible_image_copy;
+ int have_next_image_copy;
+ int unchanged_visible_image;
+ int unchanged_next_image;
int visible_buf;
- XvImage *xvimage[NUM_BUFFERS];
+ XvImage *xvimage[NUM_BUFFERS + 1];
uint32_t image_width;
uint32_t image_height;
uint32_t image_format;
@@ -86,6 +92,7 @@ struct xvctx {
uint32_t max_width, max_height; // zero means: not set
int event_fd_registered; // for uninit called from preinit
int mode_switched;
+ int osd_objects_drawn;
void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h,
unsigned char *src, unsigned char *srca,
int stride);
@@ -95,11 +102,9 @@ struct xvctx {
#endif
};
-// FIXME: dynamically allocate this stuff
static void allocate_xvimage(struct vo *, int);
-
static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h,
unsigned char *src, unsigned char *srca,
int stride)
@@ -113,6 +118,7 @@ static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h,
ctx->xvimage[ctx->current_buf]->offsets[0] +
ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + x0,
ctx->xvimage[ctx->current_buf]->pitches[0]);
+ ctx->osd_objects_drawn++;
}
static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h,
@@ -128,6 +134,7 @@ static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h,
ctx->xvimage[ctx->current_buf]->offsets[0] +
ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0,
ctx->xvimage[ctx->current_buf]->pitches[0]);
+ ctx->osd_objects_drawn++;
}
static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h,
@@ -143,6 +150,7 @@ static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h,
ctx->xvimage[ctx->current_buf]->offsets[0] +
ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0 + 1,
ctx->xvimage[ctx->current_buf]->pitches[0]);
+ ctx->osd_objects_drawn++;
}
static void draw_alpha_null(void *p, int x0, int y0, int w, int h,
@@ -154,21 +162,22 @@ static void draw_alpha_null(void *p, int x0, int y0, int w, int h,
static void deallocate_xvimage(struct vo *vo, int foo);
-static void calc_drwXY(struct vo *vo, uint32_t *drwX, uint32_t *drwY) {
+static void calc_drwXY(struct vo *vo, uint32_t *drwX, uint32_t *drwY)
+{
struct MPOpts *opts = vo->opts;
- *drwX = *drwY = 0;
- if (vo_fs) {
- aspect(vo, &vo->dwidth, &vo->dheight, A_ZOOM);
- vo->dwidth = FFMIN(vo->dwidth, opts->vo_screenwidth);
- vo->dheight = FFMIN(vo->dheight, opts->vo_screenheight);
- *drwX = (opts->vo_screenwidth - vo->dwidth) / 2;
- *drwY = (opts->vo_screenheight - vo->dheight) / 2;
- mp_msg(MSGT_VO, MSGL_V, "[xv-fs] dx: %d dy: %d dw: %d dh: %d\n",
- *drwX, *drwY, vo->dwidth, vo->dheight);
- } else if (WinID == 0) {
- *drwX = vo->dx;
- *drwY = vo->dy;
- }
+ *drwX = *drwY = 0;
+ if (vo_fs) {
+ aspect(vo, &vo->dwidth, &vo->dheight, A_ZOOM);
+ vo->dwidth = FFMIN(vo->dwidth, opts->vo_screenwidth);
+ vo->dheight = FFMIN(vo->dheight, opts->vo_screenheight);
+ *drwX = (opts->vo_screenwidth - vo->dwidth) / 2;
+ *drwY = (opts->vo_screenheight - vo->dheight) / 2;
+ mp_msg(MSGT_VO, MSGL_V, "[xv-fs] dx: %d dy: %d dw: %d dh: %d\n", *drwX,
+ *drwY, vo->dwidth, vo->dheight);
+ } else if (WinID == 0) {
+ *drwX = vo->dx;
+ *drwY = vo->dy;
+ }
}
/*
@@ -193,23 +202,25 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
ctx->image_width = width;
ctx->image_format = format;
- if ((ctx->max_width != 0 && ctx->max_height != 0) &&
- (ctx->image_width > ctx->max_width || ctx->image_height > ctx->max_height))
- {
- mp_msg( MSGT_VO, MSGL_ERR, MSGTR_VO_XV_ImagedimTooHigh,
- ctx->image_width, ctx->image_height, ctx->max_width, ctx->max_height);
+ if ((ctx->max_width != 0 && ctx->max_height != 0)
+ && (ctx->image_width > ctx->max_width
+ || ctx->image_height > ctx->max_height)) {
+ mp_msg(MSGT_VO, MSGL_ERR, MSGTR_VO_XV_ImagedimTooHigh,
+ ctx->image_width, ctx->image_height, ctx->max_width,
+ ctx->max_height);
return -1;
}
ctx->is_paused = 0;
ctx->visible_buf = -1;
+ ctx->have_visible_image_copy = false;
+ ctx->have_next_image_copy = false;
/* check image formats */
ctx->xv_format = 0;
for (i = 0; i < ctx->formats; i++) {
- mp_msg(MSGT_VO, MSGL_V,
- "Xvideo image format: 0x%x (%4.4s) %s\n", ctx->fo[i].id,
- (char *) &ctx->fo[i].id,
+ mp_msg(MSGT_VO, MSGL_V, "Xvideo image format: 0x%x (%4.4s) %s\n",
+ ctx->fo[i].id, (char *) &ctx->fo[i].id,
(ctx->fo[i].format == XvPacked) ? "packed" : "planar");
if (ctx->fo[i].id == format)
ctx->xv_format = ctx->fo[i].id;
@@ -225,8 +236,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
{
#ifdef CONFIG_XF86VM
int vm = flags & VOFLAG_MODESWITCHING;
- if (vm)
- {
+ if (vm) {
vo_vm_switch(vo);
ctx->mode_switched = 1;
}
@@ -240,25 +250,23 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
xswa.background_pixel = 0;
if (x11->xv_ck_info.method == CK_METHOD_BACKGROUND)
- {
- xswa.background_pixel = x11->xv_colorkey;
- }
+ xswa.background_pixel = x11->xv_colorkey;
xswa.border_pixel = 0;
xswamask = CWBackPixel | CWBorderPixel;
- vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, vo->dwidth, vo->dheight,
- flags, CopyFromParent, "xv", title);
- XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa);
+ vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, vo->dwidth,
+ vo->dheight, flags, CopyFromParent, "xv",
+ title);
+ XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa);
#ifdef CONFIG_XF86VM
- if (vm)
- {
+ if (vm) {
/* Grab the mouse pointer in our window */
if (vo_grabpointer)
- XGrabPointer(x11->display, x11->window, True, 0,
- GrabModeAsync, GrabModeAsync,
- x11->window, None, CurrentTime);
- XSetInputFocus(x11->display, x11->window, RevertToNone, CurrentTime);
+ XGrabPointer(x11->display, x11->window, True, 0, GrabModeAsync,
+ GrabModeAsync, x11->window, None, CurrentTime);
+ XSetInputFocus(x11->display, x11->window, RevertToNone,
+ CurrentTime);
}
#endif
}
@@ -266,42 +274,43 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
mp_msg(MSGT_VO, MSGL_V, "using Xvideo port %d for hw scaling\n",
x11->xv_port);
- switch (ctx->xv_format)
- {
- case IMGFMT_YV12:
- case IMGFMT_I420:
- case IMGFMT_IYUV:
- ctx->draw_alpha_fnc = draw_alpha_yv12;
- break;
- case IMGFMT_YUY2:
- case IMGFMT_YVYU:
- ctx->draw_alpha_fnc = draw_alpha_yuy2;
- break;
- case IMGFMT_UYVY:
- ctx->draw_alpha_fnc = draw_alpha_uyvy;
- break;
- default:
- ctx->draw_alpha_fnc = draw_alpha_null;
+ switch (ctx->xv_format) {
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ ctx->draw_alpha_fnc = draw_alpha_yv12;
+ break;
+ case IMGFMT_YUY2:
+ case IMGFMT_YVYU:
+ ctx->draw_alpha_fnc = draw_alpha_yuy2;
+ break;
+ case IMGFMT_UYVY:
+ ctx->draw_alpha_fnc = draw_alpha_uyvy;
+ break;
+ default:
+ ctx->draw_alpha_fnc = draw_alpha_null;
}
// In case config has been called before
- for (i = 0; i < ctx->num_buffers; i++)
+ for (i = 0; i < ctx->total_buffers; i++)
deallocate_xvimage(vo, i);
ctx->num_buffers =
vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1;
+ ctx->total_buffers = ctx->num_buffers + 1;
- for (i = 0; i < ctx->num_buffers; i++)
+ for (i = 0; i < ctx->total_buffers; i++)
allocate_xvimage(vo, i);
ctx->current_buf = 0;
ctx->current_ip_buf = 0;
- if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1;
+ if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0)
+ vo_fs = 1;
calc_drwXY(vo, &ctx->drwX, &ctx->drwY);
panscan_calc(vo);
-
+
vo_xv_draw_colorkey(vo, ctx->drwX - (vo->panscan_x >> 1),
ctx->drwY - (vo->panscan_y >> 1),
vo->dwidth + vo->panscan_x - 1,
@@ -324,22 +333,22 @@ static void allocate_xvimage(struct vo *vo, int foo)
#ifdef HAVE_SHM
if (x11->display_is_local && XShmQueryExtension(x11->display))
ctx->Shmem_Flag = 1;
- else
- {
+ else {
ctx->Shmem_Flag = 0;
- mp_msg(MSGT_VO, MSGL_INFO,
- MSGTR_LIBVO_XV_SharedMemoryNotSupported);
+ mp_msg(MSGT_VO, MSGL_INFO, MSGTR_LIBVO_XV_SharedMemoryNotSupported);
}
- if (ctx->Shmem_Flag)
- {
+ if (ctx->Shmem_Flag) {
ctx->xvimage[foo] =
- (XvImage *) XvShmCreateImage(x11->display, x11->xv_port, ctx->xv_format,
- NULL, ctx->image_width, ctx->image_height,
+ (XvImage *) XvShmCreateImage(x11->display, x11->xv_port,
+ ctx->xv_format, NULL,
+ ctx->image_width, ctx->image_height,
&ctx->Shminfo[foo]);
- ctx->Shminfo[foo].shmid =
- shmget(IPC_PRIVATE, ctx->xvimage[foo]->data_size, IPC_CREAT | 0777);
- ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, 0);
+ ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE,
+ ctx->xvimage[foo]->data_size,
+ IPC_CREAT | 0777);
+ ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0,
+ 0);
ctx->Shminfo[foo].readOnly = False;
ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr;
@@ -350,8 +359,9 @@ static void allocate_xvimage(struct vo *vo, int foo)
#endif
{
ctx->xvimage[foo] =
- (XvImage *) XvCreateImage(x11->display, x11->xv_port, ctx->xv_format, NULL,
- ctx->image_width, ctx->image_height);
+ (XvImage *) XvCreateImage(x11->display, x11->xv_port,
+ ctx->xv_format, NULL, ctx->image_width,
+ ctx->image_height);
ctx->xvimage[foo]->data = malloc(ctx->xvimage[foo]->data_size);
XSync(x11->display, False);
}
@@ -363,8 +373,7 @@ static void deallocate_xvimage(struct vo *vo, int foo)
{
struct xvctx *ctx = vo->priv;
#ifdef HAVE_SHM
- if (ctx->Shmem_Flag)
- {
+ if (ctx->Shmem_Flag) {
XShmDetach(vo->x11->display, &ctx->Shminfo[foo]);
shmdt(ctx->Shminfo[foo].shmaddr);
} else
@@ -383,25 +392,36 @@ static inline void put_xvimage(struct vo *vo, XvImage *xvi)
struct xvctx *ctx = vo->priv;
struct vo_x11_state *x11 = vo->x11;
#ifdef HAVE_SHM
- if (ctx->Shmem_Flag)
- {
- XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc,
- xvi, 0, 0, ctx->image_width,
- ctx->image_height, ctx->drwX - (vo->panscan_x >> 1),
- ctx->drwY - (vo->panscan_y >> 1), vo->dwidth + vo->panscan_x,
- vo->dheight + vo->panscan_y,
+ if (ctx->Shmem_Flag) {
+ XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi,
+ 0, 0, ctx->image_width, ctx->image_height,
+ ctx->drwX - (vo->panscan_x >> 1),
+ ctx->drwY - (vo->panscan_y >> 1),
+ vo->dwidth + vo->panscan_x, vo->dheight + vo->panscan_y,
False);
} else
#endif
{
- XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc,
- xvi, 0, 0, ctx->image_width, ctx->image_height,
- ctx->drwX - (vo->panscan_x >> 1), ctx->drwY - (vo->panscan_y >> 1),
- vo->dwidth + vo->panscan_x,
- vo->dheight + vo->panscan_y);
+ XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi, 0,
+ 0, ctx->image_width, ctx->image_height,
+ ctx->drwX - (vo->panscan_x >> 1),
+ ctx->drwY - (vo->panscan_y >> 1),
+ vo->dwidth + vo->panscan_x, vo->dheight + vo->panscan_y);
}
}
+// Only copies luma for planar formats as draw_alpha doesn't change others */
+void copy_backup_image(struct vo *vo, int dest, int src)
+{
+ struct xvctx *ctx = vo->priv;
+
+ XvImage *vb = ctx->xvimage[dest];
+ XvImage *cp = ctx->xvimage[src];
+ memcpy_pic(vb->data + vb->offsets[0], cp->data + cp->offsets[0],
+ vb->width, vb->height,
+ vb->pitches[0], cp->pitches[0]);
+}
+
static void check_events(struct vo *vo)
{
struct xvctx *ctx = vo->priv;
@@ -411,21 +431,18 @@ static void check_events(struct vo *vo)
if (e & VO_EVENT_RESIZE)
calc_drwXY(vo, &ctx->drwX, &ctx->drwY);
- if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE)
- {
- vo_xv_draw_colorkey(vo, ctx->drwX - (vo->panscan_x >> 1),
- ctx->drwY - (vo->panscan_y >> 1),
- vo->dwidth + vo->panscan_x - 1,
- vo->dheight + vo->panscan_y - 1);
+ if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) {
+ vo_xv_draw_colorkey(vo, ctx->drwX - (vo->panscan_x >> 1),
+ ctx->drwY - (vo->panscan_y >> 1),
+ vo->dwidth + vo->panscan_x - 1,
+ vo->dheight + vo->panscan_y - 1);
}
- if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && ctx->is_paused)
- {
+ if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && ctx->is_paused) {
/* did we already draw a buffer */
- if ( ctx->visible_buf != -1 )
- {
- /* redraw the last visible buffer */
- put_xvimage(vo, ctx->xvimage[ctx->visible_buf]);
+ if (ctx->visible_buf != -1) {
+ /* redraw the last visible buffer */
+ put_xvimage(vo, ctx->xvimage[ctx->visible_buf]);
}
}
}
@@ -434,9 +451,34 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
{
struct xvctx *ctx = vo->priv;
- osd_draw_text(osd, ctx->image_width -
- ctx->image_width * vo->panscan_x / (vo->dwidth + vo->panscan_x),
+ ctx->osd_objects_drawn = 0;
+ osd_draw_text(osd,
+ ctx->image_width -
+ ctx->image_width * vo->panscan_x / (vo->dwidth +
+ vo->panscan_x),
ctx->image_height, ctx->draw_alpha_fnc, vo);
+ if (ctx->osd_objects_drawn)
+ ctx->unchanged_next_image = false;
+}
+
+static int redraw_osd(struct vo *vo, struct osd_state *osd)
+{
+ struct xvctx *ctx = vo->priv;
+
+ if (ctx->have_visible_image_copy)
+ copy_backup_image(vo, ctx->visible_buf, ctx->num_buffers);
+ else if (ctx->unchanged_visible_image) {
+ copy_backup_image(vo, ctx->num_buffers, ctx->visible_buf);
+ ctx->have_visible_image_copy = true;
+ }
+ else
+ return false;
+ int temp = ctx->current_buf;
+ ctx->current_buf = ctx->visible_buf;
+ draw_osd(vo, osd);
+ ctx->current_buf = temp;
+ put_xvimage(vo, ctx->xvimage[ctx->visible_buf]);
+ return true;
}
static void flip_page(struct vo *vo)
@@ -447,99 +489,99 @@ static void flip_page(struct vo *vo)
/* remember the currently visible buffer */
ctx->visible_buf = ctx->current_buf;
- if (ctx->num_buffers > 1)
- {
- ctx->current_buf =
- vo_directrendering ? 0 : ((ctx->current_buf + 1) % ctx->num_buffers);
+ ctx->have_visible_image_copy = ctx->have_next_image_copy;
+ ctx->have_next_image_copy = false;
+ ctx->unchanged_visible_image = ctx->unchanged_next_image;
+ ctx->unchanged_next_image = false;
+
+ if (ctx->num_buffers > 1) {
+ ctx->current_buf = vo_directrendering ? 0 : ((ctx->current_buf + 1) %
+ ctx->num_buffers);
XFlush(vo->x11->display);
} else
XSync(vo->x11->display, False);
return;
}
-static int draw_slice(struct vo *vo, uint8_t * image[], int stride[], int w,
+static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w,
int h, int x, int y)