LCOV - code coverage report
Current view: top level - libavfilter - vf_pseudocolor.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 252 0.0 %
Date: 2017-12-16 13:57:32 Functions: 0 14 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 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/attributes.h"
      22             : #include "libavutil/common.h"
      23             : #include "libavutil/eval.h"
      24             : #include "libavutil/imgutils.h"
      25             : #include "libavutil/opt.h"
      26             : #include "libavutil/pixdesc.h"
      27             : #include "avfilter.h"
      28             : #include "formats.h"
      29             : #include "internal.h"
      30             : #include "video.h"
      31             : 
      32             : static const char *const var_names[] = {
      33             :     "w",        ///< width of the input video
      34             :     "h",        ///< height of the input video
      35             :     "val",      ///< input value for the pixel
      36             :     "ymin",
      37             :     "umin",
      38             :     "vmin",
      39             :     "amin",
      40             :     "ymax",
      41             :     "umax",
      42             :     "vmax",
      43             :     "amax",
      44             :     NULL
      45             : };
      46             : 
      47             : enum var_name {
      48             :     VAR_W,
      49             :     VAR_H,
      50             :     VAR_VAL,
      51             :     VAR_YMIN,
      52             :     VAR_UMIN,
      53             :     VAR_VMIN,
      54             :     VAR_AMIN,
      55             :     VAR_YMAX,
      56             :     VAR_UMAX,
      57             :     VAR_VMAX,
      58             :     VAR_AMAX,
      59             :     VAR_VARS_NB
      60             : };
      61             : 
      62             : typedef struct PseudoColorContext {
      63             :     const AVClass *class;
      64             :     int max;
      65             :     int index;
      66             :     int nb_planes;
      67             :     int color;
      68             :     int linesize[4];
      69             :     int width[4], height[4];
      70             :     double var_values[VAR_VARS_NB];
      71             :     char   *comp_expr_str[4];
      72             :     AVExpr *comp_expr[4];
      73             :     float lut[4][256*256];
      74             : 
      75             :     void (*filter[4])(int max, int width, int height,
      76             :                       const uint8_t *index, const uint8_t *src,
      77             :                       uint8_t *dst,
      78             :                       ptrdiff_t ilinesize,
      79             :                       ptrdiff_t slinesize,
      80             :                       ptrdiff_t dlinesize,
      81             :                       float *lut);
      82             : } PseudoColorContext;
      83             : 
      84             : #define OFFSET(x) offsetof(PseudoColorContext, x)
      85             : #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
      86             : 
      87             : static const AVOption pseudocolor_options[] = {
      88             :     { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
      89             :     { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
      90             :     { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
      91             :     { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
      92             :     { "i",  "set component as base",       OFFSET(index),            AV_OPT_TYPE_INT,    {.i64=0}, 0, 3, .flags = FLAGS },
      93             :     { NULL }
      94             : };
      95             : 
      96             : static const enum AVPixelFormat pix_fmts[] = {
      97             :     AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16,
      98             :     AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
      99             :     AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P,
     100             :     AV_PIX_FMT_YUV444P, AV_PIX_FMT_GBRP,
     101             :     AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GBRAP,
     102             :     AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUVA422P9,
     103             :     AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUVA420P9,
     104             :     AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUVA444P9,
     105             :     AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUVA420P10,
     106             :     AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUVA422P10,
     107             :     AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10,
     108             :     AV_PIX_FMT_YUV420P12,
     109             :     AV_PIX_FMT_YUV422P12,
     110             :     AV_PIX_FMT_YUV444P12,
     111             :     AV_PIX_FMT_YUV420P14,
     112             :     AV_PIX_FMT_YUV422P14,
     113             :     AV_PIX_FMT_YUV444P14,
     114             :     AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUVA420P16,
     115             :     AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUVA422P16,
     116             :     AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUVA444P16,
     117             :     AV_PIX_FMT_GBRP9,
     118             :     AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
     119             :     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
     120             :     AV_PIX_FMT_GBRP14,
     121             :     AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16,
     122             :     AV_PIX_FMT_NONE
     123             : };
     124             : 
     125           0 : static int query_formats(AVFilterContext *ctx)
     126             : {
     127           0 :     AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
     128           0 :     if (!fmts_list)
     129           0 :         return AVERROR(ENOMEM);
     130           0 :     return ff_set_common_formats(ctx, fmts_list);
     131             : }
     132             : 
     133           0 : static void pseudocolor_filter(int max, int width, int height,
     134             :                                const uint8_t *index,
     135             :                                const uint8_t *src,
     136             :                                uint8_t *dst,
     137             :                                ptrdiff_t ilinesize,
     138             :                                ptrdiff_t slinesize,
     139             :                                ptrdiff_t dlinesize,
     140             :                                float *lut)
     141             : {
     142             :     int x, y;
     143             : 
     144           0 :     for (y = 0; y < height; y++) {
     145           0 :         for (x = 0; x < width; x++) {
     146           0 :             int v = lut[index[x]];
     147             : 
     148           0 :             if (v >= 0 && v <= max) {
     149           0 :                 dst[x] = v;
     150             :             } else {
     151           0 :                 dst[x] = src[x];
     152             :             }
     153             :         }
     154           0 :         index += ilinesize;
     155           0 :         src += slinesize;
     156           0 :         dst += dlinesize;
     157             :     }
     158           0 : }
     159             : 
     160           0 : static void pseudocolor_filter_11(int max, int width, int height,
     161             :                                   const uint8_t *index,
     162             :                                   const uint8_t *src,
     163             :                                   uint8_t *dst,
     164             :                                   ptrdiff_t ilinesize,
     165             :                                   ptrdiff_t slinesize,
     166             :                                   ptrdiff_t dlinesize,
     167             :                                   float *lut)
     168             : {
     169             :     int x, y;
     170             : 
     171           0 :     for (y = 0; y < height; y++) {
     172           0 :         for (x = 0; x < width; x++) {
     173           0 :             int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
     174             : 
     175           0 :             if (v >= 0 && v <= max) {
     176           0 :                 dst[x] = v;
     177             :             } else {
     178           0 :                 dst[x] = src[x];
     179             :             }
     180             :         }
     181           0 :         src += slinesize;
     182           0 :         dst += dlinesize;
     183             :     }
     184           0 : }
     185             : 
     186           0 : static void pseudocolor_filter_11d(int max, int width, int height,
     187             :                                    const uint8_t *index,
     188             :                                    const uint8_t *src,
     189             :                                    uint8_t *dst,
     190             :                                    ptrdiff_t ilinesize,
     191             :                                    ptrdiff_t slinesize,
     192             :                                    ptrdiff_t dlinesize,
     193             :                                    float *lut)
     194             : {
     195             :     int x, y;
     196             : 
     197           0 :     for (y = 0; y < height; y++) {
     198           0 :         for (x = 0; x < width; x++) {
     199           0 :             int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
     200             : 
     201           0 :             if (v >= 0 && v <= max) {
     202           0 :                 dst[x] = v;
     203             :             } else {
     204           0 :                 dst[x] = src[x];
     205             :             }
     206             :         }
     207           0 :         src += slinesize;
     208           0 :         dst += dlinesize;
     209             :     }
     210           0 : }
     211             : 
     212           0 : static void pseudocolor_filter_10(int max, int width, int height,
     213             :                                   const uint8_t *index,
     214             :                                   const uint8_t *src,
     215             :                                   uint8_t *dst,
     216             :                                   ptrdiff_t ilinesize,
     217             :                                   ptrdiff_t slinesize,
     218             :                                   ptrdiff_t dlinesize,
     219             :                                   float *lut)
     220             : {
     221             :     int x, y;
     222             : 
     223           0 :     for (y = 0; y < height; y++) {
     224           0 :         for (x = 0; x < width; x++) {
     225           0 :             int v = lut[index[x << 1]];
     226             : 
     227           0 :             if (v >= 0 && v <= max) {
     228           0 :                 dst[x] = v;
     229             :             } else {
     230           0 :                 dst[x] = src[x];
     231             :             }
     232             :         }
     233           0 :         index += ilinesize;
     234           0 :         src += slinesize;
     235           0 :         dst += dlinesize;
     236             :     }
     237           0 : }
     238             : 
     239           0 : static void pseudocolor_filter_10d(int max, int width, int height,
     240             :                                    const uint8_t *index,
     241             :                                    const uint8_t *src,
     242             :                                    uint8_t *dst,
     243             :                                    ptrdiff_t ilinesize,
     244             :                                    ptrdiff_t slinesize,
     245             :                                    ptrdiff_t dlinesize,
     246             :                                    float *lut)
     247             : {
     248             :     int x, y;
     249             : 
     250           0 :     for (y = 0; y < height; y++) {
     251           0 :         for (x = 0; x < width; x++) {
     252           0 :             int v = lut[index[x >> 1]];
     253             : 
     254           0 :             if (v >= 0 && v <= max) {
     255           0 :                 dst[x] = v;
     256             :             } else {
     257           0 :                 dst[x] = src[x];
     258             :             }
     259             :         }
     260           0 :         index += ilinesize;
     261           0 :         src += slinesize;
     262           0 :         dst += dlinesize;
     263             :     }
     264           0 : }
     265             : 
     266           0 : static void pseudocolor_filter_16(int max, int width, int height,
     267             :                                   const uint8_t *iindex,
     268             :                                   const uint8_t *ssrc,
     269             :                                   uint8_t *ddst,
     270             :                                   ptrdiff_t ilinesize,
     271             :                                   ptrdiff_t slinesize,
     272             :                                   ptrdiff_t dlinesize,
     273             :                                   float *lut)
     274             : {
     275           0 :     const uint16_t *index = (const uint16_t *)iindex;
     276           0 :     const uint16_t *src = (const uint16_t *)ssrc;
     277           0 :     uint16_t *dst = (uint16_t *)ddst;
     278             :     int x, y;
     279             : 
     280           0 :     for (y = 0; y < height; y++) {
     281           0 :         for (x = 0; x < width; x++) {
     282           0 :             int v = lut[index[x]];
     283             : 
     284           0 :             if (v >= 0 && v <= max) {
     285           0 :                 dst[x] = v;
     286             :             } else {
     287           0 :                 dst[x] = src[x];
     288             :             }
     289             :         }
     290           0 :         index += ilinesize / 2;
     291           0 :         src += slinesize / 2;
     292           0 :         dst += dlinesize / 2;
     293             :     }
     294           0 : }
     295             : 
     296           0 : static void pseudocolor_filter_16_10(int max, int width, int height,
     297             :                                      const uint8_t *iindex,
     298             :                                      const uint8_t *ssrc,
     299             :                                      uint8_t *ddst,
     300             :                                      ptrdiff_t ilinesize,
     301             :                                      ptrdiff_t slinesize,
     302             :                                      ptrdiff_t dlinesize,
     303             :                                      float *lut)
     304             : {
     305           0 :     const uint16_t *index = (const uint16_t *)iindex;
     306           0 :     const uint16_t *src = (const uint16_t *)ssrc;
     307           0 :     uint16_t *dst = (uint16_t *)ddst;
     308             :     int x, y;
     309             : 
     310           0 :     for (y = 0; y < height; y++) {
     311           0 :         for (x = 0; x < width; x++) {
     312           0 :             int v = lut[index[x << 1]];
     313             : 
     314           0 :             if (v >= 0 && v <= max) {
     315           0 :                 dst[x] = v;
     316             :             } else {
     317           0 :                 dst[x] = src[x];
     318             :             }
     319             :         }
     320           0 :         index += ilinesize / 2;
     321           0 :         src += slinesize / 2;
     322           0 :         dst += dlinesize / 2;
     323             :     }
     324           0 : }
     325             : 
     326           0 : static void pseudocolor_filter_16_10d(int max, int width, int height,
     327             :                                       const uint8_t *iindex,
     328             :                                       const uint8_t *ssrc,
     329             :                                       uint8_t *ddst,
     330             :                                       ptrdiff_t ilinesize,
     331             :                                       ptrdiff_t slinesize,
     332             :                                       ptrdiff_t dlinesize,
     333             :                                       float *lut)
     334             : {
     335           0 :     const uint16_t *index = (const uint16_t *)iindex;
     336           0 :     const uint16_t *src = (const uint16_t *)ssrc;
     337           0 :     uint16_t *dst = (uint16_t *)ddst;
     338             :     int x, y;
     339             : 
     340           0 :     for (y = 0; y < height; y++) {
     341           0 :         for (x = 0; x < width; x++) {
     342           0 :             int v = lut[index[x >> 1]];
     343             : 
     344           0 :             if (v >= 0 && v <= max) {
     345           0 :                 dst[x] = v;
     346             :             } else {
     347           0 :                 dst[x] = src[x];
     348             :             }
     349             :         }
     350           0 :         index += ilinesize / 2;
     351           0 :         src += slinesize / 2;
     352           0 :         dst += dlinesize / 2;
     353             :     }
     354           0 : }
     355             : 
     356           0 : static void pseudocolor_filter_16_11(int max, int width, int height,
     357             :                                      const uint8_t *iindex,
     358             :                                      const uint8_t *ssrc,
     359             :                                      uint8_t *ddst,
     360             :                                      ptrdiff_t ilinesize,
     361             :                                      ptrdiff_t slinesize,
     362             :                                      ptrdiff_t dlinesize,
     363             :                                      float *lut)
     364             : {
     365           0 :     const uint16_t *index = (const uint16_t *)iindex;
     366           0 :     const uint16_t *src = (const uint16_t *)ssrc;
     367           0 :     uint16_t *dst = (uint16_t *)ddst;
     368             :     int x, y;
     369             : 
     370           0 :     ilinesize /= 2;
     371           0 :     dlinesize /= 2;
     372           0 :     slinesize /= 2;
     373             : 
     374           0 :     for (y = 0; y < height; y++) {
     375           0 :         for (x = 0; x < width; x++) {
     376           0 :             int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
     377             : 
     378           0 :             if (v >= 0 && v <= max) {
     379           0 :                 dst[x] = v;
     380             :             } else {
     381           0 :                 dst[x] = src[x];
     382             :             }
     383             :         }
     384           0 :         src += slinesize;
     385           0 :         dst += dlinesize;
     386             :     }
     387           0 : }
     388             : 
     389           0 : static void pseudocolor_filter_16_11d(int max, int width, int height,
     390             :                                       const uint8_t *iindex,
     391             :                                       const uint8_t *ssrc,
     392             :                                       uint8_t *ddst,
     393             :                                       ptrdiff_t ilinesize,
     394             :                                       ptrdiff_t slinesize,
     395             :                                       ptrdiff_t dlinesize,
     396             :                                       float *lut)
     397             : {
     398           0 :     const uint16_t *index = (const uint16_t *)iindex;
     399           0 :     const uint16_t *src = (const uint16_t *)ssrc;
     400           0 :     uint16_t *dst = (uint16_t *)ddst;
     401             :     int x, y;
     402             : 
     403           0 :     ilinesize /= 2;
     404           0 :     dlinesize /= 2;
     405           0 :     slinesize /= 2;
     406             : 
     407           0 :     for (y = 0; y < height; y++) {
     408           0 :         for (x = 0; x < width; x++) {
     409           0 :             int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
     410             : 
     411           0 :             if (v >= 0 && v <= max) {
     412           0 :                 dst[x] = v;
     413             :             } else {
     414           0 :                 dst[x] = src[x];
     415             :             }
     416             :         }
     417           0 :         src += slinesize;
     418           0 :         dst += dlinesize;
     419             :     }
     420           0 : }
     421             : 
     422           0 : static int config_input(AVFilterLink *inlink)
     423             : {
     424           0 :     AVFilterContext *ctx = inlink->dst;
     425           0 :     PseudoColorContext *s = ctx->priv;
     426           0 :     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     427             :     int depth, ret, hsub, vsub, color;
     428             : 
     429           0 :     depth = desc->comp[0].depth;
     430           0 :     s->max = (1 << depth) - 1;
     431           0 :     s->nb_planes = av_pix_fmt_count_planes(inlink->format);
     432             : 
     433           0 :     if (s->index >= s->nb_planes) {
     434           0 :         av_log(ctx, AV_LOG_ERROR, "index out of allowed range\n");
     435           0 :         return AVERROR(EINVAL);
     436             :     }
     437             : 
     438           0 :     if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
     439           0 :         return ret;
     440             : 
     441           0 :     hsub = desc->log2_chroma_w;
     442           0 :     vsub = desc->log2_chroma_h;
     443           0 :     s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
     444           0 :     s->height[0] = s->height[3] = inlink->h;
     445           0 :     s->width[1]  = s->width[2]  = AV_CEIL_RSHIFT(inlink->w, hsub);
     446           0 :     s->width[0]  = s->width[3]  = inlink->w;
     447             : 
     448           0 :     s->var_values[VAR_W] = inlink->w;
     449           0 :     s->var_values[VAR_H] = inlink->h;
     450             : 
     451           0 :     s->var_values[VAR_YMIN] = 16 * (1 << (depth - 8));
     452           0 :     s->var_values[VAR_UMIN] = 16 * (1 << (depth - 8));
     453           0 :     s->var_values[VAR_VMIN] = 16 * (1 << (depth - 8));
     454           0 :     s->var_values[VAR_AMIN] = 0;
     455           0 :     s->var_values[VAR_YMAX] = 235 * (1 << (depth - 8));
     456           0 :     s->var_values[VAR_UMAX] = 240 * (1 << (depth - 8));
     457           0 :     s->var_values[VAR_VMAX] = 240 * (1 << (depth - 8));
     458           0 :     s->var_values[VAR_AMAX] = s->max;
     459             : 
     460           0 :     for (color = 0; color < s->nb_planes; color++) {
     461             :         double res;
     462             :         int val;
     463             : 
     464             :         /* create the parsed expression */
     465           0 :         av_expr_free(s->comp_expr[color]);
     466           0 :         s->comp_expr[color] = NULL;
     467           0 :         ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
     468             :                             var_names, NULL, NULL, NULL, NULL, 0, ctx);
     469           0 :         if (ret < 0) {
     470           0 :             av_log(ctx, AV_LOG_ERROR,
     471             :                    "Error when parsing the expression '%s' for the component %d and color %d.\n",
     472             :                    s->comp_expr_str[color], color, color);
     473           0 :             return AVERROR(EINVAL);
     474             :         }
     475             : 
     476             :         /* compute the lut */
     477           0 :         for (val = 0; val < FF_ARRAY_ELEMS(s->lut[color]); val++) {
     478           0 :             s->var_values[VAR_VAL] = val;
     479             : 
     480           0 :             res = av_expr_eval(s->comp_expr[color], s->var_values, s);
     481           0 :             if (isnan(res)) {
     482           0 :                 av_log(ctx, AV_LOG_ERROR,
     483             :                        "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
     484             :                        s->comp_expr_str[color], val, color);
     485           0 :                 return AVERROR(EINVAL);
     486             :             }
     487           0 :             s->lut[color][val] = res;
     488             :         }
     489             :     }
     490             : 
     491           0 :     switch (inlink->format) {
     492           0 :     case AV_PIX_FMT_YUV444P:
     493             :     case AV_PIX_FMT_YUVA444P:
     494             :     case AV_PIX_FMT_GBRP:
     495             :     case AV_PIX_FMT_GBRAP:
     496             :     case AV_PIX_FMT_GRAY8:
     497           0 :         s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter;
     498           0 :         break;
     499           0 :     case AV_PIX_FMT_YUV420P:
     500             :     case AV_PIX_FMT_YUVA420P:
     501           0 :         switch (s->index) {
     502           0 :         case 0:
     503             :         case 3:
     504           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter;
     505           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter_11;
     506           0 :             break;
     507           0 :         case 1:
     508             :         case 2:
     509           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter_11d;
     510           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter;
     511           0 :             break;
     512             :         }
     513           0 :         break;
     514           0 :     case AV_PIX_FMT_YUV422P:
     515             :     case AV_PIX_FMT_YUVA422P:
     516           0 :         switch (s->index) {
     517           0 :         case 0:
     518             :         case 3:
     519           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter;
     520           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter_10;
     521           0 :             break;
     522           0 :         case 1:
     523             :         case 2:
     524           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter_10d;
     525           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter;
     526           0 :             break;
     527             :         }
     528           0 :         break;
     529           0 :     case AV_PIX_FMT_YUV444P9:
     530             :     case AV_PIX_FMT_YUVA444P9:
     531             :     case AV_PIX_FMT_YUV444P10:
     532             :     case AV_PIX_FMT_YUVA444P10:
     533             :     case AV_PIX_FMT_YUV444P12:
     534             :     case AV_PIX_FMT_YUV444P14:
     535             :     case AV_PIX_FMT_YUV444P16:
     536             :     case AV_PIX_FMT_YUVA444P16:
     537             :     case AV_PIX_FMT_GBRP9:
     538             :     case AV_PIX_FMT_GBRP10:
     539             :     case AV_PIX_FMT_GBRP12:
     540             :     case AV_PIX_FMT_GBRP14:
     541             :     case AV_PIX_FMT_GBRP16:
     542             :     case AV_PIX_FMT_GBRAP10:
     543             :     case AV_PIX_FMT_GBRAP12:
     544             :     case AV_PIX_FMT_GBRAP16:
     545             :     case AV_PIX_FMT_GRAY9:
     546             :     case AV_PIX_FMT_GRAY10:
     547             :     case AV_PIX_FMT_GRAY12:
     548             :     case AV_PIX_FMT_GRAY16:
     549           0 :         s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter_16;
     550           0 :         break;
     551           0 :     case AV_PIX_FMT_YUV422P9:
     552             :     case AV_PIX_FMT_YUVA422P9:
     553             :     case AV_PIX_FMT_YUV422P10:
     554             :     case AV_PIX_FMT_YUVA422P10:
     555             :     case AV_PIX_FMT_YUV422P12:
     556             :     case AV_PIX_FMT_YUV422P14:
     557             :     case AV_PIX_FMT_YUV422P16:
     558             :     case AV_PIX_FMT_YUVA422P16:
     559           0 :         switch (s->index) {
     560           0 :         case 0:
     561             :         case 3:
     562           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter_16;
     563           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter_16_10;
     564           0 :             break;
     565           0 :         case 1:
     566             :         case 2:
     567           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter_16_10d;
     568           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter_16;
     569           0 :             break;
     570             :         }
     571           0 :         break;
     572           0 :     case AV_PIX_FMT_YUV420P9:
     573             :     case AV_PIX_FMT_YUVA420P9:
     574             :     case AV_PIX_FMT_YUV420P10:
     575             :     case AV_PIX_FMT_YUVA420P10:
     576             :     case AV_PIX_FMT_YUV420P12:
     577             :     case AV_PIX_FMT_YUV420P14:
     578             :     case AV_PIX_FMT_YUV420P16:
     579             :     case AV_PIX_FMT_YUVA420P16:
     580           0 :         switch (s->index) {
     581           0 :         case 0:
     582             :         case 3:
     583           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter_16;
     584           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter_16_11;
     585           0 :             break;
     586           0 :         case 1:
     587             :         case 2:
     588           0 :             s->filter[0] = s->filter[3] = pseudocolor_filter_16_11d;
     589           0 :             s->filter[1] = s->filter[2] = pseudocolor_filter_16;
     590           0 :             break;
     591             :         }
     592           0 :         break;
     593             :     }
     594             : 
     595           0 :     return 0;
     596             : }
     597             : 
     598           0 : static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     599             : {
     600           0 :     AVFilterContext *ctx = inlink->dst;
     601           0 :     PseudoColorContext *s = ctx->priv;
     602           0 :     AVFilterLink *outlink = ctx->outputs[0];
     603             :     AVFrame *out;
     604             :     int plane;
     605             : 
     606           0 :     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     607           0 :     if (!out) {
     608           0 :         av_frame_free(&in);
     609           0 :         return AVERROR(ENOMEM);
     610             :     }
     611           0 :     av_frame_copy_props(out, in);
     612             : 
     613           0 :     for (plane = 0; plane < s->nb_planes; plane++) {
     614           0 :         const uint8_t *index = in->data[s->index];
     615           0 :         const uint8_t *src = in->data[plane];
     616           0 :         uint8_t *dst = out->data[plane];
     617           0 :         ptrdiff_t ilinesize = in->linesize[s->index];
     618           0 :         ptrdiff_t slinesize = in->linesize[plane];
     619           0 :         ptrdiff_t dlinesize = out->linesize[plane];
     620             : 
     621           0 :         s->filter[plane](s->max, s->width[plane], s->height[plane],
     622             :                          index, src, dst, ilinesize, slinesize,
     623           0 :                          dlinesize, s->lut[plane]);
     624             :     }
     625             : 
     626           0 :     av_frame_free(&in);
     627           0 :     return ff_filter_frame(outlink, out);
     628             : }
     629             : 
     630             : static const AVFilterPad inputs[] = {
     631             :     {
     632             :         .name         = "default",
     633             :         .type         = AVMEDIA_TYPE_VIDEO,
     634             :         .filter_frame = filter_frame,
     635             :         .config_props = config_input,
     636             :     },
     637             :     { NULL }
     638             : };
     639             : 
     640             : static const AVFilterPad outputs[] = {
     641             :     {
     642             :         .name = "default",
     643             :         .type = AVMEDIA_TYPE_VIDEO,
     644             :     },
     645             :     { NULL }
     646             : };
     647             : 
     648           0 : static av_cold void uninit(AVFilterContext *ctx)
     649             : {
     650           0 :     PseudoColorContext *s = ctx->priv;
     651             :     int i;
     652             : 
     653           0 :     for (i = 0; i < 4; i++) {
     654           0 :         av_expr_free(s->comp_expr[i]);
     655           0 :         s->comp_expr[i] = NULL;
     656             :     }
     657           0 : }
     658             : 
     659             : AVFILTER_DEFINE_CLASS(pseudocolor);
     660             : 
     661             : AVFilter ff_vf_pseudocolor = {
     662             :     .name          = "pseudocolor",
     663             :     .description   = NULL_IF_CONFIG_SMALL("Make pseudocolored video frames."),
     664             :     .priv_size     = sizeof(PseudoColorContext),
     665             :     .priv_class    = &pseudocolor_class,
     666             :     .uninit        = uninit,
     667             :     .query_formats = query_formats,
     668             :     .inputs        = inputs,
     669             :     .outputs       = outputs,
     670             :     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
     671             : };

Generated by: LCOV version 1.13