[MPlayer-dev-eng] [PATCH 2/2] timing: pass through endpts and time last frame correctly.
Reimar Döffinger
Reimar.Doeffinger at gmx.de
Sat Apr 29 16:05:29 EEST 2017
Both committed.
On 08.03.2017, at 00:15, Reimar Döffinger <Reimar.Doeffinger at gmx.de> wrote:
> 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.
> ---
> libmenu/vf_menu.c | 10 +++++-----
> libmpcodecs/dec_video.c | 13 +++++++++----
> libmpcodecs/dec_video.h | 4 ++--
> libmpcodecs/vf.c | 4 ++--
> libmpcodecs/vf.h | 9 +++++----
> libmpcodecs/vf_1bpp.c | 4 ++--
> libmpcodecs/vf_2xsai.c | 4 ++--
> libmpcodecs/vf_ass.c | 4 ++--
> libmpcodecs/vf_blackframe.c | 4 ++--
> libmpcodecs/vf_bmovl.c | 14 +++++++-------
> libmpcodecs/vf_boxblur.c | 4 ++--
> libmpcodecs/vf_crop.c | 6 +++---
> libmpcodecs/vf_cropdetect.c | 4 ++--
> libmpcodecs/vf_decimate.c | 4 ++--
> libmpcodecs/vf_delogo.c | 4 ++--
> libmpcodecs/vf_denoise3d.c | 4 ++--
> libmpcodecs/vf_detc.c | 4 ++--
> libmpcodecs/vf_dint.c | 4 ++--
> libmpcodecs/vf_divtc.c | 6 +++---
> libmpcodecs/vf_down3dright.c | 4 ++--
> libmpcodecs/vf_eq.c | 4 ++--
> libmpcodecs/vf_eq2.c | 4 ++--
> libmpcodecs/vf_expand.c | 8 ++++----
> libmpcodecs/vf_field.c | 4 ++--
> libmpcodecs/vf_fil.c | 6 +++---
> libmpcodecs/vf_filmdint.c | 4 ++--
> libmpcodecs/vf_fixpts.c | 4 ++--
> libmpcodecs/vf_flip.c | 6 +++---
> libmpcodecs/vf_framestep.c | 4 ++--
> libmpcodecs/vf_fspp.c | 4 ++--
> libmpcodecs/vf_geq.c | 4 ++--
> libmpcodecs/vf_gradfun.c | 4 ++--
> libmpcodecs/vf_halfpack.c | 4 ++--
> libmpcodecs/vf_harddup.c | 6 +++---
> libmpcodecs/vf_hqdn3d.c | 4 ++--
> libmpcodecs/vf_hue.c | 4 ++--
> libmpcodecs/vf_il.c | 4 ++--
> libmpcodecs/vf_ilpack.c | 4 ++--
> libmpcodecs/vf_ivtc.c | 4 ++--
> libmpcodecs/vf_kerndeint.c | 6 +++---
> libmpcodecs/vf_lavc.c | 4 ++--
> libmpcodecs/vf_lavfi.c | 2 +-
> libmpcodecs/vf_mcdeint.c | 4 ++--
> libmpcodecs/vf_mirror.c | 4 ++--
> libmpcodecs/vf_noise.c | 4 ++--
> libmpcodecs/vf_ow.c | 4 ++--
> libmpcodecs/vf_palette.c | 4 ++--
> libmpcodecs/vf_perspective.c | 4 ++--
> libmpcodecs/vf_phase.c | 4 ++--
> libmpcodecs/vf_pp.c | 4 ++--
> libmpcodecs/vf_pp7.c | 4 ++--
> libmpcodecs/vf_pullup.c | 6 +++---
> libmpcodecs/vf_qp.c | 4 ++--
> libmpcodecs/vf_rectangle.c | 4 ++--
> libmpcodecs/vf_remove_logo.c | 4 ++--
> libmpcodecs/vf_rgbtest.c | 4 ++--
> libmpcodecs/vf_rotate.c | 4 ++--
> libmpcodecs/vf_sab.c | 4 ++--
> libmpcodecs/vf_scale.c | 4 ++--
> libmpcodecs/vf_screenshot.c | 4 ++--
> libmpcodecs/vf_smartblur.c | 4 ++--
> libmpcodecs/vf_softpulldown.c | 8 ++++----
> libmpcodecs/vf_softskip.c | 4 ++--
> libmpcodecs/vf_spp.c | 4 ++--
> libmpcodecs/vf_stereo3d.c | 4 ++--
> libmpcodecs/vf_swapuv.c | 4 ++--
> libmpcodecs/vf_telecine.c | 8 ++++----
> libmpcodecs/vf_test.c | 4 ++--
> libmpcodecs/vf_tfields.c | 8 ++++----
> libmpcodecs/vf_tile.c | 4 ++--
> libmpcodecs/vf_tinterlace.c | 12 ++++++------
> libmpcodecs/vf_unsharp.c | 4 ++--
> libmpcodecs/vf_uspp.c | 4 ++--
> libmpcodecs/vf_vo.c | 9 ++++++++-
> libmpcodecs/vf_yadif.c | 6 +++---
> libmpcodecs/vf_yuvcsp.c | 4 ++--
> libmpcodecs/vf_yvu9.c | 4 ++--
> libmpcodecs/vf_zrmjpeg.c | 4 ++--
> libmpdemux/demuxer.c | 9 +++++++++
> libmpdemux/demuxer.h | 1 +
> libmpdemux/stheader.h | 2 ++
> mencoder.c | 8 ++++----
> mplayer.c | 29 ++++++++++++++++++++++-------
> 83 files changed, 237 insertions(+), 197 deletions(-)
>
> diff --git a/libmenu/vf_menu.c b/libmenu/vf_menu.c
> index cac1c040d..2e601e0dc 100644
> --- a/libmenu/vf_menu.c
> +++ b/libmenu/vf_menu.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> 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) {
> diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c
> index 97a9ac29c..dd9380fff 100644
> --- a/libmpcodecs/dec_video.c
> +++ b/libmpcodecs/dec_video.c
> @@ -388,7 +388,7 @@ int init_best_video_codec(sh_video_t *sh_video, char **video_codec_list,
> }
>
> 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, unsigned char *start, int in_size,
> 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, unsigned char *start, int in_size,
> 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, unsigned char *start, int in_size,
> 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
> diff --git a/libmpcodecs/dec_video.h b/libmpcodecs/dec_video.h
> index 4be420592..2a53a70e5 100644
> --- a/libmpcodecs/dec_video.h
> +++ b/libmpcodecs/dec_video.h
> @@ -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);
> diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
> index d7d0e5f78..046579151 100644
> --- a/libmpcodecs/vf.c
> +++ b/libmpcodecs/vf.c
> @@ -716,14 +716,14 @@ int vf_next_query_format(struct vf_instance *vf, unsigned int fmt){
> 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){
> diff --git a/libmpcodecs/vf.h b/libmpcodecs/vf.h
> index 8fad5f2e8..0276e5a2d 100644
> --- a/libmpcodecs/vf.h
> +++ b/libmpcodecs/vf.h
> @@ -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 *vf,
> 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);
> diff --git a/libmpcodecs/vf_1bpp.c b/libmpcodecs/vf_1bpp.c
> index 8d1373594..5d09935b3 100644
> --- a/libmpcodecs/vf_1bpp.c
> +++ b/libmpcodecs/vf_1bpp.c
> @@ -123,7 +123,7 @@ static void convert(mp_image_t *mpi, mp_image_t *dmpi, int value0, int value1,in
> }
> }
>
> -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 *vf, mp_image_t *mpi, double pts){
> return 0;
> }
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf,dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_2xsai.c b/libmpcodecs/vf_2xsai.c
> index a19420ff9..90eb76ee4 100644
> --- a/libmpcodecs/vf_2xsai.c
> +++ b/libmpcodecs/vf_2xsai.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_ass.c
> index a5b50d97e..cc4b8289c 100644
> --- a/libmpcodecs/vf_ass.c
> +++ b/libmpcodecs/vf_ass.c
> @@ -836,7 +836,7 @@ static void prepare_eosd(vf_instance_t *vf, struct mp_eosd_image_list *imgs)
> 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 *vf, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_blackframe.c b/libmpcodecs/vf_blackframe.c
> index c72552c99..4d745344a 100644
> --- a/libmpcodecs/vf_blackframe.c
> +++ b/libmpcodecs/vf_blackframe.c
> @@ -66,7 +66,7 @@ static int query_format(struct vf_instance *vf, unsigned fmt) {
> 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, mp_image_t *mpi, double pts){
>
> 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){
> diff --git a/libmpcodecs/vf_bmovl.c b/libmpcodecs/vf_bmovl.c
> index bfbbe0be7..a40dee4d5 100644
> --- a/libmpcodecs/vf_bmovl.c
> +++ b/libmpcodecs/vf_bmovl.c
> @@ -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_image_t* mpi, double pts){
> 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_image_t* mpi, double pts){
> 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_image_t* mpi, double pts){
> 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_image_t* mpi, double pts){
> }
> }
>
> - 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_image_t* mpi, double pts){
> } // 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
> diff --git a/libmpcodecs/vf_boxblur.c b/libmpcodecs/vf_boxblur.c
> index bc1ec8028..004dbea80 100644
> --- a/libmpcodecs/vf_boxblur.c
> +++ b/libmpcodecs/vf_boxblur.c
> @@ -127,7 +127,7 @@ static void vBlur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int s
> }
> }
>
> -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_crop.c b/libmpcodecs/vf_crop.c
> index 20b0228d8..784ce0e3b 100644
> --- a/libmpcodecs/vf_crop.c
> +++ b/libmpcodecs/vf_crop.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> }
> 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){
> diff --git a/libmpcodecs/vf_cropdetect.c b/libmpcodecs/vf_cropdetect.c
> index c3de24793..0750418ce 100644
> --- a/libmpcodecs/vf_cropdetect.c
> +++ b/libmpcodecs/vf_cropdetect.c
> @@ -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 first 2 frames - they may be empty
>
> }
>
> - 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) {
> diff --git a/libmpcodecs/vf_decimate.c b/libmpcodecs/vf_decimate.c
> index 902c29204..5d4c93734 100644
> --- a/libmpcodecs/vf_decimate.c
> +++ b/libmpcodecs/vf_decimate.c
> @@ -128,7 +128,7 @@ static int diff_to_drop(int hi, int lo, float frac, mp_image_t *old, mp_image_t
> 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 *vf, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_delogo.c b/libmpcodecs/vf_delogo.c
> index add6dc6b0..dd3714122 100644
> --- a/libmpcodecs/vf_delogo.c
> +++ b/libmpcodecs/vf_delogo.c
> @@ -195,7 +195,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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, mp_image_t *mpi, double pts){
>
> 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){
> diff --git a/libmpcodecs/vf_denoise3d.c b/libmpcodecs/vf_denoise3d.c
> index a952a2228..7619cca33 100644
> --- a/libmpcodecs/vf_denoise3d.c
> +++ b/libmpcodecs/vf_denoise3d.c
> @@ -109,7 +109,7 @@ static void deNoise(unsigned char *Frame, // mpi->planes[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 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, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_detc.c b/libmpcodecs/vf_detc.c
> index 511ae3160..a27048bb0 100644
> --- a/libmpcodecs/vf_detc.c
> +++ b/libmpcodecs/vf_detc.c
> @@ -310,10 +310,10 @@ static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
> }
>
> 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;
> diff --git a/libmpcodecs/vf_dint.c b/libmpcodecs/vf_dint.c
> index ac5bf54a5..18740a177 100644
> --- a/libmpcodecs/vf_dint.c
> +++ b/libmpcodecs/vf_dint.c
> @@ -79,7 +79,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)
> {
> int8_t rrow0[MAXROWSIZE];
> int8_t rrow1[MAXROWSIZE];
> @@ -188,7 +188,7 @@ static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts)
> }
> 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){
> diff --git a/libmpcodecs/vf_divtc.c b/libmpcodecs/vf_divtc.c
> index 111e16f97..48112a9b6 100644
> --- a/libmpcodecs/vf_divtc.c
> +++ b/libmpcodecs/vf_divtc.c
> @@ -258,7 +258,7 @@ static int match(struct vf_priv_s *p, int *diffs,
> 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 *vf, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_down3dright.c b/libmpcodecs/vf_down3dright.c
> index f1e1f49b0..d1c015d0f 100644
> --- a/libmpcodecs/vf_down3dright.c
> +++ b/libmpcodecs/vf_down3dright.c
> @@ -96,7 +96,7 @@ static void toright(unsigned char *dst[3], unsigned char *src[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 *vf, mp_image_t *mpi, double pts)
> 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,
> diff --git a/libmpcodecs/vf_eq.c b/libmpcodecs/vf_eq.c
> index c432b1368..1ee3a5970 100644
> --- a/libmpcodecs/vf_eq.c
> +++ b/libmpcodecs/vf_eq.c
> @@ -132,7 +132,7 @@ static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int
>
> /* 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, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_eq2.c b/libmpcodecs/vf_eq2.c
> index 275f19698..e02a59c88 100644
> --- a/libmpcodecs/vf_eq2.c
> +++ b/libmpcodecs/vf_eq2.c
> @@ -238,7 +238,7 @@ void apply_lut (eq2_param_t *par, unsigned char *dst, unsigned char *src,
> }
>
> 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_image_t *src, double pts)
> }
> }
>
> - return vf_next_put_image (vf, dst, pts);
> + return vf_next_put_image(vf, dst, pts, endpts);
> }
>
> static
> diff --git a/libmpcodecs/vf_expand.c b/libmpcodecs/vf_expand.c
> index 85fae067c..ef9d9030c 100644
> --- a/libmpcodecs/vf_expand.c
> +++ b/libmpcodecs/vf_expand.c
> @@ -398,12 +398,12 @@ static void draw_slice(struct vf_instance *vf,
> 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 *vf, mp_image_t *mpi, double pts){
> // 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 *vf, mp_image_t *mpi, double pts){
> #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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_field.c b/libmpcodecs/vf_field.c
> index fcf24be0b..1d735c9c3 100644
> --- a/libmpcodecs/vf_field.c
> +++ b/libmpcodecs/vf_field.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> } 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_fil.c b/libmpcodecs/vf_fil.c
> index 7df7eb0af..a16ea66a1 100644
> --- a/libmpcodecs/vf_fil.c
> +++ b/libmpcodecs/vf_fil.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> } 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_filmdint.c b/libmpcodecs/vf_filmdint.c
> index 2e43bc1a1..3795170a0 100644
> --- a/libmpcodecs/vf_filmdint.c
> +++ b/libmpcodecs/vf_filmdint.c
> @@ -1136,7 +1136,7 @@ find_breaks(struct vf_priv_s *p, struct frame_stats *s)
>
> #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 *vf, mp_image_t *mpi, double pts)
> "" : " @@@@@@@@@@@@@@@@@");
>
> 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)
> diff --git a/libmpcodecs/vf_fixpts.c b/libmpcodecs/vf_fixpts.c
> index ae32b40d8..6bf17ee40 100644
> --- a/libmpcodecs/vf_fixpts.c
> +++ b/libmpcodecs/vf_fixpts.c
> @@ -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, mp_image_t *src, double pts)
> } 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)
> diff --git a/libmpcodecs/vf_flip.c b/libmpcodecs/vf_flip.c
> index e8660ceb5..742e9fdfb 100644
> --- a/libmpcodecs/vf_flip.c
> +++ b/libmpcodecs/vf_flip.c
> @@ -59,12 +59,12 @@ static void get_image(struct vf_instance *vf, mp_image_t *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){
> 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 *vf, mp_image_t *mpi, double pts){
> } 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_framestep.c b/libmpcodecs/vf_framestep.c
> index 701e6afba..8a126790b 100644
> --- a/libmpcodecs/vf_framestep.c
> +++ b/libmpcodecs/vf_framestep.c
> @@ -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 *vf, mp_image_t *mpi, double pts)
> 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 */
> diff --git a/libmpcodecs/vf_fspp.c b/libmpcodecs/vf_fspp.c
> index 09b90096b..9bb967710 100644
> --- a/libmpcodecs/vf_fspp.c
> +++ b/libmpcodecs/vf_fspp.c
> @@ -523,7 +523,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
> 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 *vf, mp_image_t *mpi, double pts)
> #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)
> diff --git a/libmpcodecs/vf_geq.c b/libmpcodecs/vf_geq.c
> index 6360f5da1..6414ec3b2 100644
> --- a/libmpcodecs/vf_geq.c
> +++ b/libmpcodecs/vf_geq.c
> @@ -78,7 +78,7 @@ static double cr(void *vf, double x, double y){
> 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, mp_image_t *mpi, double pts){
>
> 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){
> diff --git a/libmpcodecs/vf_gradfun.c b/libmpcodecs/vf_gradfun.c
> index 2e64a42c8..8e84027b1 100644
> --- a/libmpcodecs/vf_gradfun.c
> +++ b/libmpcodecs/vf_gradfun.c
> @@ -295,7 +295,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
> 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 *vf, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_halfpack.c b/libmpcodecs/vf_halfpack.c
> index 981d09e28..2b4c8c669 100644
> --- a/libmpcodecs/vf_halfpack.c
> +++ b/libmpcodecs/vf_halfpack.c
> @@ -163,7 +163,7 @@ static void (*halfpack)(unsigned char *dst, unsigned char *src[3],
> 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 *vf, mp_image_t *mpi, double pts)
> 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,
> diff --git a/libmpcodecs/vf_harddup.c b/libmpcodecs/vf_harddup.c
> index 5b6c2ff01..249b37ae9 100644
> --- a/libmpcodecs/vf_harddup.c
> +++ b/libmpcodecs/vf_harddup.c
> @@ -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 *vf, mp_image_t *mpi, double pts)
> 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 *vf, int request, void* data)
> // 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;
> }
> diff --git a/libmpcodecs/vf_hqdn3d.c b/libmpcodecs/vf_hqdn3d.c
> index eba3439d8..922254492 100644
> --- a/libmpcodecs/vf_hqdn3d.c
> +++ b/libmpcodecs/vf_hqdn3d.c
> @@ -208,7 +208,7 @@ static void deNoise(unsigned char *Frame, // mpi->planes[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 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, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_hue.c b/libmpcodecs/vf_hue.c
> index 177142f03..80a3bc0c3 100644
> --- a/libmpcodecs/vf_hue.c
> +++ b/libmpcodecs/vf_hue.c
> @@ -76,7 +76,7 @@ static void (*process)(uint8_t *udst, uint8_t *vdst, uint8_t *usrc, uint8_t *vsr
>
> /* 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, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_il.c b/libmpcodecs/vf_il.c
> index 210e30d3f..079ea791d 100644
> --- a/libmpcodecs/vf_il.c
> +++ b/libmpcodecs/vf_il.c
> @@ -73,7 +73,7 @@ static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dstStride,
> }
> }
>
> -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_ilpack.c b/libmpcodecs/vf_ilpack.c
> index 731d93f20..214c07c62 100644
> --- a/libmpcodecs/vf_ilpack.c
> +++ b/libmpcodecs/vf_ilpack.c
> @@ -373,7 +373,7 @@ static void ilpack(unsigned char *dst, unsigned char *src[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;
>
> @@ -384,7 +384,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
>
> 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,
> diff --git a/libmpcodecs/vf_ivtc.c b/libmpcodecs/vf_ivtc.c
> index 5a19d24ab..9b41533fe 100644
> --- a/libmpcodecs/vf_ivtc.c
> +++ b/libmpcodecs/vf_ivtc.c
> @@ -452,10 +452,10 @@ static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
> }
>
> 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;
> diff --git a/libmpcodecs/vf_kerndeint.c b/libmpcodecs/vf_kerndeint.c
> index c5197fc54..f69c6e67c 100644
> --- a/libmpcodecs/vf_kerndeint.c
> +++ b/libmpcodecs/vf_kerndeint.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> 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 *vf, mp_image_t *mpi, double pts){
> }
> }
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_lavc.c b/libmpcodecs/vf_lavc.c
> index 62dcf91a4..e6bbc50d3 100644
> --- a/libmpcodecs/vf_lavc.c
> +++ b/libmpcodecs/vf_lavc.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
>
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_lavfi.c b/libmpcodecs/vf_lavfi.c
> index 0f6e71a05..905b13bfe 100644
> --- a/libmpcodecs/vf_lavfi.c
> +++ b/libmpcodecs/vf_lavfi.c
> @@ -300,7 +300,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
> 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;
> diff --git a/libmpcodecs/vf_mcdeint.c b/libmpcodecs/vf_mcdeint.c
> index 1b2d1bbaf..f2fc4711c 100644
> --- a/libmpcodecs/vf_mcdeint.c
> +++ b/libmpcodecs/vf_mcdeint.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
>
> 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){
> diff --git a/libmpcodecs/vf_mirror.c b/libmpcodecs/vf_mirror.c
> index 5ac05e914..06c299ba1 100644
> --- a/libmpcodecs/vf_mirror.c
> +++ b/libmpcodecs/vf_mirror.c
> @@ -83,7 +83,7 @@ static void mirror(unsigned char* dst,unsigned char* src,int dststride,int srcst
>
> //===========================================================================//
>
> -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_noise.c b/libmpcodecs/vf_noise.c
> index 0fe9dcb96..244294a7b 100644
> --- a/libmpcodecs/vf_noise.c
> +++ b/libmpcodecs/vf_noise.c
> @@ -339,7 +339,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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 *vf, mp_image_t *mpi, double pts){
> 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){
> diff --git a/libmpcodecs/vf_ow.c b/libmpcodecs/vf_ow.c
> index f7fb02db7..4647068cd 100644
> --- a/libmpcodecs/vf_ow.c
> +++ b/libmpcodecs/vf_ow.c
> @@ -233,7 +233,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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 *vf, mp_image_t *mpi, double pts){
> 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){
> diff --git a/libmpcodecs/vf_palette.c b/libmpcodecs/vf_palette.c
> index fc6764b0b..eafac4d02 100644
> --- a/libmpcodecs/vf_palette.c
> +++ b/libmpcodecs/vf_palette.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> }
> mpi->planes[1] = old_palette;
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_perspective.c b/libmpcodecs/vf_perspective.c
> index f5a9d6be3..e826195ab 100644
> --- a/libmpcodecs/vf_perspective.c
> +++ b/libmpcodecs/vf_perspective.c
> @@ -260,7 +260,7 @@ static inline void resampleLinear(uint8_t *dst, uint8_t *src, int w, int h, 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){
> 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, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_phase.c b/libmpcodecs/vf_phase.c
> index 101290dec..790ffa199 100644
> --- a/libmpcodecs/vf_phase.c
> +++ b/libmpcodecs/vf_phase.c
> @@ -196,7 +196,7 @@ static enum mode analyze_plane(unsigned char *old, unsigned char *new,
> 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, mp_image_t *mpi, double pts)
> &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)
> diff --git a/libmpcodecs/vf_pp.c b/libmpcodecs/vf_pp.c
> index a26b28065..9721554d0 100644
> --- a/libmpcodecs/vf_pp.c
> +++ b/libmpcodecs/vf_pp.c
> @@ -128,7 +128,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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 *vf, mp_image_t *mpi, double pts){
> mpi->pict_type);
> #endif
> }
> - return vf_next_put_image(vf,vf->dmpi, pts);
> + return vf_next_put_image(vf, vf->dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_pp7.c b/libmpcodecs/vf_pp7.c
> index e47d642ed..6d6963db6 100644
> --- a/libmpcodecs/vf_pp7.c
> +++ b/libmpcodecs/vf_pp7.c
> @@ -372,7 +372,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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 *vf, mp_image_t *mpi, double pts){
> 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){
> diff --git a/libmpcodecs/vf_pullup.c b/libmpcodecs/vf_pullup.c
> index 5d08768b7..09dbd0f42 100644
> --- a/libmpcodecs/vf_pullup.c
> +++ b/libmpcodecs/vf_pullup.c
> @@ -104,7 +104,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
> }
> #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 *vf, mp_image_t *mpi, double pts)
> 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 *vf, mp_image_t *mpi, double pts)
> 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;
> }
> diff --git a/libmpcodecs/vf_qp.c b/libmpcodecs/vf_qp.c
> index 8dd935e59..31c9b5060 100644
> --- a/libmpcodecs/vf_qp.c
> +++ b/libmpcodecs/vf_qp.c
> @@ -99,7 +99,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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 *vf, mp_image_t *mpi, double pts){
> }
> }
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> static void uninit(struct vf_instance *vf){
> diff --git a/libmpcodecs/vf_rectangle.c b/libmpcodecs/vf_rectangle.c
> index 21bc209de..c169246dc 100644
> --- a/libmpcodecs/vf_rectangle.c
> +++ b/libmpcodecs/vf_rectangle.c
> @@ -83,7 +83,7 @@ control(struct vf_instance *vf, int request, void *data)
> 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_image_t* mpi, double pts){
> p += dmpi->stride[0];
> }
> }
> - return vf_next_put_image(vf, dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> static int
> diff --git a/libmpcodecs/vf_remove_logo.c b/libmpcodecs/vf_remove_logo.c
> index 7469ced1d..0841ef6aa 100644
> --- a/libmpcodecs/vf_remove_logo.c
> +++ b/libmpcodecs/vf_remove_logo.c
> @@ -774,7 +774,7 @@ static void convert_yv12(const vf_instance_t * const vf, const char * const sour
> * 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 *vf, mp_image_t *mpi, double pts){
> return 0;
> }
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_rgbtest.c b/libmpcodecs/vf_rgbtest.c
> index cbed6ed36..1e15e71eb 100644
> --- a/libmpcodecs/vf_rgbtest.c
> +++ b/libmpcodecs/vf_rgbtest.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> }
> }
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_rotate.c b/libmpcodecs/vf_rotate.c
> index 08d73bec2..8abf6c94a 100644
> --- a/libmpcodecs/vf_rotate.c
> +++ b/libmpcodecs/vf_rotate.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_sab.c b/libmpcodecs/vf_sab.c
> index 203c468dd..b131c394f 100644
> --- a/libmpcodecs/vf_sab.c
> +++ b/libmpcodecs/vf_sab.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c
> index 8eca5120a..ef50261ea 100644
> --- a/libmpcodecs/vf_scale.c
> +++ b/libmpcodecs/vf_scale.c
> @@ -459,7 +459,7 @@ static void draw_slice(struct vf_instance *vf,
> 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 *vf, mp_image_t *mpi, double pts){
>
> 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){
> diff --git a/libmpcodecs/vf_screenshot.c b/libmpcodecs/vf_screenshot.c
> index 992ea6df3..9aafac3a2 100644
> --- a/libmpcodecs/vf_screenshot.c
> +++ b/libmpcodecs/vf_screenshot.c
> @@ -194,7 +194,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
> 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, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_smartblur.c b/libmpcodecs/vf_smartblur.c
> index 0ccd36938..6de67bf5e 100644
> --- a/libmpcodecs/vf_smartblur.c
> +++ b/libmpcodecs/vf_smartblur.c
> @@ -182,7 +182,7 @@ static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride,
> }
> }
>
> -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_softpulldown.c b/libmpcodecs/vf_softpulldown.c
> index 1a66e5607..fed233971 100644
> --- a/libmpcodecs/vf_softpulldown.c
> +++ b/libmpcodecs/vf_softpulldown.c
> @@ -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 *vf, mp_image_t *mpi, double pts)
> }
>
> 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 *vf, mp_image_t *mpi, double pts)
> 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 {
> diff --git a/libmpcodecs/vf_softskip.c b/libmpcodecs/vf_softskip.c
> index 150c3e7b7..c0189949f 100644
> --- a/libmpcodecs/vf_softskip.c
> +++ b/libmpcodecs/vf_softskip.c
> @@ -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 *vf, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_spp.c b/libmpcodecs/vf_spp.c
> index 19257fb09..97cacdc6f 100644
> --- a/libmpcodecs/vf_spp.c
> +++ b/libmpcodecs/vf_spp.c
> @@ -470,7 +470,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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 *vf, mp_image_t *mpi, double pts){
> 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){
> diff --git a/libmpcodecs/vf_stereo3d.c b/libmpcodecs/vf_stereo3d.c
> index f26d95df3..641519e32 100644
> --- a/libmpcodecs/vf_stereo3d.c
> +++ b/libmpcodecs/vf_stereo3d.c
> @@ -283,7 +283,7 @@ static int config(struct vf_instance *vf, int width, int height, int d_width,
> 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 *vf, mp_image_t *mpi, double pts)
> 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)
> diff --git a/libmpcodecs/vf_swapuv.c b/libmpcodecs/vf_swapuv.c
> index 4d0e8fcb1..c8c0d61f9 100644
> --- a/libmpcodecs/vf_swapuv.c
> +++ b/libmpcodecs/vf_swapuv.c
> @@ -48,7 +48,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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, mp_image_t *mpi, double pts){
>
> vf_clone_mpi_attributes(dmpi, mpi);
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_telecine.c b/libmpcodecs/vf_telecine.c
> index 3ffa87faf..3d90c98d6 100644
> --- a/libmpcodecs/vf_telecine.c
> +++ b/libmpcodecs/vf_telecine.c
> @@ -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 *vf, mp_image_t *mpi, double pts)
> 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 *vf, mp_image_t *mpi, double pts)
> 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 *vf, mp_image_t *mpi, double pts)
> 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) {
> diff --git a/libmpcodecs/vf_test.c b/libmpcodecs/vf_test.c
> index bef06120e..a96e077c0 100644
> --- a/libmpcodecs/vf_test.c
> +++ b/libmpcodecs/vf_test.c
> @@ -269,7 +269,7 @@ static void ring2Test(uint8_t *dst, int stride, int off)
> }
> }
>
> -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 *vf, mp_image_t *mpi, double pts){
>
> frame++;
> vf->priv->frame_num= frame;
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_tfields.c b/libmpcodecs/vf_tfields.c
> index 7eec78673..e97376220 100644
> --- a/libmpcodecs/vf_tfields.c
> +++ b/libmpcodecs/vf_tfields.c
> @@ -328,7 +328,7 @@ static void (*qpel_4tap)(unsigned char *d, unsigned char *s, int w, int h, int d
>
> 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(struct vf_instance *vf)
> 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(struct vf_instance *vf)
> 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(struct vf_instance *vf)
> 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
> diff --git a/libmpcodecs/vf_tile.c b/libmpcodecs/vf_tile.c
> index 9ec037ef4..44f14c9fb 100644
> --- a/libmpcodecs/vf_tile.c
> +++ b/libmpcodecs/vf_tile.c
> @@ -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 *vf, mp_image_t *mpi, double pts)
> /* 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 */
> diff --git a/libmpcodecs/vf_tinterlace.c b/libmpcodecs/vf_tinterlace.c
> index 8cd6ac89b..2fe3c2e7b 100644
> --- a/libmpcodecs/vf_tinterlace.c
> +++ b/libmpcodecs/vf_tinterlace.c
> @@ -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 *vf, mp_image_t *mpi, double pts)
> 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 *vf, mp_image_t *mpi, double pts)
> 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 *vf, mp_image_t *mpi, double pts)
> 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;
> }
> diff --git a/libmpcodecs/vf_unsharp.c b/libmpcodecs/vf_unsharp.c
> index 56e85f473..12aec2390 100644
> --- a/libmpcodecs/vf_unsharp.c
> +++ b/libmpcodecs/vf_unsharp.c
> @@ -179,7 +179,7 @@ static void get_image( struct vf_instance *vf, mp_image_t *mpi ) {
> 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 *vf, mp_image_t *mpi, double pts) {
> __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 ) {
> diff --git a/libmpcodecs/vf_uspp.c b/libmpcodecs/vf_uspp.c
> index dd417009c..9f1709793 100644
> --- a/libmpcodecs/vf_uspp.c
> +++ b/libmpcodecs/vf_uspp.c
> @@ -275,7 +275,7 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
> 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 *vf, mp_image_t *mpi, double pts){
> 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){
> diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
> index 6511460f7..ce5d51345 100644
> --- a/libmpcodecs/vf_vo.c
> +++ b/libmpcodecs/vf_vo.c
> @@ -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 *vf, int request, void* data)
> *(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 *vf,
> }
>
> 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:
> diff --git a/libmpcodecs/vf_yadif.c b/libmpcodecs/vf_yadif.c
> index ccd050f03..aeec5fcc9 100644
> --- a/libmpcodecs/vf_yadif.c
> +++ b/libmpcodecs/vf_yadif.c
> @@ -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, mp_image_t *mpi, double pts){
> 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(struct vf_instance *vf)
> 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))
> diff --git a/libmpcodecs/vf_yuvcsp.c b/libmpcodecs/vf_yuvcsp.c
> index 102ce1453..efb3c7118 100644
> --- a/libmpcodecs/vf_yuvcsp.c
> +++ b/libmpcodecs/vf_yuvcsp.c
> @@ -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 *vf, mp_image_t *mpi, double pts){
> 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);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_yvu9.c b/libmpcodecs/vf_yvu9.c
> index 1f74261cc..28f158d28 100644
> --- a/libmpcodecs/vf_yvu9.c
> +++ b/libmpcodecs/vf_yvu9.c
> @@ -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, mp_image_t *mpi, double pts){
>
> vf_clone_mpi_attributes(dmpi, mpi);
>
> - return vf_next_put_image(vf,dmpi, pts);
> + return vf_next_put_image(vf, dmpi, pts, endpts);
> }
>
> //===========================================================================//
> diff --git a/libmpcodecs/vf_zrmjpeg.c b/libmpcodecs/vf_zrmjpeg.c
> index 6d3c7b2aa..ef5d5f00a 100644
> --- a/libmpcodecs/vf_zrmjpeg.c
> +++ b/libmpcodecs/vf_zrmjpeg.c
> @@ -817,7 +817,7 @@ static int config(struct vf_instance *vf, int width, int height, int d_width,
> * \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 *vf, mp_image_t *mpi, double pts){
> 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
> diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
> index 29e434962..b70dae468 100644
> --- a/libmpdemux/demuxer.c
> +++ b/libmpdemux/demuxer.c
> @@ -886,14 +886,23 @@ 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)
> {
> + 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;
> }
>
> diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
> index 516e663b5..eeb878bb8 100644
> --- a/libmpdemux/demuxer.h
> +++ b/libmpdemux/demuxer.h
> @@ -405,6 +405,7 @@ static inline int demux_getc(demux_stream_t *ds){
> 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);
> diff --git a/libmpdemux/stheader.h b/libmpdemux/stheader.h
> index 9060caa02..ddf180b05 100644
> --- a/libmpdemux/stheader.h
> +++ b/libmpdemux/stheader.h
> @@ -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)
> diff --git a/mencoder.c b/mencoder.c
> index 0f6774c9e..9fc3ebe25 100644
> --- a/mencoder.c
> +++ b/mencoder.c
> @@ -463,9 +463,9 @@ static int slowseek(float end_pts, demux_stream_t *d_video,
>
> 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);
> diff --git a/mplayer.c b/mplayer.c
> index 3bffb9792..c620eb5ed 100644
> --- a/mplayer.c
> +++ b/mplayer.c
> @@ -1777,6 +1777,7 @@ static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_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_t *sh_video, demux_stream_t *d_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_t *sh_video, demux_stream_t *d_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_frame)
> // 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_frame)
>
> 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;
> --
> 2.11.0
>
> _______________________________________________
> MPlayer-dev-eng mailing list
> MPlayer-dev-eng at mplayerhq.hu
> https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
More information about the MPlayer-dev-eng
mailing list