avfilter/af_sofalizer: speed up fast convolution
[ffmpeg.git] / libavfilter / vf_vectorscope.c
index 2696a12..e3e0079 100644 (file)
@@ -62,8 +62,10 @@ typedef struct VectorscopeContext {
     int tmin;
     int tmax;
     int flags;
+    int colorspace;
     int cs;
-    uint8_t peak[4096][4096];
+    uint8_t *peak_memory;
+    uint8_t **peak;
 
     void (*vectorscope)(struct VectorscopeContext *s,
                         AVFrame *in, AVFrame *out, int pd);
@@ -111,6 +113,11 @@ static const AVOption vectorscope_options[] = {
     { "l",          "set low threshold",  OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS},
     { "hthreshold", "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
     { "h",          "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
+    { "colorspace", "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "colorspace"},
+    { "c",          "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "colorspace"},
+    {   "auto",       0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "colorspace" },
+    {   "601",        0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "colorspace" },
+    {   "709",        0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "colorspace" },
     { NULL }
 };
 
@@ -147,7 +154,7 @@ static const enum AVPixelFormat out_rgb9_pix_fmts[] = {
 };
 
 static const enum AVPixelFormat out_rgb10_pix_fmts[] = {
-    AV_PIX_FMT_GBRP10,
+    AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
     AV_PIX_FMT_NONE
 };
 
@@ -162,7 +169,7 @@ static const enum AVPixelFormat in1_pix_fmts[] = {
     AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10,
     AV_PIX_FMT_YUV444P12,
     AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP,
-    AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
+    AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
     AV_PIX_FMT_NONE
 };
@@ -174,7 +181,7 @@ static const enum AVPixelFormat in2_pix_fmts[] = {
     AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUVJ411P,
     AV_PIX_FMT_YUV440P,  AV_PIX_FMT_YUV410P,
     AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP,
-    AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
+    AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
     AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
     AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
@@ -246,10 +253,23 @@ static int query_formats(AVFilterContext *ctx)
 static int config_output(AVFilterLink *outlink)
 {
     VectorscopeContext *s = outlink->src->priv;
+    int i;
 
     s->intensity = s->fintensity * (s->size - 1);
     outlink->h = outlink->w = s->size;
     outlink->sample_aspect_ratio = (AVRational){1,1};
+
+    s->peak_memory = av_calloc(s->size, s->size);
+    if (!s->peak_memory)
+        return AVERROR(ENOMEM);
+
+    s->peak = av_calloc(s->size, sizeof(*s->peak));
+    if (!s->peak)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < s->size; i++)
+        s->peak[i] = s->peak_memory + s->size * i;
+
     return 0;
 }
 
@@ -429,8 +449,6 @@ static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int
                         continue;
 
                     dpd[pos] = FFMIN(dpd[pos] + intensity, max);
-                    if (dst[3])
-                        dst[3][pos] = max;
                 }
             }
         } else {
@@ -450,8 +468,6 @@ static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int
                     dst[0][pos] = FFMIN(dst[0][pos] + intensity, max);
                     dst[1][pos] = FFMIN(dst[1][pos] + intensity, max);
                     dst[2][pos] = FFMIN(dst[2][pos] + intensity, max);
-                    if (dst[3])
-                        dst[3][pos] = max;
                 }
             }
         }
@@ -475,8 +491,6 @@ static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int
                         dpd[pos] = FFABS(mid - x) + FFABS(mid - y);
                     dpx[pos] = x;
                     dpy[pos] = y;
-                    if (dst[3])
-                        dst[3][pos] = max;
                 }
             }
         } else {
@@ -497,8 +511,6 @@ static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int
                         dpd[pos] = FFMIN(x + y, max);
                     dpx[pos] = x;
                     dpy[pos] = y;
-                    if (dst[3])
-                        dst[3][pos] = max;
                 }
             }
         }
@@ -520,8 +532,6 @@ static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int
                 dpd[pos] = FFMIN(max, dpd[pos] + intensity);
                 dpx[pos] = x;
                 dpy[pos] = y;
-                if (dst[3])
-                    dst[3][pos] = max;
             }
         }
         break;
@@ -542,8 +552,6 @@ static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int
                 dpd[pos] = FFMAX(z, dpd[pos]);
                 dpx[pos] = x;
                 dpy[pos] = y;
-                if (dst[3])
-                    dst[3][pos] = max;
             }
         }
         break;
@@ -553,6 +561,17 @@ static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int
 
     envelope16(s, out);
 
+    if (dst[3]) {
+        for (i = 0; i < out->height; i++) {
+            for (j = 0; j < out->width; j++) {
+                int pos = i * dlinesize + j;
+
+                if (dpd[pos])
+                    dst[3][pos] = max;
+            }
+        }
+    }
+
     if (s->mode == COLOR) {
         for (i = 0; i < out->height; i++) {
             for (j = 0; j < out->width; j++) {
@@ -624,8 +643,6 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p
                         continue;
 
                     dpd[pos] = FFMIN(dpd[pos] + intensity, 255);
-                    if (dst[3])
-                        dst[3][pos] = 255;
                 }
             }
         } else {
@@ -645,8 +662,6 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p
                     dst[0][pos] = FFMIN(dst[0][pos] + intensity, 255);
                     dst[1][pos] = FFMIN(dst[1][pos] + intensity, 255);
                     dst[2][pos] = FFMIN(dst[2][pos] + intensity, 255);
-                    if (dst[3])
-                        dst[3][pos] = 255;
                 }
             }
         }
@@ -670,8 +685,6 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p
                         dpd[pos] = FFABS(128 - x) + FFABS(128 - y);
                     dpx[pos] = x;
                     dpy[pos] = y;
-                    if (dst[3])
-                        dst[3][pos] = 255;
                 }
             }
         } else {
@@ -692,8 +705,6 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p
                         dpd[pos] = FFMIN(x + y, 255);
                     dpx[pos] = x;
                     dpy[pos] = y;
-                    if (dst[3])
-                        dst[3][pos] = 255;
                 }
             }
         }
@@ -715,8 +726,6 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p
                 dpd[pos] = FFMIN(255, dpd[pos] + intensity);
                 dpx[pos] = x;
                 dpy[pos] = y;
-                if (dst[3])
-                    dst[3][pos] = 255;
             }
         }
         break;
@@ -737,8 +746,6 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p
                 dpd[pos] = FFMAX(z, dpd[pos]);
                 dpx[pos] = x;
                 dpy[pos] = y;
-                if (dst[3])
-                    dst[3][pos] = 255;
             }
         }
         break;
@@ -748,6 +755,17 @@ static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int p
 
     envelope(s, out);
 
+    if (dst[3]) {
+        for (i = 0; i < out->height; i++) {
+            for (j = 0; j < out->width; j++) {
+                int pos = i * dlinesize + j;
+
+                if (dpd[pos])
+                    dst[3][pos] = 255;
+            }
+        }
+    }
+
     if (s->mode == COLOR) {
         for (i = 0; i < out->height; i++) {
             for (j = 0; j < out->width; j++) {
@@ -893,7 +911,7 @@ static void draw_htext(AVFrame *out, int x, int y, float o1, float o2, const cha
             int v = color[plane];
 
             uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
-            for (char_y = 0; char_y < font_height; char_y++) {
+            for (char_y = font_height - 1; char_y >= 0; char_y--) {
                 for (mask = 0x80; mask; mask >>= 1) {
                     if (font[txt[i] * font_height + char_y] & mask)
                         p[0] = p[0] * o2 + v * o1;
@@ -919,7 +937,7 @@ static void draw_htext16(AVFrame *out, int x, int y, float o1, float o2, const c
             int v = color[plane];
 
             uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
-            for (char_y = 0; char_y < font_height; char_y++) {
+            for (char_y = font_height - 1; char_y >= 0; char_y--) {
                 for (mask = 0x80; mask; mask >>= 1) {
                     if (font[txt[i] * font_height + char_y] & mask)
                         p[0] = p[0] * o2 + v * o1;
@@ -1189,15 +1207,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     VectorscopeContext *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out;
+    int plane;
 
-    switch (av_frame_get_colorspace(in)) {
-    case AVCOL_SPC_SMPTE170M:
-    case AVCOL_SPC_BT470BG:
-        s->cs = (s->depth - 8) * 2 + 0;
-        break;
-    case AVCOL_SPC_BT709:
-    default:
-        s->cs = (s->depth - 8) * 2 + 1;
+    if (s->colorspace) {
+        s->cs = (s->depth - 8) * 2 + s->colorspace - 1;
+    } else {
+        switch (in->colorspace) {
+        case AVCOL_SPC_SMPTE170M:
+        case AVCOL_SPC_BT470BG:
+            s->cs = (s->depth - 8) * 2 + 0;
+            break;
+        case AVCOL_SPC_BT709:
+        default:
+            s->cs = (s->depth - 8) * 2 + 1;
+        }
     }
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
@@ -1205,11 +1228,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    out->pts = in->pts;
+    av_frame_copy_props(out, in);
 
     s->vectorscope(s, in, out, s->pd);
     s->graticulef(s, out, s->x, s->y, s->pd, s->cs);
 
+    for (plane = 0; plane < 4; plane++) {
+        if (out->data[plane]) {
+            out->data[plane]    += (s->size - 1) * out->linesize[plane];
+            out->linesize[plane] = -out->linesize[plane];
+        }
+    }
+
     av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
@@ -1290,6 +1320,14 @@ static int config_input(AVFilterLink *inlink)
     return 0;
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    VectorscopeContext *s = ctx->priv;
+
+    av_freep(&s->peak);
+    av_freep(&s->peak_memory);
+}
+
 static const AVFilterPad inputs[] = {
     {
         .name         = "default",
@@ -1315,6 +1353,7 @@ AVFilter ff_vf_vectorscope = {
     .priv_size     = sizeof(VectorscopeContext),
     .priv_class    = &vectorscope_class,
     .query_formats = query_formats,
+    .uninit        = uninit,
     .inputs        = inputs,
     .outputs       = outputs,
 };