summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--command.c8
-rw-r--r--libmpcodecs/ad_ffmpeg.c2
-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.c40
-rw-r--r--libvo/video_out.h9
-rw-r--r--libvo/vo_gl.c33
-rw-r--r--libvo/vo_vdpau.c79
-rw-r--r--libvo/vo_xv.c77
-rw-r--r--mplayer.c40
-rw-r--r--sub/sub.h1
16 files changed, 160 insertions, 156 deletions
diff --git a/command.c b/command.c
index 45f778a96c..be1d688f8f 100644
--- a/command.c
+++ b/command.c
@@ -287,19 +287,21 @@ static int mp_property_playback_speed(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
+ double orig_speed = opts->playback_speed;
switch (action) {
case M_PROPERTY_SET:
if (!arg)
return M_PROPERTY_ERROR;
- M_PROPERTY_CLAMP(prop, *(float *) arg);
opts->playback_speed = *(float *) arg;
- reinit_audio_chain(mpctx);
- return M_PROPERTY_OK;
+ goto set;
case M_PROPERTY_STEP_UP:
case M_PROPERTY_STEP_DOWN:
opts->playback_speed += (arg ? *(float *) arg : 0.1) *
(action == M_PROPERTY_STEP_DOWN ? -1 : 1);
+ set:
M_PROPERTY_CLAMP(prop, opts->playback_speed);
+ // Adjust time until next frame flip for nosound mode
+ mpctx->time_frame *= orig_speed / opts->playback_speed;
reinit_audio_chain(mpctx);
return M_PROPERTY_OK;
}
diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c
index ae7f36b791..762c80282d 100644
--- a/libmpcodecs/ad_ffmpeg.c
+++ b/libmpcodecs/ad_ffmpeg.c
@@ -214,7 +214,7 @@ static void uninit(sh_audio_t *sh)
AVCodecContext *lavc_context = ctx->avctx;
if (lavc_context) {
- if (avcodec_close(lavc_context) < 0)
+ if (lavc_context->codec && avcodec_close(lavc_context) < 0)
mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Could not close codec.\n");
av_freep(&lavc_context->extradata);
av_freep(&lavc_context);
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 499184d37f..d673c7bcd4 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 2333afcb80..205d618878 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -275,11 +275,27 @@ int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts)
}
vo->frame_loaded = true;
vo->next_pts = pts;
+ // Guaranteed to support at least DRAW_IMAGE later
+ if (vo->driver->is_new) {
+ vo->waiting_mpi = mpi;
+ return 0;
+ }
if (vo_control(vo, VOCTRL_DRAW_IMAGE, mpi) == VO_NOTIMPL)
return -1;
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)
@@ -294,6 +310,7 @@ int vo_get_buffered_frame(struct vo *vo, bool eof)
void vo_skip_frame(struct vo *vo)
{
+ vo_control(vo, VOCTRL_SKIPFRAME, NULL);
vo->frame_loaded = false;
}
@@ -310,6 +327,18 @@ int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int
return vo->driver->draw_slice(vo, src, stride, w, h, x, y);
}
+void vo_new_frame_imminent(struct vo *vo)
+{
+ if (!vo->driver->is_new)
+ return;
+ if (vo->driver->buffer_frames)
+ vo_control(vo, VOCTRL_NEWFRAME, NULL);
+ else {
+ vo_control(vo, VOCTRL_DRAW_IMAGE, vo->waiting_mpi);
+ vo->waiting_mpi = NULL;
+ }
+}
+
void vo_draw_osd(struct vo *vo, struct osd_state *osd)
{
if (!vo->config_ok)
@@ -321,8 +350,12 @@ 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->want_redraw = false;
+ vo->redrawing = false;
if (vo->driver->flip_page_timed)
vo->driver->flip_page_timed(vo, pts_us, duration);
else
@@ -466,6 +499,9 @@ int vo_config(struct vo *vo, uint32_t width, uint32_t height,
NULL, vo);
vo->registered_fd = vo->event_fd;
}
+ 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 e5d2f78c8a..06c606f4d2 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -63,7 +63,9 @@ enum mp_voctrl {
VOCTRL_XOVERLAY_SET_COLORKEY, // mp_colorkey_t
VOCTRL_XOVERLAY_SET_WIN,
- VOCTRL_REDRAW_OSD,
+ VOCTRL_NEWFRAME,
+ VOCTRL_SKIPFRAME,
+ VOCTRL_REDRAW_FRAME,
VOCTRL_ONTOP,
VOCTRL_ROOTWIN,
@@ -258,8 +260,11 @@ struct vo {
int config_count; // Total number of successful config calls
bool frame_loaded; // Is there a next frame the VO could flip to?
+ 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 want_redraw; // visible frame wrong (window resize), needs refresh
+ bool redrawing; // between redrawing frame and flipping it
double flip_queue_offset; // queue flip events at most this much in advance
@@ -303,10 +308,12 @@ 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[]);
int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y);
+void vo_new_frame_imminent(struct vo *vo);
void vo_draw_osd(struct vo *vo, struct osd_state *osd);
void vo_flip_page(struct vo *vo, unsigned int pts_us, int duration);
void vo_check_events(struct vo *vo);
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index dbaef279d8..e68465f009 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -127,8 +127,6 @@ struct gl_priv {
int mipmap_gen;
int stereo_mode;
- int int_pause;
-
struct mp_csp_equalizer video_eq;
int texture_width;
@@ -140,8 +138,6 @@ struct gl_priv {
unsigned int slice_height;
};
-static void redraw(struct vo *vo);
-
static void resize(struct vo *vo, int x, int y)
{
struct gl_priv *p = vo->priv;
@@ -185,7 +181,7 @@ static void resize(struct vo *vo, int x, int y)
vo_osd_changed(OSDTYPE_OSD);
}
gl->Clear(GL_COLOR_BUFFER_BIT);
- redraw(vo);
+ vo->want_redraw = true;
}
static void texSize(struct vo *vo, int w, int h, int *texw, int *texh)
@@ -699,8 +695,8 @@ static void check_events(struct vo *vo)
}
if (e & VO_EVENT_RESIZE)
resize(vo, vo->dwidth, vo->dheight);
- if (e & VO_EVENT_EXPOSE && p->int_pause)
- redraw(vo);
+ if (e & VO_EVENT_EXPOSE)
+ vo->want_redraw = true;
}
/**
@@ -900,15 +896,6 @@ static void flip_page(struct vo *vo)
}
}
-static void redraw(struct vo *vo)
-{
- if (vo_doublebuffering) {
- do_render(vo);
- do_render_osd(vo, RENDER_OSD | RENDER_EOSD);
- }
- flip_page(vo);
-}
-
static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
int x, int y)
{
@@ -1423,10 +1410,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
struct gl_priv *p = vo->priv;
switch (request) {
- case VOCTRL_PAUSE:
- case VOCTRL_RESUME:
- p->int_pause = (request == VOCTRL_PAUSE);
- return VO_TRUE;
case VOCTRL_QUERY_FORMAT:
return query_format(vo, *(uint32_t *)data);
case VOCTRL_GET_IMAGE:
@@ -1487,6 +1470,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
if (mp_csp_equalizer_set(&p->video_eq, args->name, args->value) < 0)
return VO_NOTIMPL;
update_yuvconv(vo);
+ vo->want_redraw = true;
return VO_TRUE;
}
break;
@@ -1495,6 +1479,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
if (vo->config_count && supports_csp) {
p->colorspace = *(struct mp_csp_details *)data;
update_yuvconv(vo);
+ vo->want_redraw = true;
}
return VO_TRUE;
}
@@ -1506,14 +1491,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 d58607e135..42200d8f5d 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -80,7 +80,7 @@
/* number of video and output surfaces */
#define MAX_OUTPUT_SURFACES 15
#define MAX_VIDEO_SURFACES 50
-#define NUM_BUFFERED_VIDEO 4
+#define NUM_BUFFERED_VIDEO 5
/* number of palette entries */
#define PALETTE_SIZE 256
@@ -195,9 +195,6 @@ struct vdpctx {
// Video equalizer
struct mp_csp_equalizer video_eq;
- int num_shown_frames;
- bool paused;
-
// These tell what's been initialized and uninit() should free/uninitialize
bool mode_switched;
};
@@ -295,7 +292,7 @@ static int video_to_output_surface(struct vo *vo)
&vc->out_rect_vid);
}
-static void get_buffered_frame(struct vo *vo, bool eof)
+static int next_deint_queue_pos(struct vo *vo, bool eof)
{
struct vdpctx *vc = vo->priv;
@@ -305,15 +302,23 @@ static void get_buffered_frame(struct vo *vo, bool eof)
else
dqp = vc->deint >= 2 ? dqp - 1 : dqp - 2 | 1;
if (dqp < (eof ? 0 : 3))
- return;
+ return -1;
+ return dqp;
+}
- dqp = FFMIN(dqp, 4);
- vc->deint_queue_pos = dqp;
+static void set_next_frame_info(struct vo *vo, bool eof)
+{
+ struct vdpctx *vc = vo->priv;
+
+ vo->frame_loaded = false;
+ int dqp = next_deint_queue_pos(vo, eof);
+ if (dqp < 0)
+ return;
vo->frame_loaded = true;
// Set pts values
struct buffered_video_surface *bv = vc->buffered_video;
- int idx = vc->deint_queue_pos >> 1;
+ int idx = dqp >> 1;
if (idx == 0) { // no future frame/pts available
vo->next_pts = bv[0].pts;
vo->next_pts2 = MP_NOPTS_VALUE;
@@ -327,7 +332,7 @@ static void get_buffered_frame(struct vo *vo, bool eof)
intermediate_pts = (bv[idx].pts + bv[idx - 1].pts) / 2;
else
intermediate_pts = bv[idx].pts;
- if (vc->deint_queue_pos & 1) { // first field
+ if (dqp & 1) { // first field
vo->next_pts = bv[idx].pts;
vo->next_pts2 = intermediate_pts;
} else {
@@ -335,8 +340,6 @@ static void get_buffered_frame(struct vo *vo, bool eof)
vo->next_pts2 = bv[idx - 1].pts;
}
}
-
- video_to_output_surface(vo);
}
static void add_new_video_surface(struct vo *vo, VdpVideoSurface surface,
@@ -358,8 +361,9 @@ static void add_new_video_surface(struct vo *vo, VdpVideoSurface surface,
.pts = pts,
};
- vc->deint_queue_pos += 2;
- get_buffered_frame(vo, false);
+ vc->deint_queue_pos = FFMIN(vc->deint_queue_pos + 2,
+ NUM_BUFFERED_VIDEO * 2 - 3);
+ set_next_frame_info(vo, false);
}
static void forget_frames(struct vo *vo)
@@ -410,7 +414,6 @@ static void resize(struct vo *vo)
int min_output_width = FFMAX(vo->dwidth, vc->vid_width);
int min_output_height = FFMAX(vo->dheight, vc->vid_height);
- bool had_frames = vc->num_shown_frames;
if (vc->output_surface_width < min_output_width
|| vc->output_surface_height < min_output_height) {
if (vc->output_surface_width < min_output_width) {
@@ -439,11 +442,8 @@ static void resize(struct vo *vo)
mp_msg(MSGT_VO, MSGL_DBG2, "vdpau out create: %u\n",
vc->output_surfaces[i]);
}
- vc->num_shown_frames = 0;
}
- if (vc->paused && had_frames)
- if (video_to_output_surface(vo) >= 0)
- flip_page_timed(vo, 0, -1);
+ vo->want_redraw = true;
}
static void preemption_callback(VdpDevice device, void *context)
@@ -825,7 +825,6 @@ static void mark_vdpau_objects_uninitialized(struct vo *vo)
};
vc->output_surface_width = vc->output_surface_height = -1;
vc->eosd_render_count = 0;
- vc->num_shown_frames = 0;
}
static int handle_preemption(struct vo *vo)
@@ -937,9 +936,6 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
static void check_events(struct vo *vo)
{
- struct vdpctx *vc = vo->priv;
- struct vdp_functions *vdp = vc->vdp;
-
if (handle_preemption(vo) < 0)
return;
@@ -947,19 +943,8 @@ static void check_events(struct vo *vo)
if (e & VO_EVENT_RESIZE)
resize(vo);
- else if (e & VO_EVENT_EXPOSE && vc->paused) {
- /* did we already draw a buffer */
- if (vc->num_shown_frames) {
- /* redraw the last visible buffer */
- VdpStatus vdp_st;
- int last_surface = WRAP_ADD(vc->surface_num, -1,
- vc->num_output_surfaces);
- vdp_st = vdp->presentation_queue_display(vc->flip_queue,
- vc->output_surfaces[last_surface],
- vo->dwidth, vo->dheight, 0);
- CHECK_ST_WARNING("Error when calling "
- "vdp_presentation_queue_display");
- }
+ else if (e & VO_EVENT_EXPOSE) {
+ vo->want_redraw = true;
}
}
@@ -1400,7 +1385,6 @@ static void flip_page_timed(struct vo *vo, unsigned int pts_us, int duration)
vc->last_ideal_time = ideal_pts;
vc->dropped_frame = false;
vc->surface_num = WRAP_ADD(vc->surface_num, 1, vc->num_output_surfaces);
- vc->num_shown_frames = FFMIN(vc->num_shown_frames + 1, 1000);
}
static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w,
@@ -1796,13 +1780,12 @@ static int control(struct vo *vo, uint32_t request, void *data)
feature_enables);
CHECK_ST_WARNING("Error changing deinterlacing settings");
}
+ vo->want_redraw = true;
return VO_TRUE;
case VOCTRL_PAUSE:
if (vc->dropped_frame)
flip_page_timed(vo, 0, -1);
- return (vc->paused = true);
- case VOCTRL_RESUME:
- return (vc->paused = false);
+ return true;
case VOCTRL_QUERY_FORMAT:
return query_format(*(uint32_t *)data);
case VOCTRL_GET_IMAGE:
@@ -1823,6 +1806,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
checked_resize(vo);
return VO_TRUE;
case VOCTRL_SET_EQUALIZER: {
+ vo->want_redraw = true;
struct voctrl_set_equalizer_args *args = data;
return set_equalizer(vo, args->name, args->value);
}
@@ -1834,6 +1818,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
vc->colorspace = *(struct mp_csp_details *)data;
if (status_ok(vo))
update_csc_matrix(vo);
+ vo->want_redraw = true;
return true;
case VOCTRL_GET_YUV_COLORSPACE:
*(struct mp_csp_details *)data = vc->colorspace;
@@ -1858,11 +1843,15 @@ static int control(struct vo *vo, uint32_t request, void *data)
r->mt = r->mb = vc->border_y;
return VO_TRUE;
}
- case VOCTRL_REDRAW_OSD:
+ case VOCTRL_NEWFRAME:
+ vc->deint_queue_pos = next_deint_queue_pos(vo, true);
+ video_to_output_surface(vo);
+ return true;
+ case VOCTRL_SKIPFRAME:
+ vc->deint_queue_pos = next_deint_queue_pos(vo, true);
+ return true;
+ 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);
@@ -1892,7 +1881,7 @@ const struct vo_driver video_out_vdpau = {
.config = config,
.control = control,
.draw_image = draw_image,
- .get_buffered_frame = get_buffered_frame,
+ .get_buffered_frame = set_next_frame_info,
.draw_slice = draw_slice,
.draw_osd = draw_osd,
.flip_page_timed = flip_page_timed,
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index deda443594..4180ac0fd0 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;
@@ -420,18 +417,11 @@ static void copy_backup_image(struct vo *vo, int dest, int src)
static void check_events(struct vo *vo)
{
- struct xvctx *ctx = vo->priv;
int e = vo_x11_check_events(vo);
- if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE)
+ if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) {
resize(vo);
-
- 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]);
- }
+ vo->want_redraw = true;
}
}
@@ -446,26 +436,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;
}
@@ -477,11 +462,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);
@@ -524,11 +504,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];
@@ -570,7 +551,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:
@@ -590,9 +571,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;
}
@@ -844,20 +825,20 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_SET_PANSCAN:
resize(vo);
return VO_TRUE;
- case VOCTRL_SET_EQUALIZER:
- {
- struct voctrl_set_equalizer_args *args = data;
- return vo_xv_set_eq(vo, x11->xv_port, args->name, args->value);
- }
- case VOCTRL_GET_EQUALIZER:
- {
- struct voctrl_get_equalizer_args *args = data;
- return vo_xv_get_eq(vo, x11->xv_port, args->name, args->valueptr);
- }
+ case VOCTRL_SET_EQUALIZER: {
+ vo->want_redraw = true;
+ struct voctrl_set_equalizer_args *args = data;
+ return vo_xv_set_eq(vo, x11->xv_port, args->name, args->value);
+ }
+ case VOCTRL_GET_EQUALIZER: {
+ struct voctrl_get_equalizer_args *args = data;
+ return vo_xv_get_eq(vo, x11->xv_port, args->name, args->valueptr);
+ }
case VOCTRL_SET_YUV_COLORSPACE:;
struct mp_csp_details* given_cspc = data;
int is_709 = given_cspc->format == MP_CSP_BT_709;
vo_xv_set_eq(vo, x11->xv_port, "bt_709", is_709 * 200 - 100);
+ vo->want_redraw = true;
return true;
case VOCTRL_GET_YUV_COLORSPACE:;
struct mp_csp_details* cspc = data;
@@ -872,8 +853,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 dec68c83fd..892455c15c 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -2928,8 +2928,7 @@ static double update_video(struct MPContext *mpctx)
while (1) {
current_module = "filter_video";
- if (!mpctx->hrseek_active
- && vo_get_buffered_frame(video_out, false) >= 0)
+ if (vo_get_buffered_frame(video_out, false) >= 0)
break;
// XXX Time used in this call is not counted in any performance
// timer now
@@ -3035,6 +3034,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++;
@@ -3071,11 +3086,10 @@ static void pause_loop(struct MPContext *mpctx)
}
if (mpctx->sh_video && mpctx->video_out)
vo_check_events(mpctx->video_out);
- usec_sleep(20000);
update_osd_msg(mpctx);
int hack = vo_osd_changed(0);
vo_osd_changed(hack);
- if (hack)
+ if (hack || mpctx->sh_video && mpctx->video_out->want_redraw)
break;
#ifdef CONFIG_STREAM_CACHE
if (!opts->quiet && stream_cache_size > 0) {
@@ -3612,7 +3626,7 @@ static void run_playloop(struct MPContext *mpctx)
vo_fps = mpctx->sh_video->fps;
bool blit_frame = mpctx->video_out->frame_loaded;
- if (!blit_frame || mpctx->hrseek_active) {
+ if (!blit_frame) {
double frame_time = update_video(mpctx);
blit_frame = mpctx->video_out->frame_loaded;
mp_dbg(MSGT_AVSYNC, MSGL_DBG2, "*** ftime=%5.3f ***\n", frame_time);
@@ -3672,12 +3686,14 @@ static void run_playloop(struct MPContext *mpctx)
current_module = "flip_page";
if (!frame_time_remaining && blit_frame) {
+ vo_new_frame_imminent(mpctx->video_out);