Mercurial > mplayer.hg
annotate libmpcodecs/vf_tfields.c @ 10009:69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
output picture doesn't bob up and down :)
author | rfelker |
---|---|
date | Mon, 28 Apr 2003 02:53:50 +0000 |
parents | e9a2af584986 |
children | 9829b7e61b55 |
rev | line source |
---|---|
9514 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 | |
5 #include "../config.h" | |
6 #include "../mp_msg.h" | |
7 | |
8 #include "img_format.h" | |
9 #include "mp_image.h" | |
10 #include "vf.h" | |
11 | |
12 #include "../libvo/fastmemcpy.h" | |
13 | |
14 struct vf_priv_s { | |
15 int mode; | |
16 }; | |
17 | |
18 static inline void *my_memcpy_pic(void * dst, void * src, int bytesPerLine, int height, int dstStride, int srcStride) | |
19 { | |
20 int i; | |
21 void *retval=dst; | |
22 | |
23 for(i=0; i<height; i++) | |
24 { | |
25 memcpy(dst, src, bytesPerLine); | |
26 src+= srcStride; | |
27 dst+= dstStride; | |
28 } | |
29 | |
30 return retval; | |
31 } | |
32 | |
33 static void deint(unsigned char *dest, int ds, unsigned char *src, int ss, int w, int h, int field) | |
34 { | |
35 int x, y; | |
36 src += ss; | |
37 dest += ds; | |
38 if (field) { | |
39 src += ss; | |
40 dest += ds; | |
41 h -= 2; | |
42 } | |
43 for (y=h/2; y; y--) { | |
44 for (x=0; x<w; x++) { | |
45 if (((src[x-ss] < src[x]) && (src[x+ss] < src[x])) || | |
46 ((src[x-ss] > src[x]) && (src[x+ss] > src[x]))) { | |
47 //dest[x] = (src[x+ss] + src[x-ss])>>1; | |
48 dest[x] = ((src[x+ss]<<1) + (src[x-ss]<<1) | |
49 + src[x+ss+1] + src[x-ss+1] | |
50 + src[x+ss-1] + src[x-ss-1])>>3; | |
51 } | |
52 else dest[x] = src[x]; | |
53 } | |
54 dest += ds<<1; | |
55 src += ss<<1; | |
56 } | |
57 } | |
58 | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
59 static void qpelup(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss) |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
60 { |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
61 int i, j; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
62 memcpy(d, s, w); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
63 for (i=h-1; i; i--) { |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
64 d += ds; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
65 s += ss; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
66 for (j=0; j<w; j++) |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
67 d[j] = (s[j-ss] + 3*s[j])>>2; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
68 } |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
69 } |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
70 |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
71 static void qpeldown(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss) |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
72 { |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
73 int i, j; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
74 for (i=h-1; i; i--) { |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
75 for (j=0; j<w; j++) |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
76 d[j] = (3*s[j] + s[j+ss])>>2; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
77 d += ds; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
78 s += ss; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
79 } |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
80 memcpy(d, s, w); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
81 } |
9514 | 82 |
83 | |
84 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi) | |
85 { | |
86 int ret; | |
87 mp_image_t *dmpi; | |
88 | |
89 switch (vf->priv->mode) { | |
90 case 0: | |
91 dmpi = vf_get_image(vf->next, mpi->imgfmt, | |
92 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
93 mpi->width, mpi->height/2); | |
94 memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, | |
95 dmpi->stride[0], mpi->stride[0]*2); | |
96 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
97 memcpy_pic(dmpi->planes[1], mpi->planes[1], | |
98 mpi->chroma_width, mpi->chroma_height/2, | |
99 dmpi->stride[1], mpi->stride[1]*2); | |
100 memcpy_pic(dmpi->planes[2], mpi->planes[2], | |
101 mpi->chroma_width, mpi->chroma_height/2, | |
102 dmpi->stride[2], mpi->stride[2]*2); | |
103 } | |
104 ret = vf_next_put_image(vf, dmpi); | |
105 | |
106 memcpy_pic(dmpi->planes[0], mpi->planes[0] + mpi->stride[0], | |
107 mpi->w, mpi->h/2, dmpi->stride[0], mpi->stride[0]*2); | |
108 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
109 memcpy_pic(dmpi->planes[1], mpi->planes[1] + mpi->stride[1], | |
110 mpi->chroma_width, mpi->chroma_height/2, | |
111 dmpi->stride[1], mpi->stride[1]*2); | |
112 memcpy_pic(dmpi->planes[2], mpi->planes[2] + mpi->stride[2], | |
113 mpi->chroma_width, mpi->chroma_height/2, | |
114 dmpi->stride[2], mpi->stride[2]*2); | |
115 } | |
116 return vf_next_put_image(vf, dmpi) || ret; | |
117 case 1: | |
118 dmpi = vf_get_image(vf->next, mpi->imgfmt, | |
119 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
120 mpi->width, mpi->height); | |
121 my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, | |
122 dmpi->stride[0]*2, mpi->stride[0]*2); | |
123 deint(dmpi->planes[0], dmpi->stride[0], mpi->planes[0], mpi->stride[0], mpi->w, mpi->h, 0); | |
124 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
125 my_memcpy_pic(dmpi->planes[1], mpi->planes[1], | |
126 mpi->chroma_width, mpi->chroma_height/2, | |
127 dmpi->stride[1]*2, mpi->stride[1]*2); | |
128 my_memcpy_pic(dmpi->planes[2], mpi->planes[2], | |
129 mpi->chroma_width, mpi->chroma_height/2, | |
130 dmpi->stride[2]*2, mpi->stride[2]*2); | |
131 deint(dmpi->planes[1], dmpi->stride[1], mpi->planes[1], mpi->stride[1], | |
132 mpi->chroma_width, mpi->chroma_height, 0); | |
133 deint(dmpi->planes[2], dmpi->stride[2], mpi->planes[2], mpi->stride[2], | |
134 mpi->chroma_width, mpi->chroma_height, 0); | |
135 } | |
136 ret = vf_next_put_image(vf, dmpi); | |
137 | |
138 my_memcpy_pic(dmpi->planes[0] + dmpi->stride[0], mpi->planes[0] + mpi->stride[0], | |
139 mpi->w, mpi->h/2, dmpi->stride[0]*2, mpi->stride[0]*2); | |
140 deint(dmpi->planes[0], dmpi->stride[0], mpi->planes[0], mpi->stride[0], mpi->w, mpi->h, 1); | |
141 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
142 my_memcpy_pic(dmpi->planes[1] + dmpi->stride[1], mpi->planes[1] + mpi->stride[1], | |
143 mpi->chroma_width, mpi->chroma_height/2, | |
144 dmpi->stride[1]*2, mpi->stride[1]*2); | |
145 my_memcpy_pic(dmpi->planes[2] + dmpi->stride[2], mpi->planes[2] + mpi->stride[2], | |
146 mpi->chroma_width, mpi->chroma_height/2, | |
147 dmpi->stride[2]*2, mpi->stride[2]*2); | |
148 deint(dmpi->planes[1], dmpi->stride[1], mpi->planes[1], mpi->stride[1], | |
149 mpi->chroma_width, mpi->chroma_height, 1); | |
150 deint(dmpi->planes[2], dmpi->stride[2], mpi->planes[2], mpi->stride[2], | |
151 mpi->chroma_width, mpi->chroma_height, 1); | |
152 } | |
153 return vf_next_put_image(vf, dmpi) || ret; | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
154 case 2: |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
155 dmpi = vf_get_image(vf->next, mpi->imgfmt, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
156 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
157 mpi->width, mpi->height/2); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
158 qpeldown(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
159 dmpi->stride[0], mpi->stride[0]*2); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
160 if (mpi->flags & MP_IMGFLAG_PLANAR) { |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
161 qpeldown(dmpi->planes[1], mpi->planes[1], |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
162 mpi->chroma_width, mpi->chroma_height/2, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
163 dmpi->stride[1], mpi->stride[1]*2); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
164 qpeldown(dmpi->planes[2], mpi->planes[2], |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
165 mpi->chroma_width, mpi->chroma_height/2, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
166 dmpi->stride[2], mpi->stride[2]*2); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
167 } |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
168 ret = vf_next_put_image(vf, dmpi); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
169 |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
170 qpelup(dmpi->planes[0], mpi->planes[0] + mpi->stride[0], |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
171 mpi->w, mpi->h/2, dmpi->stride[0], mpi->stride[0]*2); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
172 if (mpi->flags & MP_IMGFLAG_PLANAR) { |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
173 qpelup(dmpi->planes[1], mpi->planes[1] + mpi->stride[1], |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
174 mpi->chroma_width, mpi->chroma_height/2, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
175 dmpi->stride[1], mpi->stride[1]*2); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
176 qpelup(dmpi->planes[2], mpi->planes[2] + mpi->stride[2], |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
177 mpi->chroma_width, mpi->chroma_height/2, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
178 dmpi->stride[2], mpi->stride[2]*2); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
179 } |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
180 return vf_next_put_image(vf, dmpi) || ret; |
9514 | 181 } |
182 return 0; | |
183 } | |
184 | |
185 static int query_format(struct vf_instance_s* vf, unsigned int fmt) | |
186 { | |
187 /* FIXME - figure out which other formats work */ | |
188 switch (fmt) { | |
189 case IMGFMT_YV12: | |
190 case IMGFMT_IYUV: | |
191 case IMGFMT_I420: | |
192 return vf_next_query_format(vf, fmt); | |
193 } | |
194 return 0; | |
195 } | |
196 | |
197 static int config(struct vf_instance_s* vf, | |
198 int width, int height, int d_width, int d_height, | |
199 unsigned int flags, unsigned int outfmt) | |
200 { | |
201 switch (vf->priv->mode) { | |
202 case 0: | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
203 case 2: |
9514 | 204 return vf_next_config(vf,width,height/2,d_width,d_height,flags,outfmt); |
205 case 1: | |
206 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
207 } | |
208 return 0; | |
209 } | |
210 | |
211 static void uninit(struct vf_instance_s* vf) | |
212 { | |
213 free(vf->priv); | |
214 } | |
215 | |
216 static int open(vf_instance_t *vf, char* args) | |
217 { | |
218 struct vf_priv_s *p; | |
219 vf->config = config; | |
220 vf->put_image = put_image; | |
221 vf->query_format = query_format; | |
222 vf->uninit = uninit; | |
223 vf->default_reqs = VFCAP_ACCEPT_STRIDE; | |
224 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); | |
225 vf->priv->mode = 0; | |
226 if (args) sscanf(args, "%d", &vf->priv->mode); | |
227 return 1; | |
228 } | |
229 | |
230 vf_info_t vf_info_tfields = { | |
231 "temporal field separation", | |
232 "tfields", | |
233 "Rich Felker", | |
234 "", | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9514
diff
changeset
|
235 open, |
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9514
diff
changeset
|
236 NULL |
9514 | 237 }; |
238 | |
239 |