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 #include <inttypes.h>
00023
00024 #include "config.h"
00025 #include "mp_msg.h"
00026
00027 #include "mp_image.h"
00028 #include "img_format.h"
00029 #include "vf.h"
00030
00031 struct vf_priv_s {
00032 float sense;
00033 float level;
00034 unsigned int imgfmt;
00035 int diff;
00036 uint32_t max;
00037
00038
00039 int was_dint;
00040 mp_image_t *pmpi;
00041 };
00042
00043 #define MAXROWSIZE 1200
00044
00045 static int config (struct vf_instance *vf,
00046 int width, int height, int d_width, int d_height,
00047 unsigned int flags, unsigned int outfmt)
00048 {
00049 int rowsize;
00050
00051 vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP,
00052 0, width, height);
00053 if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
00054 outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 &&
00055 outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 &&
00056 outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16)
00057 {
00058 mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n");
00059 return 0;
00060 }
00061 vf->priv->imgfmt = outfmt;
00062
00063 rowsize = vf->priv->pmpi->width;
00064 if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
00065 vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2;
00066 if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR)
00067 vf->priv->diff = vf->priv->sense * 256;
00068 else
00069 vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3));
00070 if (vf->priv->diff < 0) vf->priv->diff = 0;
00071 if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
00072 vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31)
00073 vf->priv->diff = 31;
00074 mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n",
00075 vf->priv->pmpi->width, vf->priv->pmpi->height,
00076 vf->priv->diff, (unsigned int)vf->priv->max);
00077
00078 vf->priv->was_dint = 0;
00079 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00080 }
00081
00082 static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts)
00083 {
00084 int8_t rrow0[MAXROWSIZE];
00085 int8_t rrow1[MAXROWSIZE];
00086 int8_t rrow2[MAXROWSIZE];
00087 int8_t *row0 = rrow0, *row1 = rrow1, *row2 = rrow2;
00088 int rowsize = mpi->width;
00089 uint32_t nok = 0, max = vf->priv->max;
00090 int diff = vf->priv->diff;
00091 int i, j;
00092 register int n1, n2;
00093 unsigned char *cur0, *prv0;
00094 register unsigned char *cur, *prv;
00095
00096 if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
00097
00098 if (mpi->imgfmt == vf->priv->imgfmt)
00099 {
00100 cur0 = mpi->planes[0] + mpi->stride[0];
00101 prv0 = mpi->planes[0];
00102 for (j = 1; j < mpi->height && nok <= max; j++)
00103 {
00104 cur = cur0;
00105 prv = prv0;
00106
00107 if (mpi->flags & MP_IMGFLAG_PLANAR)
00108 for (i = 0; i < rowsize; i++)
00109 {
00110 if (cur[0] - prv[0] > diff)
00111 row0[i] = 1;
00112 else if (cur[0] - prv[0] < -diff)
00113 row0[i] = -1;
00114 else
00115 row0[i] = 0;
00116 cur++;
00117 prv++;
00118
00119
00120 if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
00121 (++nok) > max)
00122 break;
00123 }
00124 else if (mpi->bpp < 24)
00125 for (i = 0; i < rowsize; i++)
00126 {
00127 n1 = cur[0] + (cur[1]<<8);
00128 n2 = prv[0] + (prv[1]<<8);
00129 if ((n1&0x1f) - (n2&0x1f) > diff ||
00130 ((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff ||
00131 ((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff)
00132 row0[i] = 1;
00133 else if ((n1&0x1f) - (n2&0x1f) < -diff ||
00134 ((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff ||
00135 ((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff)
00136 row0[i] = -1;
00137 else
00138 row0[i] = 0;
00139 cur += 2;
00140 prv += 2;
00141
00142
00143 if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
00144 (++nok) > max)
00145 break;
00146 }
00147 else
00148 for (i = 0; i < rowsize; i++)
00149 {
00150 if (cur[0] - prv[0] > diff ||
00151 cur[1] - prv[1] > diff ||
00152 cur[2] - prv[2] > diff)
00153 row0[i] = 1;
00154 else if (prv[0] - cur[0] > diff ||
00155 prv[1] - cur[1] > diff ||
00156 prv[2] - cur[2] > diff)
00157 row0[i] = -1;
00158 else
00159 row0[i] = 0;
00160 cur += mpi->bpp/8;
00161 prv += mpi->bpp/8;
00162
00163
00164 if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
00165 (++nok) > max)
00166 break;
00167 }
00168 cur0 += mpi->stride[0];
00169 prv0 += mpi->stride[0];
00170
00171 cur = row2;
00172 row2 = row1;
00173 row1 = row0;
00174 row0 = cur;
00175 }
00176 }
00177
00178 if (nok > max)
00179 {
00180
00181 if (vf->priv->was_dint < 1)
00182 {
00183 vf->priv->was_dint++;
00184
00185
00186 return 0;
00187 }
00188 }
00189 vf->priv->was_dint = 0;
00190
00191 return vf_next_put_image (vf, mpi, pts);
00192 }
00193
00194 static int vf_open(vf_instance_t *vf, char *args){
00195 vf->config = config;
00196 vf->put_image = put_image;
00197
00198 vf->priv = malloc (sizeof(struct vf_priv_s));
00199 vf->priv->sense = 0.1;
00200 vf->priv->level = 0.15;
00201 vf->priv->pmpi = NULL;
00202 if (args)
00203 sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level);
00204 return 1;
00205 }
00206
00207 const vf_info_t vf_info_dint = {
00208 "drop interlaced frames",
00209 "dint",
00210 "A.G.",
00211 "",
00212 vf_open,
00213 NULL
00214 };