[FFmpeg-devel] [PATCH v4] libavfilter/vf_cover_rect: support for cover image with more pixel format and different width and height

Michael Niedermayer michael at niedermayer.cc
Fri Jun 14 12:31:12 EEST 2019


On Wed, Jun 12, 2019 at 06:50:18PM +0800, lance.lmwang at gmail.com wrote:
> From: Limin Wang <lance.lmwang at gmail.com>
> 
> Signed-off-by: Limin Wang <lance.lmwang at gmail.com>
> ---
>  doc/filters.texi            |  6 ++--
>  libavfilter/vf_cover_rect.c | 56 +++++++++++++++++++++++++++----------
>  2 files changed, 44 insertions(+), 18 deletions(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index ec1c7c7591..4594a61c13 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -10166,7 +10166,7 @@ Specifies the rectangle in which to search.
>  
>  @itemize
>  @item
> -Generate a representative palette of a given video using @command{ffmpeg}:
> +Cover a rectangular object by the supplied image of a given video using @command{ffmpeg}:
>  @example
>  ffmpeg -i file.ts -vf find_rect=newref.pgm,cover_rect=cover.jpg:mode=cover new.mkv
>  @end example
> @@ -10180,7 +10180,7 @@ It accepts the following options:
>  
>  @table @option
>  @item cover
> -Filepath of the optional cover image, needs to be in yuv420.
> +Filepath of the optional cover image.
>  
>  @item mode
>  Set covering mode.
> @@ -10200,7 +10200,7 @@ Default value is @var{blur}.
>  
>  @itemize
>  @item
> -Generate a representative palette of a given video using @command{ffmpeg}:
> +Cover a rectangular object by the supplied image of a given video using @command{ffmpeg}:
>  @example
>  ffmpeg -i file.ts -vf find_rect=newref.pgm,cover_rect=cover.jpg:mode=cover new.mkv
>  @end example
> diff --git a/libavfilter/vf_cover_rect.c b/libavfilter/vf_cover_rect.c
> index 898debf09d..36c650dd21 100644
> --- a/libavfilter/vf_cover_rect.c
> +++ b/libavfilter/vf_cover_rect.c
> @@ -28,6 +28,7 @@
>  #include "internal.h"
>  
>  #include "lavfutils.h"
> +#include "lswsutils.h"
>  
>  enum mode {
>      MODE_COVER,
> @@ -40,6 +41,7 @@ typedef struct CoverContext {
>      int mode;
>      char *cover_filename;
>      AVFrame *cover_frame;
> +    AVFrame *match_frame;
>      int width, height;
>  } CoverContext;
>  

> @@ -71,21 +73,21 @@ static int config_input(AVFilterLink *inlink)
>      return 0;
>  }
>  
> -static void cover_rect(CoverContext *cover, AVFrame *in, int offx, int offy)
> +static void cover_rect(AVFrame *cover_frame, AVFrame *in, int offx, int offy)
>  {
>      int x, y, p;
>  
>      for (p = 0; p < 3; p++) {
>          uint8_t *data = in->data[p] + (offx>>!!p) + (offy>>!!p) * in->linesize[p];
> -        const uint8_t *src = cover->cover_frame->data[p];
> -        int w = AV_CEIL_RSHIFT(cover->cover_frame->width , !!p);
> -        int h = AV_CEIL_RSHIFT(cover->cover_frame->height, !!p);
> +        const uint8_t *src = cover_frame->data[p];
> +        int w = AV_CEIL_RSHIFT(cover_frame->width , !!p);
> +        int h = AV_CEIL_RSHIFT(cover_frame->height, !!p);
>          for (y = 0; y < h; y++) {
>              for (x = 0; x < w; x++) {
>                  data[x] = src[x];
>              }
>              data += in->linesize[p];
> -            src += cover->cover_frame->linesize[p];
> +            src += cover_frame->linesize[p];
>          }
>      }
>  }

This hunk is independant and can be done in a seperate patch before


> @@ -138,7 +140,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>      CoverContext *cover = ctx->priv;
>      AVDictionaryEntry *ex, *ey, *ew, *eh;
>      int x = -1, y = -1, w = -1, h = -1;
> +    enum AVPixelFormat in_format;
>      char *xendptr = NULL, *yendptr = NULL, *wendptr = NULL, *hendptr = NULL;
> +    AVFrame *cover_frame = NULL;
> +    int ret;
>  
>      ex = av_dict_get(in->metadata, "lavfi.rect.x", NULL, AV_DICT_MATCH_CASE);
>      ey = av_dict_get(in->metadata, "lavfi.rect.y", NULL, AV_DICT_MATCH_CASE);

> @@ -167,14 +172,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>      }
>      w = FFMIN(w, in->width  - x);
>      h = FFMIN(h, in->height - y);
> +    in_format = in->format;
>  
>      if (w > in->width || h > in->height || w <= 0 || h <= 0)
>          return AVERROR(EINVAL);
>  
> -    if (cover->cover_frame) {
> -        if (w != cover->cover_frame->width || h != cover->cover_frame->height)
> -            return AVERROR(EINVAL);
> -    }
> +    if (w != cover->cover_frame->width || h != cover->cover_frame->height ||
> +            in_format != cover->cover_frame->format) {

This segfaults


> +        if (!cover->match_frame || (w != cover->match_frame->width || h != cover->match_frame->height
> +                    || in_format != cover->match_frame->format)) {
> +            if (cover->match_frame)
> +                av_freep(&cover->match_frame->data[0]);
> +            else if (!(cover->match_frame = av_frame_alloc()))
> +                return AVERROR(ENOMEM);
> +

> +            if ((ret = ff_scale_image(cover->match_frame->data, cover->match_frame->linesize,
> +                            w, h, in_format, cover->cover_frame->data, cover->cover_frame->linesize,
> +                            cover->cover_frame->width, cover->cover_frame->height,
> +                            cover->cover_frame->format, ctx)) < 0)
> +                return AVERROR(ENOMEM);

This sort of reimplements the scale filter and it
doesnt consider some parameters like AVCOL_RANGE*

Thanks

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Awnsering whenever a program halts or runs forever is
On a turing machine, in general impossible (turings halting problem).
On any real computer, always possible as a real computer has a finite number
of states N, and will either halt in less than N cycles or never halt.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20190614/7528a1d5/attachment.sig>


More information about the ffmpeg-devel mailing list