7369
|
1 #include <stdio.h>
|
|
2 #include <stdlib.h>
|
|
3 #include <string.h>
|
|
4 #include <inttypes.h>
|
|
5
|
|
6 #include "../config.h"
|
|
7 #include "../mp_msg.h"
|
|
8 #include "../libvo/fastmemcpy.h"
|
|
9
|
|
10 #include "mp_image.h"
|
|
11 #include "img_format.h"
|
|
12 #include "vf.h"
|
|
13
|
|
14 struct vf_priv_s {
|
|
15 float sense; // first parameter
|
|
16 float level; // second parameter
|
|
17 unsigned int imgfmt;
|
|
18 char diff;
|
|
19 uint32_t max;
|
|
20 // int dfr;
|
|
21 // int rdfr;
|
|
22 int was_dint;
|
|
23 mp_image_t *pmpi; // previous mpi
|
|
24 };
|
|
25
|
|
26 #define MAXROWSIZE 1200
|
|
27
|
|
28 static int config (struct vf_instance_s* vf,
|
|
29 int width, int height, int d_width, int d_height,
|
|
30 unsigned int flags, unsigned int outfmt)
|
|
31 {
|
|
32 int rowsize;
|
|
33
|
|
34 vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP,
|
|
35 0, width, height);
|
|
36 if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
|
|
37 outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 &&
|
|
38 outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 &&
|
|
39 outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16)
|
|
40 {
|
|
41 mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n");
|
|
42 return 0;
|
|
43 }
|
|
44 vf->priv->imgfmt = outfmt;
|
|
45 // recalculate internal values
|
|
46 rowsize = vf->priv->pmpi->width;
|
|
47 if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
|
|
48 vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2;
|
|
49 if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) // planar YUV
|
|
50 vf->priv->diff = vf->priv->sense * 256;
|
|
51 else
|
|
52 vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3));
|
|
53 if (vf->priv->diff < 0) vf->priv->diff = 0;
|
|
54 if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) &&
|
|
55 vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31)
|
|
56 vf->priv->diff = 31;
|
|
57 mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n",
|
|
58 vf->priv->pmpi->width, vf->priv->pmpi->height,
|
|
59 (int)vf->priv->diff, (unsigned int)vf->priv->max);
|
|
60 // vf->priv->rdfr = vf->priv->dfr = 0;
|
|
61 vf->priv->was_dint = 0;
|
|
62 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
|
|
63 }
|
|
64
|
|
65 static int put_image (struct vf_instance_s* vf, mp_image_t *mpi)
|
|
66 {
|
|
67 char rrow0[MAXROWSIZE];
|
|
68 char rrow1[MAXROWSIZE];
|
|
69 char rrow2[MAXROWSIZE];
|
|
70 char *row0 = rrow0, *row1 = rrow1, *row2 = rrow2/*, *row3 = rrow3*/;
|
|
71 int rowsize = mpi->width;
|
|
72 uint32_t nok = 0, max = vf->priv->max;
|
|
73 int diff = vf->priv->diff;
|
|
74 int i, j;
|
|
75 register int n1, n2;
|
|
76 unsigned char *cur0, *prv0;
|
|
77 register unsigned char *cur, *prv;
|
|
78
|
|
79 // check if nothing to do
|
|
80 if (mpi->imgfmt == vf->priv->imgfmt)
|
|
81 {
|
|
82 cur0 = mpi->planes[0] + mpi->stride[0];
|
|
83 prv0 = mpi->planes[0];
|
|
84 for (j = 1; j < mpi->height && nok <= max; j++)
|
|
85 {
|
|
86 cur = cur0;
|
|
87 prv = prv0;
|
|
88 // analyse row (row0)
|
|
89 if (mpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - check luminance
|
|
90 for (i = 0; i < rowsize; i++)
|
|
91 {
|
|
92 if (cur[0] - prv[0] > diff)
|
|
93 row0[i] = 1;
|
|
94 else if (cur[0] - prv[0] < -diff)
|
|
95 row0[i] = -1;
|
|
96 else
|
|
97 row0[i] = 0;
|
|
98 cur++;
|
|
99 prv++;
|
|
100 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
|
|
101 // but row3 is 1 so it's interlaced ptr (nok++)
|
|
102 if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
|
|
103 (++nok) > max)
|
|
104 break;
|
|
105 }
|
|
106 else if (mpi->bpp < 24) // RGB/BGR 16 - check all colors
|
|
107 for (i = 0; i < rowsize; i++)
|
|
108 {
|
|
109 n1 = cur[0] + (cur[1]<<8);
|
|
110 n2 = prv[0] + (prv[1]<<8);
|
|
111 if ((n1&0x1f) - (n2&0x1f) > diff ||
|
|
112 ((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff ||
|
|
113 ((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff)
|
|
114 row0[i] = 1;
|
|
115 else if ((n1&0x1f) - (n2&0x1f) < -diff ||
|
|
116 ((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff ||
|
|
117 ((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff)
|
|
118 row0[i] = -1;
|
|
119 else
|
|
120 row0[i] = 0;
|
|
121 cur += 2;
|
|
122 prv += 2;
|
|
123 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
|
|
124 // but row3 is 1 so it's interlaced ptr (nok++)
|
|
125 if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
|
|
126 (++nok) > max)
|
|
127 break;
|
|
128 }
|
|
129 else // RGB/BGR 24/32
|
|
130 for (i = 0; i < rowsize; i++)
|
|
131 {
|
|
132 if (cur[0] - prv[0] > diff ||
|
|
133 cur[1] - prv[1] > diff ||
|
|
134 cur[2] - prv[2] > diff)
|
|
135 row0[i] = 1;
|
|
136 else if (prv[0] - cur[0] > diff ||
|
|
137 prv[1] - cur[1] > diff ||
|
|
138 prv[2] - cur[2] > diff)
|
|
139 row0[i] = -1;
|
|
140 else
|
|
141 row0[i] = 0;
|
|
142 cur += mpi->bpp/8;
|
|
143 prv += mpi->bpp/8;
|
|
144 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
|
|
145 // but row3 is 1 so it's interlaced ptr (nok++)
|
|
146 if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
|
|
147 (++nok) > max)
|
|
148 break;
|
|
149 }
|
|
150 cur0 += mpi->stride[0];
|
|
151 prv0 += mpi->stride[0];
|
|
152 // rotate rows
|
|
153 cur = row2;
|
|
154 row2 = row1;
|
|
155 row1 = row0;
|
|
156 row0 = cur;
|
|
157 }
|
|
158 }
|
|
159 // check if number of interlaced is above of max
|
|
160 if (nok > max)
|
|
161 {
|
|
162 // vf->priv->dfr++;
|
|
163 if (vf->priv->was_dint < 1) // can skip at most one frame!
|
|
164 {
|
|
165 vf->priv->was_dint++;
|
|
166 // vf->priv->rdfr++;
|
|
167 // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
|
|
168 return 0;
|
|
169 }
|
|
170 }
|
|
171 vf->priv->was_dint = 0;
|
|
172 // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
|
|
173 return vf_next_put_image (vf, mpi);
|
|
174 }
|
|
175
|
|
176 static int open (vf_instance_t *vf, char* args){
|
|
177 vf->config = config;
|
|
178 vf->put_image = put_image;
|
|
179 // vf->default_reqs=VFCAP_ACCEPT_STRIDE;
|
|
180 vf->priv = malloc (sizeof(struct vf_priv_s));
|
7631
|
181 vf->priv->sense = 0.1;
|
7369
|
182 vf->priv->level = 0.15;
|
|
183 vf->priv->pmpi = NULL;
|
|
184 if (args)
|
|
185 sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level);
|
|
186 return 1;
|
|
187 }
|
|
188
|
|
189 vf_info_t vf_info_dint = {
|
|
190 "drop interlaced frames",
|
|
191 "dint",
|
|
192 "A.G.",
|
|
193 "",
|
9593
|
194 open,
|
|
195 NULL
|
7369
|
196 };
|