Mercurial > mplayer.hg
comparison libmpcodecs/vf_dint.c @ 7369:b34b005ab4f8
drop-deinterlace (dint) filter by Andriy N. Gritsenko <andrej@lucky.net>
author | arpi |
---|---|
date | Tue, 10 Sep 2002 23:18:31 +0000 |
parents | |
children | 04a6df4fb976 |
comparison
equal
deleted
inserted
replaced
7368:a894e99c1e51 | 7369:b34b005ab4f8 |
---|---|
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)); | |
181 vf->priv->sense = 0.01; | |
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 "", | |
194 open | |
195 }; |