From 350fc4f5a2f6f4fdf9cc689d786d525f6397df5d Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Fri, 18 Sep 2009 16:27:55 +0300 Subject: core/VO: Allow VO drivers to add/modify frames Add interfaces to allow VO drivers to add or remove frames from the video stream and to alter timestamps. Currently this functionality only works with in correct-pts mode. Use the new functionality in vo_vdpau to properly support frame-adding deinterlace modes. Frames added by the VDPAU deinterlacing code are now properly timed. Before every second frame was always shown immediately (probably next monitor refresh) after the previous one, even if you were watching things in slow motion, and framestepping didn't stop at them at all. When seeking the deinterlace algorithm is no longer fed a mix of frames from old and new positions. As a side effect of the changes a problem with resize events was also fixed. Resizing calls video_to_output_surface() to render the frame at the new resolution, but before this function also changed the list of history frames, so resizing could give an image different from the original one, and also corrupt next frames due to them seeing the wrong history. Now the function has no such side effects. There are more resize-related problems though that will be fixed in a later commit. The deint_mpi[] list of reserved frames is increased from 2 to 3 entries for reasons related to the above. Having 2 entries is enough when you initially get a new frame in draw_image() because then you'll have those two entries plus the new one for a total of 3 (the code relied on the oldest mpi implicitly staying reserved for the duration of the call even after usage count was decreased). However if you want to be able to reproduce the rendering outside draw_image(), relying on the explicitly reserved list only, then it needs to store 3 entries. --- libmpcodecs/vf.h | 1 - libmpcodecs/vf_vo.c | 13 +++---------- 2 files changed, 3 insertions(+), 11 deletions(-) (limited to 'libmpcodecs') diff --git a/libmpcodecs/vf.h b/libmpcodecs/vf.h index 99321b3afa..099135c5da 100644 --- a/libmpcodecs/vf.h +++ b/libmpcodecs/vf.h @@ -88,7 +88,6 @@ typedef struct vf_seteq_s #define VFCTRL_SCREENSHOT 14 /* Make a screenshot */ #define VFCTRL_INIT_EOSD 15 /* Select EOSD renderer */ #define VFCTRL_DRAW_EOSD 16 /* Render EOSD */ -#define VFCTRL_GET_PTS 17 /* Return last pts value that reached vf_vo*/ #define VFCTRL_SET_DEINTERLACE 18 /* Set deinterlacing status */ #define VFCTRL_GET_DEINTERLACE 19 /* Get deinterlacing status */ /* Hack to make the OSD state object available to vf_expand which accesses diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c index 7b3e16224f..53dc8267b6 100644 --- a/libmpcodecs/vf_vo.c +++ b/libmpcodecs/vf_vo.c @@ -22,7 +22,6 @@ extern int sub_visibility; extern float sub_delay; struct vf_priv_s { - double pts; struct vo *vo; #ifdef CONFIG_ASS ASS_Renderer *ass_priv; @@ -127,7 +126,7 @@ static int control(struct vf_instance* vf, int request, void* data) case VFCTRL_DRAW_EOSD: { mp_eosd_images_t images = {NULL, 2}; - double pts = vf->priv->pts; + double pts = video_out->next_pts; if (!video_out->config_ok || !vf->priv->ass_priv) return CONTROL_FALSE; if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE)) { mp_eosd_res_t res; @@ -148,11 +147,6 @@ static int control(struct vf_instance* vf, int request, void* data) return vo_control(video_out, VOCTRL_DRAW_EOSD, &images) == VO_TRUE; } #endif - case VFCTRL_GET_PTS: - { - *(double *)data = vf->priv->pts; - return CONTROL_TRUE; - } } return CONTROL_UNKNOWN; } @@ -179,10 +173,9 @@ static void get_image(struct vf_instance* vf, static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ if(!video_out->config_ok) return 0; // vo not configured? - // record pts (potentially modified by filters) for main loop - vf->priv->pts = pts; // first check, maybe the vo/vf plugin implements draw_image using mpi: - if (vo_control(video_out, VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; // done. + if (vo_draw_image(video_out, mpi, pts) >= 0) + return 1; // nope, fallback to old draw_frame/draw_slice: if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))){ // blit frame: -- cgit v1.2.3 From 56088ff4dc5180e95ea0c60f86a4b5ffc5c76611 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Fri, 18 Sep 2009 17:13:35 +0300 Subject: vo_vdpau: Fix memory corruption bug with MP_IMGTYPE_NUMBERED The way vo_vdpau kept references to vf mpi objects was unsafe; with fixed-vo enabled the vf object could be destroyed and a new one created, but vo_vdpau would still keep the now stale references and modify memory through them to adjust usage counts. Send a VOCTRL_RESET from vf_vo uninit() to allow vo_vdpau to erase such references. --- libmpcodecs/vf_vo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libmpcodecs') diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c index 53dc8267b6..c782a5517b 100644 --- a/libmpcodecs/vf_vo.c +++ b/libmpcodecs/vf_vo.c @@ -203,6 +203,9 @@ static void draw_slice(struct vf_instance* vf, static void uninit(struct vf_instance* vf) { if (vf->priv) { + /* Allow VO (which may live on to work with another instance of vf_vo) + * to get rid of numbered-mpi references that will now be invalid. */ + vo_control(video_out, VOCTRL_RESET, NULL); #ifdef CONFIG_ASS if (vf->priv->ass_priv) ass_renderer_done(vf->priv->ass_priv); -- cgit v1.2.3