Mercurial > mplayer.hg
annotate libmpcodecs/vf_tile.c @ 18049:77a3b0d11ca5
Limit the number of entires to the amount that does fit into the chunk.
the function need rewrite as it assumes quite many things that are not guaranteed by the specifications.
author | iive |
---|---|
date | Thu, 06 Apr 2006 20:04:02 +0000 |
parents | bcd805923554 |
children | 00fff9a3b735 |
rev | line source |
---|---|
10751 | 1 /* |
2 * vf_tile.c - filter to tile a serie of image in a single, bigger, image | |
3 * | |
4 * The parameters are: | |
5 * | |
6 * xtile: number of tile on the x axis (5) | |
7 * ytile: number of tile on the y axis (5) | |
8 * xytile: when write the image, it can be different then xtile * ytile | |
9 * (for example you can write 8 * 7 tile, writing the file every | |
10 * 50 frame, to have one image every 2 seconds @ 25 fps ). | |
11 * start: pixel at the start (x/y), default 2 | |
12 * delta: pixel between 2 tile, (x/y), default 4 | |
13 * | |
14 * For example a valid command line is: | |
15 * ... -vf tile=10:5:-1:4:8 ... | |
16 * that make images of 10 * 5 tiles, with 4 pixel at the beginning and | |
17 * 8 pixel between tiles. | |
18 * | |
19 * The default command is: | |
20 * ... -vf tile=5:5:25:2:4 | |
21 * | |
22 * If you omit a parameter or put a value less then 0, the default is used. | |
23 * ... -vf tile=10:5::-1:10 | |
24 * | |
25 * You can also stop when you're ok | |
26 * ... -vf tile=10:5 | |
27 * (and this is probably the option you will use more often ...) | |
28 * | |
29 * Probably is good to put the scale filter before the tile :-) | |
30 * | |
31 * Daniele Forghieri ( guru@digitalfantasy.it ) | |
32 */ | |
33 | |
34 // strtoi memcpy_pic | |
35 | |
36 #include <stdio.h> | |
37 #include <stdlib.h> | |
38 #include <string.h> | |
39 | |
17012 | 40 #include "config.h" |
41 #include "mp_msg.h" | |
18004
bcd805923554
Part2 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu with LOTS of modifications by me
reynaldo
parents:
17969
diff
changeset
|
42 #include "help_mp.h" |
17012 | 43 #include "cpudetect.h" |
10751 | 44 |
45 #include "img_format.h" | |
46 #include "mp_image.h" | |
47 #include "vf.h" | |
48 | |
17012 | 49 #include "libvo/fastmemcpy.h" |
10751 | 50 |
51 /* private data */ | |
52 struct vf_priv_s { | |
53 /* configuration data */ | |
54 /* Number on hor/ver tiles */ | |
55 int xtile; | |
56 int ytile; | |
57 /* When write the whole frame (default = xtile * ytile) */ | |
58 int xytile; | |
59 /* pixel at start / end (default = 4) */ | |
60 int start; | |
61 /* pixel between image (default = 2) */ | |
62 int delta; | |
63 // /* Background color, in destination format */ | |
64 // int bkgSet; | |
65 | |
66 /* Work data */ | |
67 int frame_cur; | |
68 }; | |
69 | |
70 | |
71 static int config(struct vf_instance_s* vf, | |
72 int width, int height, int d_width, int d_height, | |
73 unsigned int flags, unsigned int outfmt){ | |
74 | |
75 struct vf_priv_s *priv; | |
76 int xw; | |
77 int yh; | |
78 | |
79 /* Calculate new destination size */ | |
80 priv = vf->priv; | |
81 xw = priv->start * 2 + | |
82 priv->xtile * width + | |
83 (priv->xtile - 1) * priv->delta; | |
84 yh = priv->start * 2 + | |
85 priv->ytile * height + | |
86 (priv->ytile - 1) * priv->delta; | |
87 | |
88 mp_msg(MSGT_VFILTER,MSGL_V,"vf_tile:config size set to %d * %d\n", xw, yh); | |
89 | |
90 return vf_next_config(vf, xw, yh, xw, yh, flags, outfmt); | |
91 } | |
92 | |
93 /* Filter handler */ | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17012
diff
changeset
|
94 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) |
10751 | 95 { |
96 mp_image_t *dmpi; | |
97 struct vf_priv_s *priv; | |
98 int t; | |
99 int xw; | |
100 int yh; | |
101 int xi; | |
102 int yi; | |
103 int by; | |
104 int dw; | |
105 | |
106 /* Calculate new size */ | |
107 priv = vf->priv; | |
108 xw = priv->start * 2 + | |
109 priv->xtile * mpi->w + | |
110 (priv->xtile - 1) * priv->delta; | |
111 yh = priv->start * 2 + | |
112 priv->ytile * mpi->h+ | |
113 (priv->ytile - 1) * priv->delta; | |
114 | |
115 /* Get the big image! */ | |
116 dmpi=vf_get_image(vf->next, mpi->imgfmt, | |
117 MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE, | |
118 xw, yh); | |
119 | |
120 /* bytes x pixel & bytes x line */ | |
121 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
122 by = 1; | |
123 dw = mpi->w; | |
124 } | |
125 else { | |
126 by = (mpi->bpp + 7) / 8; | |
127 dw = mpi->w * by; | |
128 } | |
129 /* Index position */ | |
130 t = priv->frame_cur % priv->xytile; | |
131 // if ((t == 0) && (bkg != 0)) { | |
132 // /* First frame, delete the background */ | |
133 // | |
134 // } | |
135 | |
136 /* Position of image */ | |
137 xi = priv->start + (mpi->w + priv->delta) * (t % priv->xtile); | |
138 yi = priv->start + (mpi->h + priv->delta) * (t / priv->xtile); | |
139 | |
140 /* Copy first (or only) plane */ | |
141 memcpy_pic( dmpi->planes[0] + xi * by + yi * dmpi->stride[0], | |
142 mpi->planes[0], | |
143 dw, | |
144 mpi->h, | |
145 dmpi->stride[0], | |
146 mpi->stride[0]); | |
147 | |
148 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
149 /* Copy the other 2 planes */ | |
150 memcpy_pic( dmpi->planes[1] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[1], | |
151 mpi->planes[1], | |
152 mpi->chroma_width, | |
153 mpi->chroma_height, | |
154 dmpi->stride[1], | |
155 mpi->stride[1]); | |
156 memcpy_pic( dmpi->planes[2] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[2], | |
157 mpi->planes[2], | |
158 mpi->chroma_width, | |
159 mpi->chroma_height, | |
160 dmpi->stride[2], | |
161 mpi->stride[2]); | |
162 } | |
163 | |
164 /* Increment current frame */ | |
165 ++priv->frame_cur; | |
166 | |
167 if (t == priv->xytile - 1) { | |
168 /* Display the composition */ | |
169 dmpi->width = xw; | |
170 dmpi->height = yh; | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17012
diff
changeset
|
171 return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); |
10751 | 172 } |
173 else { | |
174 /* Skip the frame */ | |
175 return(0); | |
176 } | |
177 } | |
178 | |
179 static void uninit(struct vf_instance_s* vf) | |
180 { | |
181 /* free local data */ | |
182 free(vf->priv); | |
183 } | |
184 | |
185 /* rgb/bgr 15->32 supported & some Yxxx */ | |
186 static int query_format(struct vf_instance_s* vf, unsigned int fmt) | |
187 { | |
188 switch (fmt) { | |
189 /* rgb 15 -> 32 bit */ | |
190 case IMGFMT_RGB15: | |
191 case IMGFMT_RGB16: | |
192 case IMGFMT_RGB24: | |
193 case IMGFMT_RGB32: | |
194 /* bgr 15 -> 32 bit */ | |
195 case IMGFMT_BGR15: | |
196 case IMGFMT_BGR16: | |
197 case IMGFMT_BGR24: | |
198 case IMGFMT_BGR32: | |
199 /* Various Yxxx Formats */ | |
200 case IMGFMT_444P: | |
201 case IMGFMT_422P: | |
202 case IMGFMT_411P: | |
203 case IMGFMT_YUY2: | |
204 case IMGFMT_YV12: | |
205 case IMGFMT_I420: | |
206 case IMGFMT_YVU9: | |
207 case IMGFMT_IF09: | |
208 case IMGFMT_IYUV: | |
209 return vf_next_query_format(vf, fmt); | |
210 } | |
211 return 0; | |
212 } | |
213 | |
214 /* Get an integer from the string pointed by s, adjusting s. | |
215 * If the value is less then 0 def_val is used. | |
216 * Return 0 for ok | |
217 * | |
218 * Look below ( in open(...) ) for a use ... | |
219 */ | |
220 static int parse_int(char **s, int *rt, int def_val) | |
221 { | |
222 | |
223 int t = 0; | |
224 | |
225 if (**s) { | |
226 /* Get value (dec, hex or octal) */ | |
227 t = strtol( *s, s, 0 ); | |
228 | |
229 /* Use default */ | |
230 if (t < 0) { | |
231 t = def_val; | |
232 } | |
233 | |
234 if (**s == ':') { | |
235 /* Point to next character (problably a digit) */ | |
236 ++(*s); | |
237 } | |
238 else if (**s != '\0') { | |
239 /* Error, we got some wrong char */ | |
240 return(1); | |
241 } | |
242 } | |
243 else { | |
244 t = def_val; | |
245 } | |
246 | |
247 *rt = t; | |
248 return(0); | |
249 | |
250 } | |
251 | |
252 /* Main entry funct for the filter */ | |
253 static int open(vf_instance_t *vf, char* args) | |
254 { | |
255 struct vf_priv_s *p; | |
256 int er; | |
257 | |
258 vf->put_image = put_image; | |
259 vf->query_format = query_format; | |
260 vf->config = config; | |
261 vf->uninit = uninit; | |
262 vf->default_reqs = VFCAP_ACCEPT_STRIDE; | |
263 /* Private data */ | |
264 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); | |
265 if (p == NULL) { | |
266 return(0); | |
267 } | |
268 | |
269 if (args == NULL) { | |
270 /* Use the default */ | |
271 args = ""; | |
272 } | |
273 /* Parse all the arguments */ | |
274 er = parse_int( &args, &p->xtile, 5 ); | |
275 er |= parse_int( &args, &p->ytile, 5 ); | |
276 er |= parse_int( &args, &p->xytile, 0 ); | |
277 er |= parse_int( &args, &p->start, 2 ); | |
278 er |= parse_int( &args, &p->delta, 4 ); | |
279 // er |= parse_int( &args, &p->bkgSet, 0 ); | |
280 | |
281 if (er) { | |
18004
bcd805923554
Part2 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu with LOTS of modifications by me
reynaldo
parents:
17969
diff
changeset
|
282 mp_msg(MSGT_VFILTER, MSGL_ERR, MSGTR_MPCODECS_ErrorParsingArgument); |
10751 | 283 return(0); |
284 } | |
285 /* Load some default */ | |
286 if ((p->xytile <= 0) || (p->xytile > p->xtile * p->ytile)) { | |
287 p->xytile = p->xtile * p->ytile; | |
288 } | |
289 | |
290 /* Say what happen: use mp_msg(...)? */ | |
17969
843e0427b5b9
Change 'if(verbose)' to the more appropriate mp_msg_test.
diego
parents:
17906
diff
changeset
|
291 if ( mp_msg_test(MSGT_VFILTER,MSGL_V) ) { |
10751 | 292 printf("vf_tile: tiling %d * %d, output every %d frames\n", |
293 p->xtile, | |
294 p->ytile, | |
295 p->xytile); | |
296 printf("vf_tile: start pixel %d, delta pixel %d\n", | |
297 p->start, | |
298 p->delta); | |
299 // printf("vf_tile: background 0x%x\n", | |
300 // p->bkgSet); | |
301 } | |
302 return 1; | |
303 } | |
304 | |
305 vf_info_t vf_info_tile = { | |
306 "Make a single image tiling x/y images", | |
307 "tile", | |
308 "Daniele Forghieri", | |
309 "", | |
310 open, | |
311 NULL | |
312 }; |