LCOV - code coverage report
Current view: top level - libavfilter - vf_vectorscope.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 196 741 26.5 %
Date: 2017-12-17 16:07:53 Functions: 8 22 36.4 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Paul B Mahol
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include "libavutil/avassert.h"
      22             : #include "libavutil/intreadwrite.h"
      23             : #include "libavutil/opt.h"
      24             : #include "libavutil/parseutils.h"
      25             : #include "libavutil/pixdesc.h"
      26             : #include "libavutil/xga_font_data.h"
      27             : #include "avfilter.h"
      28             : #include "formats.h"
      29             : #include "internal.h"
      30             : #include "video.h"
      31             : 
      32             : enum VectorscopeMode {
      33             :     GRAY,
      34             :     COLOR,
      35             :     COLOR2,
      36             :     COLOR3,
      37             :     COLOR4,
      38             :     COLOR5,
      39             :     MODE_NB
      40             : };
      41             : 
      42             : typedef struct VectorscopeContext {
      43             :     const AVClass *class;
      44             :     int mode;
      45             :     int intensity;
      46             :     float fintensity;
      47             :     uint16_t bg_color[4];
      48             :     int planewidth[4];
      49             :     int planeheight[4];
      50             :     int hsub, vsub;
      51             :     int x, y, pd;
      52             :     int is_yuv;
      53             :     int size;
      54             :     int depth;
      55             :     int mult;
      56             :     int envelope;
      57             :     int graticule;
      58             :     float opacity;
      59             :     float bgopacity;
      60             :     float lthreshold;
      61             :     float hthreshold;
      62             :     int tmin;
      63             :     int tmax;
      64             :     int flags;
      65             :     int colorspace;
      66             :     int cs;
      67             :     uint8_t *peak_memory;
      68             :     uint8_t **peak;
      69             : 
      70             :     void (*vectorscope)(struct VectorscopeContext *s,
      71             :                         AVFrame *in, AVFrame *out, int pd);
      72             :     void (*graticulef)(struct VectorscopeContext *s, AVFrame *out,
      73             :                        int X, int Y, int D, int P);
      74             : } VectorscopeContext;
      75             : 
      76             : #define OFFSET(x) offsetof(VectorscopeContext, x)
      77             : #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
      78             : 
      79             : static const AVOption vectorscope_options[] = {
      80             :     { "mode", "set vectorscope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, MODE_NB-1, FLAGS, "mode"},
      81             :     { "m",    "set vectorscope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, MODE_NB-1, FLAGS, "mode"},
      82             :     {   "gray",   0, 0, AV_OPT_TYPE_CONST, {.i64=GRAY},   0, 0, FLAGS, "mode" },
      83             :     {   "color",  0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR},  0, 0, FLAGS, "mode" },
      84             :     {   "color2", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR2}, 0, 0, FLAGS, "mode" },
      85             :     {   "color3", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR3}, 0, 0, FLAGS, "mode" },
      86             :     {   "color4", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR4}, 0, 0, FLAGS, "mode" },
      87             :     {   "color5", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR5}, 0, 0, FLAGS, "mode" },
      88             :     { "x", "set color component on X axis", OFFSET(x), AV_OPT_TYPE_INT, {.i64=1}, 0, 2, FLAGS},
      89             :     { "y", "set color component on Y axis", OFFSET(y), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS},
      90             :     { "intensity", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.004}, 0, 1, FLAGS},
      91             :     { "i",         "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.004}, 0, 1, FLAGS},
      92             :     { "envelope",  "set envelope", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope"},
      93             :     { "e",         "set envelope", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope"},
      94             :     {   "none",         0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "envelope" },
      95             :     {   "instant",      0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "envelope" },
      96             :     {   "peak",         0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "envelope" },
      97             :     {   "peak+instant", 0, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "envelope" },
      98             :     { "graticule", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "graticule"},
      99             :     { "g",         "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "graticule"},
     100             :     {   "none",         0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "graticule" },
     101             :     {   "green",        0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "graticule" },
     102             :     {   "color",        0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "graticule" },
     103             :     { "opacity", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS},
     104             :     { "o",       "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS},
     105             :     { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, FLAGS, "flags"},
     106             :     { "f",     "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, FLAGS, "flags"},
     107             :     {   "white", "draw white point", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "flags" },
     108             :     {   "black", "draw black point", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "flags" },
     109             :     {   "name",  "draw point name",  0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "flags" },
     110             :     { "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, FLAGS},
     111             :     { "b",         "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, FLAGS},
     112             :     { "lthreshold", "set low threshold",  OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS},
     113             :     { "l",          "set low threshold",  OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS},
     114             :     { "hthreshold", "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
     115             :     { "h",          "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
     116             :     { "colorspace", "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "colorspace"},
     117             :     { "c",          "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "colorspace"},
     118             :     {   "auto",       0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "colorspace" },
     119             :     {   "601",        0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "colorspace" },
     120             :     {   "709",        0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "colorspace" },
     121             :     { NULL }
     122             : };
     123             : 
     124             : AVFILTER_DEFINE_CLASS(vectorscope);
     125             : 
     126             : static const enum AVPixelFormat out_yuv8_pix_fmts[] = {
     127             :     AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P,
     128             :     AV_PIX_FMT_NONE
     129             : };
     130             : 
     131             : static const enum AVPixelFormat out_yuv9_pix_fmts[] = {
     132             :     AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUV444P9,
     133             :     AV_PIX_FMT_NONE
     134             : };
     135             : 
     136             : static const enum AVPixelFormat out_yuv10_pix_fmts[] = {
     137             :     AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUV444P10,
     138             :     AV_PIX_FMT_NONE
     139             : };
     140             : 
     141             : static const enum AVPixelFormat out_yuv12_pix_fmts[] = {
     142             :     AV_PIX_FMT_YUV444P12,
     143             :     AV_PIX_FMT_NONE
     144             : };
     145             : 
     146             : static const enum AVPixelFormat out_rgb8_pix_fmts[] = {
     147             :     AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP,
     148             :     AV_PIX_FMT_NONE
     149             : };
     150             : 
     151             : static const enum AVPixelFormat out_rgb9_pix_fmts[] = {
     152             :     AV_PIX_FMT_GBRP9,
     153             :     AV_PIX_FMT_NONE
     154             : };
     155             : 
     156             : static const enum AVPixelFormat out_rgb10_pix_fmts[] = {
     157             :     AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
     158             :     AV_PIX_FMT_NONE
     159             : };
     160             : 
     161             : static const enum AVPixelFormat out_rgb12_pix_fmts[] = {
     162             :     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
     163             :     AV_PIX_FMT_NONE
     164             : };
     165             : 
     166             : static const enum AVPixelFormat in1_pix_fmts[] = {
     167             :     AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
     168             :     AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10,
     169             :     AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10,
     170             :     AV_PIX_FMT_YUV444P12,
     171             :     AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP,
     172             :     AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
     173             :     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
     174             :     AV_PIX_FMT_NONE
     175             : };
     176             : 
     177             : static const enum AVPixelFormat in2_pix_fmts[] = {
     178             :     AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P,
     179             :     AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P,
     180             :     AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
     181             :     AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUVJ411P,
     182             :     AV_PIX_FMT_YUV440P,  AV_PIX_FMT_YUV410P,
     183             :     AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP,
     184             :     AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
     185             :     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
     186             :     AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
     187             :     AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
     188             :     AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
     189             :     AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
     190             :     AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12,
     191             :     AV_PIX_FMT_NONE
     192             : };
     193             : 
     194          12 : static int query_formats(AVFilterContext *ctx)
     195             : {
     196          12 :     VectorscopeContext *s = ctx->priv;
     197             :     const enum AVPixelFormat *out_pix_fmts;
     198             :     const AVPixFmtDescriptor *desc;
     199             :     AVFilterFormats *avff;
     200             :     int depth, rgb, i, ret;
     201             : 
     202          18 :     if (!ctx->inputs[0]->in_formats ||
     203           6 :         !ctx->inputs[0]->in_formats->nb_formats) {
     204           6 :         return AVERROR(EAGAIN);
     205             :     }
     206             : 
     207           6 :     if (!ctx->inputs[0]->out_formats) {
     208             :         const enum AVPixelFormat *in_pix_fmts;
     209             : 
     210           6 :         if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1))
     211           5 :             in_pix_fmts = in2_pix_fmts;
     212             :         else
     213           1 :             in_pix_fmts = in1_pix_fmts;
     214           6 :         if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0)
     215           0 :             return ret;
     216             :     }
     217             : 
     218           6 :     avff = ctx->inputs[0]->in_formats;
     219           6 :     desc = av_pix_fmt_desc_get(avff->formats[0]);
     220           6 :     rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
     221           6 :     depth = desc->comp[0].depth;
     222           6 :     for (i = 1; i < avff->nb_formats; i++) {
     223           0 :         desc = av_pix_fmt_desc_get(avff->formats[i]);
     224           0 :         if (rgb != (desc->flags & AV_PIX_FMT_FLAG_RGB) ||
     225           0 :             depth != desc->comp[0].depth)
     226           0 :             return AVERROR(EAGAIN);
     227             :     }
     228             : 
     229           6 :     if (rgb && depth == 8)
     230           0 :         out_pix_fmts = out_rgb8_pix_fmts;
     231           6 :     else if (rgb && depth == 9)
     232           0 :         out_pix_fmts = out_rgb9_pix_fmts;
     233           6 :     else if (rgb && depth == 10)
     234           0 :         out_pix_fmts = out_rgb10_pix_fmts;
     235           6 :     else if (rgb && depth == 12)
     236           0 :         out_pix_fmts = out_rgb12_pix_fmts;
     237           6 :     else if (depth == 8)
     238           6 :         out_pix_fmts = out_yuv8_pix_fmts;
     239           0 :     else if (depth == 9)
     240           0 :         out_pix_fmts = out_yuv9_pix_fmts;
     241           0 :     else if (depth == 10)
     242           0 :         out_pix_fmts = out_yuv10_pix_fmts;
     243           0 :     else if (depth == 12)
     244           0 :         out_pix_fmts = out_yuv12_pix_fmts;
     245             :     else
     246           0 :         return AVERROR(EAGAIN);
     247           6 :     if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0)
     248           0 :         return ret;
     249             : 
     250           6 :     return 0;
     251             : }
     252             : 
     253           6 : static int config_output(AVFilterLink *outlink)
     254             : {
     255           6 :     VectorscopeContext *s = outlink->src->priv;
     256             :     int i;
     257             : 
     258           6 :     s->intensity = s->fintensity * (s->size - 1);
     259           6 :     outlink->h = outlink->w = s->size;
     260           6 :     outlink->sample_aspect_ratio = (AVRational){1,1};
     261             : 
     262           6 :     s->peak_memory = av_calloc(s->size, s->size);
     263           6 :     if (!s->peak_memory)
     264           0 :         return AVERROR(ENOMEM);
     265             : 
     266           6 :     s->peak = av_calloc(s->size, sizeof(*s->peak));
     267           6 :     if (!s->peak)
     268           0 :         return AVERROR(ENOMEM);
     269             : 
     270        1542 :     for (i = 0; i < s->size; i++)
     271        1536 :         s->peak[i] = s->peak_memory + s->size * i;
     272             : 
     273           6 :     return 0;
     274             : }
     275             : 
     276           0 : static void envelope_instant16(VectorscopeContext *s, AVFrame *out)
     277             : {
     278           0 :     const int dlinesize = out->linesize[0] / 2;
     279           0 :     uint16_t *dpd = s->mode == COLOR || !s->is_yuv ? (uint16_t *)out->data[s->pd] : (uint16_t *)out->data[0];
     280           0 :     const int max = s->size - 1;
     281             :     int i, j;
     282             : 
     283           0 :     for (i = 0; i < out->height; i++) {
     284           0 :         for (j = 0; j < out->width; j++) {
     285           0 :             const int pos = i * dlinesize + j;
     286           0 :             const int poa = (i - 1) * dlinesize + j;
     287           0 :             const int pob = (i + 1) * dlinesize + j;
     288             : 
     289           0 :             if (dpd[pos] && (((!j || !dpd[pos - 1]) || ((j == (out->width - 1)) || !dpd[pos + 1]))
     290           0 :                          || ((!i || !dpd[poa]) || ((i == (out->height - 1)) || !dpd[pob])))) {
     291           0 :                 dpd[pos] = max;
     292             :             }
     293             :         }
     294             :     }
     295           0 : }
     296             : 
     297           0 : static void envelope_peak16(VectorscopeContext *s, AVFrame *out)
     298             : {
     299           0 :     const int dlinesize = out->linesize[0] / 2;
     300           0 :     uint16_t *dpd = s->mode == COLOR || !s->is_yuv ? (uint16_t *)out->data[s->pd] : (uint16_t *)out->data[0];
     301           0 :     const int max = s->size - 1;
     302             :     int i, j;
     303             : 
     304           0 :     for (i = 0; i < out->height; i++) {
     305           0 :         for (j = 0; j < out->width; j++) {
     306           0 :             const int pos = i * dlinesize + j;
     307             : 
     308           0 :             if (dpd[pos])
     309           0 :                 s->peak[i][j] = 1;
     310             :         }
     311             :     }
     312             : 
     313           0 :     if (s->envelope == 3)
     314           0 :         envelope_instant16(s, out);
     315             : 
     316           0 :     for (i = 0; i < out->height; i++) {
     317           0 :         for (j = 0; j < out->width; j++) {
     318           0 :             const int pos = i * dlinesize + j;
     319             : 
     320           0 :             if (s->peak[i][j] && (((!j || !s->peak[i][j-1]) || ((j == (out->width - 1)) || !s->peak[i][j + 1]))
     321           0 :                               || ((!i || !s->peak[i-1][j]) || ((i == (out->height - 1)) || !s->peak[i + 1][j])))) {
     322           0 :                 dpd[pos] = max;
     323             :             }
     324             :         }
     325             :     }
     326           0 : }
     327             : 
     328           0 : static void envelope_instant(VectorscopeContext *s, AVFrame *out)
     329             : {
     330           0 :     const int dlinesize = out->linesize[0];
     331           0 :     uint8_t *dpd = s->mode == COLOR || !s->is_yuv ? out->data[s->pd] : out->data[0];
     332             :     int i, j;
     333             : 
     334           0 :     for (i = 0; i < out->height; i++) {
     335           0 :         for (j = 0; j < out->width; j++) {
     336           0 :             const int pos = i * dlinesize + j;
     337           0 :             const int poa = (i - 1) * dlinesize + j;
     338           0 :             const int pob = (i + 1) * dlinesize + j;
     339             : 
     340           0 :             if (dpd[pos] && (((!j || !dpd[pos - 1]) || ((j == (out->width - 1)) || !dpd[pos + 1]))
     341           0 :                          || ((!i || !dpd[poa]) || ((i == (out->height - 1)) || !dpd[pob])))) {
     342           0 :                 dpd[pos] = 255;
     343             :             }
     344             :         }
     345             :     }
     346           0 : }
     347             : 
     348           0 : static void envelope_peak(VectorscopeContext *s, AVFrame *out)
     349             : {
     350           0 :     const int dlinesize = out->linesize[0];
     351           0 :     uint8_t *dpd = s->mode == COLOR || !s->is_yuv ? out->data[s->pd] : out->data[0];
     352             :     int i, j;
     353             : 
     354           0 :     for (i = 0; i < out->height; i++) {
     355           0 :         for (j = 0; j < out->width; j++) {
     356           0 :             const int pos = i * dlinesize + j;
     357             : 
     358           0 :             if (dpd[pos])
     359           0 :                 s->peak[i][j] = 1;
     360             :         }
     361             :     }
     362             : 
     363           0 :     if (s->envelope == 3)
     364           0 :         envelope_instant(s, out);
     365             : 
     366           0 :     for (i = 0; i < out->height; i++) {
     367           0 :         for (j = 0; j < out->width; j++) {
     368           0 :             const int pos = i * dlinesize + j;
     369             : 
     370           0 :             if (s->peak[i][j] && (((!j || !s->peak[i][j-1]) || ((j == (out->width - 1)) || !s->peak[i][j + 1]))
     371           0 :                               || ((!i || !s->peak[i-1][j]) || ((i == (out->height - 1)) || !s->peak[i + 1][j])))) {
     372           0 :                 dpd[pos] = 255;
     373             :             }
     374             :         }
     375             :     }
     376           0 : }
     377             : 
     378           0 : static void envelope16(VectorscopeContext *s, AVFrame *out)
     379             : {
     380           0 :     if (!s->envelope) {
     381           0 :         return;
     382           0 :     } else if (s->envelope == 1) {
     383           0 :         envelope_instant16(s, out);
     384             :     } else {
     385           0 :         envelope_peak16(s, out);
     386             :     }
     387             : }
     388             : 
     389          18 : static void envelope(VectorscopeContext *s, AVFrame *out)
     390             : {
     391          18 :     if (!s->envelope) {
     392          18 :         return;
     393           0 :     } else if (s->envelope == 1) {
     394           0 :         envelope_instant(s, out);
     395             :     } else {
     396           0 :         envelope_peak(s, out);
     397             :     }
     398             : }
     399             : 
     400           0 : static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
     401             : {
     402           0 :     const uint16_t * const *src = (const uint16_t * const *)in->data;
     403           0 :     const int slinesizex = in->linesize[s->x] / 2;
     404           0 :     const int slinesizey = in->linesize[s->y] / 2;
     405           0 :     const int slinesized = in->linesize[pd] / 2;
     406           0 :     const int dlinesize = out->linesize[0] / 2;
     407           0 :     const int intensity = s->intensity;
     408           0 :     const int px = s->x, py = s->y;
     409           0 :     const int h = s->planeheight[py];
     410           0 :     const int w = s->planewidth[px];
     411           0 :     const uint16_t *spx = src[px];
     412           0 :     const uint16_t *spy = src[py];
     413           0 :     const uint16_t *spd = src[pd];
     414           0 :     const int hsub = s->hsub;
     415           0 :     const int vsub = s->vsub;
     416           0 :     uint16_t **dst = (uint16_t **)out->data;
     417           0 :     uint16_t *dpx = dst[px];
     418           0 :     uint16_t *dpy = dst[py];
     419           0 :     uint16_t *dpd = dst[pd];
     420           0 :     const int max = s->size - 1;
     421           0 :     const int mid = s->size / 2;
     422           0 :     const int tmin = s->tmin;
     423           0 :     const int tmax = s->tmax;
     424             :     int i, j, k;
     425             : 
     426           0 :     for (k = 0; k < 4 && dst[k]; k++) {
     427           0 :         for (i = 0; i < out->height ; i++)
     428           0 :             for (j = 0; j < out->width; j++)
     429           0 :                 AV_WN16(out->data[k] + i * out->linesize[k] + j * 2,
     430             :                         (s->mode == COLOR || s->mode == COLOR5) && k == s->pd ? 0 : s->bg_color[k]);
     431             :     }
     432             : 
     433           0 :     switch (s->mode) {
     434           0 :     case COLOR:
     435             :     case COLOR5:
     436             :     case GRAY:
     437           0 :         if (s->is_yuv) {
     438           0 :             for (i = 0; i < h; i++) {
     439           0 :                 const int iwx = i * slinesizex;
     440           0 :                 const int iwy = i * slinesizey;
     441           0 :                 const int iwd = i * slinesized;
     442           0 :                 for (j = 0; j < w; j++) {
     443           0 :                     const int x = FFMIN(spx[iwx + j], max);
     444           0 :                     const int y = FFMIN(spy[iwy + j], max);
     445           0 :                     const int z = spd[iwd + j];
     446           0 :                     const int pos = y * dlinesize + x;
     447             : 
     448           0 :                     if (z < tmin || z > tmax)
     449           0 :                         continue;
     450             : 
     451           0 :                     dpd[pos] = FFMIN(dpd[pos] + intensity, max);
     452             :                 }
     453             :             }
     454             :         } else {
     455           0 :             for (i = 0; i < h; i++) {
     456           0 :                 const int iwx = i * slinesizex;
     457           0 :                 const int iwy = i * slinesizey;
     458           0 :                 const int iwd = i * slinesized;
     459           0 :                 for (j = 0; j < w; j++) {
     460           0 :                     const int x = FFMIN(spx[iwx + j], max);
     461           0 :                     const int y = FFMIN(spy[iwy + j], max);
     462           0 :                     const int z = spd[iwd + j];
     463           0 :                     const int pos = y * dlinesize + x;
     464             : 
     465           0 :                     if (z < tmin || z > tmax)
     466           0 :                         continue;
     467             : 
     468           0 :                     dst[0][pos] = FFMIN(dst[0][pos] + intensity, max);
     469           0 :                     dst[1][pos] = FFMIN(dst[1][pos] + intensity, max);
     470           0 :                     dst[2][pos] = FFMIN(dst[2][pos] + intensity, max);
     471             :                 }
     472             :             }
     473             :         }
     474           0 :         break;
     475           0 :     case COLOR2:
     476           0 :         if (s->is_yuv) {
     477           0 :             for (i = 0; i < h; i++) {
     478           0 :                 const int iw1 = i * slinesizex;
     479           0 :                 const int iw2 = i * slinesizey;
     480           0 :                 const int iwd = i * slinesized;
     481           0 :                 for (j = 0; j < w; j++) {
     482           0 :                     const int x = FFMIN(spx[iw1 + j], max);
     483           0 :                     const int y = FFMIN(spy[iw2 + j], max);
     484           0 :                     const int z = spd[iwd + j];
     485           0 :                     const int pos = y * dlinesize + x;
     486             : 
     487           0 :                     if (z < tmin || z > tmax)
     488           0 :                         continue;
     489             : 
     490           0 :                     if (!dpd[pos])
     491           0 :                         dpd[pos] = FFABS(mid - x) + FFABS(mid - y);
     492           0 :                     dpx[pos] = x;
     493           0 :                     dpy[pos] = y;
     494             :                 }
     495             :             }
     496             :         } else {
     497           0 :             for (i = 0; i < h; i++) {
     498           0 :                 const int iw1 = i * slinesizex;
     499           0 :                 const int iw2 = i * slinesizey;
     500           0 :                 const int iwd = i * slinesized;
     501           0 :                 for (j = 0; j < w; j++) {
     502           0 :                     const int x = FFMIN(spx[iw1 + j], max);
     503           0 :                     const int y = FFMIN(spy[iw2 + j], max);
     504           0 :                     const int z = spd[iwd + j];
     505           0 :                     const int pos = y * dlinesize + x;
     506             : 
     507           0 :                     if (z < tmin || z > tmax)
     508           0 :                         continue;
     509             : 
     510           0 :                     if (!dpd[pos])
     511           0 :                         dpd[pos] = FFMIN(x + y, max);
     512           0 :                     dpx[pos] = x;
     513           0 :                     dpy[pos] = y;
     514             :                 }
     515             :             }
     516             :         }
     517           0 :         break;
     518           0 :     case COLOR3:
     519           0 :         for (i = 0; i < h; i++) {
     520           0 :             const int iw1 = i * slinesizex;
     521           0 :             const int iw2 = i * slinesizey;
     522           0 :             const int iwd = i * slinesized;
     523           0 :             for (j = 0; j < w; j++) {
     524           0 :                 const int x = FFMIN(spx[iw1 + j], max);
     525           0 :                 const int y = FFMIN(spy[iw2 + j], max);
     526           0 :                 const int z = spd[iwd + j];
     527           0 :                 const int pos = y * dlinesize + x;
     528             : 
     529           0 :                 if (z < tmin || z > tmax)
     530           0 :                     continue;
     531             : 
     532           0 :                 dpd[pos] = FFMIN(max, dpd[pos] + intensity);
     533           0 :                 dpx[pos] = x;
     534           0 :                 dpy[pos] = y;
     535             :             }
     536             :         }
     537           0 :         break;
     538           0 :     case COLOR4:
     539           0 :         for (i = 0; i < in->height; i++) {
     540           0 :             const int iwx = (i >> vsub) * slinesizex;
     541           0 :             const int iwy = (i >> vsub) * slinesizey;
     542           0 :             const int iwd = i * slinesized;
     543           0 :             for (j = 0; j < in->width; j++) {
     544           0 :                 const int x = FFMIN(spx[iwx + (j >> hsub)], max);
     545           0 :                 const int y = FFMIN(spy[iwy + (j >> hsub)], max);
     546           0 :                 const int z = spd[iwd + j];
     547           0 :                 const int pos = y * dlinesize + x;
     548             : 
     549           0 :                 if (z < tmin || z > tmax)
     550           0 :                     continue;
     551             : 
     552           0 :                 dpd[pos] = FFMAX(z, dpd[pos]);
     553           0 :                 dpx[pos] = x;
     554           0 :                 dpy[pos] = y;
     555             :             }
     556             :         }
     557           0 :         break;
     558           0 :     default:
     559           0 :         av_assert0(0);
     560             :     }
     561             : 
     562           0 :     envelope16(s, out);
     563             : 
     564           0 :     if (dst[3]) {
     565           0 :         for (i = 0; i < out->height; i++) {
     566           0 :             for (j = 0; j < out->width; j++) {
     567           0 :                 int pos = i * dlinesize + j;
     568             : 
     569           0 :                 if (dpd[pos])
     570           0 :                     dst[3][pos] = max;
     571             :             }
     572             :         }
     573             :     }
     574             : 
     575           0 :     if (s->mode == COLOR) {
     576           0 :         for (i = 0; i < out->height; i++) {
     577           0 :             for (j = 0; j < out->width; j++) {
     578           0 :                 if (!dpd[i * dlinesize + j]) {
     579           0 :                     dpx[i * dlinesize + j] = j;
     580           0 :                     dpy[i * dlinesize + j] = i;
     581           0 :                     dpd[i * dlinesize + j] = mid;
     582             :                 }
     583             :             }
     584             :         }
     585           0 :     } else if (s->mode == COLOR5) {
     586           0 :         for (i = 0; i < out->height; i++) {
     587           0 :             for (j = 0; j < out->width; j++) {
     588           0 :                 if (!dpd[i * dlinesize + j]) {
     589           0 :                     dpx[i * dlinesize + j] = j;
     590           0 :                     dpy[i * dlinesize + j] = i;
     591           0 :                     dpd[i * dlinesize + j] = mid * M_SQRT2 - hypot(i - mid, j - mid);
     592             :                 }
     593             :             }
     594             :         }
     595             :     }
     596           0 : }
     597             : 
     598          18 : static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
     599             : {
     600          18 :     const uint8_t * const *src = (const uint8_t * const *)in->data;
     601          18 :     const int slinesizex = in->linesize[s->x];
     602          18 :     const int slinesizey = in->linesize[s->y];
     603          18 :     const int slinesized = in->linesize[pd];
     604          18 :     const int dlinesize = out->linesize[0];
     605          18 :     const int intensity = s->intensity;
     606          18 :     const int px = s->x, py = s->y;
     607          18 :     const int h = s->planeheight[py];
     608          18 :     const int w = s->planewidth[px];
     609          18 :     const uint8_t *spx = src[px];
     610          18 :     const uint8_t *spy = src[py];
     611          18 :     const uint8_t *spd = src[pd];
     612          18 :     const int hsub = s->hsub;
     613          18 :     const int vsub = s->vsub;
     614          18 :     uint8_t **dst = out->data;
     615          18 :     uint8_t *dpx = dst[px];
     616          18 :     uint8_t *dpy = dst[py];
     617          18 :     uint8_t *dpd = dst[pd];
     618          18 :     const int tmin = s->tmin;
     619          18 :     const int tmax = s->tmax;
     620             :     int i, j, k;
     621             : 
     622          72 :     for (k = 0; k < 4 && dst[k]; k++)
     623       13878 :         for (i = 0; i < out->height ; i++)
     624       40704 :             memset(dst[k] + i * out->linesize[k],
     625       39168 :                    (s->mode == COLOR || s->mode == COLOR5) && k == s->pd ? 0 : s->bg_color[k], out->width);
     626             : 
     627          18 :     switch (s->mode) {
     628           9 :     case COLOR5:
     629             :     case COLOR:
     630             :     case GRAY:
     631           9 :         if (s->is_yuv) {
     632        1737 :             for (i = 0; i < h; i++) {
     633        1728 :                 const int iwx = i * slinesizex;
     634        1728 :                 const int iwy = i * slinesizey;
     635        1728 :                 const int iwd = i * slinesized;
     636      457920 :                 for (j = 0; j < w; j++) {
     637      456192 :                     const int x = spx[iwx + j];
     638      456192 :                     const int y = spy[iwy + j];
     639      456192 :                     const int z = spd[iwd + j];
     640      456192 :                     const int pos = y * dlinesize + x;
     641             : 
     642      456192 :                     if (z < tmin || z > tmax)
     643           0 :                         continue;
     644             : 
     645      456192 :                     dpd[pos] = FFMIN(dpd[pos] + intensity, 255);
     646             :                 }
     647             :             }
     648             :         } else {
     649           0 :             for (i = 0; i < h; i++) {
     650           0 :                 const int iwx = i * slinesizex;
     651           0 :                 const int iwy = i * slinesizey;
     652           0 :                 const int iwd = i * slinesized;
     653           0 :                 for (j = 0; j < w; j++) {
     654           0 :                     const int x = spx[iwx + j];
     655           0 :                     const int y = spy[iwy + j];
     656           0 :                     const int z = spd[iwd + j];
     657           0 :                     const int pos = y * dlinesize + x;
     658             : 
     659           0 :                     if (z < tmin || z > tmax)
     660           0 :                         continue;
     661             : 
     662           0 :                     dst[0][pos] = FFMIN(dst[0][pos] + intensity, 255);
     663           0 :                     dst[1][pos] = FFMIN(dst[1][pos] + intensity, 255);
     664           0 :                     dst[2][pos] = FFMIN(dst[2][pos] + intensity, 255);
     665             :                 }
     666             :             }
     667             :         }
     668           9 :         break;
     669           3 :     case COLOR2:
     670           3 :         if (s->is_yuv) {
     671         435 :             for (i = 0; i < h; i++) {
     672         432 :                 const int iw1 = i * slinesizex;
     673         432 :                 const int iw2 = i * slinesizey;
     674         432 :                 const int iwd = i * slinesized;
     675       76464 :                 for (j = 0; j < w; j++) {
     676       76032 :                     const int x = spx[iw1 + j];
     677       76032 :                     const int y = spy[iw2 + j];
     678       76032 :                     const int z = spd[iwd + j];
     679       76032 :                     const int pos = y * dlinesize + x;
     680             : 
     681       76032 :                     if (z < tmin || z > tmax)
     682           0 :                         continue;
     683             : 
     684       76032 :                     if (!dpd[pos])
     685       44303 :                         dpd[pos] = FFABS(128 - x) + FFABS(128 - y);
     686       76032 :                     dpx[pos] = x;
     687       76032 :                     dpy[pos] = y;
     688             :                 }
     689             :             }
     690             :         } else {
     691           0 :             for (i = 0; i < h; i++) {
     692           0 :                 const int iw1 = i * slinesizex;
     693           0 :                 const int iw2 = i * slinesizey;
     694           0 :                 const int iwd = i * slinesized;
     695           0 :                 for (j = 0; j < w; j++) {
     696           0 :                     const int x = spx[iw1 + j];
     697           0 :                     const int y = spy[iw2 + j];
     698           0 :                     const int z = spd[iwd + j];
     699           0 :                     const int pos = y * dlinesize + x;
     700             : 
     701           0 :                     if (z < tmin || z > tmax)
     702           0 :                         continue;
     703             : 
     704           0 :                     if (!dpd[pos])
     705           0 :                         dpd[pos] = FFMIN(x + y, 255);
     706           0 :                     dpx[pos] = x;
     707           0 :                     dpy[pos] = y;
     708             :                 }
     709             :             }
     710             :         }
     711           3 :         break;
     712           3 :     case COLOR3:
     713         435 :         for (i = 0; i < h; i++) {
     714         432 :             const int iw1 = i * slinesizex;
     715         432 :             const int iw2 = i * slinesizey;
     716         432 :             const int iwd = i * slinesized;
     717       76464 :             for (j = 0; j < w; j++) {
     718       76032 :                 const int x = spx[iw1 + j];
     719       76032 :                 const int y = spy[iw2 + j];
     720       76032 :                 const int z = spd[iwd + j];
     721       76032 :                 const int pos = y * dlinesize + x;
     722             : 
     723       76032 :                 if (z < tmin || z > tmax)
     724           0 :                     continue;
     725             : 
     726       76032 :                 dpd[pos] = FFMIN(255, dpd[pos] + intensity);
     727       76032 :                 dpx[pos] = x;
     728       76032 :                 dpy[pos] = y;
     729             :             }
     730             :         }
     731           3 :         break;
     732           3 :     case COLOR4:
     733         867 :         for (i = 0; i < in->height; i++) {
     734         864 :             const int iwx = (i >> vsub) * slinesizex;
     735         864 :             const int iwy = (i >> vsub) * slinesizey;
     736         864 :             const int iwd = i * slinesized;
     737      304992 :             for (j = 0; j < in->width; j++) {
     738      304128 :                 const int x = spx[iwx + (j >> hsub)];
     739      304128 :                 const int y = spy[iwy + (j >> hsub)];
     740      304128 :                 const int z = spd[iwd + j];
     741      304128 :                 const int pos = y * dlinesize + x;
     742             : 
     743      304128 :                 if (z < tmin || z > tmax)
     744           0 :                     continue;
     745             : 
     746      304128 :                 dpd[pos] = FFMAX(z, dpd[pos]);
     747      304128 :                 dpx[pos] = x;
     748      304128 :                 dpy[pos] = y;
     749             :             }
     750             :         }
     751           3 :         break;
     752           0 :     default:
     753           0 :         av_assert0(0);
     754             :     }
     755             : 
     756          18 :     envelope(s, out);
     757             : 
     758          18 :     if (dst[3]) {
     759           0 :         for (i = 0; i < out->height; i++) {
     760           0 :             for (j = 0; j < out->width; j++) {
     761           0 :                 int pos = i * dlinesize + j;
     762             : 
     763           0 :                 if (dpd[pos])
     764           0 :                     dst[3][pos] = 255;
     765             :             }
     766             :         }
     767             :     }
     768             : 
     769          18 :     if (s->mode == COLOR) {
     770         771 :         for (i = 0; i < out->height; i++) {
     771      197376 :             for (j = 0; j < out->width; j++) {
     772      196608 :                 if (!dpd[i * out->linesize[pd] + j]) {
     773      152318 :                     dpx[i * out->linesize[px] + j] = j;
     774      152318 :                     dpy[i * out->linesize[py] + j] = i;
     775      152318 :                     dpd[i * out->linesize[pd] + j] = 128;
     776             :                 }
     777             :             }
     778             :         }
     779          15 :     } else if (s->mode == COLOR5) {
     780           0 :         for (i = 0; i < out->height; i++) {
     781           0 :             for (j = 0; j < out->width; j++) {
     782           0 :                 if (!dpd[i * out->linesize[pd] + j]) {
     783           0 :                     dpx[i * out->linesize[px] + j] = j;
     784           0 :                     dpy[i * out->linesize[py] + j] = i;
     785           0 :                     dpd[i * out->linesize[pd] + j] = 128 * M_SQRT2 - hypot(i - 128, j - 128);
     786             :                 }
     787             :             }
     788             :         }
     789             :     }
     790          18 : }
     791             : 
     792             : const static char *positions_name[] = {
     793             :     "R", "B", "Cy", "Yl", "G", "Mg",
     794             : };
     795             : 
     796             : const static uint16_t positions[][14][3] = {
     797             :   {
     798             :     {  81,  90, 240 }, {  41, 240, 110 }, { 170, 166,  16 },
     799             :     { 210,  16, 146 }, { 145,  54,  34 }, { 106, 202, 222 },
     800             :     { 162,  44, 142 }, { 131, 156,  44 }, { 112,  72,  58 },
     801             :     {  84, 184, 198 }, {  65, 100, 212 }, {  35, 212, 114 },
     802             :     { 235, 128, 128 }, { 16, 128, 128 } },
     803             :   { {  63, 102, 240 }, {  32, 240, 118 }, { 188, 154,  16 },
     804             :     { 219,  16, 138 }, { 173,  42,  26 }, {  78, 214, 230 },
     805             :     {  28, 212, 120 }, {  51, 109, 212 }, {  63, 193, 204 },
     806             :     { 133,  63,  52 }, { 145, 147,  44 }, { 168,  44, 136 },
     807             :     { 235, 128, 128 }, { 16, 128, 128 } },
     808             :   { {  81*2,  90*2, 240*2 }, {  41*2, 240*2, 110*2 }, { 170*2, 166*2,  16*2 },
     809             :     { 210*2,  16*2, 146*2 }, { 145*2,  54*2,  34*2 }, { 106*2, 202*2, 222*2 },
     810             :     { 162*2,  44*2, 142*2 }, { 131*2, 156*2,  44*2 }, { 112*2,  72*2,  58*2 },
     811             :     {  84*2, 184*2, 198*2 }, {  65*2, 100*2, 212*2 }, {  35*2, 212*2, 114*2 },
     812             :     { 470, 256, 256 }, { 32, 256, 256 } },
     813             :   { {  63*2, 102*2, 240*2 }, {  32*2, 240*2, 118*2 }, { 188*2, 154*2,  16*2 },
     814             :     { 219*2,  16*2, 138*2 }, { 173*2,  42*2,  26*2 }, {  78*2, 214*2, 230*2 },
     815             :     {  28*2, 212*2, 120*2 }, {  51*2, 109*2, 212*2 }, {  63*2, 193*2, 204*2 },
     816             :     { 133*2,  63*2,  52*2 }, { 145*2, 147*2,  44*2 }, { 168*2,  44*2, 136*2 },
     817             :     { 470, 256, 256 }, { 32, 256, 256 } },
     818             :   { {  81*4,  90*4, 240*4 }, {  41*4, 240*4, 110*4 }, { 170*4, 166*4,  16*4 },
     819             :     { 210*4,  16*4, 146*4 }, { 145*4,  54*4,  34*4 }, { 106*4, 202*4, 222*4 },
     820             :     { 162*4,  44*4, 142*4 }, { 131*4, 156*4,  44*4 }, { 112*4,  72*4,  58*4 },
     821             :     {  84*4, 184*4, 198*4 }, {  65*4, 100*4, 212*4 }, {  35*4, 212*4, 114*4 },
     822             :     { 940, 512, 512 }, { 64, 512, 512 } },
     823             :   { {  63*4, 102*4, 240*4 }, {  32*4, 240*4, 118*4 }, { 188*4, 154*4,  16*4 },
     824             :     { 219*4,  16*4, 138*4 }, { 173*4,  42*4,  26*4 }, {  78*4, 214*4, 230*4 },
     825             :     {  28*4, 212*4, 120*4 }, {  51*4, 109*4, 212*4 }, {  63*4, 193*4, 204*4 },
     826             :     { 133*4,  63*4,  52*4 }, { 145*4, 147*4,  44*4 }, { 168*4,  44*4, 136*4 },
     827             :     { 940, 512, 512 }, { 64, 512, 512 } },
     828             :   { {  81*8,  90*4, 240*8 }, {  41*8, 240*8, 110*8 }, { 170*8, 166*8,  16*8 },
     829             :     { 210*8,  16*4, 146*8 }, { 145*8,  54*8,  34*8 }, { 106*8, 202*8, 222*8 },
     830             :     { 162*8,  44*4, 142*8 }, { 131*8, 156*8,  44*8 }, { 112*8,  72*8,  58*8 },
     831             :     {  84*8, 184*4, 198*8 }, {  65*8, 100*8, 212*8 }, {  35*8, 212*8, 114*8 },
     832             :     { 1880, 1024, 1024 }, { 128, 1024, 1024 } },
     833             :   { {  63*8, 102*8, 240*8 }, {  32*8, 240*8, 118*8 }, { 188*8, 154*8,  16*8 },
     834             :     { 219*8,  16*8, 138*8 }, { 173*8,  42*8,  26*8 }, {  78*8, 214*8, 230*8 },
     835             :     {  28*8, 212*8, 120*8 }, {  51*8, 109*8, 212*8 }, {  63*8, 193*8, 204*8 },
     836             :     { 133*8,  63*8,  52*8 }, { 145*8, 147*8,  44*8 }, { 168*8,  44*8, 136*8 },
     837             :     { 1880, 1024, 1024 }, { 128, 1024, 1024 } },
     838             :   { {  81*16,  90*16, 240*16 }, {  41*16, 240*16, 110*16 }, { 170*16, 166*16,  16*16 },
     839             :     { 210*16,  16*16, 146*16 }, { 145*16,  54*16,  34*16 }, { 106*16, 202*16, 222*16 },
     840             :     { 162*16,  44*16, 142*16 }, { 131*16, 156*16,  44*16 }, { 112*16,  72*16,  58*16 },
     841             :     {  84*16, 184*16, 198*16 }, {  65*16, 100*16, 212*16 }, {  35*16, 212*16, 114*16 },
     842             :     { 3760, 2048, 2048 }, { 256, 2048, 2048 } },
     843             :   { {  63*16, 102*16, 240*16 }, {  32*16, 240*16, 118*16 }, { 188*16, 154*16,  16*16 },
     844             :     { 219*16,  16*16, 138*16 }, { 173*16,  42*16,  26*16 }, {  78*16, 214*16, 230*16 },
     845             :     {  28*16, 212*16, 120*16 }, {  51*16, 109*16, 212*16 }, {  63*16, 193*16, 204*16 },
     846             :     { 133*16,  63*16,  52*16 }, { 145*16, 147*16,  44*16 }, { 168*16,  44*16, 136*16 },
     847             :     { 3760, 2048, 2048 }, { 256, 2048, 2048 } },
     848             : };
     849             : 
     850           0 : static void draw_dots(uint8_t *dst, int L, int v, float o)
     851             : {
     852           0 :     const float f = 1. - o;
     853           0 :     const float V = o * v;
     854           0 :     int l = L * 2;
     855             : 
     856           0 :     dst[ l - 3] = dst[ l - 3] * f + V;
     857           0 :     dst[ l + 3] = dst[ l + 3] * f + V;
     858           0 :     dst[-l - 3] = dst[-l - 3] * f + V;
     859           0 :     dst[-l + 3] = dst[-l + 3] * f + V;
     860             : 
     861           0 :     l += L;
     862             : 
     863           0 :     dst[ l - 3] = dst[ l - 3] * f + V;
     864           0 :     dst[ l + 3] = dst[ l + 3] * f + V;
     865           0 :     dst[ l - 2] = dst[ l - 2] * f + V;
     866           0 :     dst[ l + 2] = dst[ l + 2] * f + V;
     867           0 :     dst[-l - 3] = dst[-l - 3] * f + V;
     868           0 :     dst[-l + 3] = dst[-l + 3] * f + V;
     869           0 :     dst[-l - 2] = dst[-l - 2] * f + V;
     870           0 :     dst[-l + 2] = dst[-l + 2] * f + V;
     871           0 : }
     872             : 
     873           0 : static void draw_dots16(uint16_t *dst, int L, int v, float o)
     874             : {
     875           0 :     const float f = 1. - o;
     876           0 :     const float V = o * v;
     877           0 :     int l = L * 2;
     878             : 
     879           0 :     dst[ l - 3] = dst[ l - 3] * f + V;
     880           0 :     dst[ l + 3] = dst[ l + 3] * f + V;
     881           0 :     dst[-l - 3] = dst[-l - 3] * f + V;
     882           0 :     dst[-l + 3] = dst[-l + 3] * f + V;
     883             : 
     884           0 :     l += L;
     885             : 
     886           0 :     dst[ l - 3] = dst[ l - 3] * f + V;
     887           0 :     dst[ l + 3] = dst[ l + 3] * f + V;
     888           0 :     dst[ l - 2] = dst[ l - 2] * f + V;
     889           0 :     dst[ l + 2] = dst[ l + 2] * f + V;
     890           0 :     dst[-l - 3] = dst[-l - 3] * f + V;
     891           0 :     dst[-l + 3] = dst[-l + 3] * f + V;
     892           0 :     dst[-l - 2] = dst[-l - 2] * f + V;
     893           0 :     dst[-l + 2] = dst[-l + 2] * f + V;
     894           0 : }
     895             : 
     896          18 : static void none_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
     897             : {
     898          18 : }
     899             : 
     900           0 : static void draw_htext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4])
     901             : {
     902             :     const uint8_t *font;
     903             :     int font_height;
     904             :     int i, plane;
     905             : 
     906           0 :     font = avpriv_cga_font,   font_height =  8;
     907             : 
     908           0 :     for (plane = 0; plane < 4 && out->data[plane]; plane++) {
     909           0 :         for (i = 0; txt[i]; i++) {
     910             :             int char_y, mask;
     911           0 :             int v = color[plane];
     912             : 
     913           0 :             uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
     914           0 :             for (char_y = font_height - 1; char_y >= 0; char_y--) {
     915           0 :                 for (mask = 0x80; mask; mask >>= 1) {
     916           0 :                     if (font[txt[i] * font_height + char_y] & mask)
     917           0 :                         p[0] = p[0] * o2 + v * o1;
     918           0 :                     p++;
     919             :                 }
     920           0 :                 p += out->linesize[plane] - 8;
     921             :             }
     922             :         }
     923             :     }
     924           0 : }
     925             : 
     926           0 : static void draw_htext16(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint16_t color[4])
     927             : {
     928             :     const uint8_t *font;
     929             :     int font_height;
     930             :     int i, plane;
     931             : 
     932           0 :     font = avpriv_cga_font,   font_height =  8;
     933             : 
     934           0 :     for (plane = 0; plane < 4 && out->data[plane]; plane++) {
     935           0 :         for (i = 0; txt[i]; i++) {
     936             :             int char_y, mask;
     937           0 :             int v = color[plane];
     938             : 
     939           0 :             uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
     940           0 :             for (char_y = font_height - 1; char_y >= 0; char_y--) {
     941           0 :                 for (mask = 0x80; mask; mask >>= 1) {
     942           0 :                     if (font[txt[i] * font_height + char_y] & mask)
     943           0 :                         p[0] = p[0] * o2 + v * o1;
     944           0 :                     p++;
     945             :                 }
     946           0 :                 p += out->linesize[plane] / 2 - 8;
     947             :             }
     948             :         }
     949             :     }
     950           0 : }
     951             : 
     952           0 : static void color_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
     953             : {
     954           0 :     const int max = s->size - 1;
     955           0 :     const float o = s->opacity;
     956             :     int i;
     957             : 
     958           0 :     for (i = 0; i < 12; i++) {
     959           0 :         int x = positions[P][i][X];
     960           0 :         int y = positions[P][i][Y];
     961           0 :         int d = positions[P][i][D];
     962             : 
     963           0 :         draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
     964           0 :         draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
     965           0 :         draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
     966           0 :         if (out->data[3])
     967           0 :             draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
     968             :     }
     969             : 
     970           0 :     if (s->flags & 1) {
     971           0 :         int x = positions[P][12][X];
     972           0 :         int y = positions[P][12][Y];
     973           0 :         int d = positions[P][12][D];
     974             : 
     975           0 :         draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
     976           0 :         draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
     977           0 :         draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
     978           0 :         if (out->data[3])
     979           0 :             draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
     980             :     }
     981             : 
     982           0 :     if (s->flags & 2) {
     983           0 :         int x = positions[P][13][X];
     984           0 :         int y = positions[P][13][Y];
     985           0 :         int d = positions[P][13][D];
     986             : 
     987           0 :         draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
     988           0 :         draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
     989           0 :         draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
     990           0 :         if (out->data[3])
     991           0 :             draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
     992             :     }
     993             : 
     994           0 :     for (i = 0; i < 6 && s->flags & 4; i++) {
     995           0 :         uint16_t color[4] = { 0, 0, 0, 0 };
     996           0 :         int x = positions[P][i][X];
     997           0 :         int y = positions[P][i][Y];
     998           0 :         int d = positions[P][i][D];
     999             : 
    1000           0 :         color[D] = d;
    1001           0 :         color[X] = x;
    1002           0 :         color[Y] = y;
    1003           0 :         color[3] = max;
    1004             : 
    1005           0 :         if (x > max / 2)
    1006           0 :             x += 8;
    1007             :         else
    1008           0 :             x -= 14;
    1009           0 :         if (y > max / 2)
    1010           0 :             y += 8;
    1011             :         else
    1012           0 :             y -= 14;
    1013             : 
    1014           0 :         x = av_clip(x, 0, out->width - 9);
    1015           0 :         y = av_clip(y, 0, out->height - 9);
    1016           0 :         draw_htext16(out, x, y, o, 1. - o, positions_name[i], color);
    1017             :     }
    1018           0 : }
    1019             : 
    1020           0 : static void color_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
    1021             : {
    1022           0 :     const float o = s->opacity;
    1023             :     int i;
    1024             : 
    1025           0 :     for (i = 0; i < 12; i++) {
    1026           0 :         int x = positions[P][i][X];
    1027           0 :         int y = positions[P][i][Y];
    1028           0 :         int d = positions[P][i][D];
    1029             : 
    1030           0 :         draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
    1031           0 :         draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
    1032           0 :         draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
    1033           0 :         if (out->data[3])
    1034           0 :             draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
    1035             :     }
    1036             : 
    1037           0 :     if (s->flags & 1) {
    1038           0 :         int x = positions[P][12][X];
    1039           0 :         int y = positions[P][12][Y];
    1040           0 :         int d = positions[P][12][D];
    1041             : 
    1042           0 :         draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
    1043           0 :         draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
    1044           0 :         draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
    1045           0 :         if (out->data[3])
    1046           0 :             draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
    1047             :     }
    1048             : 
    1049           0 :     if (s->flags & 2) {
    1050           0 :         int x = positions[P][13][X];
    1051           0 :         int y = positions[P][13][Y];
    1052           0 :         int d = positions[P][12][D];
    1053             : 
    1054           0 :         draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
    1055           0 :         draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
    1056           0 :         draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
    1057           0 :         if (out->data[3])
    1058           0 :             draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
    1059             :     }
    1060             : 
    1061           0 :     for (i = 0; i < 6 && s->flags & 4; i++) {
    1062           0 :         uint8_t color[4] = { 0, 0, 0, 255 };
    1063           0 :         int x = positions[P][i][X];
    1064           0 :         int y = positions[P][i][Y];
    1065           0 :         int d = positions[P][i][D];
    1066             : 
    1067           0 :         color[D] = d;
    1068           0 :         color[X] = x;
    1069           0 :         color[Y] = y;
    1070             : 
    1071           0 :         if (x > 128)
    1072           0 :             x += 8;
    1073             :         else
    1074           0 :             x -= 14;
    1075           0 :         if (y > 128)
    1076           0 :             y += 8;
    1077             :         else
    1078           0 :             y -= 14;
    1079             : 
    1080           0 :         x = av_clip(x, 0, out->width - 9);
    1081           0 :         y = av_clip(y, 0, out->height - 9);
    1082           0 :         draw_htext(out, x, y, o, 1. - o, positions_name[i], color);
    1083             :     }
    1084           0 : }
    1085             : 
    1086           0 : static void green_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
    1087             : {
    1088           0 :     const int max = s->size - 1;
    1089           0 :     const float o = s->opacity;
    1090           0 :     const int m = s->mult;
    1091             :     int i;
    1092             : 
    1093           0 :     for (i = 0; i < 12; i++) {
    1094           0 :         int x = positions[P][i][X];
    1095           0 :         int y = positions[P][i][Y];
    1096             : 
    1097           0 :         draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
    1098           0 :         draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
    1099           0 :         draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
    1100           0 :         if (out->data[3])
    1101           0 :             draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
    1102             :     }
    1103             : 
    1104           0 :     if (s->flags & 1) {
    1105           0 :         int x = positions[P][12][X];
    1106           0 :         int y = positions[P][12][Y];
    1107             : 
    1108           0 :         draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
    1109           0 :         draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
    1110           0 :         draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
    1111           0 :         if (out->data[3])
    1112           0 :             draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
    1113             :     }
    1114             : 
    1115           0 :     if (s->flags & 2) {
    1116           0 :         int x = positions[P][13][X];
    1117           0 :         int y = positions[P][13][Y];
    1118             : 
    1119           0 :         draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
    1120           0 :         draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
    1121           0 :         draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
    1122           0 :         if (out->data[3])
    1123           0 :             draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
    1124             :     }
    1125             : 
    1126           0 :     for (i = 0; i < 6 && s->flags & 4; i++) {
    1127           0 :         const uint16_t color[4] = { 128 * m, 0, 0, max };
    1128           0 :         int x = positions[P][i][X];
    1129           0 :         int y = positions[P][i][Y];
    1130             : 
    1131           0 :         if (x > max / 2)
    1132           0 :             x += 8;
    1133             :         else
    1134           0 :             x -= 14;
    1135           0 :         if (y > max / 2)
    1136           0 :             y += 8;
    1137             :         else
    1138           0 :             y -= 14;
    1139             : 
    1140           0 :         x = av_clip(x, 0, out->width - 9);
    1141           0 :         y = av_clip(y, 0, out->height - 9);
    1142           0 :         draw_htext16(out, x, y, o, 1. - o, positions_name[i], color);
    1143             :     }
    1144           0 : }
    1145             : 
    1146           0 : static void green_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
    1147             : {
    1148           0 :     const float o = s->opacity;
    1149             :     int i;
    1150             : 
    1151           0 :     for (i = 0; i < 12; i++) {
    1152           0 :         int x = positions[P][i][X];
    1153           0 :         int y = positions[P][i][Y];
    1154             : 
    1155           0 :         draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
    1156           0 :         draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
    1157           0 :         draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
    1158           0 :         if (out->data[3])
    1159           0 :             draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
    1160             :     }
    1161             : 
    1162           0 :     if (s->flags & 1) {
    1163           0 :         int x = positions[P][12][X];
    1164           0 :         int y = positions[P][12][Y];
    1165             : 
    1166           0 :         draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
    1167           0 :         draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
    1168           0 :         draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
    1169           0 :         if (out->data[3])
    1170           0 :             draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
    1171             :     }
    1172             : 
    1173           0 :     if (s->flags & 2) {
    1174           0 :         int x = positions[P][13][X];
    1175           0 :         int y = positions[P][13][Y];
    1176             : 
    1177           0 :         draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
    1178           0 :         draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
    1179           0 :         draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
    1180           0 :         if (out->data[3])
    1181           0 :             draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
    1182             :     }
    1183             : 
    1184           0 :     for (i = 0; i < 6 && s->flags & 4; i++) {
    1185           0 :         const uint8_t color[4] = { 128, 0, 0, 255 };
    1186           0 :         int x = positions[P][i][X];
    1187           0 :         int y = positions[P][i][Y];
    1188             : 
    1189           0 :         if (x > 128)
    1190           0 :             x += 8;
    1191             :         else
    1192           0 :             x -= 14;
    1193           0 :         if (y > 128)
    1194           0 :             y += 8;
    1195             :         else
    1196           0 :             y -= 14;
    1197             : 
    1198           0 :         x = av_clip(x, 0, out->width - 9);
    1199           0 :         y = av_clip(y, 0, out->height - 9);
    1200           0 :         draw_htext(out, x, y, o, 1. - o, positions_name[i], color);
    1201             :     }
    1202           0 : }
    1203             : 
    1204          18 : static int filter_frame(AVFilterLink *inlink, AVFrame *in)
    1205             : {
    1206          18 :     AVFilterContext *ctx  = inlink->dst;
    1207          18 :     VectorscopeContext *s = ctx->priv;
    1208          18 :     AVFilterLink *outlink = ctx->outputs[0];
    1209             :     AVFrame *out;
    1210             :     int plane;
    1211             : 
    1212          18 :     if (s->colorspace) {
    1213           0 :         s->cs = (s->depth - 8) * 2 + s->colorspace - 1;
    1214             :     } else {
    1215          18 :         switch (in->colorspace) {
    1216           0 :         case AVCOL_SPC_SMPTE170M:
    1217             :         case AVCOL_SPC_BT470BG:
    1218           0 :             s->cs = (s->depth - 8) * 2 + 0;
    1219           0 :             break;
    1220          18 :         case AVCOL_SPC_BT709:
    1221             :         default:
    1222          18 :             s->cs = (s->depth - 8) * 2 + 1;
    1223             :         }
    1224             :     }
    1225             : 
    1226          18 :     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
    1227          18 :     if (!out) {
    1228           0 :         av_frame_free(&in);
    1229           0 :         return AVERROR(ENOMEM);
    1230             :     }
    1231          18 :     av_frame_copy_props(out, in);
    1232             : 
    1233          18 :     s->vectorscope(s, in, out, s->pd);
    1234          18 :     s->graticulef(s, out, s->x, s->y, s->pd, s->cs);
    1235             : 
    1236          90 :     for (plane = 0; plane < 4; plane++) {
    1237          72 :         if (out->data[plane]) {
    1238          54 :             out->data[plane]    += (s->size - 1) * out->linesize[plane];
    1239          54 :             out->linesize[plane] = -out->linesize[plane];
    1240             :         }
    1241             :     }
    1242             : 
    1243          18 :     av_frame_free(&in);
    1244          18 :     return ff_filter_frame(outlink, out);
    1245             : }
    1246             : 
    1247           6 : static int config_input(AVFilterLink *inlink)
    1248             : {
    1249           6 :     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
    1250           6 :     AVFilterContext *ctx = inlink->dst;
    1251           6 :     VectorscopeContext *s = ctx->priv;
    1252             : 
    1253           6 :     s->is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB);
    1254           6 :     s->size = 1 << desc->comp[0].depth;
    1255           6 :     s->mult = s->size / 256;
    1256           6 :     s->depth = desc->comp[0].depth;
    1257           6 :     s->tmin = s->lthreshold * (s->size - 1);
    1258           6 :     s->tmax = s->hthreshold * (s->size - 1);
    1259             : 
    1260           6 :     if (s->tmin > s->tmax) {
    1261           0 :         av_log(ctx, AV_LOG_ERROR, "low threshold should be less than high threshold\n");
    1262           0 :         return AVERROR(EINVAL);
    1263             :     }
    1264             : 
    1265           6 :     if (s->mode == GRAY && s->is_yuv)
    1266           2 :         s->pd = 0;
    1267             :     else {
    1268           4 :         if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1))
    1269           4 :             s->pd = 0;
    1270           0 :         else if ((s->x == 0 && s->y == 2) || (s->x == 2 && s->y == 0))
    1271           0 :             s->pd = 1;
    1272           0 :         else if ((s->x == 0 && s->y == 1) || (s->x == 1 && s->y == 0))
    1273           0 :             s->pd = 2;
    1274             :     }
    1275             : 
    1276           6 :     if (s->size == 256)
    1277           6 :         s->vectorscope = vectorscope8;
    1278             :     else
    1279           0 :         s->vectorscope = vectorscope16;
    1280             : 
    1281           6 :     s->graticulef = none_graticule;
    1282             : 
    1283           6 :     if (s->is_yuv && s->size == 256) {
    1284          12 :         if (s->graticule == 1)
    1285           0 :             s->graticulef = green_graticule;
    1286           6 :         else if (s->graticule == 2)
    1287           0 :             s->graticulef = color_graticule;
    1288           0 :     } else if (s->is_yuv) {
    1289           0 :         if (s->graticule == 1)
    1290           0 :             s->graticulef = green_graticule16;
    1291           0 :         else if (s->graticule == 2)
    1292           0 :             s->graticulef = color_graticule16;
    1293             :     }
    1294             : 
    1295           6 :     s->bg_color[3] = s->bgopacity * (s->size - 1);
    1296             : 
    1297           6 :     switch (inlink->format) {
    1298           0 :     case AV_PIX_FMT_GBRP12:
    1299             :     case AV_PIX_FMT_GBRP10:
    1300             :     case AV_PIX_FMT_GBRP9:
    1301             :     case AV_PIX_FMT_GBRAP:
    1302             :     case AV_PIX_FMT_GBRP:
    1303           0 :         s->bg_color[0] = 0;
    1304           0 :         s->bg_color[1] = 0;
    1305           0 :         s->bg_color[2] = 0;
    1306           0 :         break;
    1307           6 :     default:
    1308           6 :         s->bg_color[0] = 0;
    1309           6 :         s->bg_color[1] = s->size / 2 - 1;
    1310           6 :         s->bg_color[2] = s->size / 2 - 1;
    1311             :     }
    1312             : 
    1313           6 :     s->hsub = desc->log2_chroma_w;
    1314           6 :     s->vsub = desc->log2_chroma_h;
    1315           6 :     s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
    1316           6 :     s->planeheight[0] = s->planeheight[3] = inlink->h;
    1317           6 :     s->planewidth[1]  = s->planewidth[2]  = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
    1318           6 :     s->planewidth[0]  = s->planewidth[3]  = inlink->w;
    1319             : 
    1320           6 :     return 0;
    1321             : }
    1322             : 
    1323           6 : static av_cold void uninit(AVFilterContext *ctx)
    1324             : {
    1325           6 :     VectorscopeContext *s = ctx->priv;
    1326             : 
    1327           6 :     av_freep(&s->peak);
    1328           6 :     av_freep(&s->peak_memory);
    1329           6 : }
    1330             : 
    1331             : static const AVFilterPad inputs[] = {
    1332             :     {
    1333             :         .name         = "default",
    1334             :         .type         = AVMEDIA_TYPE_VIDEO,
    1335             :         .filter_frame = filter_frame,
    1336             :         .config_props = config_input,
    1337             :     },
    1338             :     { NULL }
    1339             : };
    1340             : 
    1341             : static const AVFilterPad outputs[] = {
    1342             :     {
    1343             :         .name         = "default",
    1344             :         .type         = AVMEDIA_TYPE_VIDEO,
    1345             :         .config_props = config_output,
    1346             :     },
    1347             :     { NULL }
    1348             : };
    1349             : 
    1350             : AVFilter ff_vf_vectorscope = {
    1351             :     .name          = "vectorscope",
    1352             :     .description   = NULL_IF_CONFIG_SMALL("Video vectorscope."),
    1353             :     .priv_size     = sizeof(VectorscopeContext),
    1354             :     .priv_class    = &vectorscope_class,
    1355             :     .query_formats = query_formats,
    1356             :     .uninit        = uninit,
    1357             :     .inputs        = inputs,
    1358             :     .outputs       = outputs,
    1359             : };

Generated by: LCOV version 1.13