Mercurial > mplayer.hg
comparison libmpcodecs/vf_delogo.c @ 33400:f18abad8054c
vf_delogo: allow to change the rectangle based on the time
author | cigaes |
---|---|
date | Mon, 23 May 2011 16:32:14 +0000 |
parents | 7af3e6f901fd |
children | f055dbc340f6 |
comparison
equal
deleted
inserted
replaced
33399:38aca587c55c | 33400:f18abad8054c |
---|---|
22 | 22 |
23 #include <stdio.h> | 23 #include <stdio.h> |
24 #include <stdlib.h> | 24 #include <stdlib.h> |
25 #include <string.h> | 25 #include <string.h> |
26 #include <inttypes.h> | 26 #include <inttypes.h> |
27 #include <limits.h> | |
28 #include <errno.h> | |
27 #include <math.h> | 29 #include <math.h> |
28 | 30 |
29 #include "mp_msg.h" | 31 #include "mp_msg.h" |
30 #include "cpudetect.h" | 32 #include "cpudetect.h" |
31 #include "img_format.h" | 33 #include "img_format.h" |
39 //===========================================================================// | 41 //===========================================================================// |
40 | 42 |
41 static struct vf_priv_s { | 43 static struct vf_priv_s { |
42 unsigned int outfmt; | 44 unsigned int outfmt; |
43 int xoff, yoff, lw, lh, band, show; | 45 int xoff, yoff, lw, lh, band, show; |
46 const char *file; | |
47 struct timed_rectangle { | |
48 int ts, x, y, w, h, b; | |
49 } *timed_rect; | |
50 int n_timed_rect; | |
51 int cur_timed_rect; | |
44 } const vf_priv_dflt = { | 52 } const vf_priv_dflt = { |
45 0, | 53 0, |
46 0, 0, 0, 0, 0, 0 | 54 0, 0, 0, 0, 0, 0, |
55 NULL, NULL, 0, 0, | |
47 }; | 56 }; |
48 | 57 |
49 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | 58 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) |
50 #define MAX(a,b) (((a) > (b)) ? (a) : (b)) | 59 #define MAX(a,b) (((a) > (b)) ? (a) : (b)) |
60 | |
61 /** | |
62 * Adjust the coordinates to suit the band width | |
63 * Also print a notice in verbose mode | |
64 */ | |
65 static void fix_band(struct vf_priv_s *p) | |
66 { | |
67 p->show = 0; | |
68 if (p->band < 0) { | |
69 p->band = 4; | |
70 p->show = 1; | |
71 } | |
72 p->lw += p->band*2; | |
73 p->lh += p->band*2; | |
74 p->xoff -= p->band; | |
75 p->yoff -= p->band; | |
76 mp_msg(MSGT_VFILTER, MSGL_V, "delogo: %d x %d, %d x %d, band = %d\n", | |
77 p->xoff, p->yoff, p->lw, p->lh, p->band); | |
78 } | |
79 | |
80 static void update_sub(struct vf_priv_s *p, double pts) | |
81 { | |
82 int ipts = pts * 1000; | |
83 int tr = p->cur_timed_rect; | |
84 while (tr < p->n_timed_rect - 1 && ipts >= p->timed_rect[tr + 1].ts) | |
85 tr++; | |
86 while (tr >= 0 && ipts < p->timed_rect[tr].ts) | |
87 tr--; | |
88 if (tr == p->cur_timed_rect) | |
89 return; | |
90 p->cur_timed_rect = tr; | |
91 if (tr >= 0) { | |
92 p->xoff = p->timed_rect[tr].x; | |
93 p->yoff = p->timed_rect[tr].y; | |
94 p->lw = p->timed_rect[tr].w; | |
95 p->lh = p->timed_rect[tr].h; | |
96 p->band = p->timed_rect[tr].b; | |
97 } else { | |
98 p->xoff = p->yoff = p->lw = p->lh = p->band = 0; | |
99 } | |
100 fix_band(p); | |
101 } | |
51 | 102 |
52 static void delogo(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height, | 103 static void delogo(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height, |
53 int logo_x, int logo_y, int logo_w, int logo_h, int band, int show, int direct) { | 104 int logo_x, int logo_y, int logo_w, int logo_h, int band, int show, int direct) { |
54 int y, x; | 105 int y, x; |
55 int interp, dist; | 106 int interp, dist; |
152 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | 203 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, |
153 mpi->w,mpi->h); | 204 mpi->w,mpi->h); |
154 } | 205 } |
155 dmpi= vf->dmpi; | 206 dmpi= vf->dmpi; |
156 | 207 |
208 if (vf->priv->timed_rect) | |
209 update_sub(vf->priv, pts); | |
157 delogo(dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, | 210 delogo(dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, |
158 vf->priv->xoff, vf->priv->yoff, vf->priv->lw, vf->priv->lh, vf->priv->band, vf->priv->show, | 211 vf->priv->xoff, vf->priv->yoff, vf->priv->lw, vf->priv->lh, vf->priv->band, vf->priv->show, |
159 mpi->flags&MP_IMGFLAG_DIRECT); | 212 mpi->flags&MP_IMGFLAG_DIRECT); |
160 delogo(dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2, | 213 delogo(dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2, |
161 vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show, | 214 vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show, |
194 IMGFMT_I420, | 247 IMGFMT_I420, |
195 IMGFMT_IYUV, | 248 IMGFMT_IYUV, |
196 0 | 249 0 |
197 }; | 250 }; |
198 | 251 |
252 static int load_timed_rectangles(struct vf_priv_s *delogo) | |
253 { | |
254 FILE *f; | |
255 char line[LINE_MAX]; | |
256 int lineno = 0, p; | |
257 double ts, last_ts = 0; | |
258 struct timed_rectangle *rect = NULL, *nr; | |
259 int n_rect = 0, alloc_rect = 0; | |
260 | |
261 f = fopen(delogo->file, "r"); | |
262 if (!f) { | |
263 mp_msg(MSGT_VFILTER, MSGL_ERR, "delogo: unable to load %s: %s\n", | |
264 delogo->file, strerror(errno)); | |
265 return -1; | |
266 } | |
267 while (fgets(line, sizeof(line), f)) { | |
268 lineno++; | |
269 if (*line == '#' || *line == '\n') | |
270 continue; | |
271 if (n_rect == alloc_rect) { | |
272 if (alloc_rect > INT_MAX / 2 / (int)sizeof(*rect)) { | |
273 mp_msg(MSGT_VFILTER, MSGL_WARN, | |
274 "delogo: too many rectangles\n"); | |
275 goto load_error; | |
276 } | |
277 alloc_rect = alloc_rect ? 2 * alloc_rect : 256; | |
278 nr = realloc(rect, alloc_rect * sizeof(*rect)); | |
279 if (!nr) { | |
280 mp_msg(MSGT_VFILTER, MSGL_WARN, "delogo: out of memory\n"); | |
281 goto load_error; | |
282 } | |
283 rect = nr; | |
284 } | |
285 nr = rect + n_rect; | |
286 memset(nr, 0, sizeof(*nr)); | |
287 p = sscanf(line, "%lf %d:%d:%d:%d:%d", | |
288 &ts, &nr->x, &nr->y, &nr->w, &nr->h, &nr->b); | |
289 if ((p == 2 && !nr->x) || p == 5 || p == 6) { | |
290 if (ts <= last_ts) | |
291 mp_msg(MSGT_VFILTER, MSGL_WARN, "delogo: %s:%d: wrong time\n", | |
292 delogo->file, lineno); | |
293 nr->ts = 1000 * ts + 0.5; | |
294 n_rect++; | |
295 } else { | |
296 mp_msg(MSGT_VFILTER, MSGL_WARN, "delogo: %s:%d: syntax error\n", | |
297 delogo->file, lineno); | |
298 } | |
299 } | |
300 fclose(f); | |
301 if (!n_rect) { | |
302 mp_msg(MSGT_VFILTER, MSGL_ERR, "delogo: %s: no rectangles found\n", | |
303 delogo->file); | |
304 free(rect); | |
305 return -1; | |
306 } | |
307 nr = realloc(rect, n_rect * sizeof(*rect)); | |
308 if (nr) | |
309 rect = nr; | |
310 delogo->timed_rect = rect; | |
311 delogo->n_timed_rect = n_rect; | |
312 return 0; | |
313 | |
314 load_error: | |
315 free(rect); | |
316 fclose(f); | |
317 return -1; | |
318 } | |
319 | |
199 static int vf_open(vf_instance_t *vf, char *args){ | 320 static int vf_open(vf_instance_t *vf, char *args){ |
200 vf->config=config; | 321 vf->config=config; |
201 vf->put_image=put_image; | 322 vf->put_image=put_image; |
202 vf->get_image=get_image; | 323 vf->get_image=get_image; |
203 vf->query_format=query_format; | 324 vf->query_format=query_format; |
204 vf->uninit=uninit; | 325 vf->uninit=uninit; |
205 | 326 |
206 mp_msg(MSGT_VFILTER, MSGL_V, "delogo: %d x %d, %d x %d, band = %d\n", | 327 if (vf->priv->file) { |
207 vf->priv->xoff, vf->priv->yoff, | 328 if (load_timed_rectangles(vf->priv)) |
208 vf->priv->lw, vf->priv->lh, | 329 return 0; |
209 vf->priv->band); | 330 mp_msg(MSGT_VFILTER, MSGL_V, "delogo: %d from %s\n", |
210 | 331 vf->priv->n_timed_rect, vf->priv->file); |
211 vf->priv->show = 0; | 332 vf->priv->cur_timed_rect = -1; |
212 | 333 } |
213 if (vf->priv->band < 0) { | 334 fix_band(vf->priv); |
214 vf->priv->band = 4; | |
215 vf->priv->show = 1; | |
216 } | |
217 | |
218 | |
219 vf->priv->lw += vf->priv->band*2; | |
220 vf->priv->lh += vf->priv->band*2; | |
221 vf->priv->xoff -= vf->priv->band; | |
222 vf->priv->yoff -= vf->priv->band; | |
223 | 335 |
224 // check csp: | 336 // check csp: |
225 vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12); | 337 vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12); |
226 if(!vf->priv->outfmt) | 338 if(!vf->priv->outfmt) |
227 { | 339 { |
238 { "y", ST_OFF(yoff), CONF_TYPE_INT, 0, 0, 0, NULL }, | 350 { "y", ST_OFF(yoff), CONF_TYPE_INT, 0, 0, 0, NULL }, |
239 { "w", ST_OFF(lw), CONF_TYPE_INT, 0, 0, 0, NULL }, | 351 { "w", ST_OFF(lw), CONF_TYPE_INT, 0, 0, 0, NULL }, |
240 { "h", ST_OFF(lh), CONF_TYPE_INT, 0, 0, 0, NULL }, | 352 { "h", ST_OFF(lh), CONF_TYPE_INT, 0, 0, 0, NULL }, |
241 { "t", ST_OFF(band), CONF_TYPE_INT, 0, 0, 0, NULL }, | 353 { "t", ST_OFF(band), CONF_TYPE_INT, 0, 0, 0, NULL }, |
242 { "band", ST_OFF(band), CONF_TYPE_INT, 0, 0, 0, NULL }, // alias | 354 { "band", ST_OFF(band), CONF_TYPE_INT, 0, 0, 0, NULL }, // alias |
355 { "file", ST_OFF(file), CONF_TYPE_STRING, 0, 0, 0, NULL }, | |
243 { NULL, NULL, 0, 0, 0, 0, NULL } | 356 { NULL, NULL, 0, 0, 0, 0, NULL } |
244 }; | 357 }; |
245 | 358 |
246 static const m_struct_t vf_opts = { | 359 static const m_struct_t vf_opts = { |
247 "delogo", | 360 "delogo", |