]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vf_displace.c
Merge commit '3ad825793a43253154bed05827f27425fc0757df'
[ffmpeg] / libavfilter / vf_displace.c
index 9daa0c9ddba89c6b1c4dfc19fc72bf4835d6b33d..768af6def478df448c7a028c55421b8f2280cb4e 100644 (file)
@@ -31,6 +31,7 @@ enum EdgeMode {
     EDGE_BLANK,
     EDGE_SMEAR,
     EDGE_WRAP,
+    EDGE_MIRROR,
     EDGE_NB
 };
 
@@ -53,9 +54,10 @@ typedef struct DisplaceContext {
 
 static const AVOption displace_options[] = {
     { "edge", "set edge mode", OFFSET(edge), AV_OPT_TYPE_INT, {.i64=EDGE_SMEAR}, 0, EDGE_NB-1, FLAGS, "edge" },
-    {   "blank", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_BLANK}, 0, 0, FLAGS, "edge" },
-    {   "smear", "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_SMEAR}, 0, 0, FLAGS, "edge" },
-    {   "wrap" , "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_WRAP},  0, 0, FLAGS, "edge" },
+    {   "blank",   "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_BLANK},  0, 0, FLAGS, "edge" },
+    {   "smear",   "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_SMEAR},  0, 0, FLAGS, "edge" },
+    {   "wrap" ,   "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_WRAP},   0, 0, FLAGS, "edge" },
+    {   "mirror" , "", 0, AV_OPT_TYPE_CONST, {.i64=EDGE_MIRROR}, 0, 0, FLAGS, "edge" },
     { NULL }
 };
 
@@ -130,6 +132,22 @@ static void displace_planar(DisplaceContext *s, const AVFrame *in,
                     dst[x] = src[Y * slinesize + X];
                 }
                 break;
+            case EDGE_MIRROR:
+                for (x = 0; x < w; x++) {
+                    int Y = y + ysrc[x] - 128;
+                    int X = x + xsrc[x] - 128;
+
+                    if (Y < 0)
+                        Y = (-Y) % h;
+                    if (X < 0)
+                        X = (-X) % w;
+                    if (Y >= h)
+                        Y = h - (Y % h) - 1;
+                    if (X >= w)
+                        X = w - (X % w) - 1;
+                    dst[x] = src[Y * slinesize + X];
+                }
+                break;
             }
 
             ysrc += ylinesize;
@@ -196,6 +214,24 @@ static void displace_packed(DisplaceContext *s, const AVFrame *in,
                 }
             }
             break;
+        case EDGE_MIRROR:
+            for (x = 0; x < w; x++) {
+                for (c = 0; c < s->nb_components; c++) {
+                    int Y = y + ysrc[x * step + c] - 128;
+                    int X = x + xsrc[x * step + c] - 128;
+
+                    if (Y < 0)
+                        Y = (-Y) % h;
+                    if (X < 0)
+                        X = (-X) % w;
+                    if (Y >= h)
+                        Y = h - (Y % h) - 1;
+                    if (X >= w)
+                        X = w - (X % w) - 1;
+                    dst[x * step + c] = src[Y * slinesize + X * step + c];
+                }
+            }
+            break;
         }
 
         ysrc += ylinesize;
@@ -280,27 +316,17 @@ static int config_output(AVFilterLink *outlink)
         av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n");
         return AVERROR(EINVAL);
     }
-    if (srclink->w                       != xlink->w ||
-        srclink->h                       != xlink->h ||
-        srclink->sample_aspect_ratio.num != xlink->sample_aspect_ratio.num ||
-        srclink->sample_aspect_ratio.den != xlink->sample_aspect_ratio.den ||
-        srclink->w                       != ylink->w ||
-        srclink->h                       != ylink->h ||
-        srclink->sample_aspect_ratio.num != ylink->sample_aspect_ratio.num ||
-        srclink->sample_aspect_ratio.den != ylink->sample_aspect_ratio.den) {
+    if (srclink->w != xlink->w ||
+        srclink->h != xlink->h ||
+        srclink->w != ylink->w ||
+        srclink->h != ylink->h) {
         av_log(ctx, AV_LOG_ERROR, "First input link %s parameters "
-               "(size %dx%d, SAR %d:%d) do not match the corresponding "
-               "second input link %s parameters (%dx%d, SAR %d:%d) "
-               "and/or third input link %s parameters (%dx%d, SAR %d:%d)\n",
+               "(size %dx%d) do not match the corresponding "
+               "second input link %s parameters (%dx%d) "
+               "and/or third input link %s parameters (%dx%d)\n",
                ctx->input_pads[0].name, srclink->w, srclink->h,
-               srclink->sample_aspect_ratio.num,
-               srclink->sample_aspect_ratio.den,
                ctx->input_pads[1].name, xlink->w, xlink->h,
-               xlink->sample_aspect_ratio.num,
-               xlink->sample_aspect_ratio.den,
-               ctx->input_pads[2].name, ylink->w, ylink->h,
-               ylink->sample_aspect_ratio.num,
-               ylink->sample_aspect_ratio.den);
+               ctx->input_pads[2].name, ylink->w, ylink->h);
         return AVERROR(EINVAL);
     }
 
@@ -333,16 +359,10 @@ static int config_output(AVFilterLink *outlink)
     return ff_framesync_configure(&s->fs);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
+static int activate(AVFilterContext *ctx)
 {
-    DisplaceContext *s = inlink->dst->priv;
-    return ff_framesync_filter_frame(&s->fs, inlink, buf);
-}
-
-static int request_frame(AVFilterLink *outlink)
-{
-    DisplaceContext *s = outlink->src->priv;
-    return ff_framesync_request_frame(&s->fs, outlink);
+    DisplaceContext *s = ctx->priv;
+    return ff_framesync_activate(&s->fs);
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
@@ -356,18 +376,15 @@ static const AVFilterPad displace_inputs[] = {
     {
         .name         = "source",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .filter_frame = filter_frame,
         .config_props = config_input,
     },
     {
         .name         = "xmap",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .filter_frame = filter_frame,
     },
     {
         .name         = "ymap",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .filter_frame = filter_frame,
     },
     { NULL }
 };
@@ -377,7 +394,6 @@ static const AVFilterPad displace_outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
-        .request_frame = request_frame,
     },
     { NULL }
 };
@@ -388,6 +404,7 @@ AVFilter ff_vf_displace = {
     .priv_size     = sizeof(DisplaceContext),
     .uninit        = uninit,
     .query_formats = query_formats,
+    .activate      = activate,
     .inputs        = displace_inputs,
     .outputs       = displace_outputs,
     .priv_class    = &displace_class,