summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmpcodecs/dec_video.c8
-rw-r--r--libmpcodecs/dec_video.h1
-rw-r--r--libmpcodecs/vf.h1
-rw-r--r--libmpcodecs/vf_ass.c2
-rw-r--r--libmpcodecs/vf_expand.c6
-rw-r--r--libmpcodecs/vf_vo.c7
-rw-r--r--libmpcodecs/vfcap.h2
-rw-r--r--libvo/video_out.c19
-rw-r--r--libvo/video_out.h4
-rw-r--r--libvo/vo_gl.c8
-rw-r--r--libvo/vo_vdpau.c5
-rw-r--r--libvo/vo_xv.c46
-rw-r--r--mplayer.c19
-rw-r--r--sub/sub.h1
14 files changed, 66 insertions, 63 deletions
diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c
index cd3083faa4..14cf029fbe 100644
--- a/libmpcodecs/dec_video.c
+++ b/libmpcodecs/dec_video.c
@@ -195,14 +195,6 @@ 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 f7210e02c3..ab4b55bef7 100644
--- a/libmpcodecs/dec_video.h
+++ b/libmpcodecs/dec_video.h
@@ -44,7 +44,6 @@ struct mp_csp_details;
void get_detected_video_colorspace(struct sh_video *sh, struct mp_csp_details *csp);
void set_video_colorspace(struct sh_video *sh);
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);
void video_reset_aspect(struct sh_video *sh_video);
int get_current_video_decoder_lag(sh_video_t *sh_video);
diff --git a/libmpcodecs/vf.h b/libmpcodecs/vf.h
index 0dac19c9f6..d97e363778 100644
--- a/libmpcodecs/vf.h
+++ b/libmpcodecs/vf.h
@@ -112,7 +112,6 @@ struct vf_ctrl_screenshot {
/* Hack to make the OSD state object available to vf_expand and vf_ass which
* access OSD/subtitle state outside of normal OSD draw time. */
#define VFCTRL_SET_OSD_OBJ 20
-#define VFCTRL_REDRAW_OSD 21 // Change user-visible OSD immediately
#define VFCTRL_SET_YUV_COLORSPACE 22 // arg is struct mp_csp_details*
#define VFCTRL_GET_YUV_COLORSPACE 23 // arg is struct mp_csp_details*
diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_ass.c
index c5613ce992..a062149364 100644
--- a/libmpcodecs/vf_ass.c
+++ b/libmpcodecs/vf_ass.c
@@ -463,7 +463,7 @@ static int vf_open(vf_instance_t *vf, char *args)
vf->control = control;
vf->get_image = get_image;
vf->put_image = put_image;
- vf->default_caps = VFCAP_EOSD;
+ vf->default_caps = VFCAP_EOSD | VFCAP_EOSD_FILTER;
return 1;
}
diff --git a/libmpcodecs/vf_expand.c b/libmpcodecs/vf_expand.c
index 95580b9f26..a640108e0e 100644
--- a/libmpcodecs/vf_expand.c
+++ b/libmpcodecs/vf_expand.c
@@ -452,10 +452,6 @@ static int control(struct vf_instance *vf, int request, void* data){
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);
@@ -481,6 +477,8 @@ static int vf_open(vf_instance_t *vf, char *args){
vf->priv->osd_enabled,
vf->priv->aspect,
vf->priv->round);
+ if (vf->priv->osd_enabled)
+ vf->default_caps = VFCAP_OSD_FILTER;
return 1;
}
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index 9e2612654c..2d9514d3d2 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -117,8 +117,6 @@ 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_SET_EQUALIZER:
{
vf_equalizer_t *eq=data;
@@ -153,7 +151,6 @@ static int control(struct vf_instance *vf, int request, void* data)
{
struct osd_state *osd = data;
mp_eosd_images_t images = {NULL, 2};
- double pts = video_out->next_pts;
ASS_Renderer *renderer;
double scale;
if (osd->vsfilter_aspect && vf->opts->ass_vsfilter_aspect_compat) {
@@ -168,7 +165,7 @@ static int control(struct vf_instance *vf, int request, void* data)
if (osd->ass_track_changed)
vf->priv->prev_visibility = false;
osd->ass_track_changed = false;
- if (sub_visibility && osd->ass_track && (pts != MP_NOPTS_VALUE)) {
+ if (sub_visibility && osd->ass_track && (osd->pts != MP_NOPTS_VALUE)) {
struct mp_eosd_res res = {0};
if (vo_control(video_out, VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) {
ass_set_frame_size(renderer, res.w, res.h);
@@ -181,7 +178,7 @@ static int control(struct vf_instance *vf, int request, void* data)
mp_ass_reload_options(vf->priv->renderer_vsfilter, vf->opts);
}
images.imgs = ass_render_frame(renderer, osd->ass_track,
- (pts+sub_delay) * 1000 + .5,
+ (osd->pts+sub_delay) * 1000 + .5,
&images.changed);
if (!vf->priv->prev_visibility || osd->ass_force_reload)
images.changed = 2;
diff --git a/libmpcodecs/vfcap.h b/libmpcodecs/vfcap.h
index 611d642869..c9b943177d 100644
--- a/libmpcodecs/vfcap.h
+++ b/libmpcodecs/vfcap.h
@@ -52,5 +52,7 @@
#define VFCAP_EOSD_UNSCALED 0x4000
// used by libvo and vf_vo, indicates the VO does not support draw_slice for this format
#define VOCAP_NOSLICES 0x8000
+#define VFCAP_OSD_FILTER 0x10000 // OSD is drawn in filter chain
+#define VFCAP_EOSD_FILTER 0x20000 // EOSD is drawn in filter chain
#endif /* MPLAYER_VFCAP_H */
diff --git a/libvo/video_out.c b/libvo/video_out.c
index 82cf0dbbfe..0b1f7d1fab 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -285,6 +285,17 @@ int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts)
return 0;
}
+int vo_redraw_frame(struct vo *vo)
+{
+ if (!vo->config_ok)
+ return -1;
+ if (vo_control(vo, VOCTRL_REDRAW_FRAME, NULL) == true) {
+ vo->redrawing = true;
+ return 0;
+ }
+ return -1;
+}
+
int vo_get_buffered_frame(struct vo *vo, bool eof)
{
if (!vo->config_ok)
@@ -339,8 +350,11 @@ void vo_flip_page(struct vo *vo, unsigned int pts_us, int duration)
{
if (!vo->config_ok)
return;
- vo->frame_loaded = false;
- vo->next_pts = MP_NOPTS_VALUE;
+ if (!vo->redrawing) {
+ vo->frame_loaded = false;
+ vo->next_pts = MP_NOPTS_VALUE;
+ }
+ vo->redrawing = false;
if (vo->driver->flip_page_timed)
vo->driver->flip_page_timed(vo, pts_us, duration);
else
@@ -486,6 +500,7 @@ int vo_config(struct vo *vo, uint32_t width, uint32_t height,
}
vo->frame_loaded = false;
vo->waiting_mpi = NULL;
+ vo->redrawing = false;
return ret;
}
diff --git a/libvo/video_out.h b/libvo/video_out.h
index a710f7de4a..032a32b1cc 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -65,7 +65,7 @@ enum mp_voctrl {
VOCTRL_NEWFRAME,
VOCTRL_SKIPFRAME,
- VOCTRL_REDRAW_OSD,
+ VOCTRL_REDRAW_FRAME,
VOCTRL_ONTOP,
VOCTRL_ROOTWIN,
@@ -263,6 +263,7 @@ struct vo {
struct mp_image *waiting_mpi;
double next_pts; // pts value of the next frame if any
double next_pts2; // optional pts of frame after that
+ bool redrawing; // between redrawing frame and flipping it
double flip_queue_offset; // queue flip events at most this much in advance
@@ -306,6 +307,7 @@ void list_video_out(void);
int vo_control(struct vo *vo, uint32_t request, void *data);
int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts);
+int vo_redraw_frame(struct vo *vo);
int vo_get_buffered_frame(struct vo *vo, bool eof);
void vo_skip_frame(struct vo *vo);
int vo_draw_frame(struct vo *vo, uint8_t *src[]);
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index b38a8d75e4..ec6e6573e6 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -1506,14 +1506,10 @@ static int control(struct vo *vo, uint32_t request, void *data)
break;
p->glctx->update_xinerama_info(vo);
return VO_TRUE;
- case VOCTRL_REDRAW_OSD:
+ case VOCTRL_REDRAW_FRAME:
if (vo_doublebuffering)
do_render(vo);
- draw_osd(vo, data);
- if (vo_doublebuffering)
- do_render_osd(vo, 2);
- flip_page(vo);
- return VO_TRUE;
+ return true;
case VOCTRL_SCREENSHOT: {
struct voctrl_screenshot_args *args = data;
if (args->full_window)
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index f087f6cf38..bb82b7613d 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -1872,11 +1872,8 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_SKIPFRAME:
vc->deint_queue_pos = next_deint_queue_pos(vo, true);
return true;
- case VOCTRL_REDRAW_OSD:
+ case VOCTRL_REDRAW_FRAME:
video_to_output_surface(vo);
- draw_eosd(vo);
- draw_osd(vo, data);
- flip_page_timed(vo, 0, -1);
return true;
case VOCTRL_RESET:
forget_frames(vo);
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 694dbc048a..4d1a354937 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -89,10 +89,8 @@ struct xvctx {
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;
+ bool have_image_copy;
+ bool unchanged_image;
int visible_buf;
XvImage *xvimage[NUM_BUFFERS + 1];
uint32_t image_width;
@@ -227,8 +225,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
}
ctx->visible_buf = -1;
- ctx->have_visible_image_copy = false;
- ctx->have_next_image_copy = false;
+ ctx->have_image_copy = false;
/* check image formats */
ctx->xv_format = 0;
@@ -447,26 +444,21 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
vo->panscan_x),
ctx->image_height, ctx->draw_alpha_fnc, vo);
if (ctx->osd_objects_drawn)
- ctx->unchanged_next_image = false;
+ ctx->unchanged_image = false;
}
-static int redraw_osd(struct vo *vo, struct osd_state *osd)
+static int redraw_frame(struct vo *vo)
{
struct xvctx *ctx = vo->priv;
- if (ctx->have_visible_image_copy)
+ if (ctx->have_image_copy)
copy_backup_image(vo, ctx->visible_buf, ctx->num_buffers);
- else if (ctx->unchanged_visible_image) {
+ else if (ctx->unchanged_image) {
copy_backup_image(vo, ctx->num_buffers, ctx->visible_buf);
- ctx->have_visible_image_copy = true;
- }
- else
+ ctx->have_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;
}
@@ -478,11 +470,6 @@ static void flip_page(struct vo *vo)
/* remember the currently visible buffer */
ctx->visible_buf = ctx->current_buf;
- 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);
@@ -525,11 +512,12 @@ static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w,
return 0;
}
-static mp_image_t *get_screenshot(struct vo *vo) {
+static mp_image_t *get_screenshot(struct vo *vo)
+{
struct xvctx *ctx = vo->priv;
// try to get an image without OSD
- if (ctx->have_visible_image_copy)
+ if (ctx->have_image_copy)
copy_backup_image(vo, ctx->visible_buf, ctx->num_buffers);
XvImage *xv_image = ctx->xvimage[ctx->visible_buf];
@@ -571,7 +559,7 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
{
struct xvctx *ctx = vo->priv;
- ctx->have_next_image_copy = false;
+ ctx->have_image_copy = false;
if (mpi->flags & MP_IMGFLAG_DIRECT)
// direct rendering:
@@ -591,9 +579,9 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
if (ctx->is_paused) {
copy_backup_image(vo, ctx->num_buffers, ctx->current_buf);
- ctx->have_next_image_copy = true;
+ ctx->have_image_copy = true;
}
- ctx->unchanged_next_image = true;
+ ctx->unchanged_image = true;
return true;
}
@@ -873,8 +861,8 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_UPDATE_SCREENINFO:
update_xinerama_info(vo);
return VO_TRUE;
- case VOCTRL_REDRAW_OSD:
- return redraw_osd(vo, data);
+ case VOCTRL_REDRAW_FRAME:
+ return redraw_frame(vo);
case VOCTRL_SCREENSHOT: {
struct voctrl_screenshot_args *args = data;
args->out_image = get_screenshot(vo);
diff --git a/mplayer.c b/mplayer.c
index 041d0d5298..79407e85a3 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -3035,6 +3035,22 @@ void unpause_player(struct MPContext *mpctx)
(void)get_relative_time(mpctx); // ignore time that passed during pause
}
+static int redraw_osd(struct MPContext *mpctx)
+{
+ struct sh_video *sh_video = mpctx->sh_video;
+ struct vf_instance *vf = sh_video->vfilter;
+ if (sh_video->output_flags & VFCAP_OSD_FILTER)
+ return -1;
+ if (vo_redraw_frame(mpctx->video_out) < 0)
+ return -1;
+ mpctx->osd->pts = mpctx->video_pts;
+ if (!(sh_video->output_flags & VFCAP_EOSD_FILTER))
+ vf->control(vf, VFCTRL_DRAW_EOSD, mpctx->osd);
+ vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
+ vo_flip_page(mpctx->video_out, 0, -1);
+ return 0;
+}
+
void add_step_frame(struct MPContext *mpctx)
{
mpctx->step_frames++;
@@ -3679,6 +3695,7 @@ static void run_playloop(struct MPContext *mpctx)
update_teletext(sh_video, mpctx->demuxer, 0);
update_osd_msg(mpctx);
struct vf_instance *vf = sh_video->vfilter;
+ mpctx->osd->pts = mpctx->video_pts;
vf->control(vf, VFCTRL_DRAW_EOSD, mpctx->osd);
vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd);
vo_osd_changed(0);
@@ -3820,7 +3837,7 @@ static void run_playloop(struct MPContext *mpctx)
int hack = vo_osd_changed(0);
vo_osd_changed(hack);
if (hack) {
- if (redraw_osd(mpctx->sh_video, mpctx->osd) < 0) {
+ if (redraw_osd(mpctx) < 0) {
add_step_frame(mpctx);
break;
} else
diff --git a/sub/sub.h b/sub/sub.h
index e7ded2556a..2f8c4e0ffc 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -75,6 +75,7 @@ struct osd_state {
char *osd_text;
struct font_desc *sub_font;
struct ass_track *ass_track;
+ double pts;
bool ass_track_changed;
bool vsfilter_aspect;
};