[FFmpeg-devel] [PATCH] vf_delogo: allow to change the rectangle based on the time

Stefano Sabatini stefano.sabatini-lala at poste.it
Sat Aug 20 20:37:16 CEST 2011


On date Saturday 2011-08-20 14:17:48 +0200, Nicolas George encoded:
> Thanks for the review.
[...]
> From fc783354adf03019df7a685e3d433b502d481e88 Mon Sep 17 00:00:00 2001
> From: Nicolas George <nicolas.george at normalesup.org>
> Date: Mon, 15 Aug 2011 15:10:57 +0200
> Subject: [PATCH] vf_delogo: allow to change the rectangle based on the time.
> 
> This is a port of MPlayer's commit 33488.
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
>  doc/filters.texi        |   21 +++++++
>  libavfilter/vf_delogo.c |  143 +++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 152 insertions(+), 12 deletions(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index ce7d064..2638aca 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -470,6 +470,13 @@ When set to 1, a green rectangle is drawn on the screen to simplify
>  finding the right @var{x}, @var{y}, @var{w}, @var{h} parameters, and
>  @var{band} is set to 4. The default value is 0.
>  
> + at item file
> +Read timestamps and coordinates from @var{file}. @var{file} is a text file
> +with on each line a timestamp (in seconds and in ascending order) and the
> +x:y:w:h:band coordinates (band can be omitted), or just 0.
> +Empty lines and lines beginning with "#" are ignored.
> +If this option is present, the other options are ignored.
> +
>  @end table
>  
>  Some examples follow.
> @@ -489,6 +496,20 @@ As the previous example, but use named options:
>  delogo=x=0:y=0:w=100:h=77:band=10
>  @end example
>  
> + at item
> +As the previous example, but only remove the logo from time 5s to time 10s
> +and from time 1800s to time 1805s:
> + at example
> +delogo=file=top_left_5s.txt
> + at end example
> + at code{top_left_5s.txt} contains:
> + at example
> +5    0:0:100:77:10
> +10   0
> +1800 0:0:100:77:10
> +1805 0
> + at end example
> +
>  @end itemize
>  
>  @section drawbox
> diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
> index f0852f8..35b1792 100644
> --- a/libavfilter/vf_delogo.c
> +++ b/libavfilter/vf_delogo.c
> @@ -133,6 +133,13 @@ static void apply_delogo(uint8_t *dst, int dst_linesize,
>  typedef struct {
>      const AVClass *class;
>      int x, y, w, h, band, show;
> +    const char *file;
> +    struct timed_rectangle {
> +        double ts;
> +        int x, y, w, h, b;
> +    } *timed_rects;
> +    int nb_timed_rects;
> +    int cur_timed_rect;
>  }  DelogoContext;
>  
>  #define OFFSET(x) offsetof(DelogoContext, x)
> @@ -145,6 +152,7 @@ static const AVOption delogo_options[]= {
>      {"band", "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, {.dbl= 4}, -1, INT_MAX },
>      {"t",    "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, {.dbl= 4}, -1, INT_MAX },
>      {"show", "show delogo area",          OFFSET(show), FF_OPT_TYPE_INT, {.dbl= 0},  0, 1       },
> +    {"file", "read times and coordinates from a file", OFFSET(file), FF_OPT_TYPE_STRING, {.str= NULL}, 0, 0 },
>      {NULL},
>  };
>  
> @@ -172,6 +180,108 @@ static int query_formats(AVFilterContext *ctx)
>      return 0;
>  }
>  
> +static void fix_band(DelogoContext *delogo, int show)
> +{
> +    delogo->show = show || delogo->band < 0;
> +    if (delogo->show)
> +        delogo->band = 4;
> +    delogo->w += delogo->band*2;
> +    delogo->h += delogo->band*2;
> +    delogo->x -= delogo->band;
> +    delogo->y -= delogo->band;
> +}
> +
> +static void update_rectangle(DelogoContext *p, double pts)
> +{
> +    int tr = p->cur_timed_rect;
> +    while (tr < p->nb_timed_rects - 1 && pts >= p->timed_rects[tr + 1].ts)
> +        tr++;
> +    while (tr >= 0 && pts < p->timed_rects[tr].ts)
> +        tr--;
> +    if (tr == p->cur_timed_rect)
> +        return;
> +    p->cur_timed_rect = tr;
> +    if (tr >= 0) {
> +        p->x    = p->timed_rects[tr].x;
> +        p->y    = p->timed_rects[tr].y;
> +        p->w    = p->timed_rects[tr].w;
> +        p->h    = p->timed_rects[tr].h;
> +        p->band = p->timed_rects[tr].b;
> +    } else {
> +        p->x = p->y = p->w = p->h = p->band = 0;
> +    }
> +    fix_band(p, 0);
> +}
> +
> +static int load_timed_rectangles(AVFilterContext *ctx, DelogoContext *delogo)
> +{
> +    FILE *f;
> +    char line[2048];
> +    int lineno = 0, n_fields;
> +    double ts, last_ts = 0;
> +    struct timed_rectangle *rects = NULL, *nr;
> +    int nb_rects = 0, nb_alloc_rects = 0;
> +    int error = AVERROR(EINVAL);
> +
> +    f = fopen(delogo->file, "r");
> +    if (!f) {

> +        av_log(ctx, AV_LOG_ERROR, "unable to load %s: %s\n",
> +            delogo->file, strerror(errno));

Nit: "Could not load file '%s': %s\n"
weird indent

> +        return AVERROR(errno);
> +    }
> +    while (fgets(line, sizeof(line), f)) {
> +        lineno++;
> +        if (*line == '#' || *line == '\n')
> +            continue;

> +        if (nb_rects == nb_alloc_rects) {
> +            if (nb_alloc_rects > INT_MAX / 2 / (int)sizeof(*rects)) {

> +                error = AVERROR(errno);

why?
=> AVERROR(EINVAL)

> +                av_log(ctx, AV_LOG_ERROR, "too many rectangles\n");

Nit+: "Too many ..."

> +                goto load_error;
> +            }
> +            nb_alloc_rects = nb_alloc_rects ? 2 * nb_alloc_rects : 256;
> +            nr = av_realloc(rects, nb_alloc_rects * sizeof(*rects));

> +            if (!nr) {
> +                error = AVERROR(errno);

shouldn't this be AVERROR(ENOMEM)?

> +                av_log(ctx, AV_LOG_ERROR, "out of memory\n");
> +                goto load_error;


> +            }
> +            rects = nr;
> +        }
> +        nr = rects + nb_rects;
> +        memset(nr, 0, sizeof(*nr));
> +        n_fields = sscanf(line, "%lf %d:%d:%d:%d:%d",
> +                   &ts, &nr->x, &nr->y, &nr->w, &nr->h, &nr->b);
> +        if ((n_fields == 2 && !nr->x) || n_fields == 5 || n_fields == 6) {
> +            if (ts <= last_ts)
> +                av_log(ctx, AV_LOG_ERROR,
> +                       "%s:%d: invalid time, time %f is less than "
> +                       "time %f in the previous line\n",
> +                       delogo->file, lineno, ts, last_ts);
> +            nr->ts = ts;
> +            nb_rects++;
> +        } else {
> +            av_log(ctx, AV_LOG_ERROR, "%s:%d: syntax error\n",
> +                   delogo->file, lineno);
> +        }
> +    }
> +    fclose(f);

> +    if (!nb_rects) {
> +        av_log(ctx, AV_LOG_ERROR, "%s: no rectangles found\n", delogo->file);

Nit++: No rectangles specified in '%s'\b

> +        av_free(rects);
> +        return AVERROR(EINVAL);
> +    }
> +    nr = av_realloc(rects, nb_rects * sizeof(*rects));
> +    delogo->timed_rects    = nr ? nr : rects;
> +    delogo->nb_timed_rects = nb_rects;
> +    return 0;
> +
> +load_error:
> +    av_free(rects);
> +    fclose(f);
> +    return error;
> +}
> +
>  static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
>  {
>      DelogoContext *delogo = ctx->priv;
> @@ -183,14 +293,19 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
>      if (args)
>          ret = sscanf(args, "%d:%d:%d:%d:%d",
>                       &delogo->x, &delogo->y, &delogo->w, &delogo->h, &delogo->band);
> -    if (ret == 5) {
> -        if (delogo->band < 0)
> -            delogo->show = 1;
> -    } else if ((ret = (av_set_options_string(delogo, args, "=", ":"))) < 0) {
> +    if (ret != 5 &&
> +        (ret = (av_set_options_string(delogo, args, "=", ":"))) < 0) {
>          av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
>          return ret;
>      }
>  
> +    if (delogo->file) {
> +        if ((ret = load_timed_rectangles(ctx, delogo)) < 0)
> +            return ret;

> +        av_log(ctx, AV_LOG_INFO, "%d from %s\n",
> +            delogo->nb_timed_rects, delogo->file);

Nit: Read %d rectangles from file '%s'\n

[...]

Also remember to bump micro when committing (added feature, extended
interface).

Looks fine otherwise, thanks.
-- 
FFmpeg = Fast and Fierce MultiPurpose Erudite Governor


More information about the ffmpeg-devel mailing list