[FFmpeg-devel,5/7] vf_crop: Add support for cropping hardware frames

Submitted by Mark Thompson on March 11, 2018, 10:41 p.m.

Details

Message ID 20180311224156.23986-5-sw@jkqxz.net
State New
Headers show

Commit Message

Mark Thompson March 11, 2018, 10:41 p.m.
Set the cropping fields in the AVFrame.
---
 libavfilter/vf_crop.c | 61 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 43 insertions(+), 18 deletions(-)

Comments

Mark Thompson March 18, 2018, 8:48 p.m.
On 11/03/18 22:41, Mark Thompson wrote:
> Set the cropping fields in the AVFrame.
> ---
>  libavfilter/vf_crop.c | 61 ++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 43 insertions(+), 18 deletions(-)
> 
> diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
> index 0fdc4949e3..0b1b8a048b 100644
> --- a/libavfilter/vf_crop.c
> +++ b/libavfilter/vf_crop.c
> @@ -98,9 +98,17 @@ static int query_formats(AVFilterContext *ctx)
>  
>      for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) {
>          const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
> -        if (!(desc->flags & (AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM)) &&
> -            !((desc->log2_chroma_w || desc->log2_chroma_h) && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) &&
> -            (ret = ff_add_format(&formats, fmt)) < 0)
> +        if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
> +            continue;
> +        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
> +            // Not usable if there is any subsampling but the format is
> +            // not planar (e.g. YUYV422).
> +            if ((desc->log2_chroma_w || desc->log2_chroma_h) &&
> +                !(desc->flags & AV_PIX_FMT_FLAG_PLANAR))
> +                continue;
> +        }
> +        ret = ff_add_format(&formats, fmt);
> +        if (ret < 0)
>              return ret;
>      }
>  
> @@ -157,8 +165,14 @@ static int config_input(AVFilterLink *link)
>      s->var_values[VAR_POS]   = NAN;
>  
>      av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc);
> -    s->hsub = pix_desc->log2_chroma_w;
> -    s->vsub = pix_desc->log2_chroma_h;
> +
> +    if (pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
> +        s->hsub = 1;
> +        s->vsub = 1;
> +    } else {
> +        s->hsub = pix_desc->log2_chroma_w;
> +        s->vsub = pix_desc->log2_chroma_h;
> +    }
>  
>      if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
>                                        var_names, s->var_values,
> @@ -285,22 +299,33 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
>              (int)s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
>              s->x, s->y, s->x+s->w, s->y+s->h);
>  
> -    frame->data[0] += s->y * frame->linesize[0];
> -    frame->data[0] += s->x * s->max_step[0];
> -
> -    if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
> -        for (i = 1; i < 3; i ++) {
> -            if (frame->data[i]) {
> -                frame->data[i] += (s->y >> s->vsub) * frame->linesize[i];
> -                frame->data[i] += (s->x * s->max_step[i]) >> s->hsub;
> +    if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
> +        frame->crop_top   += s->y;
> +        frame->crop_left  += s->x;
> +        frame->crop_bottom = frame->height - frame->crop_top - frame->crop_bottom - s->h;
> +        frame->crop_right  = frame->width  - frame->crop_left - frame->crop_right - s->w;
> +
> +    } else {
> +        frame->width  = s->w;
> +        frame->height = s->h;
> +
> +        frame->data[0] += s->y * frame->linesize[0];
> +        frame->data[0] += s->x * s->max_step[0];
> +
> +        if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
> +            for (i = 1; i < 3; i ++) {
> +                if (frame->data[i]) {
> +                    frame->data[i] += (s->y >> s->vsub) * frame->linesize[i];
> +                    frame->data[i] += (s->x * s->max_step[i]) >> s->hsub;
> +                }
>              }
>          }
> -    }
>  
> -    /* alpha plane */
> -    if (frame->data[3]) {
> -        frame->data[3] += s->y * frame->linesize[3];
> -        frame->data[3] += s->x * s->max_step[3];
> +        /* alpha plane */
> +        if (frame->data[3]) {
> +            frame->data[3] += s->y * frame->linesize[3];
> +            frame->data[3] += s->x * s->max_step[3];
> +        }
>      }
>  
>      return ff_filter_frame(link->dst->outputs[0], frame);
> 

Ping.

Patch hide | download patch | download mbox

diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 0fdc4949e3..0b1b8a048b 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -98,9 +98,17 @@  static int query_formats(AVFilterContext *ctx)
 
     for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
-        if (!(desc->flags & (AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM)) &&
-            !((desc->log2_chroma_w || desc->log2_chroma_h) && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) &&
-            (ret = ff_add_format(&formats, fmt)) < 0)
+        if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
+            continue;
+        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
+            // Not usable if there is any subsampling but the format is
+            // not planar (e.g. YUYV422).
+            if ((desc->log2_chroma_w || desc->log2_chroma_h) &&
+                !(desc->flags & AV_PIX_FMT_FLAG_PLANAR))
+                continue;
+        }
+        ret = ff_add_format(&formats, fmt);
+        if (ret < 0)
             return ret;
     }
 
@@ -157,8 +165,14 @@  static int config_input(AVFilterLink *link)
     s->var_values[VAR_POS]   = NAN;
 
     av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc);
-    s->hsub = pix_desc->log2_chroma_w;
-    s->vsub = pix_desc->log2_chroma_h;
+
+    if (pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
+        s->hsub = 1;
+        s->vsub = 1;
+    } else {
+        s->hsub = pix_desc->log2_chroma_w;
+        s->vsub = pix_desc->log2_chroma_h;
+    }
 
     if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
                                       var_names, s->var_values,
@@ -285,22 +299,33 @@  static int filter_frame(AVFilterLink *link, AVFrame *frame)
             (int)s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
             s->x, s->y, s->x+s->w, s->y+s->h);
 
-    frame->data[0] += s->y * frame->linesize[0];
-    frame->data[0] += s->x * s->max_step[0];
-
-    if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
-        for (i = 1; i < 3; i ++) {
-            if (frame->data[i]) {
-                frame->data[i] += (s->y >> s->vsub) * frame->linesize[i];
-                frame->data[i] += (s->x * s->max_step[i]) >> s->hsub;
+    if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
+        frame->crop_top   += s->y;
+        frame->crop_left  += s->x;
+        frame->crop_bottom = frame->height - frame->crop_top - frame->crop_bottom - s->h;
+        frame->crop_right  = frame->width  - frame->crop_left - frame->crop_right - s->w;
+
+    } else {
+        frame->width  = s->w;
+        frame->height = s->h;
+
+        frame->data[0] += s->y * frame->linesize[0];
+        frame->data[0] += s->x * s->max_step[0];
+
+        if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
+            for (i = 1; i < 3; i ++) {
+                if (frame->data[i]) {
+                    frame->data[i] += (s->y >> s->vsub) * frame->linesize[i];
+                    frame->data[i] += (s->x * s->max_step[i]) >> s->hsub;
+                }
             }
         }
-    }
 
-    /* alpha plane */
-    if (frame->data[3]) {
-        frame->data[3] += s->y * frame->linesize[3];
-        frame->data[3] += s->x * s->max_step[3];
+        /* alpha plane */
+        if (frame->data[3]) {
+            frame->data[3] += s->y * frame->linesize[3];
+            frame->data[3] += s->x * s->max_step[3];
+        }
     }
 
     return ff_filter_frame(link->dst->outputs[0], frame);