summaryrefslogtreecommitdiffstats
path: root/libmpcodecs/vf_telecine.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs/vf_telecine.c')
-rw-r--r--libmpcodecs/vf_telecine.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/libmpcodecs/vf_telecine.c b/libmpcodecs/vf_telecine.c
index 9071dfab98..4ae96f2434 100644
--- a/libmpcodecs/vf_telecine.c
+++ b/libmpcodecs/vf_telecine.c
@@ -31,8 +31,31 @@
struct vf_priv_s {
int frame;
+ double pts;
+ double lastpts;
+ mp_image_t *buffered_mpi;
};
+static int continue_buffered_image_fullframe(struct vf_instance *vf)
+{
+ mp_image_t *mpi = vf->priv->buffered_mpi;
+ mp_image_t *dmpi = vf_get_image(vf->next, mpi->imgfmt,
+ MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+ MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
+
+ memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
+ dmpi->stride[0], mpi->stride[0]);
+ if (mpi->flags & MP_IMGFLAG_PLANAR) {
+ memcpy_pic(dmpi->planes[1], mpi->planes[1],
+ mpi->chroma_width, mpi->chroma_height,
+ dmpi->stride[1], mpi->stride[1]);
+ memcpy_pic(dmpi->planes[2], mpi->planes[2],
+ mpi->chroma_width, mpi->chroma_height,
+ dmpi->stride[2], mpi->stride[2]);
+ }
+ return vf_next_put_image(vf, dmpi, vf->priv->pts);
+}
+
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
{
mp_image_t *dmpi;
@@ -40,14 +63,26 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
vf->priv->frame = (vf->priv->frame+1)%4;
- dmpi = vf_get_image(vf->next, mpi->imgfmt,
- MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
- MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
+ if (pts != MP_NOPTS_VALUE) {
+ if (vf->priv->lastpts == MP_NOPTS_VALUE) {
+ vf->priv->pts = pts;
+ vf->priv->lastpts = pts;
+ } else {
+ // we only increase by 80% of input pts at each frame; in the case
+ // in which we render two frames, we jump back
+ // this turns 23.98fps perfectly into 29.97fps
+ vf->priv->pts += 0.8 * (pts - vf->priv->lastpts);
+ vf->priv->lastpts = pts;
+ }
+ }
ret = 0;
// 0/0 1/1 2/2 2/3 3/0
switch (vf->priv->frame) {
case 0:
+ dmpi = vf_get_image(vf->next, mpi->imgfmt,
+ MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+ MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2,
dmpi->stride[0]*2, mpi->stride[0]*2);
@@ -61,21 +96,19 @@ 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, vf->priv->pts);
+ vf->priv->pts = pts;
+ vf->priv->buffered_mpi = mpi;
+ vf_queue_frame(vf, continue_buffered_image_fullframe);
+ return ret;
case 1:
case 2:
- memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
- dmpi->stride[0], mpi->stride[0]);
- if (mpi->flags & MP_IMGFLAG_PLANAR) {
- memcpy_pic(dmpi->planes[1], mpi->planes[1],
- mpi->chroma_width, mpi->chroma_height,
- dmpi->stride[1], mpi->stride[1]);
- memcpy_pic(dmpi->planes[2], mpi->planes[2],
- mpi->chroma_width, mpi->chroma_height,
- dmpi->stride[2], mpi->stride[2]);
- }
- return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) || ret;
+ vf->priv->buffered_mpi = mpi;
+ return continue_buffered_image_fullframe(vf);
case 3:
+ dmpi = vf_get_image(vf->next, mpi->imgfmt,
+ MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+ MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2,
dmpi->stride[0]*2, mpi->stride[0]*2);
@@ -89,7 +122,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, vf->priv->pts);
my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
dmpi->stride[0]*2, mpi->stride[0]*2);
if (mpi->flags & MP_IMGFLAG_PLANAR) {
@@ -142,6 +175,8 @@ static int vf_open(vf_instance_t *vf, char *args)
vf->priv->frame = 1;
if (args) sscanf(args, "%d", &vf->priv->frame);
vf->priv->frame--;
+ vf->priv->pts = MP_NOPTS_VALUE;
+ vf->priv->lastpts = MP_NOPTS_VALUE;
return 1;
}