[MPlayer-cvslog] r37936 - in trunk: libmenu/vf_menu.c libmpcodecs/dec_video.c libmpcodecs/dec_video.h libmpcodecs/vf.c libmpcodecs/vf.h libmpcodecs/vf_1bpp.c libmpcodecs/vf_2xsai.c libmpcodecs/vf_ass.c libmpcodecs/...

reimar subversion at mplayerhq.hu
Sat Apr 29 14:09:30 EEST 2017


Author: reimar
Date: Sat Apr 29 14:09:30 2017
New Revision: 37936

Log:
timing: pass through endpts and time last frame correctly.

endpts is the only way we can get correct timing
for the last frame.
It should also be useful to implement e.g. correctly
interpolated pts for frame-doubling deinterlacing and
to fix timing for -nodouble rendering (which draws
the frame a decode time, so we need to know the approximately
right time to decode the next frame before it was decoded/filtered).

Fixes trac issue #2315.

Modified:
   trunk/libmenu/vf_menu.c
   trunk/libmpcodecs/dec_video.c
   trunk/libmpcodecs/dec_video.h
   trunk/libmpcodecs/vf.c
   trunk/libmpcodecs/vf.h
   trunk/libmpcodecs/vf_1bpp.c
   trunk/libmpcodecs/vf_2xsai.c
   trunk/libmpcodecs/vf_ass.c
   trunk/libmpcodecs/vf_blackframe.c
   trunk/libmpcodecs/vf_bmovl.c
   trunk/libmpcodecs/vf_boxblur.c
   trunk/libmpcodecs/vf_crop.c
   trunk/libmpcodecs/vf_cropdetect.c
   trunk/libmpcodecs/vf_decimate.c
   trunk/libmpcodecs/vf_delogo.c
   trunk/libmpcodecs/vf_denoise3d.c
   trunk/libmpcodecs/vf_detc.c
   trunk/libmpcodecs/vf_dint.c
   trunk/libmpcodecs/vf_divtc.c
   trunk/libmpcodecs/vf_down3dright.c
   trunk/libmpcodecs/vf_eq.c
   trunk/libmpcodecs/vf_eq2.c
   trunk/libmpcodecs/vf_expand.c
   trunk/libmpcodecs/vf_field.c
   trunk/libmpcodecs/vf_fil.c
   trunk/libmpcodecs/vf_filmdint.c
   trunk/libmpcodecs/vf_fixpts.c
   trunk/libmpcodecs/vf_flip.c
   trunk/libmpcodecs/vf_framestep.c
   trunk/libmpcodecs/vf_fspp.c
   trunk/libmpcodecs/vf_geq.c
   trunk/libmpcodecs/vf_gradfun.c
   trunk/libmpcodecs/vf_halfpack.c
   trunk/libmpcodecs/vf_harddup.c
   trunk/libmpcodecs/vf_hqdn3d.c
   trunk/libmpcodecs/vf_hue.c
   trunk/libmpcodecs/vf_il.c
   trunk/libmpcodecs/vf_ilpack.c
   trunk/libmpcodecs/vf_ivtc.c
   trunk/libmpcodecs/vf_kerndeint.c
   trunk/libmpcodecs/vf_lavc.c
   trunk/libmpcodecs/vf_lavfi.c
   trunk/libmpcodecs/vf_mcdeint.c
   trunk/libmpcodecs/vf_mirror.c
   trunk/libmpcodecs/vf_noise.c
   trunk/libmpcodecs/vf_ow.c
   trunk/libmpcodecs/vf_palette.c
   trunk/libmpcodecs/vf_perspective.c
   trunk/libmpcodecs/vf_phase.c
   trunk/libmpcodecs/vf_pp.c
   trunk/libmpcodecs/vf_pp7.c
   trunk/libmpcodecs/vf_pullup.c
   trunk/libmpcodecs/vf_qp.c
   trunk/libmpcodecs/vf_rectangle.c
   trunk/libmpcodecs/vf_remove_logo.c
   trunk/libmpcodecs/vf_rgbtest.c
   trunk/libmpcodecs/vf_rotate.c
   trunk/libmpcodecs/vf_sab.c
   trunk/libmpcodecs/vf_scale.c
   trunk/libmpcodecs/vf_screenshot.c
   trunk/libmpcodecs/vf_smartblur.c
   trunk/libmpcodecs/vf_softpulldown.c
   trunk/libmpcodecs/vf_softskip.c
   trunk/libmpcodecs/vf_spp.c
   trunk/libmpcodecs/vf_stereo3d.c
   trunk/libmpcodecs/vf_swapuv.c
   trunk/libmpcodecs/vf_telecine.c
   trunk/libmpcodecs/vf_test.c
   trunk/libmpcodecs/vf_tfields.c
   trunk/libmpcodecs/vf_tile.c
   trunk/libmpcodecs/vf_tinterlace.c
   trunk/libmpcodecs/vf_unsharp.c
   trunk/libmpcodecs/vf_uspp.c
   trunk/libmpcodecs/vf_vo.c
   trunk/libmpcodecs/vf_yadif.c
   trunk/libmpcodecs/vf_yuvcsp.c
   trunk/libmpcodecs/vf_yvu9.c
   trunk/libmpcodecs/vf_zrmjpeg.c
   trunk/libmpdemux/demuxer.c
   trunk/libmpdemux/demuxer.h
   trunk/libmpdemux/stheader.h
   trunk/mencoder.c
   trunk/mplayer.c

Modified: trunk/libmenu/vf_menu.c
==============================================================================
--- trunk/libmenu/vf_menu.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmenu/vf_menu.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -54,12 +54,12 @@ struct vf_priv_s {
   int passthrough;
 };
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts);
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts);
 
 void vf_menu_pause_update(struct vf_instance *vf) {
   const vo_functions_t *video_out = mpctx_get_video_out(vf->priv->current->ctx);
   if(pause_mpi) {
-    put_image(vf,pause_mpi, MP_NOPTS_VALUE);
+    put_image(vf,pause_mpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
     // Don't draw the osd atm
     //vf->control(vf,VFCTRL_DRAW_OSD,NULL);
     video_out->flip_page();
@@ -137,14 +137,14 @@ static int key_cb(int code) {
   return menu_read_key(st_priv->current,code);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
   mp_image_t *dmpi = NULL;
 
   if (vf->priv->passthrough) {
     dmpi=vf_get_image(vf->next, IMGFMT_MPEGPES, MP_IMGTYPE_EXPORT,
                       0, mpi->w, mpi->h);
     dmpi->planes[0]=mpi->planes[0];
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf,dmpi, pts, endpts);
   }
 
   // Close all menu who requested it
@@ -202,7 +202,7 @@ static int put_image(struct vf_instance
       dmpi->priv      = mpi->priv;
     }
   }
-  return vf_next_put_image(vf,dmpi, pts);
+  return vf_next_put_image(vf,dmpi, pts, endpts);
 }
 
 static void uninit(vf_instance_t *vf) {

Modified: trunk/libmpcodecs/dec_video.c
==============================================================================
--- trunk/libmpcodecs/dec_video.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/dec_video.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -388,7 +388,7 @@ int init_best_video_codec(sh_video_t *sh
 }
 
 void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size,
-                   int drop_frame, double pts, int *full_frame)
+                   int drop_frame, double pts, double endpts, int *full_frame)
 {
     mp_image_t *mpi = NULL;
     unsigned int t = GetTimer();
@@ -420,9 +420,12 @@ void *decode_video(sh_video_t *sh_video,
             for (i = 0; i < sh_video->num_buffered_pts; i++)
                 if (sh_video->buffered_pts[i] < pts)
                     break;
-            for (j = sh_video->num_buffered_pts; j > i; j--)
+            for (j = sh_video->num_buffered_pts; j > i; j--) {
                 sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1];
+                sh_video->buffered_endpts[j] = sh_video->buffered_endpts[j - 1];
+            }
             sh_video->buffered_pts[i] = pts;
+            sh_video->buffered_endpts[i] = endpts;
             sh_video->num_buffered_pts++;
         }
     }
@@ -454,10 +457,12 @@ void *decode_video(sh_video_t *sh_video,
         if (sh_video->num_buffered_pts) {
             sh_video->num_buffered_pts--;
             sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts];
+            sh_video->endpts = sh_video->buffered_endpts[sh_video->num_buffered_pts];
         } else {
             mp_msg(MSGT_CPLAYER, MSGL_ERR,
                    "No pts value from demuxer to use for frame!\n");
             sh_video->pts = MP_NOPTS_VALUE;
+            sh_video->endpts = MP_NOPTS_VALUE;
         }
         if (delay >= 0) {
             // limit buffered pts only afterwards so we do not get confused
@@ -479,13 +484,13 @@ void *decode_video(sh_video_t *sh_video,
     return mpi;
 }
 
-int filter_video(sh_video_t *sh_video, void *frame, double pts)
+int filter_video(sh_video_t *sh_video, void *frame, double pts, double endpts)
 {
     mp_image_t *mpi = frame;
     unsigned int t2 = GetTimer();
     vf_instance_t *vf = sh_video->vfilter;
     // apply video filters and call the leaf vo/ve
-    int ret = vf->put_image(vf, mpi, pts);
+    int ret = vf->put_image(vf, mpi, pts, endpts);
     if (ret > 0) {
         // draw EOSD first so it ends up below the OSD.
         // Note that changing this is will not work right with vf_ass and the

Modified: trunk/libmpcodecs/dec_video.h
==============================================================================
--- trunk/libmpcodecs/dec_video.h	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/dec_video.h	Sat Apr 29 14:09:30 2017	(r37936)
@@ -29,8 +29,8 @@ void vfm_help(void);
 int init_best_video_codec(sh_video_t *sh_video, char** video_codec_list, char** video_fm_list);
 void uninit_video(sh_video_t *sh_video);
 
-void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, int drop_frame, double pts, int *full_frame);
-int filter_video(sh_video_t *sh_video, void *frame, double pts);
+void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, int drop_frame, double pts, double endpts, int *full_frame);
+int filter_video(sh_video_t *sh_video, void *frame, double pts, double endpts);
 
 int get_video_quality_max(sh_video_t *sh_video);
 void set_video_quality(sh_video_t *sh_video, int quality);

Modified: trunk/libmpcodecs/vf.c
==============================================================================
--- trunk/libmpcodecs/vf.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -716,14 +716,14 @@ int vf_next_query_format(struct vf_insta
     return flags;
 }
 
-int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
+int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts, double endpts){
     mpi->usage_count--;
     if (mpi->usage_count < 0) {
         mp_msg(MSGT_VFILTER, MSGL_V, "Bad mp_image usage count %i in vf_%s (type %i)\n",
                mpi->usage_count, vf->info->name, mpi->type);
         mpi->usage_count = 0;
     }
-    return vf->next->put_image(vf->next,mpi, pts);
+    return vf->next->put_image(vf->next,mpi, pts, endpts);
 }
 
 void vf_next_draw_slice(struct vf_instance *vf,unsigned char** src, int * stride,int w, int h, int x, int y){

Modified: trunk/libmpcodecs/vf.h
==============================================================================
--- trunk/libmpcodecs/vf.h	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf.h	Sat Apr 29 14:09:30 2017	(r37936)
@@ -66,7 +66,7 @@ typedef struct vf_instance {
     void (*get_image)(struct vf_instance *vf,
         mp_image_t *mpi);
     int (*put_image)(struct vf_instance *vf,
-        mp_image_t *mpi, double pts);
+        mp_image_t *mpi, double pts, double endpts);
     void (*start_slice)(struct vf_instance *vf,
         mp_image_t *mpi);
     void (*draw_slice)(struct vf_instance *vf,
@@ -109,8 +109,9 @@ typedef struct vf_seteq_s
 #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 */
+#define VFCTRL_GET_ENDPTS      18 /* Return last endpts value that reached vf_vo*/
+#define VFCTRL_SET_DEINTERLACE 19 /* Set deinterlacing status */
+#define VFCTRL_GET_DEINTERLACE 20 /* Get deinterlacing status */
 
 #include "vfcap.h"
 
@@ -138,7 +139,7 @@ int vf_next_config(struct vf_instance *v
 int vf_next_control(struct vf_instance *vf, int request, void* data);
 void vf_extra_flip(struct vf_instance *vf);
 int vf_next_query_format(struct vf_instance *vf, unsigned int fmt);
-int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts);
+int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts, double endpts);
 void vf_next_draw_slice (struct vf_instance *vf, unsigned char** src, int* stride, int w,int h, int x, int y);
 
 vf_instance_t* append_filters(vf_instance_t* last);

Modified: trunk/libmpcodecs/vf_1bpp.c
==============================================================================
--- trunk/libmpcodecs/vf_1bpp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_1bpp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -123,7 +123,7 @@ static void convert(mp_image_t *mpi, mp_
     }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     // hope we'll get DR buffer:
@@ -173,7 +173,7 @@ static int put_image(struct vf_instance
 	return 0;
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf,dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_2xsai.c
==============================================================================
--- trunk/libmpcodecs/vf_2xsai.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_2xsai.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -290,7 +290,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,2*width,2*height,2*d_width,2*d_height,flags,outfmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     // hope we'll get DR buffer:
@@ -302,7 +302,7 @@ static int put_image(struct vf_instance
                   dmpi->planes[0], dmpi->stride[0],
                   mpi->w, mpi->h, mpi->bpp/8);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf,dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_ass.c
==============================================================================
--- trunk/libmpcodecs/vf_ass.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_ass.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -836,7 +836,7 @@ static void prepare_eosd(vf_instance_t *
     vf->priv->prepare_buffer(vf);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     struct mp_eosd_image_list images;
     eosd_render_frame(pts, &images);
@@ -844,7 +844,7 @@ static int put_image(struct vf_instance
     if (images.changed)
         prepare_eosd(vf, &images);
     vf->priv->render_frame(vf);
-    return vf_next_put_image(vf, vf->dmpi, pts);
+    return vf_next_put_image(vf, vf->dmpi, pts, endpts);
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt)

Modified: trunk/libmpcodecs/vf_blackframe.c
==============================================================================
--- trunk/libmpcodecs/vf_blackframe.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_blackframe.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -66,7 +66,7 @@ static int query_format(struct vf_instan
     return 0;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     int x, y;
     int nblack=0, pblack=0;
@@ -107,7 +107,7 @@ static int put_image(struct vf_instance
 
     vf_clone_mpi_attributes(dmpi, mpi);
 
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data){

Modified: trunk/libmpcodecs/vf_bmovl.c
==============================================================================
--- trunk/libmpcodecs/vf_bmovl.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_bmovl.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -217,7 +217,7 @@ _read_cmd(int fd, char *cmd, char *args)
 
 
 static int
-put_image(struct vf_instance *vf, mp_image_t* mpi, double pts){
+put_image(struct vf_instance *vf, mp_image_t* mpi, double pts, double endpts){
 	int buf_x=0, buf_y=0, buf_pos=0;
 	int have, got, want;
 	int xpos=0, ypos=0, pos=0;
@@ -264,10 +264,10 @@ put_image(struct vf_instance *vf, mp_ima
 			else if( strncmp(cmd,"OPAQUE",6)==0 ) vf->priv->opaque=TRUE;
 			else if( strncmp(cmd,"SHOW",  4)==0 ) vf->priv->hidden=FALSE;
 			else if( strncmp(cmd,"HIDE",  4)==0 ) vf->priv->hidden=TRUE;
-			else if( strncmp(cmd,"FLUSH" ,5)==0 ) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+			else if( strncmp(cmd,"FLUSH" ,5)==0 ) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 			else {
 			    mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Unknown command: '%s'. Ignoring.\n", cmd);
-			    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+			    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 			}
 
 			if(command == CMD_ALPHA) {
@@ -286,7 +286,7 @@ put_image(struct vf_instance *vf, mp_ima
 			    buffer = malloc(imgw*imgh*pxsz);
 			    if(!buffer) {
 			    	mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Couldn't allocate temporary buffer! Skipping...\n\n");
-					return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+					return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 			    }
   				/* pipes/sockets might need multiple calls to read(): */
 			    want = (imgw*imgh*pxsz);
@@ -347,7 +347,7 @@ put_image(struct vf_instance *vf, mp_ima
 					if( (imgx <= vf->priv->x2) && ( (imgx+imgw) >= vf->priv->x2) )
 						vf->priv->x2 = imgx;
 				}
-				return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+				return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 			}
 
 			for( buf_y=0 ; (buf_y < imgh) && (buf_y < (vf->priv->h-imgy)) ; buf_y++ ) {
@@ -405,7 +405,7 @@ put_image(struct vf_instance *vf, mp_ima
 		}
     }
 
-	if(vf->priv->hidden) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+	if(vf->priv->hidden) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 
 	if(vf->priv->opaque) {	// Just copy buffer memory to screen
 		for( ypos=vf->priv->y1 ; ypos < vf->priv->y2 ; ypos++ ) {
@@ -460,7 +460,7 @@ put_image(struct vf_instance *vf, mp_ima
 			} // for xpos
 		} // for ypos
 	} // if !opaque
-    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 } // put_image
 
 static int

Modified: trunk/libmpcodecs/vf_boxblur.c
==============================================================================
--- trunk/libmpcodecs/vf_boxblur.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_boxblur.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -127,7 +127,7 @@ static void vBlur(uint8_t *dst, uint8_t
         }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
         int cw= mpi->w >> mpi->chroma_x_shift;
         int ch= mpi->h >> mpi->chroma_y_shift;
 
@@ -151,7 +151,7 @@ static int put_image(struct vf_instance
         vBlur(dmpi->planes[2], dmpi->planes[2], cw,ch,
                 dmpi->stride[2], dmpi->stride[2], vf->priv->chromaParam.radius, vf->priv->chromaParam.power);
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf,dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_crop.c
==============================================================================
--- trunk/libmpcodecs/vf_crop.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_crop.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -84,10 +84,10 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,vf->priv->crop_w,vf->priv->crop_h,d_width,d_height,flags,outfmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     if (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
-	return vf_next_put_image(vf,vf->dmpi, pts);
+	return vf_next_put_image(vf,vf->dmpi, pts, endpts);
     dmpi=vf_get_image(vf->next,mpi->imgfmt,
 	MP_IMGTYPE_EXPORT, 0,
 	vf->priv->crop_w, vf->priv->crop_h);
@@ -108,7 +108,7 @@ static int put_image(struct vf_instance
     }
     dmpi->stride[0]=mpi->stride[0];
     dmpi->width=mpi->width;
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf,dmpi, pts, endpts);
 }
 
 static void start_slice(struct vf_instance *vf, mp_image_t *mpi){

Modified: trunk/libmpcodecs/vf_cropdetect.c
==============================================================================
--- trunk/libmpcodecs/vf_cropdetect.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_cropdetect.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -72,7 +72,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     int bpp=mpi->bpp/8;
     int w,h,x,y,shrink_by;
@@ -161,7 +161,7 @@ if(++vf->priv->fno>0){        // ignore
 
 }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf,dmpi, pts, endpts);
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt) {

Modified: trunk/libmpcodecs/vf_decimate.c
==============================================================================
--- trunk/libmpcodecs/vf_decimate.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_decimate.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -128,7 +128,7 @@ static int diff_to_drop(int hi, int lo,
         new->w*(new->bpp/8), new->h, old->stride[0], new->stride[0]);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
 
@@ -161,7 +161,7 @@ static int put_image(struct vf_instance
             mpi->chroma_width, mpi->chroma_height,
             dmpi->stride[2], mpi->stride[2]);
     }
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf)

Modified: trunk/libmpcodecs/vf_delogo.c
==============================================================================
--- trunk/libmpcodecs/vf_delogo.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_delogo.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -195,7 +195,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     if(mpi->flags&MP_IMGFLAG_DIRECT) {
@@ -223,7 +223,7 @@ static int put_image(struct vf_instance
 
     vf_clone_mpi_attributes(dmpi, mpi);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_denoise3d.c
==============================================================================
--- trunk/libmpcodecs/vf_denoise3d.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_denoise3d.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -109,7 +109,7 @@ static void deNoise(unsigned char *Frame
 
 
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
         int cw= mpi->w >> mpi->chroma_x_shift;
         int ch= mpi->h >> mpi->chroma_y_shift;
         int W = mpi->w, H = mpi->h;
@@ -142,7 +142,7 @@ static int put_image(struct vf_instance
                 vf->priv->Coefs[3] + 256);
 
         vf->priv->pmpi=dmpi; // save reference image
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_detc.c
==============================================================================
--- trunk/libmpcodecs/vf_detc.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_detc.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -310,10 +310,10 @@ static int do_put_image(struct vf_instan
         }
 
         p->outframes++;
-        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
         int ret=0;
         mp_image_t *dmpi;

Modified: trunk/libmpcodecs/vf_dint.c
==============================================================================
--- trunk/libmpcodecs/vf_dint.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_dint.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -79,7 +79,7 @@ static int config (struct vf_instance *v
     return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
 }
 
-static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     int8_t rrow0[MAXROWSIZE];
     int8_t rrow1[MAXROWSIZE];
@@ -188,7 +188,7 @@ static int put_image (struct vf_instance
     }
     vf->priv->was_dint = 0;
 //    mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
-    return vf_next_put_image (vf, mpi, pts);
+    return vf_next_put_image(vf, mpi, pts, endpts);
 }
 
 static int vf_open(vf_instance_t *vf, char *args){

Modified: trunk/libmpcodecs/vf_divtc.c
==============================================================================
--- trunk/libmpcodecs/vf_divtc.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_divtc.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -258,7 +258,7 @@ static int match(struct vf_priv_s *p, in
    return m;
    }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
    {
    mp_image_t *dmpi, *tmpi=0;
    int n, m, f, newphase;
@@ -373,12 +373,12 @@ static int put_image(struct vf_instance
             imgop(copyop, tmpi, mpi, 0);
             imgop(deghost_plane, tmpi, dmpi, p->deghost);
             imgop(copyop, dmpi, mpi, 0);
-            return vf_next_put_image(vf, tmpi, MP_NOPTS_VALUE);
+            return vf_next_put_image(vf, tmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
             }
       }
 
    imgop(copyop, dmpi, mpi, 0);
-   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
    }
 
 static int analyze(struct vf_priv_s *p)

Modified: trunk/libmpcodecs/vf_down3dright.c
==============================================================================
--- trunk/libmpcodecs/vf_down3dright.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_down3dright.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -96,7 +96,7 @@ static void toright(unsigned char *dst[3
         }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
         mp_image_t *dmpi;
 
@@ -110,7 +110,7 @@ static int put_image(struct vf_instance
         toright(dmpi->planes, mpi->planes, dmpi->stride,
                 mpi->stride, mpi->w, mpi->h, vf->priv);
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int config(struct vf_instance *vf,

Modified: trunk/libmpcodecs/vf_eq.c
==============================================================================
--- trunk/libmpcodecs/vf_eq.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_eq.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -132,7 +132,7 @@ static void (*process)(unsigned char *de
 
 /* FIXME: add packed yuv version of process */
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
         mp_image_t *dmpi;
 
@@ -158,7 +158,7 @@ static int put_image(struct vf_instance
                         vf->priv->contrast);
         }
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data)

Modified: trunk/libmpcodecs/vf_eq2.c
==============================================================================
--- trunk/libmpcodecs/vf_eq2.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_eq2.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -238,7 +238,7 @@ void apply_lut (eq2_param_t *par, unsign
 }
 
 static
-int put_image (vf_instance_t *vf, mp_image_t *src, double pts)
+int put_image (vf_instance_t *vf, mp_image_t *src, double pts, double endpts)
 {
   unsigned      i;
   vf_eq2_t      *eq2;
@@ -278,7 +278,7 @@ int put_image (vf_instance_t *vf, mp_ima
     }
   }
 
-  return vf_next_put_image (vf, dst, pts);
+  return vf_next_put_image(vf, dst, pts, endpts);
 }
 
 static

Modified: trunk/libmpcodecs/vf_expand.c
==============================================================================
--- trunk/libmpcodecs/vf_expand.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_expand.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -398,12 +398,12 @@ static void draw_slice(struct vf_instanc
     vf->priv->first_slice = 0;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     if (vf->priv->passthrough) {
       mp_image_t *dmpi = vf_get_image(vf->next, IMGFMT_MPEGPES,
                                       MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h);
       dmpi->planes[0]=mpi->planes[0];
-      return vf_next_put_image(vf,dmpi, pts);
+      return vf_next_put_image(vf, dmpi, pts, endpts);
     }
 
     if(mpi->flags&MP_IMGFLAG_DIRECT || mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){
@@ -423,7 +423,7 @@ static int put_image(struct vf_instance
 	// we've used DR, so we're ready...
 	if(!(mpi->flags&MP_IMGFLAG_PLANAR))
 	    vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
-	return vf_next_put_image(vf,vf->dmpi, pts);
+	return vf_next_put_image(vf, vf->dmpi, pts, endpts);
     }
 
     // hope we'll get DR buffer:
@@ -455,7 +455,7 @@ static int put_image(struct vf_instance
 #ifdef OSD_SUPPORT
     if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h);
 #endif
-    return vf_next_put_image(vf,vf->dmpi, pts);
+    return vf_next_put_image(vf, vf->dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_field.c
==============================================================================
--- trunk/libmpcodecs/vf_field.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_field.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -38,7 +38,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,width,height/2,d_width,d_height,flags,outfmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
         MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
         mpi->width, mpi->height/2);
@@ -56,7 +56,7 @@ static int put_image(struct vf_instance
     } else
         vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!!
 
-    return vf_next_put_image(vf,vf->dmpi, pts);
+    return vf_next_put_image(vf, vf->dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_fil.c
==============================================================================
--- trunk/libmpcodecs/vf_fil.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_fil.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -63,10 +63,10 @@ static int config(struct vf_instance *vf
         (d_width*vf->priv->stridefactor)>>1, 2*d_height/vf->priv->stridefactor, flags, outfmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     if(mpi->flags&MP_IMGFLAG_DIRECT){
         // we've used DR, so we're ready...
-        return vf_next_put_image(vf,(mp_image_t*)mpi->priv, pts);
+        return vf_next_put_image(vf, (mp_image_t*)mpi->priv, pts, endpts);
     }
 
     vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
@@ -84,7 +84,7 @@ static int put_image(struct vf_instance
     } else
         vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!!
 
-    return vf_next_put_image(vf,vf->dmpi, pts);
+    return vf_next_put_image(vf, vf->dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_filmdint.c
==============================================================================
--- trunk/libmpcodecs/vf_filmdint.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_filmdint.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -1136,7 +1136,7 @@ find_breaks(struct vf_priv_s *p, struct
 
 #define ITOC(X) (!(X) ? ' ' : (X) + ((X)>9 ? 'a'-10 : '0'))
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
     struct vf_priv_s *p = vf->priv;
@@ -1331,7 +1331,7 @@ static int put_image(struct vf_instance
                "" : " @@@@@@@@@@@@@@@@@");
 
     p->merge_time += get_time() - diff_time;
-    return show_fields ? vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) : 0;
+    return show_fields ? vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE) : 0;
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt)

Modified: trunk/libmpcodecs/vf_fixpts.c
==============================================================================
--- trunk/libmpcodecs/vf_fixpts.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_fixpts.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -38,7 +38,7 @@ struct vf_priv_s {
     unsigned print:1;
 };
 
-static int put_image(vf_instance_t *vf, mp_image_t *src, double pts)
+static int put_image(vf_instance_t *vf, mp_image_t *src, double pts, double endpts)
 {
     struct vf_priv_s *p = vf->priv;
 
@@ -63,7 +63,7 @@ static int put_image(vf_instance_t *vf,
     } else {
         pts = MP_NOPTS_VALUE;
     }
-    return vf_next_put_image(vf, src, pts);
+    return vf_next_put_image(vf, src, pts, endpts);
 }
 
 static void uninit(vf_instance_t *vf)

Modified: trunk/libmpcodecs/vf_flip.c
==============================================================================
--- trunk/libmpcodecs/vf_flip.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_flip.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -59,12 +59,12 @@ static void get_image(struct vf_instance
     }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     if(mpi->flags&MP_IMGFLAG_DIRECT){
 	// we've used DR, so we're ready...
 	if(!(mpi->flags&MP_IMGFLAG_PLANAR))
 	    ((mp_image_t*)mpi->priv)->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
-	return vf_next_put_image(vf,(mp_image_t*)mpi->priv, pts);
+	return vf_next_put_image(vf, (mp_image_t*)mpi->priv, pts, endpts);
     }
 
     vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
@@ -85,7 +85,7 @@ static int put_image(struct vf_instance
     } else
 	vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!!
 
-    return vf_next_put_image(vf,vf->dmpi, pts);
+    return vf_next_put_image(vf, vf->dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_framestep.c
==============================================================================
--- trunk/libmpcodecs/vf_framestep.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_framestep.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -89,7 +89,7 @@ struct vf_priv_s {
 };
 
 /* Filter handler */
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t        *dmpi;
     struct vf_priv_s  *priv;
@@ -139,7 +139,7 @@ static int put_image(struct vf_instance
         dmpi->height    = mpi->height;
 
         /* Chain to next filter / output ... */
-        return vf_next_put_image(vf, dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
     }
 
     /* Skip the frame */

Modified: trunk/libmpcodecs/vf_fspp.c
==============================================================================
--- trunk/libmpcodecs/vf_fspp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_fspp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -523,7 +523,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
@@ -574,7 +574,7 @@ static int put_image(struct vf_instance
 #if HAVE_MMXEXT_INLINE
     if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf)

Modified: trunk/libmpcodecs/vf_geq.c
==============================================================================
--- trunk/libmpcodecs/vf_geq.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_geq.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -78,7 +78,7 @@ static double cr(void *vf, double x, dou
     return getpix(vf, x, y, 2);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     int x,y, plane;
 
@@ -124,7 +124,7 @@ static int put_image(struct vf_instance
 
     vf->priv->framenum++;
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_gradfun.c
==============================================================================
--- trunk/libmpcodecs/vf_gradfun.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_gradfun.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -295,7 +295,7 @@ static void get_image(struct vf_instance
     mpi->flags |= MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi = vf->dmpi;
     int p;
@@ -326,7 +326,7 @@ static int put_image(struct vf_instance
                        dmpi->stride[p], mpi->stride[p]);
     }
 
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt)

Modified: trunk/libmpcodecs/vf_halfpack.c
==============================================================================
--- trunk/libmpcodecs/vf_halfpack.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_halfpack.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -163,7 +163,7 @@ static void (*halfpack)(unsigned char *d
 	int dststride, int srcstride[3], int w, int h);
 
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
 	const uint8_t *src[MP_MAX_PLANES] = {
 		mpi->planes[0] + mpi->stride[0]*vf->priv->field,
@@ -187,7 +187,7 @@ static int put_image(struct vf_instance
 			mpi->stride, mpi->w, mpi->h);
 	}
 
-	return vf_next_put_image(vf,dmpi, pts);
+	return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int config(struct vf_instance *vf,

Modified: trunk/libmpcodecs/vf_harddup.c
==============================================================================
--- trunk/libmpcodecs/vf_harddup.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_harddup.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -31,7 +31,7 @@ struct vf_priv_s {
     mp_image_t *last_mpi;
 };
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
 
@@ -49,7 +49,7 @@ static int put_image(struct vf_instance
         dmpi->stride[2] = mpi->stride[2];
     }
 
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data)
@@ -61,7 +61,7 @@ static int control(struct vf_instance *v
         // has been called earlier in the filter chain
         // since the last put_image. This is reasonable
         // because we're handling a duplicate frame!
-        if (put_image(vf, vf->priv->last_mpi, MP_NOPTS_VALUE))
+        if (put_image(vf, vf->priv->last_mpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE))
             return CONTROL_TRUE;
         break;
     }

Modified: trunk/libmpcodecs/vf_hqdn3d.c
==============================================================================
--- trunk/libmpcodecs/vf_hqdn3d.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_hqdn3d.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -208,7 +208,7 @@ static void deNoise(unsigned char *Frame
 }
 
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
         int cw= mpi->w >> mpi->chroma_x_shift;
         int ch= mpi->h >> mpi->chroma_y_shift;
         int W = mpi->w, H = mpi->h;
@@ -238,7 +238,7 @@ static int put_image(struct vf_instance
                 vf->priv->Coefs[2],
                 vf->priv->Coefs[3]);
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_hue.c
==============================================================================
--- trunk/libmpcodecs/vf_hue.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_hue.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -76,7 +76,7 @@ static void (*process)(uint8_t *udst, ui
 
 /* FIXME: add packed yuv version of process */
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
         mp_image_t *dmpi;
 
@@ -107,7 +107,7 @@ static int put_image(struct vf_instance
                         vf->priv->hue, vf->priv->saturation);
         }
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data)

Modified: trunk/libmpcodecs/vf_il.c
==============================================================================
--- trunk/libmpcodecs/vf_il.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_il.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -73,7 +73,7 @@ static void interleave(uint8_t *dst, uin
     }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     int w;
     FilterParam *luma  = &vf->priv->lumaParam;
     FilterParam *chroma= &vf->priv->chromaParam;
@@ -100,7 +100,7 @@ static int put_image(struct vf_instance
             dmpi->stride[2], mpi->stride[2], chroma->interleave, luma->swap);
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_ilpack.c
==============================================================================
--- trunk/libmpcodecs/vf_ilpack.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_ilpack.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -373,7 +373,7 @@ static void ilpack(unsigned char *dst, u
 }
 
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
 
@@ -384,7 +384,7 @@ static int put_image(struct vf_instance
 
     ilpack(dmpi->planes[0], mpi->planes, dmpi->stride[0], mpi->stride, mpi->w, mpi->h, vf->priv->pack);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int config(struct vf_instance *vf,

Modified: trunk/libmpcodecs/vf_ivtc.c
==============================================================================
--- trunk/libmpcodecs/vf_ivtc.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_ivtc.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -452,10 +452,10 @@ static int do_put_image(struct vf_instan
     }
 
     p->outframes++;
-    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     int ret=0;
     struct vf_priv_s *p = vf->priv;

Modified: trunk/libmpcodecs/vf_kerndeint.c
==============================================================================
--- trunk/libmpcodecs/vf_kerndeint.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_kerndeint.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -74,7 +74,7 @@ static inline int IsYUY2(mp_image_t *mpi
 #define PLANAR_U 1
 #define PLANAR_V 2
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     int cw= mpi->w >> mpi->chroma_x_shift;
     int ch= mpi->h >> mpi->chroma_y_shift;
     int W = mpi->w, H = mpi->h;
@@ -98,7 +98,7 @@ static int put_image(struct vf_instance
     mp_image_t *dmpi, *pmpi;
 
     if(!vf->priv->do_deinterlace)
-        return vf_next_put_image(vf, mpi, pts);
+        return vf_next_put_image(vf, mpi, pts, endpts);
 
     dmpi=vf_get_image(vf->next,mpi->imgfmt,
         MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE,
@@ -273,7 +273,7 @@ static int put_image(struct vf_instance
         }
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_lavc.c
==============================================================================
--- trunk/libmpcodecs/vf_lavc.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_lavc.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -82,7 +82,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_MPEGPES);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t* dmpi;
     int out_size;
     AVFrame *pic= vf->priv->pic;
@@ -116,7 +116,7 @@ static int put_image(struct vf_instance
 
     dmpi->planes[0]=(unsigned char*)&vf->priv->pes;
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_lavfi.c
==============================================================================
--- trunk/libmpcodecs/vf_lavfi.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_lavfi.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -300,7 +300,7 @@ static void get_image(struct vf_instance
     mpi->priv = buf;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     AVFilterBufferRef *buf;
     mp_image_t *cmpi = NULL;

Modified: trunk/libmpcodecs/vf_mcdeint.c
==============================================================================
--- trunk/libmpcodecs/vf_mcdeint.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_mcdeint.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -282,7 +282,7 @@ return; //caused problems, dunno why
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
@@ -298,7 +298,7 @@ static int put_image(struct vf_instance
 
     filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_mirror.c
==============================================================================
--- trunk/libmpcodecs/vf_mirror.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_mirror.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -83,7 +83,7 @@ static void mirror(unsigned char* dst,un
 
 //===========================================================================//
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     // hope we'll get DR buffer:
@@ -108,7 +108,7 @@ static int put_image(struct vf_instance
         dmpi->planes[1]=mpi->planes[1]; // passthrough rgb8 palette
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_noise.c
==============================================================================
--- trunk/libmpcodecs/vf_noise.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_noise.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -339,7 +339,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
         mp_image_t *dmpi;
 
         if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
@@ -365,7 +365,7 @@ static int put_image(struct vf_instance
         if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_ow.c
==============================================================================
--- trunk/libmpcodecs/vf_ow.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_ow.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -233,7 +233,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
@@ -251,7 +251,7 @@ static int put_image(struct vf_instance
     filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
     filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_palette.c
==============================================================================
--- trunk/libmpcodecs/vf_palette.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_palette.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -112,7 +112,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     uint8_t *old_palette = mpi->planes[1];
 
@@ -171,7 +171,7 @@ static int put_image(struct vf_instance
     }
     mpi->planes[1] = old_palette;
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_perspective.c
==============================================================================
--- trunk/libmpcodecs/vf_perspective.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_perspective.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -260,7 +260,7 @@ static inline void resampleLinear(uint8_
     }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     int cw= mpi->w >> mpi->chroma_x_shift;
     int ch= mpi->h >> mpi->chroma_y_shift;
 
@@ -286,7 +286,7 @@ static int put_image(struct vf_instance
                 vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_phase.c
==============================================================================
--- trunk/libmpcodecs/vf_phase.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_phase.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -196,7 +196,7 @@ static enum mode analyze_plane(unsigned
    return mode;
    }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
    {
    mp_image_t *dmpi;
    int w;
@@ -237,7 +237,7 @@ static int put_image(struct vf_instance
                &vf->priv->buf[2], mode);
       }
 
-   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
    }
 
 static void uninit(struct vf_instance *vf)

Modified: trunk/libmpcodecs/vf_pp.c
==============================================================================
--- trunk/libmpcodecs/vf_pp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_pp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -128,7 +128,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
 	// no DR, so get a new image! hope we'll get DR buffer:
 	vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
@@ -153,7 +153,7 @@ static int put_image(struct vf_instance
 		    mpi->pict_type);
 #endif
     }
-    return vf_next_put_image(vf,vf->dmpi, pts);
+    return vf_next_put_image(vf, vf->dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_pp7.c
==============================================================================
--- trunk/libmpcodecs/vf_pp7.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_pp7.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -372,7 +372,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     if(mpi->flags&MP_IMGFLAG_DIRECT){
@@ -404,7 +404,7 @@ static int put_image(struct vf_instance
     if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_pullup.c
==============================================================================
--- trunk/libmpcodecs/vf_pullup.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_pullup.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -104,7 +104,7 @@ static void get_image(struct vf_instance
 }
 #endif
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     struct pullup_context *c = vf->priv->ctx;
     struct pullup_buffer *b;
@@ -230,7 +230,7 @@ static int put_image(struct vf_instance
             dmpi->qstride = mpi->qstride;
             dmpi->qscale_type = mpi->qscale_type;
         }
-        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
     }
     dmpi = vf_get_image(vf->next, mpi->imgfmt,
         MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
@@ -249,7 +249,7 @@ static int put_image(struct vf_instance
         dmpi->qstride = mpi->qstride;
         dmpi->qscale_type = mpi->qscale_type;
     }
-    ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
     pullup_release_frame(f);
     return ret;
 }

Modified: trunk/libmpcodecs/vf_qp.c
==============================================================================
--- trunk/libmpcodecs/vf_qp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_qp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -99,7 +99,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
         mp_image_t *dmpi;
         int x,y;
 
@@ -139,7 +139,7 @@ static int put_image(struct vf_instance
             }
         }
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_rectangle.c
==============================================================================
--- trunk/libmpcodecs/vf_rectangle.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_rectangle.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -83,7 +83,7 @@ control(struct vf_instance *vf, int requ
     return 0;
 }
 static int
-put_image(struct vf_instance *vf, mp_image_t* mpi, double pts){
+put_image(struct vf_instance *vf, mp_image_t* mpi, double pts, double endpts){
     mp_image_t* dmpi;
     unsigned int bpp = mpi->bpp / 8;
     int x, y, w, h;
@@ -152,7 +152,7 @@ put_image(struct vf_instance *vf, mp_ima
             p += dmpi->stride[0];
         }
     }
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int

Modified: trunk/libmpcodecs/vf_remove_logo.c
==============================================================================
--- trunk/libmpcodecs/vf_remove_logo.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_remove_logo.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -774,7 +774,7 @@ static void convert_yv12(const vf_instan
  * filter, has the logo removed by the filter, and is then sent to the next
  * filter.
  */
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     dmpi=vf_get_image(vf->next,vf->priv->fmt,
@@ -813,7 +813,7 @@ static int put_image(struct vf_instance
         return 0;
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_rgbtest.c
==============================================================================
--- trunk/libmpcodecs/vf_rgbtest.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_rgbtest.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -113,7 +113,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     int x, y;
     int w = vf->priv->w > 0 ? vf->priv->w : mpi->w;
@@ -137,7 +137,7 @@ static int put_image(struct vf_instance
          }
      }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_rotate.c
==============================================================================
--- trunk/libmpcodecs/vf_rotate.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_rotate.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -84,7 +84,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,height,width,d_height,d_width,flags,outfmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     // hope we'll get DR buffer:
@@ -109,7 +109,7 @@ static int put_image(struct vf_instance
         dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette
     }
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_sab.c
==============================================================================
--- trunk/libmpcodecs/vf_sab.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_sab.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -241,7 +241,7 @@ if((x/32)&1){
     }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     int cw= mpi->w >> mpi->chroma_x_shift;
     int ch= mpi->h >> mpi->chroma_y_shift;
 
@@ -255,7 +255,7 @@ static int put_image(struct vf_instance
     blur(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma);
     blur(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_scale.c
==============================================================================
--- trunk/libmpcodecs/vf_scale.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_scale.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -459,7 +459,7 @@ static void draw_slice(struct vf_instanc
     scale(vf->priv->ctx, vf->priv->ctx2, src, stride, y, h, dmpi->planes, dmpi->stride, vf->priv->interlaced);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi=mpi->priv;
 
 //  printf("vf_scale::put_image(): processing whole frame! dmpi=%p flag=%d\n",
@@ -483,7 +483,7 @@ static int put_image(struct vf_instance
 
     if(vf->priv->palette) dmpi->planes[1]=vf->priv->palette; // export palette!
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data){

Modified: trunk/libmpcodecs/vf_screenshot.c
==============================================================================
--- trunk/libmpcodecs/vf_screenshot.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_screenshot.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -194,7 +194,7 @@ static void get_image(struct vf_instance
     mpi->priv=vf->dmpi;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi = (mp_image_t *)mpi->priv;
 
@@ -224,7 +224,7 @@ static int put_image(struct vf_instance
         vf->priv->store_slices = 0;
     }
 
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int control (vf_instance_t *vf, int request, void *data)

Modified: trunk/libmpcodecs/vf_smartblur.c
==============================================================================
--- trunk/libmpcodecs/vf_smartblur.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_smartblur.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -182,7 +182,7 @@ static inline void blur(uint8_t *dst, ui
     }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     int cw= mpi->w >> mpi->chroma_x_shift;
     int ch= mpi->h >> mpi->chroma_y_shift;
     int threshold = vf->priv->luma.threshold || vf->priv->chroma.threshold;
@@ -198,7 +198,7 @@ static int put_image(struct vf_instance
     blur(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma);
     blur(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_softpulldown.c
==============================================================================
--- trunk/libmpcodecs/vf_softpulldown.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_softpulldown.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -35,7 +35,7 @@ struct vf_priv_s {
     long long out;
 };
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
     int ret = 0;
@@ -61,7 +61,7 @@ static int put_image(struct vf_instance
     }
 
     if (state == 0) {
-        ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+        ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         vf->priv->out++;
         if (flags & MP_IMGFIELD_REPEAT_FIRST) {
             my_memcpy_pic(dmpi->planes[0],
@@ -97,10 +97,10 @@ static int put_image(struct vf_instance
                           mpi->chroma_width, mpi->chroma_height/2,
                           dmpi->stride[2]*2, mpi->stride[2]*2);
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         vf->priv->out++;
         if (flags & MP_IMGFIELD_REPEAT_FIRST) {
-            ret |= vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+            ret |= vf_next_put_image(vf, mpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
             vf->priv->out++;
             state=0;
         } else {

Modified: trunk/libmpcodecs/vf_softskip.c
==============================================================================
--- trunk/libmpcodecs/vf_softskip.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_softskip.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -31,7 +31,7 @@ struct vf_priv_s {
     int skipflag;
 };
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
 
@@ -51,7 +51,7 @@ static int put_image(struct vf_instance
         dmpi->stride[2] = mpi->stride[2];
     }
 
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int control(struct vf_instance *vf, int request, void* data)

Modified: trunk/libmpcodecs/vf_spp.c
==============================================================================
--- trunk/libmpcodecs/vf_spp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_spp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -470,7 +470,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
         mp_image_t *dmpi;
 
         if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
@@ -519,7 +519,7 @@ static int put_image(struct vf_instance
         if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-        return vf_next_put_image(vf,dmpi, pts);
+        return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_stereo3d.c
==============================================================================
--- trunk/libmpcodecs/vf_stereo3d.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_stereo3d.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -283,7 +283,7 @@ static int config(struct vf_instance *vf
                           d_width, d_height, flags, outfmt);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
     if (vf->priv->in.fmt == vf->priv->out.fmt) { //nothing to do
@@ -384,7 +384,7 @@ static int put_image(struct vf_instance
             break;
         }
     }
-    return vf_next_put_image(vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static int query_format(struct vf_instance *vf, unsigned int fmt)

Modified: trunk/libmpcodecs/vf_swapuv.c
==============================================================================
--- trunk/libmpcodecs/vf_swapuv.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_swapuv.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -48,7 +48,7 @@ static void get_image(struct vf_instance
     mpi->priv=(void*)dmpi;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     if(mpi->flags&MP_IMGFLAG_DIRECT){
@@ -67,7 +67,7 @@ static int put_image(struct vf_instance
 
     vf_clone_mpi_attributes(dmpi, mpi);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_telecine.c
==============================================================================
--- trunk/libmpcodecs/vf_telecine.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_telecine.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -33,7 +33,7 @@ struct vf_priv_s {
     int frame;
 };
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t *dmpi;
     int ret;
@@ -63,7 +63,7 @@ static int put_image(struct vf_instance
                 chroma_width, mpi->chroma_height/2,
                 dmpi->stride[2]*2, mpi->stride[2]*2);
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         /* Fallthrough */
     case 1:
     case 2:
@@ -77,7 +77,7 @@ static int put_image(struct vf_instance
                 chroma_width, mpi->chroma_height,
                 dmpi->stride[2], mpi->stride[2]);
         }
-        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) || ret;
+        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE) || ret;
     case 3:
         my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
             mpi->planes[0]+mpi->stride[0], w, mpi->h/2,
@@ -92,7 +92,7 @@ static int put_image(struct vf_instance
                 chroma_width, mpi->chroma_height/2,
                 dmpi->stride[2]*2, mpi->stride[2]*2);
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         my_memcpy_pic(dmpi->planes[0], mpi->planes[0], w, mpi->h/2,
             dmpi->stride[0]*2, mpi->stride[0]*2);
         if (mpi->flags & MP_IMGFLAG_PLANAR) {

Modified: trunk/libmpcodecs/vf_test.c
==============================================================================
--- trunk/libmpcodecs/vf_test.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_test.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -269,7 +269,7 @@ static void ring2Test(uint8_t *dst, int
         }
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     int frame= vf->priv->frame_num;
 
@@ -302,7 +302,7 @@ static int put_image(struct vf_instance
 
     frame++;
     vf->priv->frame_num= frame;
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_tfields.c
==============================================================================
--- trunk/libmpcodecs/vf_tfields.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_tfields.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -328,7 +328,7 @@ static void (*qpel_4tap)(unsigned char *
 
 static int continue_buffered_image(struct vf_instance *vf);
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
 	vf->priv->buffered_mpi = mpi;
 	vf->priv->buffered_pts = pts;
@@ -392,7 +392,7 @@ static int continue_buffered_image(struc
 				dmpi->stride[1] = 2*mpi->stride[1];
 				dmpi->stride[2] = 2*mpi->stride[2];
 			}
-			ret |= vf_next_put_image(vf, dmpi, calc_pts(pts, i));
+			ret |= vf_next_put_image(vf, dmpi, calc_pts(pts, i), MP_NOPTS_VALUE);
 			if (correct_pts)
 				break;
 			else
@@ -422,7 +422,7 @@ static int continue_buffered_image(struc
 				deint(dmpi->planes[2], dmpi->stride[2], mpi->planes[2], mpi->stride[2],
 					mpi->chroma_width, mpi->chroma_height, (i^!tff));
 			}
-			ret |= vf_next_put_image(vf, dmpi, calc_pts(pts, i));
+			ret |= vf_next_put_image(vf, dmpi, calc_pts(pts, i), MP_NOPTS_VALUE);
 			if (correct_pts)
 				break;
 			else
@@ -448,7 +448,7 @@ static int continue_buffered_image(struc
 					mpi->chroma_width, mpi->chroma_height/2,
 					dmpi->stride[2], mpi->stride[2]*2, (i^!tff));
 			}
-			ret |= vf_next_put_image(vf, dmpi, calc_pts(pts, i));
+			ret |= vf_next_put_image(vf, dmpi, calc_pts(pts, i), MP_NOPTS_VALUE);
 			if (correct_pts)
 				break;
 			else

Modified: trunk/libmpcodecs/vf_tile.c
==============================================================================
--- trunk/libmpcodecs/vf_tile.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_tile.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -107,7 +107,7 @@ static int config(struct vf_instance *vf
 }
 
 /* Filter handler */
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     mp_image_t        *dmpi;
     struct vf_priv_s  *priv;
@@ -184,7 +184,7 @@ static int put_image(struct vf_instance
         /* Display the composition */
         dmpi->width  = xw;
         dmpi->height = yh;
-        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
     }
     else {
         /* Skip the frame */

Modified: trunk/libmpcodecs/vf_tinterlace.c
==============================================================================
--- trunk/libmpcodecs/vf_tinterlace.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_tinterlace.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -37,7 +37,7 @@ struct vf_priv_s {
     mp_image_t *dmpi;
 };
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts)
 {
     int ret = 0;
     mp_image_t *dmpi;
@@ -76,16 +76,16 @@ static int put_image(struct vf_instance
                        mpi->chroma_width, mpi->chroma_height,
                        dmpi->stride[2]*2, mpi->stride[2]);
             }
-            ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+            ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         }
         break;
     case 1:
         if (vf->priv->frame & 1)
-            ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+            ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         break;
     case 2:
         if ((vf->priv->frame & 1) == 0)
-            ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+            ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         break;
     case 3:
         dmpi = vf_get_image(vf->next, mpi->imgfmt,
@@ -116,7 +116,7 @@ static int put_image(struct vf_instance
                        dmpi->stride[2]*2, mpi->stride[2]);
             }
         }
-        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         break;
     case 4:
         // Interleave even lines (only) from Frame 'i' with odd
@@ -166,7 +166,7 @@ static int put_image(struct vf_instance
                           mpi->chroma_width, mpi->chroma_height/2,
                           dmpi->stride[2]*2, mpi->stride[2]*2);
             }
-            ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+            ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
         }
         break;
     }

Modified: trunk/libmpcodecs/vf_unsharp.c
==============================================================================
--- trunk/libmpcodecs/vf_unsharp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_unsharp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -179,7 +179,7 @@ static void get_image( struct vf_instanc
     mpi->flags |= MP_IMGFLAG_DIRECT;
 }
 
-static int put_image( struct vf_instance *vf, mp_image_t *mpi, double pts) {
+static int put_image( struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts) {
     mp_image_t *dmpi = mpi->priv;
     mpi->priv = NULL;
 
@@ -202,7 +202,7 @@ static int put_image( struct vf_instance
         __asm__ volatile ("sfence\n\t");
 #endif
 
-    return vf_next_put_image( vf, dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit( struct vf_instance *vf ) {

Modified: trunk/libmpcodecs/vf_uspp.c
==============================================================================
--- trunk/libmpcodecs/vf_uspp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_uspp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -275,7 +275,7 @@ static void get_image(struct vf_instance
     mpi->flags|=MP_IMGFLAG_DIRECT;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
 
     if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
@@ -307,7 +307,7 @@ static int put_image(struct vf_instance
     if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
 #endif
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 static void uninit(struct vf_instance *vf){

Modified: trunk/libmpcodecs/vf_vo.c
==============================================================================
--- trunk/libmpcodecs/vf_vo.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_vo.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -34,6 +34,7 @@
 
 struct vf_priv_s {
     double pts;
+    double endpts;
     const vo_functions_t *vo;
 };
 #define video_out (vf->priv->vo)
@@ -136,6 +137,11 @@ static int control(struct vf_instance *v
 	*(double *)data = vf->priv->pts;
 	return CONTROL_TRUE;
     }
+    case VFCTRL_GET_ENDPTS:
+    {
+	*(double *)data = vf->priv->endpts;
+	return CONTROL_TRUE;
+    }
     }
     // return video_out->control(request,data);
     return CONTROL_UNKNOWN;
@@ -160,10 +166,11 @@ static void get_image(struct vf_instance
 }
 
 static int put_image(struct vf_instance *vf,
-        mp_image_t *mpi, double pts){
+        mp_image_t *mpi, double pts, double endpts){
   if(!vo_config_count) return 0; // vo not configured?
   // record pts (potentially modified by filters) for main loop
   vf->priv->pts = pts;
+  vf->priv->endpts = endpts;
   // first check, maybe the vo/vf plugin implements draw_image using mpi:
   if(video_out->control(VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; // done.
   // nope, fallback to old draw_frame/draw_slice:

Modified: trunk/libmpcodecs/vf_yadif.c
==============================================================================
--- trunk/libmpcodecs/vf_yadif.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_yadif.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -396,7 +396,7 @@ static int config(struct vf_instance *vf
 
 static int continue_buffered_image(struct vf_instance *vf);
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     int tff;
 
     if(vf->priv->parity < 0) {
@@ -415,7 +415,7 @@ static int put_image(struct vf_instance
     vf->priv->buffered_pts = pts;
 
     if(vf->priv->do_deinterlace == 0)
-        return vf_next_put_image(vf, mpi, pts);
+        return vf_next_put_image(vf, mpi, pts, endpts);
     else if(vf->priv->do_deinterlace == 1){
         vf->priv->do_deinterlace= 2;
         return 0;
@@ -443,7 +443,7 @@ static int continue_buffered_image(struc
         filter(vf->priv, dmpi->planes, dmpi->stride, mpi->w, mpi->h, i ^ tff ^ 1, tff);
         if (correct_pts && i < (vf->priv->mode & 1))
             vf_queue_frame(vf, continue_buffered_image);
-        ret |= vf_next_put_image(vf, dmpi, pts /*FIXME*/);
+        ret |= vf_next_put_image(vf, dmpi, pts /*FIXME*/, MP_NOPTS_VALUE);
         if (correct_pts)
             break;
         if(i<(vf->priv->mode&1))

Modified: trunk/libmpcodecs/vf_yuvcsp.c
==============================================================================
--- trunk/libmpcodecs/vf_yuvcsp.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_yuvcsp.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -48,7 +48,7 @@ static inline int clamp_c(int x){
     return (x > 240) ? 240 : (x < 16) ? 16 : x;
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     int i,j;
     uint8_t *y_in, *cb_in, *cr_in;
     uint8_t *y_out, *cb_out, *cr_out;
@@ -76,7 +76,7 @@ static int put_image(struct vf_instance
             cr_out[i*vf->dmpi->stride[2]+j] = clamp_c(cr_in[i*mpi->stride[2]+j]);
         }
 
-    return vf_next_put_image(vf,vf->dmpi, pts);
+    return vf_next_put_image(vf, vf->dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_yvu9.c
==============================================================================
--- trunk/libmpcodecs/vf_yvu9.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_yvu9.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -45,7 +45,7 @@ static int config(struct vf_instance *vf
     return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_YV12);
 }
 
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t *dmpi;
     int y,w,h;
 
@@ -75,7 +75,7 @@ static int put_image(struct vf_instance
 
     vf_clone_mpi_attributes(dmpi, mpi);
 
-    return vf_next_put_image(vf,dmpi, pts);
+    return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 //===========================================================================//

Modified: trunk/libmpcodecs/vf_zrmjpeg.c
==============================================================================
--- trunk/libmpcodecs/vf_zrmjpeg.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpcodecs/vf_zrmjpeg.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -817,7 +817,7 @@ static int config(struct vf_instance *vf
  * \param mpi pointer to mp_image_t structure
  * \param pts
  */
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
 	struct vf_priv_s *priv = vf->priv;
 	int size = 0;
 	int i;
@@ -833,7 +833,7 @@ static int put_image(struct vf_instance
 			MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h);
 	dmpi->planes[0] = (uint8_t*)priv->buf;
 	dmpi->planes[1] = (uint8_t*)size;
-	return vf_next_put_image(vf,dmpi, pts);
+	return vf_next_put_image(vf, dmpi, pts, endpts);
 }
 
 /// query_format entrypoint for the ZRMJPEG vf filter

Modified: trunk/libmpdemux/demuxer.c
==============================================================================
--- trunk/libmpdemux/demuxer.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpdemux/demuxer.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -886,14 +886,23 @@ int ds_get_packet(demux_stream_t *ds, un
 
 int ds_get_packet_pts(demux_stream_t *ds, unsigned char **start, double *pts)
 {
+    double dummy;
+    return ds_get_packet_pts_endpts(ds, start, pts, &dummy);
+}
+
+int ds_get_packet_pts_endpts(demux_stream_t *ds, unsigned char **start, double *pts, double *endpts)
+{
     int len;
     *pts = MP_NOPTS_VALUE;
+    *endpts = MP_NOPTS_VALUE;
     len = ds_get_packet(ds, start);
     if (len < 0)
         return len;
     // Return pts unless this read starts from the middle of a packet
     if (len == ds->buffer_pos)
         *pts = ds->current->pts;
+    if (len == ds->buffer_size)
+        *endpts = ds->current->endpts;
     return len;
 }
 

Modified: trunk/libmpdemux/demuxer.h
==============================================================================
--- trunk/libmpdemux/demuxer.h	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpdemux/demuxer.h	Sat Apr 29 14:09:30 2017	(r37936)
@@ -406,6 +406,7 @@ static inline int demux_getc(demux_strea
 void ds_free_packs(demux_stream_t *ds);
 int ds_get_packet(demux_stream_t *ds,unsigned char **start);
 int ds_get_packet_pts(demux_stream_t *ds, unsigned char **start, double *pts);
+int ds_get_packet_pts_endpts(demux_stream_t *ds, unsigned char **start, double *pts, double *endpts);
 int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start,
                       double *pts, double *endpts);
 double ds_get_next_pts(demux_stream_t *ds);

Modified: trunk/libmpdemux/stheader.h
==============================================================================
--- trunk/libmpdemux/stheader.h	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/libmpdemux/stheader.h	Sat Apr 29 14:09:30 2017	(r37936)
@@ -38,6 +38,7 @@
   /* audio: last known pts value in output from decoder \
    * video: predicted/interpolated PTS of the current frame */ \
   double pts; \
+  double endpts; \
   /* codec-specific: */ \
   void* context;   /* codec-specific stuff (usually HANDLE or struct pointer) */ \
   char* lang; /* track language */ \
@@ -102,6 +103,7 @@ typedef struct sh_video {
   float next_frame_time;
   double last_pts;
   double buffered_pts[64];
+  double buffered_endpts[64];
   int num_buffered_pts;
   // output format: (set by demuxer)
   float fps;              // frames per second (set only if constant fps)

Modified: trunk/mencoder.c
==============================================================================
--- trunk/mencoder.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/mencoder.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -463,9 +463,9 @@ static int slowseek(float end_pts, demux
 
         if (vfilter) {
             int softskip = (vfilter->control(vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) == CONTROL_TRUE);
-            void *decoded_frame = decode_video(sh_video, frame_data->start, frame_data->in_size, !softskip, MP_NOPTS_VALUE, NULL);
+            void *decoded_frame = decode_video(sh_video, frame_data->start, frame_data->in_size, !softskip, MP_NOPTS_VALUE, MP_NOPTS_VALUE, NULL);
 	    if (decoded_frame)
-		filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);
+		filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
 	    else if (frame_data->flush)
 		return 2;
         }
@@ -1504,7 +1504,7 @@ default:
                      (!sh_video->vfilter ||
                       ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE);
     void *decoded_frame = decode_video(sh_video,frame_data.start,frame_data.in_size,
-                                       drop_frame, MP_NOPTS_VALUE, NULL);
+                                       drop_frame, MP_NOPTS_VALUE, MP_NOPTS_VALUE, NULL);
     if (frame_data.flush && !decoded_frame)
         at_eof = 3;
     if (did_seek && sh_video->pts != MP_NOPTS_VALUE) {
@@ -1517,7 +1517,7 @@ default:
     // sh_video->pts causes flickering with subtitles and complaints from MPEG-4
     // encoder due to not being monotonic.
     // If you change this please note the reason here!
-    blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, v_muxer_time + sub_offset);}
+    blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, v_muxer_time + sub_offset, MP_NOPTS_VALUE);}
     v_muxer_time = adjusted_muxer_time(mux_v); // update after muxing
 
     if (sh_video->vf_initialized < 0) mencoder_exit(1, NULL);

Modified: trunk/mplayer.c
==============================================================================
--- trunk/mplayer.c	Sat Apr 29 14:09:23 2017	(r37935)
+++ trunk/mplayer.c	Sat Apr 29 14:09:30 2017	(r37936)
@@ -1777,6 +1777,7 @@ static int generate_video_frame(sh_video
     int in_size;
     int hit_eof = 0;
     double pts;
+    double endpts;
 
     while (1) {
         int drop_frame = 0;
@@ -1787,7 +1788,7 @@ static int generate_video_frame(sh_video
         if (vf_output_queued_frame(sh_video->vfilter))
             break;
         current_module = "video_read_frame";
-        in_size = ds_get_packet_pts(d_video, &start, &pts);
+        in_size = ds_get_packet_pts_endpts(d_video, &start, &pts, &endpts);
         if (in_size < 0) {
             // try to extract last frames in case of decoder lag
             in_size = 0;
@@ -1799,13 +1800,13 @@ static int generate_video_frame(sh_video
         if (in_size > max_framesize)
             max_framesize = in_size;
         current_module = "decode video";
-        decoded_frame  = decode_video(sh_video, start, in_size, drop_frame, pts, NULL);
+        decoded_frame  = decode_video(sh_video, start, in_size, drop_frame, pts, endpts, NULL);
         if (decoded_frame) {
             update_subtitles(sh_video, sh_video->pts, mpctx->d_sub, 0);
             update_teletext(sh_video, mpctx->demuxer, 0);
             update_osd_msg();
             current_module = "filter video";
-            if (filter_video(sh_video, decoded_frame, sh_video->pts))
+            if (filter_video(sh_video, decoded_frame, sh_video->pts, sh_video->endpts))
                 break;
         } else if (drop_frame)
             return -1;
@@ -2491,7 +2492,7 @@ static double update_video(int *blit_fra
             // still frame has been reached, no need to decode
             if ((in_size > 0 || flush) && !decoded_frame)
             decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
-                                         sh_video->pts, &full_frame);
+                                         sh_video->pts, sh_video->endpts, &full_frame);
 
             if (flush && !decoded_frame)
                 return -1;
@@ -2512,13 +2513,15 @@ static double update_video(int *blit_fra
 
         current_module = "filter_video";
         *blit_frame    = (decoded_frame && filter_video(sh_video, decoded_frame,
-                                                        sh_video->pts));
+                                                        sh_video->pts, sh_video->endpts));
     } else {
         int res = generate_video_frame(sh_video, mpctx->d_video);
         if (!res)
             return -1;
         ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
                                                       VFCTRL_GET_PTS, &sh_video->pts);
+        ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
+                                                      VFCTRL_GET_ENDPTS, &sh_video->endpts);
         if (sh_video->pts == MP_NOPTS_VALUE) {
             mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_PtsAfterFiltersMissing);
             sh_video->pts = sh_video->last_pts;
@@ -3795,7 +3798,7 @@ goto_enable_cache:
                 update_osd_msg();
             } else {
                 int frame_time_remaining = 0;
-                int blit_frame = 1;
+                int blit_frame = mpctx->num_buffered_frames > 0;
                 // skip timing after seek
                 int skip_timing = mpctx->startup_decode_retry > 0;
 
@@ -3822,13 +3825,25 @@ goto_enable_cache:
                         goto goto_next_file;
                     }
                     if (frame_time < 0) {
+                        // try to figure out duration of last frame
+                        if (correct_pts && mpctx->sh_video->endpts != MP_NOPTS_VALUE &&
+                            mpctx->sh_video->pts != MP_NOPTS_VALUE &&
+                            mpctx->sh_video->endpts > mpctx->sh_video->pts) {
+                            frame_time = mpctx->sh_video->endpts - mpctx->sh_video->pts;
+                        } else {
+                            frame_time = mpctx->sh_video->frametime;
+                        }
+                        mpctx->sh_video->frametime = -1;
+                        mpctx->sh_video->endpts = MP_NOPTS_VALUE;
+                    }
+                    if (frame_time < 0) {
                         // if we have no more video, sleep some arbitrary time
                         frame_time = 1.0 / 20.0;
                         // Ensure vo_pts is updated so that ao_pcm will not hang.
                         advance_timer(frame_time);
                         // only stop playing when audio is at end as well
                         if (!mpctx->sh_audio || (mpctx->d_audio->eof && !ds_fill_buffer(mpctx->d_audio)))
-                            mpctx->eof = 1;
+                            mpctx->eof = mpctx->time_frame <= 0;
                     } else {
                         // might return with !eof && !blit_frame if !correct_pts
                         mpctx->num_buffered_frames += blit_frame;


More information about the MPlayer-cvslog mailing list