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",