00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022
00023 #include "config.h"
00024 #include "mp_msg.h"
00025
00026 #include "img_format.h"
00027 #include "mp_image.h"
00028 #include "vf.h"
00029
00030 #include "libvo/fastmemcpy.h"
00031
00032 struct vf_priv_s {
00033 int frame;
00034 };
00035
00036 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
00037 {
00038 mp_image_t *dmpi;
00039 int ret;
00040 int w = (IMGFMT_IS_YUVP16(mpi->imgfmt) ? 2 : 1) * mpi->w;
00041 int chroma_width = (IMGFMT_IS_YUVP16(mpi->imgfmt) ? 2 : 1) * mpi->chroma_width;
00042
00043 vf->priv->frame = (vf->priv->frame+1)%4;
00044
00045 dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
00046 MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
00047 MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
00048
00049 ret = 0;
00050
00051 switch (vf->priv->frame) {
00052 case 0:
00053 my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
00054 mpi->planes[0]+mpi->stride[0], w, mpi->h/2,
00055 dmpi->stride[0]*2, mpi->stride[0]*2);
00056 if (mpi->flags & MP_IMGFLAG_PLANAR) {
00057 my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
00058 mpi->planes[1]+mpi->stride[1],
00059 chroma_width, mpi->chroma_height/2,
00060 dmpi->stride[1]*2, mpi->stride[1]*2);
00061 my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
00062 mpi->planes[2]+mpi->stride[2],
00063 chroma_width, mpi->chroma_height/2,
00064 dmpi->stride[2]*2, mpi->stride[2]*2);
00065 }
00066 ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
00067
00068 case 1:
00069 case 2:
00070 memcpy_pic(dmpi->planes[0], mpi->planes[0], w, mpi->h,
00071 dmpi->stride[0], mpi->stride[0]);
00072 if (mpi->flags & MP_IMGFLAG_PLANAR) {
00073 memcpy_pic(dmpi->planes[1], mpi->planes[1],
00074 chroma_width, mpi->chroma_height,
00075 dmpi->stride[1], mpi->stride[1]);
00076 memcpy_pic(dmpi->planes[2], mpi->planes[2],
00077 chroma_width, mpi->chroma_height,
00078 dmpi->stride[2], mpi->stride[2]);
00079 }
00080 return ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) || ret;
00081 case 3:
00082 my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
00083 mpi->planes[0]+mpi->stride[0], w, mpi->h/2,
00084 dmpi->stride[0]*2, mpi->stride[0]*2);
00085 if (mpi->flags & MP_IMGFLAG_PLANAR) {
00086 my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
00087 mpi->planes[1]+mpi->stride[1],
00088 chroma_width, mpi->chroma_height/2,
00089 dmpi->stride[1]*2, mpi->stride[1]*2);
00090 my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
00091 mpi->planes[2]+mpi->stride[2],
00092 chroma_width, mpi->chroma_height/2,
00093 dmpi->stride[2]*2, mpi->stride[2]*2);
00094 }
00095 ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
00096 my_memcpy_pic(dmpi->planes[0], mpi->planes[0], w, mpi->h/2,
00097 dmpi->stride[0]*2, mpi->stride[0]*2);
00098 if (mpi->flags & MP_IMGFLAG_PLANAR) {
00099 my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
00100 chroma_width, mpi->chroma_height/2,
00101 dmpi->stride[1]*2, mpi->stride[1]*2);
00102 my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
00103 chroma_width, mpi->chroma_height/2,
00104 dmpi->stride[2]*2, mpi->stride[2]*2);
00105 }
00106 return ret;
00107 }
00108 return 0;
00109 }
00110
00111 #if 0
00112 static int query_format(struct vf_instance *vf, unsigned int fmt)
00113 {
00114
00115 switch (fmt) {
00116 case IMGFMT_YV12:
00117 case IMGFMT_IYUV:
00118 case IMGFMT_I420:
00119 return ff_vf_next_query_format(vf, fmt);
00120 }
00121 return 0;
00122 }
00123
00124 static int config(struct vf_instance *vf,
00125 int width, int height, int d_width, int d_height,
00126 unsigned int flags, unsigned int outfmt)
00127 {
00128 return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00129 }
00130 #endif
00131
00132 static void uninit(struct vf_instance *vf)
00133 {
00134 free(vf->priv);
00135 }
00136
00137 static int vf_open(vf_instance_t *vf, char *args)
00138 {
00139
00140 vf->put_image = put_image;
00141
00142 vf->uninit = uninit;
00143 vf->default_reqs = VFCAP_ACCEPT_STRIDE;
00144 vf->priv = calloc(1, sizeof(struct vf_priv_s));
00145 vf->priv->frame = 1;
00146 if (args) sscanf(args, "%d", &vf->priv->frame);
00147 vf->priv->frame--;
00148 return 1;
00149 }
00150
00151 const vf_info_t ff_vf_info_telecine = {
00152 "telecine filter",
00153 "telecine",
00154 "Rich Felker",
00155 "",
00156 vf_open,
00157 NULL
00158 };