# HG changeset patch # User rfelker # Date 1083124966 0 # Node ID eeddcef4fb08bf3d4d9d7c6df0580e393063c115 # Parent 80036bf4a9f5d6ec768206f1f11a5b8a900f481e "hard" frame duplication for mencoder. this finally makes it possible to generate valid mpeg output from avi's that have duplicate frames in them, or when using inverse telecine filters. to use it, put the "harddup" filter at the end of your filter chain. diff -r 80036bf4a9f5 -r eeddcef4fb08 libmpcodecs/Makefile --- a/libmpcodecs/Makefile Wed Apr 28 03:19:35 2004 +0000 +++ b/libmpcodecs/Makefile Wed Apr 28 04:02:46 2004 +0000 @@ -14,7 +14,7 @@ VIDEO_SRCS_OPT=vd_realvid.c vd_ffmpeg.c vd_dshow.c vd_dmo.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_zrmjpeg.c vd_xanim.c vd_xvid.c vd_xvid4.c vd_libdv.c vd_qtvideo.c vd_theora.c VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT) -VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_scale.c vf_format.c vf_noformat.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c vf_framestep.c vf_tile.c vf_delogo.c vf_fil.c vf_hue.c vf_spp.c vf_yuvcsp.c vf_filmdint.c vf_kerndeint.c vf_rgbtest.c vf_qp.c vf_phase.c vf_divtc.c +VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_scale.c vf_format.c vf_noformat.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c vf_framestep.c vf_tile.c vf_delogo.c vf_fil.c vf_hue.c vf_spp.c vf_yuvcsp.c vf_filmdint.c vf_kerndeint.c vf_rgbtest.c vf_qp.c vf_phase.c vf_divtc.c vf_harddup.c ifeq ($(HAVE_FFPOSTPROCESS),yes) VFILTER_SRCS += vf_pp.c endif diff -r 80036bf4a9f5 -r eeddcef4fb08 libmpcodecs/vf.c --- a/libmpcodecs/vf.c Wed Apr 28 03:19:35 2004 +0000 +++ b/libmpcodecs/vf.c Wed Apr 28 04:02:46 2004 +0000 @@ -89,6 +89,7 @@ extern vf_info_t vf_info_qp; extern vf_info_t vf_info_phase; extern vf_info_t vf_info_divtc; +extern vf_info_t vf_info_harddup; // list of available filters: static vf_info_t* filter_list[]={ @@ -171,6 +172,7 @@ #endif &vf_info_phase, &vf_info_divtc, + &vf_info_harddup, NULL }; diff -r 80036bf4a9f5 -r eeddcef4fb08 libmpcodecs/vf_harddup.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpcodecs/vf_harddup.c Wed Apr 28 04:02:46 2004 +0000 @@ -0,0 +1,92 @@ +#include +#include +#include + +#include "../config.h" +#include "../mp_msg.h" + +#include "img_format.h" +#include "mp_image.h" +#include "vf.h" + +#include "../libvo/fastmemcpy.h" + +struct vf_priv_s { + mp_image_t *last_mpi; +}; + +static int put_image(struct vf_instance_s* vf, mp_image_t *mpi) +{ + mp_image_t *dmpi; + int ret; + + vf->priv->last_mpi = mpi; + + dmpi = vf_get_image(vf->next, mpi->imgfmt, + MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height); + + dmpi->planes[0] = mpi->planes[0]; + dmpi->stride[0] = mpi->stride[0]; + if (dmpi->flags&MP_IMGFLAG_PLANAR) { + dmpi->planes[1] = mpi->planes[1]; + dmpi->stride[1] = mpi->stride[1]; + dmpi->planes[2] = mpi->planes[2]; + dmpi->stride[2] = mpi->stride[2]; + } + + return vf_next_put_image(vf, dmpi); +} + +static int control(struct vf_instance_s* vf, int request, void* data) +{ + switch (request) { + case VFCTRL_DUPLICATE_FRAME: + if (!vf->priv->last_mpi) break; + // This is a huge hack. We assume nothing + // has been called earlier in the filter chain + // since the last put_image. This is reasonable + // because we're handling a duplicate frame! + puts("hard dup!"); + if (put_image(vf, vf->priv->last_mpi)) + return CONTROL_TRUE; + break; + } + return vf_next_control(vf, request, data); +} + +static int query_format(struct vf_instance_s* vf, unsigned int fmt) +{ + /* FIXME - figure out which other formats work */ + switch (fmt) { + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + return vf_next_query_format(vf, fmt); + } + return 0; +} + +static void uninit(struct vf_instance_s* vf) +{ + free(vf->priv); +} + +static int open(vf_instance_t *vf, char* args) +{ + vf->put_image = put_image; + vf->control = control; + vf->uninit = uninit; + vf->priv = calloc(1, sizeof(struct vf_priv_s)); + return 1; +} + +vf_info_t vf_info_harddup = { + "resubmit duplicate frames for encoding", + "harddup", + "Rich Felker", + "", + open, + NULL +}; + + diff -r 80036bf4a9f5 -r eeddcef4fb08 mencoder.c --- a/mencoder.c Wed Apr 28 03:19:35 2004 +0000 +++ b/mencoder.c Wed Apr 28 04:02:46 2004 +0000 @@ -189,6 +189,7 @@ #endif int auto_expand=1; +int encode_duplicates=1; // infos are empty by default char *info_name=NULL; @@ -1312,7 +1313,8 @@ if(file_format != DEMUXER_TYPE_TV && !verbose) printf(MSGTR_DuplicateFrames,-skip_flag); while(skip_flag<0){ duplicatedframes++; - muxer_write_chunk(mux_v,0,0); + if (!encode_duplicates || vf_next_control(sh_video->vfilter, VFCTRL_DUPLICATE_FRAME, 0) != CONTROL_TRUE) + muxer_write_chunk(mux_v,0,0); ++skip_flag; } } else