• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavfilter/libmpcodecs/vf_ivtc.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of MPlayer.
00003  *
00004  * MPlayer is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * MPlayer is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License along
00015  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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 #include "cpudetect.h"
00026 
00027 #include "img_format.h"
00028 #include "mp_image.h"
00029 #include "vf.h"
00030 
00031 #include "libvo/fastmemcpy.h"
00032 
00033 
00034 struct metrics {
00035     /* difference: total, even lines, odd lines */
00036     int d, e, o;
00037     /* noise: temporal, spacial (current), spacial (past) */
00038     int t, s, p;
00039 };
00040 
00041 struct frameinfo {
00042     /* peak, relative, mean */
00043     struct metrics p, r, m;
00044 };
00045 
00046 struct vf_priv_s {
00047     struct frameinfo fi[2];
00048     mp_image_t *dmpi;
00049     int first;
00050     int drop, lastdrop, dropnext;
00051     int inframes, outframes;
00052 };
00053 
00054 enum {
00055     F_DROP,
00056     F_MERGE,
00057     F_NEXT,
00058     F_SHOW
00059 };
00060 
00061 #if HAVE_MMX && HAVE_EBX_AVAILABLE
00062 static void block_diffs_MMX(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns)
00063 {
00064     int i;
00065     short out[24]; // output buffer for the partial metrics from the mmx code
00066 
00067     __asm__ (
00068         "movl $4, %%ecx \n\t"
00069         "pxor %%mm4, %%mm4 \n\t" // 4 even difference sums
00070         "pxor %%mm5, %%mm5 \n\t" // 4 odd difference sums
00071         "pxor %%mm7, %%mm7 \n\t" // all zeros
00072 
00073         ASMALIGN(4)
00074         "1: \n\t"
00075 
00076         // Even difference
00077         "movq (%%"REG_S"), %%mm0 \n\t"
00078         "movq (%%"REG_S"), %%mm2 \n\t"
00079         "add %%"REG_a", %%"REG_S" \n\t"
00080         "movq (%%"REG_D"), %%mm1 \n\t"
00081         "add %%"REG_b", %%"REG_D" \n\t"
00082         "psubusb %%mm1, %%mm2 \n\t"
00083         "psubusb %%mm0, %%mm1 \n\t"
00084         "movq %%mm2, %%mm0 \n\t"
00085         "movq %%mm1, %%mm3 \n\t"
00086         "punpcklbw %%mm7, %%mm0 \n\t"
00087         "punpcklbw %%mm7, %%mm1 \n\t"
00088         "punpckhbw %%mm7, %%mm2 \n\t"
00089         "punpckhbw %%mm7, %%mm3 \n\t"
00090         "paddw %%mm0, %%mm4 \n\t"
00091         "paddw %%mm1, %%mm4 \n\t"
00092         "paddw %%mm2, %%mm4 \n\t"
00093         "paddw %%mm3, %%mm4 \n\t"
00094 
00095         // Odd difference
00096         "movq (%%"REG_S"), %%mm0 \n\t"
00097         "movq (%%"REG_S"), %%mm2 \n\t"
00098         "add %%"REG_a", %%"REG_S" \n\t"
00099         "movq (%%"REG_D"), %%mm1 \n\t"
00100         "add %%"REG_b", %%"REG_D" \n\t"
00101         "psubusb %%mm1, %%mm2 \n\t"
00102         "psubusb %%mm0, %%mm1 \n\t"
00103         "movq %%mm2, %%mm0 \n\t"
00104         "movq %%mm1, %%mm3 \n\t"
00105         "punpcklbw %%mm7, %%mm0 \n\t"
00106         "punpcklbw %%mm7, %%mm1 \n\t"
00107         "punpckhbw %%mm7, %%mm2 \n\t"
00108         "punpckhbw %%mm7, %%mm3 \n\t"
00109         "paddw %%mm0, %%mm5 \n\t"
00110         "paddw %%mm1, %%mm5 \n\t"
00111         "paddw %%mm2, %%mm5 \n\t"
00112         "paddw %%mm3, %%mm5 \n\t"
00113 
00114         "decl %%ecx \n\t"
00115         "jnz 1b \n\t"
00116         "movq %%mm4, (%%"REG_d") \n\t"
00117         "movq %%mm5, 8(%%"REG_d") \n\t"
00118         :
00119         : "S" (old), "D" (new), "a" (os), "b" (ns), "d" (out)
00120         : "memory"
00121         );
00122     m->e = out[0]+out[1]+out[2]+out[3];
00123     m->o = out[4]+out[5]+out[6]+out[7];
00124     m->d = m->e + m->o;
00125 
00126     __asm__ (
00127         // First loop to measure first four columns
00128         "movl $4, %%ecx \n\t"
00129         "pxor %%mm4, %%mm4 \n\t" // Past spacial noise
00130         "pxor %%mm5, %%mm5 \n\t" // Temporal noise
00131         "pxor %%mm6, %%mm6 \n\t" // Current spacial noise
00132 
00133         ASMALIGN(4)
00134         "2: \n\t"
00135 
00136         "movq (%%"REG_S"), %%mm0 \n\t"
00137         "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t"
00138         "add %%"REG_a", %%"REG_S" \n\t"
00139         "add %%"REG_a", %%"REG_S" \n\t"
00140         "movq (%%"REG_D"), %%mm2 \n\t"
00141         "movq (%%"REG_D",%%"REG_b"), %%mm3 \n\t"
00142         "add %%"REG_b", %%"REG_D" \n\t"
00143         "add %%"REG_b", %%"REG_D" \n\t"
00144         "punpcklbw %%mm7, %%mm0 \n\t"
00145         "punpcklbw %%mm7, %%mm1 \n\t"
00146         "punpcklbw %%mm7, %%mm2 \n\t"
00147         "punpcklbw %%mm7, %%mm3 \n\t"
00148         "paddw %%mm1, %%mm4 \n\t"
00149         "paddw %%mm1, %%mm5 \n\t"
00150         "paddw %%mm3, %%mm6 \n\t"
00151         "psubw %%mm0, %%mm4 \n\t"
00152         "psubw %%mm2, %%mm5 \n\t"
00153         "psubw %%mm2, %%mm6 \n\t"
00154 
00155         "decl %%ecx \n\t"
00156         "jnz 2b \n\t"
00157 
00158         "movq %%mm0, %%mm1 \n\t"
00159         "movq %%mm0, %%mm2 \n\t"
00160         "movq %%mm0, %%mm3 \n\t"
00161         "pcmpgtw %%mm4, %%mm1 \n\t"
00162         "pcmpgtw %%mm5, %%mm2 \n\t"
00163         "pcmpgtw %%mm6, %%mm3 \n\t"
00164         "pxor %%mm1, %%mm4 \n\t"
00165         "pxor %%mm2, %%mm5 \n\t"
00166         "pxor %%mm3, %%mm6 \n\t"
00167         "psubw %%mm1, %%mm4 \n\t"
00168         "psubw %%mm2, %%mm5 \n\t"
00169         "psubw %%mm3, %%mm6 \n\t"
00170         "movq %%mm4, (%%"REG_d") \n\t"
00171         "movq %%mm5, 16(%%"REG_d") \n\t"
00172         "movq %%mm6, 32(%%"REG_d") \n\t"
00173 
00174         "mov %%"REG_a", %%"REG_c" \n\t"
00175         "shl $3, %%"REG_c" \n\t"
00176         "sub %%"REG_c", %%"REG_S" \n\t"
00177         "mov %%"REG_b", %%"REG_c" \n\t"
00178         "shl $3, %%"REG_c" \n\t"
00179         "sub %%"REG_c", %%"REG_D" \n\t"
00180 
00181         // Second loop for the last four columns
00182         "movl $4, %%ecx \n\t"
00183         "pxor %%mm4, %%mm4 \n\t"
00184         "pxor %%mm5, %%mm5 \n\t"
00185         "pxor %%mm6, %%mm6 \n\t"
00186 
00187         ASMALIGN(4)
00188         "3: \n\t"
00189 
00190         "movq (%%"REG_S"), %%mm0 \n\t"
00191         "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t"
00192         "add %%"REG_a", %%"REG_S" \n\t"
00193         "add %%"REG_a", %%"REG_S" \n\t"
00194         "movq (%%"REG_D"), %%mm2 \n\t"
00195         "movq (%%"REG_D",%%"REG_b"), %%mm3 \n\t"
00196         "add %%"REG_b", %%"REG_D" \n\t"
00197         "add %%"REG_b", %%"REG_D" \n\t"
00198         "punpckhbw %%mm7, %%mm0 \n\t"
00199         "punpckhbw %%mm7, %%mm1 \n\t"
00200         "punpckhbw %%mm7, %%mm2 \n\t"
00201         "punpckhbw %%mm7, %%mm3 \n\t"
00202         "paddw %%mm1, %%mm4 \n\t"
00203         "paddw %%mm1, %%mm5 \n\t"
00204         "paddw %%mm3, %%mm6 \n\t"
00205         "psubw %%mm0, %%mm4 \n\t"
00206         "psubw %%mm2, %%mm5 \n\t"
00207         "psubw %%mm2, %%mm6 \n\t"
00208 
00209         "decl %%ecx \n\t"
00210         "jnz 3b \n\t"
00211 
00212         "movq %%mm0, %%mm1 \n\t"
00213         "movq %%mm0, %%mm2 \n\t"
00214         "movq %%mm0, %%mm3 \n\t"
00215         "pcmpgtw %%mm4, %%mm1 \n\t"
00216         "pcmpgtw %%mm5, %%mm2 \n\t"
00217         "pcmpgtw %%mm6, %%mm3 \n\t"
00218         "pxor %%mm1, %%mm4 \n\t"
00219         "pxor %%mm2, %%mm5 \n\t"
00220         "pxor %%mm3, %%mm6 \n\t"
00221         "psubw %%mm1, %%mm4 \n\t"
00222         "psubw %%mm2, %%mm5 \n\t"
00223         "psubw %%mm3, %%mm6 \n\t"
00224         "movq %%mm4, 8(%%"REG_d") \n\t"
00225         "movq %%mm5, 24(%%"REG_d") \n\t"
00226         "movq %%mm6, 40(%%"REG_d") \n\t"
00227 
00228         "emms \n\t"
00229         :
00230         : "S" (old), "D" (new), "a" ((long)os), "b" ((long)ns), "d" (out)
00231         : "memory"
00232         );
00233     m->p = m->t = m->s = 0;
00234     for (i=0; i<8; i++) {
00235         m->p += out[i];
00236         m->t += out[8+i];
00237         m->s += out[16+i];
00238     }
00239     //printf("e=%d o=%d d=%d p=%d t=%d s=%d\n", m->e, m->o, m->d, m->p, m->t, m->s);
00240 }
00241 #endif
00242 
00243 //#define MAG(a) ((a)*(a))
00244 //#define MAG(a) (abs(a))
00245 #define MAG(a) (((a)^((a)>>31))-((a)>>31))
00246 
00247 //#define LOWPASS(s) (((s)[-2] + 4*(s)[-1] + 6*(s)[0] + 4*(s)[1] + (s)[2])>>4)
00248 //#define LOWPASS(s) (((s)[-1] + 2*(s)[0] + (s)[1])>>2)
00249 #define LOWPASS(s) ((s)[0])
00250 
00251 
00252 static void block_diffs_C(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns)
00253 {
00254     int x, y, e=0, o=0, s=0, p=0, t=0;
00255     unsigned char *oldp, *newp;
00256     m->s = m->p = m->t = 0;
00257     for (x = 8; x; x--) {
00258         oldp = old++;
00259         newp = new++;
00260         s = p = t = 0;
00261         for (y = 4; y; y--) {
00262             e += MAG(newp[0]-oldp[0]);
00263             o += MAG(newp[ns]-oldp[os]);
00264             s += newp[ns]-newp[0];
00265             p += oldp[os]-oldp[0];
00266             t += oldp[os]-newp[0];
00267             oldp += os<<1;
00268             newp += ns<<1;
00269         }
00270         m->s += MAG(s);
00271         m->p += MAG(p);
00272         m->t += MAG(t);
00273     }
00274     m->e = e;
00275     m->o = o;
00276     m->d = e+o;
00277 }
00278 
00279 static void (*block_diffs)(struct metrics *, unsigned char *, unsigned char *, int, int);
00280 
00281 #define MAXUP(a,b) ((a) = ((a)>(b)) ? (a) : (b))
00282 
00283 static void diff_planes(struct frameinfo *fi,
00284     unsigned char *old, unsigned char *new, int w, int h, int os, int ns)
00285 {
00286     int x, y;
00287     struct metrics l;
00288     struct metrics *peak=&fi->p, *rel=&fi->r, *mean=&fi->m;
00289     memset(peak, 0, sizeof(struct metrics));
00290     memset(rel, 0, sizeof(struct metrics));
00291     memset(mean, 0, sizeof(struct metrics));
00292     for (y = 0; y < h-7; y += 8) {
00293         for (x = 8; x < w-8-7; x += 8) {
00294             block_diffs(&l, old+x+y*os, new+x+y*ns, os, ns);
00295             mean->d += l.d;
00296             mean->e += l.e;
00297             mean->o += l.o;
00298             mean->s += l.s;
00299             mean->p += l.p;
00300             mean->t += l.t;
00301             MAXUP(peak->d, l.d);
00302             MAXUP(peak->e, l.e);
00303             MAXUP(peak->o, l.o);
00304             MAXUP(peak->s, l.s);
00305             MAXUP(peak->p, l.p);
00306             MAXUP(peak->t, l.t);
00307             MAXUP(rel->e, l.e-l.o);
00308             MAXUP(rel->o, l.o-l.e);
00309             MAXUP(rel->s, l.s-l.t);
00310             MAXUP(rel->p, l.p-l.t);
00311             MAXUP(rel->t, l.t-l.p);
00312             MAXUP(rel->d, l.t-l.s); /* hack */
00313         }
00314     }
00315     x = (w/8-2)*(h/8);
00316     mean->d /= x;
00317     mean->e /= x;
00318     mean->o /= x;
00319     mean->s /= x;
00320     mean->p /= x;
00321     mean->t /= x;
00322 }
00323 
00324 static void diff_fields(struct frameinfo *fi, mp_image_t *old, mp_image_t *new)
00325 {
00326     diff_planes(fi, old->planes[0], new->planes[0],
00327         new->w, new->h, old->stride[0], new->stride[0]);
00328 }
00329 
00330 static void stats(struct frameinfo *f)
00331 {
00332     mp_msg(MSGT_VFILTER, MSGL_V, "       pd=%d re=%d ro=%d rp=%d rt=%d rs=%d rd=%d pp=%d pt=%d ps=%d\r",
00333         f->p.d, f->r.e, f->r.o, f->r.p, f->r.t, f->r.s, f->r.d, f->p.p, f->p.t, f->p.s);
00334 }
00335 
00336 static int foo(struct vf_priv_s *p, mp_image_t *new, mp_image_t *cur)
00337 {
00338     struct frameinfo *f = p->fi;
00339 
00340     f[0] = f[1];
00341     diff_fields(&f[1], cur, new);
00342     stats(&f[1]);
00343 
00344     // Immediately drop this frame if it's already been used.
00345     if (p->dropnext) {
00346         p->dropnext = 0;
00347         return F_DROP;
00348     }
00349 
00350     // Sometimes a pulldown frame comes all by itself, so both
00351     // its top and bottom field are duplicates from the adjacent
00352     // two frames. We can just drop such a frame, but we
00353     // immediately show the next frame instead to keep the frame
00354     // drops evenly spaced during normal 3:2 pulldown sequences.
00355     if ((3*f[1].r.o < f[1].r.e) && (f[1].r.s < f[1].r.d)) {
00356         p->dropnext = 1;
00357         return F_NEXT;
00358     }
00359 
00360     // If none of these conditions hold, we will consider the frame
00361     // progressive and just show it as-is.
00362     if (!(  (3*f[0].r.e < f[0].r.o) ||
00363         ((2*f[0].r.d < f[0].r.s) && (f[0].r.s > 1200)) ||
00364         ((2*f[1].r.t < f[1].r.p) && (f[1].r.p > 1200))  ))
00365         return F_SHOW;
00366 
00367     // Otherwise, we have to decide whether to merge or drop.
00368     // If the noise metric only increases minimally, we're off
00369     // to a good start...
00370     if (((2*f[1].r.t < 3*f[1].r.p) && (f[1].r.t < 3600)) ||
00371         (f[1].r.t < 900) || (f[1].r.d < 900)) {
00372         // ...and if noise decreases or the duplicate even field
00373         // is detected, we go ahead with the merge.
00374         if ((3*f[0].r.e < f[0].r.o) || (2*f[1].r.t < f[1].r.p)) {
00375             p->dropnext = 1;
00376             return F_MERGE;
00377         }
00378     }
00379     return F_DROP;
00380 }
00381 
00382 
00383 
00384 static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field)
00385 {
00386     switch (field) {
00387     case 0:
00388         my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
00389             dmpi->stride[0]*2, mpi->stride[0]*2);
00390         if (mpi->flags & MP_IMGFLAG_PLANAR) {
00391             my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
00392                 mpi->chroma_width, mpi->chroma_height/2,
00393                 dmpi->stride[1]*2, mpi->stride[1]*2);
00394             my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
00395                 mpi->chroma_width, mpi->chroma_height/2,
00396                 dmpi->stride[2]*2, mpi->stride[2]*2);
00397         }
00398         break;
00399     case 1:
00400         my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
00401             mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2,
00402             dmpi->stride[0]*2, mpi->stride[0]*2);
00403         if (mpi->flags & MP_IMGFLAG_PLANAR) {
00404             my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
00405                 mpi->planes[1]+mpi->stride[1],
00406                 mpi->chroma_width, mpi->chroma_height/2,
00407                 dmpi->stride[1]*2, mpi->stride[1]*2);
00408             my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
00409                 mpi->planes[2]+mpi->stride[2],
00410                 mpi->chroma_width, mpi->chroma_height/2,
00411                 dmpi->stride[2]*2, mpi->stride[2]*2);
00412         }
00413         break;
00414     case 2:
00415         memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
00416             dmpi->stride[0], mpi->stride[0]);
00417         if (mpi->flags & MP_IMGFLAG_PLANAR) {
00418             memcpy_pic(dmpi->planes[1], mpi->planes[1],
00419                 mpi->chroma_width, mpi->chroma_height,
00420                 dmpi->stride[1], mpi->stride[1]);
00421             memcpy_pic(dmpi->planes[2], mpi->planes[2],
00422                 mpi->chroma_width, mpi->chroma_height,
00423                 dmpi->stride[2], mpi->stride[2]);
00424         }
00425         break;
00426     }
00427 }
00428 
00429 static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
00430 {
00431     struct vf_priv_s *p = vf->priv;
00432     int dropflag=0;
00433 
00434     if (!p->dropnext) switch (p->drop) {
00435     case 0:
00436         dropflag = 0;
00437         break;
00438     case 1:
00439         dropflag = (++p->lastdrop >= 5);
00440         break;
00441     case 2:
00442         dropflag = (++p->lastdrop >= 5) && (4*p->inframes <= 5*p->outframes);
00443         break;
00444     }
00445 
00446     if (dropflag) {
00447         //mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n",
00448         //    p->outframes, p->inframes, (float)p->outframes/p->inframes);
00449         mp_msg(MSGT_VFILTER, MSGL_V, "!");
00450         p->lastdrop = 0;
00451         return 0;
00452     }
00453 
00454     p->outframes++;
00455     return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
00456 }
00457 
00458 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
00459 {
00460     int ret=0;
00461     struct vf_priv_s *p = vf->priv;
00462 
00463     p->inframes++;
00464 
00465     if (p->first) { /* hack */
00466         p->first = 0;
00467         return 1;
00468     }
00469 
00470     if (!p->dmpi) p->dmpi = vf_get_image(vf->next, mpi->imgfmt,
00471         MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
00472         MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE,
00473         mpi->width, mpi->height);
00474     /* FIXME -- not correct, off by one frame! */
00475     p->dmpi->qscale = mpi->qscale;
00476     p->dmpi->qstride = mpi->qstride;
00477     p->dmpi->qscale_type = mpi->qscale_type;
00478 
00479     switch (foo(p, mpi, p->dmpi)) {
00480     case F_DROP:
00481         copy_image(p->dmpi, mpi, 2);
00482         ret = 0;
00483         p->lastdrop = 0;
00484         mp_msg(MSGT_VFILTER, MSGL_V, "DROP\n");
00485         break;
00486     case F_MERGE:
00487         copy_image(p->dmpi, mpi, 0);
00488         ret = do_put_image(vf, p->dmpi);
00489         copy_image(p->dmpi, mpi, 1);
00490         mp_msg(MSGT_VFILTER, MSGL_V, "MERGE\n");
00491         p->dmpi = NULL;
00492         break;
00493     case F_NEXT:
00494         copy_image(p->dmpi, mpi, 2);
00495         ret = do_put_image(vf, p->dmpi);
00496         mp_msg(MSGT_VFILTER, MSGL_V, "NEXT\n");
00497         p->dmpi = NULL;
00498         break;
00499     case F_SHOW:
00500         ret = do_put_image(vf, p->dmpi);
00501         copy_image(p->dmpi, mpi, 2);
00502         mp_msg(MSGT_VFILTER, MSGL_V, "OK\n");
00503         p->dmpi = NULL;
00504         break;
00505     }
00506     return ret;
00507 }
00508 
00509 static int query_format(struct vf_instance *vf, unsigned int fmt)
00510 {
00511     switch (fmt) {
00512     case IMGFMT_YV12:
00513     case IMGFMT_IYUV:
00514     case IMGFMT_I420:
00515         return vf_next_query_format(vf, fmt);
00516     }
00517     return 0;
00518 }
00519 
00520 static void uninit(struct vf_instance *vf)
00521 {
00522     free(vf->priv);
00523 }
00524 
00525 static int vf_open(vf_instance_t *vf, char *args)
00526 {
00527     struct vf_priv_s *p;
00528     vf->put_image = put_image;
00529     vf->query_format = query_format;
00530     vf->uninit = uninit;
00531     vf->default_reqs = VFCAP_ACCEPT_STRIDE;
00532     vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
00533     p->drop = 0;
00534     p->first = 1;
00535     if (args) sscanf(args, "%d", &p->drop);
00536     block_diffs = block_diffs_C;
00537 #if HAVE_MMX && HAVE_EBX_AVAILABLE
00538     if(gCpuCaps.hasMMX) block_diffs = block_diffs_MMX;
00539 #endif
00540     return 1;
00541 }
00542 
00543 const vf_info_t vf_info_ivtc = {
00544     "inverse telecine, take 2",
00545     "ivtc",
00546     "Rich Felker",
00547     "",
00548     vf_open,
00549     NULL
00550 };

Generated on Wed Apr 11 2012 07:31:36 for FFmpeg by  doxygen 1.7.1