summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/ad_ffmpeg.c2
-rw-r--r--libmpcodecs/pullup.c12
-rw-r--r--libmpcodecs/pullup.h5
-rw-r--r--libmpcodecs/vd_ffmpeg.c10
-rw-r--r--libmpcodecs/vf.c84
-rw-r--r--libmpcodecs/vf.h16
-rw-r--r--libmpcodecs/vf_bmovl.c12
-rw-r--r--libmpcodecs/vf_detc.c13
-rw-r--r--libmpcodecs/vf_divtc.c7
-rw-r--r--libmpcodecs/vf_filmdint.c5
-rw-r--r--libmpcodecs/vf_geq.c4
-rw-r--r--libmpcodecs/vf_ivtc.c15
-rw-r--r--libmpcodecs/vf_lavc.c3
-rw-r--r--libmpcodecs/vf_phase.c2
-rw-r--r--libmpcodecs/vf_pp.c2
-rw-r--r--libmpcodecs/vf_pp7.c4
-rw-r--r--libmpcodecs/vf_pullup.c38
-rw-r--r--libmpcodecs/vf_softpulldown.c31
-rw-r--r--libmpcodecs/vf_telecine.c67
-rw-r--r--libmpcodecs/vf_tile.c5
-rw-r--r--libmpcodecs/vf_tinterlace.c10
-rw-r--r--libmpcodecs/vf_yadif.c2
22 files changed, 280 insertions, 69 deletions
diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c
index ec6a2f77ac..8f56e71b5d 100644
--- a/libmpcodecs/ad_ffmpeg.c
+++ b/libmpcodecs/ad_ffmpeg.c
@@ -127,7 +127,7 @@ static int init(sh_audio_t *sh_audio)
}
lavc_context->request_channels = opts->audio_output_channels;
lavc_context->codec_tag = sh_audio->format; //FOURCC
- lavc_context->codec_type = CODEC_TYPE_AUDIO;
+ lavc_context->codec_type = AVMEDIA_TYPE_AUDIO;
lavc_context->codec_id = lavc_codec->id; // not sure if required, imho not --A'rpi
/* alloc extra data */
diff --git a/libmpcodecs/pullup.c b/libmpcodecs/pullup.c
index 2675be6146..b70aa9b56f 100644
--- a/libmpcodecs/pullup.c
+++ b/libmpcodecs/pullup.c
@@ -22,6 +22,7 @@
#include "config.h"
#include "pullup.h"
#include "cpudetect.h"
+#include "mpcommon.h"
@@ -412,7 +413,8 @@ static void check_field_queue(struct pullup_context *c)
}
}
-void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity)
+void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b,
+ int parity, double pts)
{
struct pullup_field *f;
@@ -428,6 +430,7 @@ void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int
f->flags = 0;
f->breaks = 0;
f->affinity = 0;
+ f->pts = pts;
compute_metric(c, f, parity, f->prev->prev, parity, c->diff, f->diffs);
compute_metric(c, parity?f->prev:f, 0, parity?f:f->prev, 1, c->comb, f->comb);
@@ -663,12 +666,19 @@ struct pullup_frame *pullup_get_frame(struct pullup_context *c)
fr->length = n;
fr->parity = c->first->parity;
fr->buffer = 0;
+ fr->pts = 0;
for (i = 0; i < n; i++) {
/* We cheat and steal the buffer without release+relock */
fr->ifields[i] = c->first->buffer;
c->first->buffer = 0;
+ if (c->first->pts == MP_NOPTS_VALUE || fr->pts == MP_NOPTS_VALUE)
+ fr->pts = MP_NOPTS_VALUE;
+ else
+ fr->pts += c->first->pts;
c->first = c->first->next;
}
+ if (fr->pts != MP_NOPTS_VALUE)
+ fr->pts /= n;
if (n == 1) {
fr->ofields[fr->parity] = fr->ifields[0];
diff --git a/libmpcodecs/pullup.h b/libmpcodecs/pullup.h
index eb7b143da6..0db8f6f894 100644
--- a/libmpcodecs/pullup.h
+++ b/libmpcodecs/pullup.h
@@ -40,6 +40,7 @@ struct pullup_buffer
struct pullup_field
{
int parity;
+ double pts;
struct pullup_buffer *buffer;
unsigned int flags;
int breaks;
@@ -55,6 +56,7 @@ struct pullup_frame
int lock;
int length;
int parity;
+ double pts;
struct pullup_buffer **ifields, *ofields[2];
struct pullup_buffer *buffer;
};
@@ -87,7 +89,8 @@ struct pullup_buffer *pullup_lock_buffer(struct pullup_buffer *b, int parity);
void pullup_release_buffer(struct pullup_buffer *b, int parity);
struct pullup_buffer *pullup_get_buffer(struct pullup_context *c, int parity);
-void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity);
+void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b,
+ int parity, double pts);
void pullup_flush_fields(struct pullup_context *c);
struct pullup_frame *pullup_get_frame(struct pullup_context *c);
diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c
index a4683e4080..598be093c1 100644
--- a/libmpcodecs/vd_ffmpeg.c
+++ b/libmpcodecs/vd_ffmpeg.c
@@ -208,7 +208,7 @@ static int init(sh_video_t *sh){
ctx->avctx = avcodec_alloc_context();
avctx = ctx->avctx;
avctx->opaque = sh;
- avctx->codec_type = CODEC_TYPE_VIDEO;
+ avctx->codec_type = AVMEDIA_TYPE_VIDEO;
avctx->codec_id = lavc_codec->id;
if (lavc_codec->capabilities & CODEC_CAP_HWACCEL // XvMC
@@ -544,14 +544,12 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
type = MP_IMGTYPE_STATIC;
flags |= MP_IMGFLAG_PRESERVE;
}
- flags|=(!avctx->hurry_up && ctx->do_slices) ?
- MP_IMGFLAG_DRAW_CALLBACK:0;
+ flags |= ctx->do_slices ? MP_IMGFLAG_DRAW_CALLBACK : 0;
mp_msg(MSGT_DECVIDEO, MSGL_DBG2, type == MP_IMGTYPE_STATIC ? "using STATIC\n" : "using TEMP\n");
} else {
if(!pic->reference){
ctx->b_count++;
- flags|=(!avctx->hurry_up && ctx->do_slices) ?
- MP_IMGFLAG_DRAW_CALLBACK:0;
+ flags |= ctx->do_slices ? MP_IMGFLAG_DRAW_CALLBACK:0;
}else{
ctx->ip_count++;
flags|= MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE
@@ -796,7 +794,7 @@ static struct mp_image *decode(struct sh_video *sh, void *data, int len,
pkt.data = data;
pkt.size = len;
// HACK: make PNGs decode normally instead of as CorePNG delta frames
- pkt.flags = PKT_FLAG_KEY;
+ pkt.flags = AV_PKT_FLAG_KEY;
// The avcodec opaque field stupidly supports only int64_t type
*(double *)&avctx->reordered_opaque = *reordered_pts;
ret = avcodec_decode_video2(avctx, pic, &got_picture, &pkt);
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index 6355076726..eefdaa3c46 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -751,3 +751,87 @@ void vf_uninit_filter_chain(vf_instance_t* vf){
vf=next;
}
}
+
+void vf_detc_init_pts_buf(struct vf_detc_pts_buf *p)
+{
+ p->inpts_prev = MP_NOPTS_VALUE;
+ p->outpts_prev = MP_NOPTS_VALUE;
+ p->lastdelta = 0;
+}
+
+static double vf_detc_adjust_pts_internal(struct vf_detc_pts_buf *p,
+ double pts, bool reset_pattern,
+ bool skip_frame, double delta,
+ double boundfactor_minus,
+ double increasefactor,
+ double boundfactor_plus)
+{
+ double newpts;
+
+ if (pts == MP_NOPTS_VALUE)
+ return pts;
+
+ if (delta <= 0) {
+ if (p->inpts_prev == MP_NOPTS_VALUE)
+ delta = 0;
+ else if(pts == p->inpts_prev)
+ delta = p->lastdelta;
+ else
+ delta = pts - p->inpts_prev;
+ }
+ //mp_msg(MSGT_VFILTER, MSGL_INFO, "filmdint: (1) inpts %f (delta: %f, increase: %f)\n", pts, delta, delta * increasefactor);
+ p->inpts_prev = pts;
+ p->lastdelta = delta;
+
+ if (skip_frame)
+ return MP_NOPTS_VALUE;
+
+ // detect bogus deltas and then passthru pts (possibly caused by seeking, or bad input)
+ if (p->outpts_prev == MP_NOPTS_VALUE || reset_pattern || delta <= 0.0 || delta >= 0.5) {
+ newpts = pts;
+ } else {
+ // turn 5 frames into 4
+ newpts = p->outpts_prev + delta * increasefactor;
+
+ // bound to input pts in a sensible way; these numbers come because we
+ // map frames the following way when ivtc'ing:
+ // 0/30 -> 0/24 diff=0
+ // 1/30 -> 1/24 diff=1/120
+ // 2/30 -> -
+ // 3/30 -> 2/24 diff=-1/60
+ // 4/30 -> 3/24 diff=-1/120
+ if (newpts < pts - delta * boundfactor_minus)
+ newpts = pts - delta * boundfactor_minus;
+ if (newpts > pts + delta * boundfactor_plus)
+ newpts = pts + delta * boundfactor_plus;
+ if (newpts < p->outpts_prev)
+ newpts = p->outpts_prev; // damage control
+ }
+ //mp_msg(MSGT_VFILTER, MSGL_INFO, "filmdint: (2) outpts %f (delta: %f)\n", newpts, newpts - p->outpts_prev);
+ p->outpts_prev = newpts;
+
+ return newpts;
+}
+
+double vf_detc_adjust_pts(struct vf_detc_pts_buf *p, double pts,
+ bool reset_pattern, bool skip_frame)
+{
+ // standard telecine (see above)
+ return vf_detc_adjust_pts_internal(p, pts, reset_pattern, skip_frame,
+ 0, 0.5, 1.25, 0.25);
+}
+
+double vf_softpulldown_adjust_pts(struct vf_detc_pts_buf *p, double pts,
+ bool reset_pattern, bool skip_frame,
+ int last_frame_duration)
+{
+ // for the softpulldown filter we get:
+ // 0/60 -> 0/30
+ // 2/60 -> 1/30
+ // 5/60 -> 2/30
+ // 7/60 -> 3/30, 4/30
+ return vf_detc_adjust_pts_internal(p, pts, reset_pattern, skip_frame,
+ 0, 1.0 / last_frame_duration,
+ 2.0 / last_frame_duration,
+ 1.0 / last_frame_duration);
+}
diff --git a/libmpcodecs/vf.h b/libmpcodecs/vf.h
index 58cfaaf787..ec1a9c23ff 100644
--- a/libmpcodecs/vf.h
+++ b/libmpcodecs/vf.h
@@ -21,6 +21,7 @@
#include "mp_image.h"
#include "mpcommon.h"
+#include "stdbool.h"
struct MPOpts;
struct vf_instance;
@@ -169,4 +170,19 @@ static inline int norm_qscale(int qscale, int type)
return qscale;
}
+struct vf_detc_pts_buf {
+ double inpts_prev, outpts_prev;
+ double lastdelta;
+};
+void vf_detc_init_pts_buf(struct vf_detc_pts_buf *p);
+/* Adjust pts when detelecining.
+ * skip_frame: do not render this frame
+ * reset_pattern: set to 1 if the telecine pattern has reset due to scene cut
+ */
+double vf_detc_adjust_pts(struct vf_detc_pts_buf *p, double pts,
+ bool reset_pattern, bool skip_frame);
+double vf_softpulldown_adjust_pts(struct vf_detc_pts_buf *p, double pts,
+ bool reset_pattern, bool skip_frame,
+ int last_frame_duration);
+
#endif /* MPLAYER_VF_H */
diff --git a/libmpcodecs/vf_bmovl.c b/libmpcodecs/vf_bmovl.c
index 3b46e1ebcc..b6b9940832 100644
--- a/libmpcodecs/vf_bmovl.c
+++ b/libmpcodecs/vf_bmovl.c
@@ -261,10 +261,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, pts);
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, pts);
}
if(command == CMD_ALPHA) {
@@ -283,7 +283,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, pts);
}
/* pipes/sockets might need multiple calls to read(): */
want = (imgw*imgh*pxsz);
@@ -344,7 +344,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, pts);
}
for( buf_y=0 ; (buf_y < imgh) && (buf_y < (vf->priv->h-imgy)) ; buf_y++ ) {
@@ -402,7 +402,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, pts);
if(vf->priv->opaque) { // Just copy buffer memory to screen
for( ypos=vf->priv->y1 ; ypos < vf->priv->y2 ; ypos++ ) {
@@ -454,7 +454,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, pts);
} // put_image
static int
diff --git a/libmpcodecs/vf_detc.c b/libmpcodecs/vf_detc.c
index cf294ac7f7..bbc22fca6c 100644
--- a/libmpcodecs/vf_detc.c
+++ b/libmpcodecs/vf_detc.c
@@ -45,6 +45,7 @@ struct vf_priv_s {
int mode;
int (*analyze)(struct vf_priv_s *, mp_image_t *, mp_image_t *);
int needread;
+ struct vf_detc_pts_buf ptsbuf;
};
#define COMPE(a,b,e) (abs((a)-(b)) < (((a)+(b))>>(e)))
@@ -285,7 +286,7 @@ static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field)
}
}
-static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
+static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi, double pts)
{
struct vf_priv_s *p = vf->priv;
int dropflag;
@@ -306,11 +307,12 @@ static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n",
p->outframes, p->inframes, (float)p->outframes/p->inframes);
p->lastdrop = 0;
+ vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1);
return 0;
}
p->outframes++;
- return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+ return vf_next_put_image(vf, dmpi, vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 0));
}
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
@@ -335,22 +337,24 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
/* Don't copy anything unless we'll need to read it. */
if (p->needread) copy_image(dmpi, mpi, 2);
p->lastdrop = 0;
+ vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1);
break;
case TC_PROG:
/* Copy and display the whole frame. */
copy_image(dmpi, mpi, 2);
- ret = do_put_image(vf, dmpi);
+ ret = do_put_image(vf, dmpi, pts);
break;
case TC_IL1:
/* Only copy bottom field unless we need to read. */
if (p->needread) copy_image(dmpi, mpi, 2);
else copy_image(dmpi, mpi, 1);
p->lastdrop = 0;
+ vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1);
break;
case TC_IL2:
/* Copy top field and show frame, then copy bottom if needed. */
copy_image(dmpi, mpi, 0);
- ret = do_put_image(vf, dmpi);
+ ret = do_put_image(vf, dmpi, pts);
if (p->needread) copy_image(dmpi, mpi, 1);
break;
}
@@ -440,6 +444,7 @@ static int vf_open(vf_instance_t *vf, char *args)
if (args) parse_args(p, args);
p->analyze = anal_funcs[p->mode].func;
p->needread = anal_funcs[p->mode].needread;
+ vf_detc_init_pts_buf(&p->ptsbuf);
return 1;
}
diff --git a/libmpcodecs/vf_divtc.c b/libmpcodecs/vf_divtc.c
index d632a4c60d..b3d84d200f 100644
--- a/libmpcodecs/vf_divtc.c
+++ b/libmpcodecs/vf_divtc.c
@@ -45,6 +45,7 @@ struct vf_priv_s
char *bdata;
unsigned int *csdata;
int *history;
+ struct vf_detc_pts_buf ptsbuf;
};
/*
@@ -358,6 +359,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
{
case 0:
imgop(copyop, dmpi, mpi, 0);
+ vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1);
return 0;
case 4:
@@ -372,12 +374,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, vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 0));
}
}
imgop(copyop, dmpi, mpi, 0);
- return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+ return vf_next_put_image(vf, dmpi, vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 0));
}
static int analyze(struct vf_priv_s *p)
@@ -706,6 +708,7 @@ static int vf_open(vf_instance_t *vf, char *args)
#endif
free(args);
+ vf_detc_init_pts_buf(&p->ptsbuf);
return 1;
}
diff --git a/libmpcodecs/vf_filmdint.c b/libmpcodecs/vf_filmdint.c
index c8da011d81..b40a66831a 100644
--- a/libmpcodecs/vf_filmdint.c
+++ b/libmpcodecs/vf_filmdint.c
@@ -91,6 +91,7 @@ struct vf_priv_s {
struct metrics thres;
char chflag;
double diff_time, merge_time, decode_time, vo_time, filter_time;
+ struct vf_detc_pts_buf ptsbuf;
};
#define PPZ { 2000, 2000, 0, 2000 }
@@ -1331,7 +1332,8 @@ 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;
+ pts = vf_detc_adjust_pts(&p->ptsbuf, pts, 0, !show_fields);
+ return show_fields ? vf_next_put_image(vf, dmpi, pts) : 0;
}
static int query_format(struct vf_instance *vf, unsigned int fmt)
@@ -1357,6 +1359,7 @@ static int config(struct vf_instance *vf,
unsigned long cxm = 0;
unsigned long cym = 0;
struct vf_priv_s *p = vf->priv;
+ vf_detc_init_pts_buf(&p->ptsbuf);
// rounding:
if(!IMGFMT_IS_RGB(outfmt) && !IMGFMT_IS_BGR(outfmt)){
switch(outfmt){
diff --git a/libmpcodecs/vf_geq.c b/libmpcodecs/vf_geq.c
index ed855d1b7d..68a9cf780c 100644
--- a/libmpcodecs/vf_geq.c
+++ b/libmpcodecs/vf_geq.c
@@ -116,7 +116,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
const_values[3]=y;
for(x=0; x<w; x++){
const_values[2]=x;
- dst[x + y * dst_stride] = av_eval_expr(vf->priv->e[plane],
+ dst[x + y * dst_stride] = av_expr_eval(vf->priv->e[plane],
const_values, vf);
}
}
@@ -176,7 +176,7 @@ static int vf_open(vf_instance_t *vf, char *args){
plane==0 ? lum : (plane==1 ? cb : cr),
NULL
};
- res = av_parse_expr(&vf->priv->e[plane], eq[plane], const_names, NULL, NULL, func2_names, func2, 0, NULL);
+ res = av_expr_parse(&vf->priv->e[plane], eq[plane], const_names, NULL, NULL, func2_names, func2, 0, NULL);
if (res < 0) {
mp_msg(MSGT_VFILTER, MSGL_ERR, "geq: error loading equation `%s'\n", eq[plane]);
diff --git a/libmpcodecs/vf_ivtc.c b/libmpcodecs/vf_ivtc.c
index 5622ee03b8..966292ff14 100644
--- a/libmpcodecs/vf_ivtc.c
+++ b/libmpcodecs/vf_ivtc.c
@@ -49,6 +49,7 @@ struct vf_priv_s {
int first;
int drop, lastdrop, dropnext;
int inframes, outframes;
+ struct vf_detc_pts_buf ptsbuf;
};
enum {
@@ -426,7 +427,7 @@ static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field)
}
}
-static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
+static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi, double pts)
{
struct vf_priv_s *p = vf->priv;
int dropflag=0;
@@ -448,11 +449,12 @@ static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
// p->outframes, p->inframes, (float)p->outframes/p->inframes);
mp_msg(MSGT_VFILTER, MSGL_V, "!");
p->lastdrop = 0;
+ vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1);
return 0;
}
p->outframes++;
- return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+ return vf_next_put_image(vf, dmpi, vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 0));
}
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
@@ -464,6 +466,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
if (p->first) { /* hack */
p->first = 0;
+ vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1);
return 1;
}
@@ -482,22 +485,23 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
ret = 0;
p->lastdrop = 0;
mp_msg(MSGT_VFILTER, MSGL_V, "DROP\n");
+ vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1);
break;
case F_MERGE:
copy_image(p->dmpi, mpi, 0);
- ret = do_put_image(vf, p->dmpi);
+ ret = do_put_image(vf, p->dmpi, pts);
copy_image(p->dmpi, mpi, 1);
mp_msg(MSGT_VFILTER, MSGL_V, "MERGE\n");
p->dmpi = NULL;
break;
case F_NEXT:
copy_image(p->dmpi, mpi, 2);
- ret = do_put_image(vf, p->dmpi);
+ ret = do_put_image(vf, p->dmpi, pts);
mp_msg(MSGT_VFILTER, MSGL_V, "NEXT\n");
p->dmpi = NULL;
break;
case F_SHOW:
- ret = do_put_image(vf, p->dmpi);
+ ret = do_put_image(vf, p->dmpi, pts);
copy_image(p->dmpi, mpi, 2);
mp_msg(MSGT_VFILTER, MSGL_V, "OK\n");
p->dmpi = NULL;
@@ -537,6 +541,7 @@ static int vf_open(vf_instance_t *vf, char *args)
#if HAVE_MMX && HAVE_EBX_AVAILABLE
if(gCpuCaps.hasMMX) block_diffs = block_diffs_MMX;
#endif
+ vf_detc_init_pts_buf(&p->ptsbuf);
return 1;
}
diff --git a/libmpcodecs/vf_lavc.c b/libmpcodecs/vf_lavc.c
index 63de4ffdf5..c31044ba21 100644
--- a/libmpcodecs/vf_lavc.c
+++ b/libmpcodecs/vf_lavc.c
@@ -30,7 +30,6 @@
#include "vd_ffmpeg.h"
#include "libavcodec/avcodec.h"
-
struct vf_priv_s {
unsigned char* outbuf;
int outbuf_size;
@@ -114,7 +113,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, MP_NOPTS_VALUE);
+ return vf_next_put_image(vf,dmpi, pts);
}
//===========================================================================//
diff --git a/libmpcodecs/vf_phase.c b/libmpcodecs/vf_phase.c
index 5b0eaaa17d..b9ea66c506 100644
--- a/libmpcodecs/vf_phase.c
+++ b/libmpcodecs/vf_phase.c
@@ -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, pts);
}
static void uninit(struct vf_instance *vf)
diff --git a/libmpcodecs/vf_pp.c b/libmpcodecs/vf_pp.c
index f3dc4d9537..10c4edf707 100644
--- a/libmpcodecs/vf_pp.c
+++ b/libmpcodecs/vf_pp.c
@@ -37,7 +37,7 @@
struct vf_priv_s {
int pp;
- pp_mode_t *ppMode[PP_QUALITY_MAX+1];
+ pp_mode *ppMode[PP_QUALITY_MAX+1];
void *context;
unsigned int outfmt;
};
diff --git a/libmpcodecs/vf_pp7.c b/libmpcodecs/vf_pp7.c
index 58f3e3ef06..1c0274d24f 100644
--- a/libmpcodecs/vf_pp7.c
+++ b/libmpcodecs/vf_pp7.c
@@ -288,8 +288,8 @@ static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stri
int x, y;
const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15));
uint8_t *p_src= p->src + 8*stride;
- DCTELEM *block= p->src;
- DCTELEM *temp= p->src + 32;
+ DCTELEM *block= (DCTELEM *)p->src;
+ DCTELEM *temp= (DCTELEM *)(p->src + 32);
if (!src || !dst) return; // HACK avoid crash for Y8 colourspace
for(y=0; y<height; y++){
diff --git a/libmpcodecs/vf_pullup.c b/libmpcodecs/vf_pullup.c
index 2dafe20b31..356774b060 100644
--- a/libmpcodecs/vf_pullup.c
+++ b/libmpcodecs/vf_pullup.c
@@ -40,6 +40,7 @@ struct vf_priv_s {
int init;
int fakecount;
char *qbuf;
+ double lastpts;
};
static void init_pullup(struct vf_instance *vf, mp_image_t *mpi)
@@ -145,10 +146,35 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
p = mpi->fields & MP_IMGFIELD_TOP_FIRST ? 0 :
(mpi->fields & MP_IMGFIELD_ORDERED ? 1 : 0);
- pullup_submit_field(c, b, p);
- pullup_submit_field(c, b, p^1);
- if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST)
- pullup_submit_field(c, b, p);
+
+ if (pts == MP_NOPTS_VALUE) {
+ pullup_submit_field(c, b, p, MP_NOPTS_VALUE);
+ pullup_submit_field(c, b, p^1, MP_NOPTS_VALUE);
+ if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST)
+ pullup_submit_field(c, b, p, MP_NOPTS_VALUE);
+ } else {
+ double delta;
+ if (vf->priv->lastpts == MP_NOPTS_VALUE)
+ delta = 1001.0/60000.0; // delta = field time distance
+ else
+ delta = (pts - vf->priv->lastpts) / 2;
+ if (delta <= 0.0 || delta >= 0.5) {
+ pullup_submit_field(c, b, p, pts);
+ pullup_submit_field(c, b, p^1, pts);
+ if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST)
+ pullup_submit_field(c, b, p, pts);
+ } else {
+ vf->priv->lastpts = pts;
+ if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST) {
+ pullup_submit_field(c, b, p, pts - delta);
+ pullup_submit_field(c, b, p^1, pts);
+ pullup_submit_field(c, b, p, pts + delta);
+ } else {
+ pullup_submit_field(c, b, p, pts - delta * 0.5);
+ pullup_submit_field(c, b, p^1, pts + delta * 0.5);
+ }
+ }
+ }
pullup_release_buffer(b, 2);
@@ -230,7 +256,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, f->pts);
}
dmpi = vf_get_image(vf->next, mpi->imgfmt,
MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
@@ -249,7 +275,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, f->pts);
pullup_release_frame(f);
return ret;
}
diff --git a/libmpcodecs/vf_softpulldown.c b/libmpcodecs/vf_softpulldown.c
index ab45c698ce..5bd5e66bfd 100644
--- a/libmpcodecs/vf_softpulldown.c
+++ b/libmpcodecs/vf_softpulldown.c
@@ -33,8 +33,22 @@ struct vf_priv_s {
int state;
long long in;
long long out;
+ struct vf_detc_pts_buf ptsbuf;
+ int last_frame_duration;
+ double buffered_pts;
+ mp_image_t *buffered_mpi;
+ int buffered_last_frame_duration;
};
+static int continue_buffered_image(struct vf_instance *vf)
+{
+ double pts = vf->priv->buffered_pts;
+ mp_image_t *mpi = vf->priv->buffered_mpi;
+ vf->priv->out++;
+ vf->priv->state=0;
+ return vf_next_put_image(vf, mpi, vf_softpulldown_adjust_pts(&vf->priv->ptsbuf, pts, 0, 0, vf->priv->buffered_last_frame_duration));
+}
+
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
{
mp_image_t *dmpi;
@@ -61,7 +75,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, vf_softpulldown_adjust_pts(&vf->priv->ptsbuf, pts, 0, 0, vf->priv->last_frame_duration));
vf->priv->out++;
if (flags & MP_IMGFIELD_REPEAT_FIRST) {
my_memcpy_pic(dmpi->planes[0],
@@ -97,12 +111,13 @@ 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_softpulldown_adjust_pts(&vf->priv->ptsbuf, pts, 0, 0, vf->priv->last_frame_duration));
vf->priv->out++;
if (flags & MP_IMGFIELD_REPEAT_FIRST) {
- ret |= vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
- vf->priv->out++;
- state=0;
+ vf->priv->buffered_mpi = mpi;
+ vf->priv->buffered_pts = pts;
+ vf->priv->buffered_last_frame_duration = vf->priv->last_frame_duration;
+ vf_queue_frame(vf, continue_buffered_image);
} else {
my_memcpy_pic(dmpi->planes[0],
mpi->planes[0], mpi->w, mpi->h/2,
@@ -125,6 +140,10 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
}
vf->priv->state = state;
+ if (flags & MP_IMGFIELD_REPEAT_FIRST)
+ vf->priv->last_frame_duration = 3;
+ else
+ vf->priv->last_frame_duration = 2;
return ret;
}
@@ -151,6 +170,8 @@ static int vf_open(vf_instance_t *vf, char *args)
vf->default_reqs = VFCAP_ACCEPT_STRIDE;
vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
vf->priv->state = 0;
+ vf->priv->last_frame_duration = 2;
+ vf_detc_init_pts_buf(&vf->priv->ptsbuf);
return 1;
}
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-&