diff options
Diffstat (limited to 'libmpcodecs')
-rw-r--r-- | libmpcodecs/ad_ffmpeg.c | 2 | ||||
-rw-r--r-- | libmpcodecs/pullup.c | 12 | ||||
-rw-r--r-- | libmpcodecs/pullup.h | 5 | ||||
-rw-r--r-- | libmpcodecs/vd_ffmpeg.c | 10 | ||||
-rw-r--r-- | libmpcodecs/vf.c | 84 | ||||
-rw-r--r-- | libmpcodecs/vf.h | 16 | ||||
-rw-r--r-- | libmpcodecs/vf_bmovl.c | 12 | ||||
-rw-r--r-- | libmpcodecs/vf_detc.c | 13 | ||||
-rw-r--r-- | libmpcodecs/vf_divtc.c | 7 | ||||
-rw-r--r-- | libmpcodecs/vf_filmdint.c | 5 | ||||
-rw-r--r-- | libmpcodecs/vf_geq.c | 4 | ||||
-rw-r--r-- | libmpcodecs/vf_ivtc.c | 15 | ||||
-rw-r--r-- | libmpcodecs/vf_lavc.c | 3 | ||||
-rw-r--r-- | libmpcodecs/vf_phase.c | 2 | ||||
-rw-r--r-- | libmpcodecs/vf_pp.c | 2 | ||||
-rw-r--r-- | libmpcodecs/vf_pp7.c | 4 | ||||
-rw-r--r-- | libmpcodecs/vf_pullup.c | 38 | ||||
-rw-r--r-- | libmpcodecs/vf_softpulldown.c | 31 | ||||
-rw-r--r-- | libmpcodecs/vf_telecine.c | 67 | ||||
-rw-r--r-- | libmpcodecs/vf_tile.c | 5 | ||||
-rw-r--r-- | libmpcodecs/vf_tinterlace.c | 10 | ||||
-rw-r--r-- | libmpcodecs/vf_yadif.c | 2 |
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 |