Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2012-2013 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/opt.h"
  23. #include "libavutil/parseutils.h"
  24. #include "libavutil/pixdesc.h"
  25. #include "libavutil/imgutils.h"
  26. #include "libavutil/intreadwrite.h"
  27. #include "avfilter.h"
  28. #include "formats.h"
  29. #include "internal.h"
  30. #include "video.h"
  31.  
  32. enum HistogramMode {
  33.     MODE_LEVELS,
  34.     MODE_WAVEFORM,
  35.     MODE_COLOR,
  36.     MODE_COLOR2,
  37.     MODE_NB
  38. };
  39.  
  40. typedef struct HistogramContext {
  41.     const AVClass *class;               ///< AVClass context for log and options purpose
  42.     int mode;                           ///< HistogramMode
  43.     unsigned       histogram[256*256];
  44.     int            histogram_size;
  45.     int            mult;
  46.     int            ncomp;
  47.     const uint8_t  *bg_color;
  48.     const uint8_t  *fg_color;
  49.     int            level_height;
  50.     int            scale_height;
  51.     int            step;
  52.     int            waveform_mode;
  53.     int            waveform_mirror;
  54.     int            display_mode;
  55.     int            levels_mode;
  56.     const AVPixFmtDescriptor *desc, *odesc;
  57.     int            components;
  58.     int            planewidth[4];
  59.     int            planeheight[4];
  60. } HistogramContext;
  61.  
  62. #define OFFSET(x) offsetof(HistogramContext, x)
  63. #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
  64.  
  65. static const AVOption histogram_options[] = {
  66.     { "mode", "set histogram mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_LEVELS}, 0, MODE_NB-1, FLAGS, "mode"},
  67.     { "levels", "standard histogram", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LEVELS}, 0, 0, FLAGS, "mode" },
  68.     { "waveform", "per row/column luminance graph", 0, AV_OPT_TYPE_CONST, {.i64=MODE_WAVEFORM}, 0, 0, FLAGS, "mode" },
  69.     { "color", "chroma values in vectorscope", 0, AV_OPT_TYPE_CONST, {.i64=MODE_COLOR}, 0, 0, FLAGS, "mode" },
  70.     { "color2", "chroma values in vectorscope", 0, AV_OPT_TYPE_CONST, {.i64=MODE_COLOR2}, 0, 0, FLAGS, "mode" },
  71.     { "level_height", "set level height", OFFSET(level_height), AV_OPT_TYPE_INT, {.i64=200}, 50, 2048, FLAGS},
  72.     { "scale_height", "set scale height", OFFSET(scale_height), AV_OPT_TYPE_INT, {.i64=12}, 0, 40, FLAGS},
  73.     { "step", "set waveform step value", OFFSET(step), AV_OPT_TYPE_INT, {.i64=10}, 1, 255, FLAGS},
  74.     { "waveform_mode", "set waveform mode", OFFSET(waveform_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "waveform_mode"},
  75.     { "row",   NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "waveform_mode" },
  76.     { "column", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "waveform_mode" },
  77.     { "waveform_mirror", "set waveform mirroring", OFFSET(waveform_mirror), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "waveform_mirror"},
  78.     { "display_mode", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "display_mode"},
  79.     { "parade",  NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "display_mode" },
  80.     { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "display_mode" },
  81.     { "levels_mode", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "levels_mode"},
  82.     { "linear",      NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "levels_mode" },
  83.     { "logarithmic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "levels_mode" },
  84.     { "components", "set color components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 1, 15, FLAGS},
  85.     { NULL }
  86. };
  87.  
  88. AVFILTER_DEFINE_CLASS(histogram);
  89.  
  90. static const enum AVPixelFormat color_pix_fmts[] = {
  91.     AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVJ444P,
  92.     AV_PIX_FMT_NONE
  93. };
  94.  
  95. static const enum AVPixelFormat levels_in_pix_fmts[] = {
  96.     AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P,
  97.     AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P,
  98.     AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUVJ411P,
  99.     AV_PIX_FMT_YUV440P,  AV_PIX_FMT_YUV410P,
  100.     AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
  101.     AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
  102.     AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
  103.     AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
  104.     AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
  105.     AV_PIX_FMT_GBRAP,    AV_PIX_FMT_GBRP,
  106.     AV_PIX_FMT_GBRP9,    AV_PIX_FMT_GBRP10,
  107.     AV_PIX_FMT_GRAY8,
  108.     AV_PIX_FMT_NONE
  109. };
  110.  
  111. static const enum AVPixelFormat levels_out_yuv8_pix_fmts[] = {
  112.     AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P,
  113.     AV_PIX_FMT_NONE
  114. };
  115.  
  116. static const enum AVPixelFormat levels_out_yuv9_pix_fmts[] = {
  117.     AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUV444P9,
  118.     AV_PIX_FMT_NONE
  119. };
  120.  
  121. static const enum AVPixelFormat levels_out_yuv10_pix_fmts[] = {
  122.     AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUV444P10,
  123.     AV_PIX_FMT_NONE
  124. };
  125.  
  126. static const enum AVPixelFormat levels_out_rgb8_pix_fmts[] = {
  127.     AV_PIX_FMT_GBRAP,    AV_PIX_FMT_GBRP,
  128.     AV_PIX_FMT_NONE
  129. };
  130.  
  131. static const enum AVPixelFormat levels_out_rgb9_pix_fmts[] = {
  132.     AV_PIX_FMT_GBRP9,
  133.     AV_PIX_FMT_NONE
  134. };
  135.  
  136. static const enum AVPixelFormat levels_out_rgb10_pix_fmts[] = {
  137.     AV_PIX_FMT_GBRP10,
  138.     AV_PIX_FMT_NONE
  139. };
  140.  
  141. static const enum AVPixelFormat waveform_pix_fmts[] = {
  142.      AV_PIX_FMT_GBRP,     AV_PIX_FMT_GBRAP,
  143.      AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV420P,
  144.      AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV440P,
  145.      AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P,
  146.      AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P,
  147.      AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
  148.      AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
  149.      AV_PIX_FMT_GRAY8,
  150.      AV_PIX_FMT_NONE
  151. };
  152.  
  153. static int query_formats(AVFilterContext *ctx)
  154. {
  155.     HistogramContext *h = ctx->priv;
  156.     const enum AVPixelFormat *pix_fmts;
  157.     AVFilterFormats *fmts_list;
  158.  
  159.     switch (h->mode) {
  160.     case MODE_WAVEFORM:
  161.         pix_fmts = waveform_pix_fmts;
  162.         break;
  163.     case MODE_LEVELS:
  164.     {
  165.         AVFilterFormats *avff;
  166.         const AVPixFmtDescriptor *desc;
  167.         const enum AVPixelFormat *out_pix_fmts;
  168.         int rgb, i, bits;
  169.  
  170.         if (!ctx->inputs[0]->in_formats ||
  171.             !ctx->inputs[0]->in_formats->nb_formats) {
  172.             return AVERROR(EAGAIN);
  173.         }
  174.  
  175.         if (!ctx->inputs[0]->out_formats)
  176.             ff_formats_ref(ff_make_format_list(levels_in_pix_fmts), &ctx->inputs[0]->out_formats);
  177.         avff = ctx->inputs[0]->in_formats;
  178.         desc = av_pix_fmt_desc_get(avff->formats[0]);
  179.         rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
  180.         bits = desc->comp[0].depth_minus1;
  181.         for (i = 1; i < avff->nb_formats; i++) {
  182.             desc = av_pix_fmt_desc_get(avff->formats[i]);
  183.             if ((rgb != (desc->flags & AV_PIX_FMT_FLAG_RGB)) ||
  184.                 (bits != desc->comp[0].depth_minus1))
  185.                 return AVERROR(EAGAIN);
  186.         }
  187.  
  188.         if (rgb && bits == 7)
  189.             out_pix_fmts = levels_out_rgb8_pix_fmts;
  190.         else if (rgb && bits == 8)
  191.             out_pix_fmts = levels_out_rgb9_pix_fmts;
  192.         else if (rgb && bits == 9)
  193.             out_pix_fmts = levels_out_rgb10_pix_fmts;
  194.         else if (bits == 7)
  195.             out_pix_fmts = levels_out_yuv8_pix_fmts;
  196.         else if (bits == 8)
  197.             out_pix_fmts = levels_out_yuv9_pix_fmts;
  198.         else // if (bits == 9)
  199.             out_pix_fmts = levels_out_yuv10_pix_fmts;
  200.         ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats);
  201.  
  202.         return 0;
  203.     }
  204.         break;
  205.     case MODE_COLOR:
  206.     case MODE_COLOR2:
  207.         pix_fmts = color_pix_fmts;
  208.         break;
  209.     default:
  210.         av_assert0(0);
  211.     }
  212.  
  213.     fmts_list = ff_make_format_list(pix_fmts);
  214.     if (!fmts_list)
  215.         return AVERROR(ENOMEM);
  216.     return ff_set_common_formats(ctx, fmts_list);
  217. }
  218.  
  219. static const uint8_t black_yuva_color[4] = { 0, 127, 127, 255 };
  220. static const uint8_t black_gbrp_color[4] = { 0, 0, 0, 255 };
  221. static const uint8_t white_yuva_color[4] = { 255, 127, 127, 255 };
  222. static const uint8_t white_gbrp_color[4] = { 255, 255, 255, 255 };
  223.  
  224. static int config_input(AVFilterLink *inlink)
  225. {
  226.     HistogramContext *h = inlink->dst->priv;
  227.  
  228.     h->desc  = av_pix_fmt_desc_get(inlink->format);
  229.     h->ncomp = h->desc->nb_components;
  230.     h->histogram_size = 1 << (h->desc->comp[0].depth_minus1 + 1);
  231.     h->mult = h->histogram_size / 256;
  232.  
  233.     switch (inlink->format) {
  234.     case AV_PIX_FMT_GBRP10:
  235.     case AV_PIX_FMT_GBRP9:
  236.     case AV_PIX_FMT_GBRAP:
  237.     case AV_PIX_FMT_GBRP:
  238.         h->bg_color = black_gbrp_color;
  239.         h->fg_color = white_gbrp_color;
  240.         break;
  241.     default:
  242.         h->bg_color = black_yuva_color;
  243.         h->fg_color = white_yuva_color;
  244.     }
  245.  
  246.     h->planeheight[1] = h->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, h->desc->log2_chroma_h);
  247.     h->planeheight[0] = h->planeheight[3] = inlink->h;
  248.     h->planewidth[1]  = h->planewidth[2]  = FF_CEIL_RSHIFT(inlink->w, h->desc->log2_chroma_w);
  249.     h->planewidth[0]  = h->planewidth[3]  = inlink->w;
  250.  
  251.     return 0;
  252. }
  253.  
  254. static int config_output(AVFilterLink *outlink)
  255. {
  256.     AVFilterContext *ctx = outlink->src;
  257.     HistogramContext *h = ctx->priv;
  258.     int ncomp = 0, i;
  259.  
  260.     switch (h->mode) {
  261.     case MODE_LEVELS:
  262.         for (i = 0; i < h->ncomp; i++) {
  263.             if ((1 << i) & h->components)
  264.                 ncomp++;
  265.         }
  266.         outlink->w = h->histogram_size;
  267.         outlink->h = (h->level_height + h->scale_height) * FFMAX(ncomp * h->display_mode, 1);
  268.         break;
  269.     case MODE_WAVEFORM:
  270.         av_log(ctx, AV_LOG_WARNING, "This mode is deprecated, please use waveform filter instead.\n");
  271.         if (h->waveform_mode)
  272.             outlink->h = 256 * FFMAX(h->ncomp * h->display_mode, 1);
  273.         else
  274.             outlink->w = 256 * FFMAX(h->ncomp * h->display_mode, 1);
  275.         break;
  276.     case MODE_COLOR:
  277.     case MODE_COLOR2:
  278.         av_log(ctx, AV_LOG_WARNING, "This mode is deprecated, use vectorscope filter instead.");
  279.         outlink->h = outlink->w = 256;
  280.         break;
  281.     default:
  282.         av_assert0(0);
  283.     }
  284.  
  285.     h->odesc = av_pix_fmt_desc_get(outlink->format);
  286.     outlink->sample_aspect_ratio = (AVRational){1,1};
  287.  
  288.     return 0;
  289. }
  290.  
  291. static void gen_waveform(HistogramContext *h, AVFrame *inpicref, AVFrame *outpicref,
  292.                          int component, int intensity, int offset, int col_mode)
  293. {
  294.     const int plane = h->desc->comp[component].plane;
  295.     const int mirror = h->waveform_mirror;
  296.     const int is_chroma = (component == 1 || component == 2);
  297.     const int shift_w = (is_chroma ? h->desc->log2_chroma_w : 0);
  298.     const int shift_h = (is_chroma ? h->desc->log2_chroma_h : 0);
  299.     const int src_linesize = inpicref->linesize[plane];
  300.     const int dst_linesize = outpicref->linesize[plane];
  301.     const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
  302.     uint8_t *src_data = inpicref->data[plane];
  303.     uint8_t *dst_data = outpicref->data[plane] + (col_mode ? (offset >> shift_h) * dst_linesize : offset >> shift_w);
  304.     uint8_t * const dst_bottom_line = dst_data + dst_linesize * ((256 >> shift_h) - 1);
  305.     uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
  306.     const uint8_t max = 255 - intensity;
  307.     const int src_h = FF_CEIL_RSHIFT(inpicref->height, shift_h);
  308.     const int src_w = FF_CEIL_RSHIFT(inpicref->width, shift_w);
  309.     uint8_t *dst, *p;
  310.     int y;
  311.  
  312.     if (!col_mode && mirror)
  313.         dst_data += 256 >> shift_w;
  314.     for (y = 0; y < src_h; y++) {
  315.         const uint8_t *src_data_end = src_data + src_w;
  316.         dst = dst_line;
  317.         for (p = src_data; p < src_data_end; p++) {
  318.             uint8_t *target;
  319.             if (col_mode) {
  320.                 target = dst++ + dst_signed_linesize * (*p >> shift_h);
  321.             } else {
  322.                 if (mirror)
  323.                     target = dst_data - (*p >> shift_w);
  324.                 else
  325.                     target = dst_data + (*p >> shift_w);
  326.             }
  327.             if (*target <= max)
  328.                 *target += intensity;
  329.             else
  330.                 *target = 255;
  331.         }
  332.         src_data += src_linesize;
  333.         dst_data += dst_linesize;
  334.     }
  335. }
  336.  
  337.  
  338. static int filter_frame(AVFilterLink *inlink, AVFrame *in)
  339. {
  340.     HistogramContext *h   = inlink->dst->priv;
  341.     AVFilterContext *ctx  = inlink->dst;
  342.     AVFilterLink *outlink = ctx->outputs[0];
  343.     AVFrame *out;
  344.     uint8_t *dst;
  345.     int i, j, k, l, m;
  346.  
  347.     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
  348.     if (!out) {
  349.         av_frame_free(&in);
  350.         return AVERROR(ENOMEM);
  351.     }
  352.  
  353.     out->pts = in->pts;
  354.  
  355.     for (k = 0; k < 4 && out->data[k]; k++) {
  356.         const int is_chroma = (k == 1 || k == 2);
  357.         const int dst_h = FF_CEIL_RSHIFT(outlink->h, (is_chroma ? h->odesc->log2_chroma_h : 0));
  358.         const int dst_w = FF_CEIL_RSHIFT(outlink->w, (is_chroma ? h->odesc->log2_chroma_w : 0));
  359.  
  360.         if (h->histogram_size <= 256) {
  361.             for (i = 0; i < dst_h ; i++)
  362.                 memset(out->data[h->odesc->comp[k].plane] +
  363.                        i * out->linesize[h->odesc->comp[k].plane],
  364.                        h->bg_color[k], dst_w);
  365.         } else {
  366.             const int mult = h->mult;
  367.  
  368.             for (i = 0; i < dst_h ; i++)
  369.                 for (j = 0; j < dst_w; j++)
  370.                     AV_WN16(out->data[h->odesc->comp[k].plane] +
  371.                         i * out->linesize[h->odesc->comp[k].plane] + j * 2,
  372.                         h->bg_color[k] * mult);
  373.         }
  374.     }
  375.  
  376.     switch (h->mode) {
  377.     case MODE_LEVELS:
  378.         for (m = 0, k = 0; k < h->ncomp; k++) {
  379.             const int p = h->desc->comp[k].plane;
  380.             const int height = h->planeheight[p];
  381.             const int width = h->planewidth[p];
  382.             double max_hval_log;
  383.             unsigned max_hval = 0;
  384.             int start;
  385.  
  386.             if (!((1 << k) & h->components))
  387.                 continue;
  388.             start = m++ * (h->level_height + h->scale_height) * h->display_mode;
  389.  
  390.             if (h->histogram_size <= 256) {
  391.                 for (i = 0; i < height; i++) {
  392.                     const uint8_t *src = in->data[p] + i * in->linesize[p];
  393.                     for (j = 0; j < width; j++)
  394.                         h->histogram[src[j]]++;
  395.                 }
  396.             } else {
  397.                 for (i = 0; i < height; i++) {
  398.                     const uint16_t *src = (const uint16_t *)(in->data[p] + i * in->linesize[p]);
  399.                     for (j = 0; j < width; j++)
  400.                         h->histogram[src[j]]++;
  401.                 }
  402.             }
  403.  
  404.             for (i = 0; i < h->histogram_size; i++)
  405.                 max_hval = FFMAX(max_hval, h->histogram[i]);
  406.             max_hval_log = log2(max_hval + 1);
  407.  
  408.             for (i = 0; i < outlink->w; i++) {
  409.                 int col_height;
  410.  
  411.                 if (h->levels_mode)
  412.                     col_height = round(h->level_height * (1. - (log2(h->histogram[i] + 1) / max_hval_log)));
  413.                 else
  414.                     col_height = h->level_height - (h->histogram[i] * (int64_t)h->level_height + max_hval - 1) / max_hval;
  415.  
  416.                 if (h->histogram_size <= 256) {
  417.                     for (j = h->level_height - 1; j >= col_height; j--) {
  418.                         if (h->display_mode) {
  419.                             for (l = 0; l < h->ncomp; l++)
  420.                                 out->data[l][(j + start) * out->linesize[l] + i] = h->fg_color[l];
  421.                         } else {
  422.                             out->data[p][(j + start) * out->linesize[p] + i] = 255;
  423.                         }
  424.                     }
  425.                     for (j = h->level_height + h->scale_height - 1; j >= h->level_height; j--)
  426.                         out->data[p][(j + start) * out->linesize[p] + i] = i;
  427.                 } else {
  428.                     const int mult = h->mult;
  429.  
  430.                     for (j = h->level_height - 1; j >= col_height; j--) {
  431.                         if (h->display_mode) {
  432.                             for (l = 0; l < h->ncomp; l++)
  433.                                 AV_WN16(out->data[l] + (j + start) * out->linesize[l] + i * 2, h->fg_color[l] * mult);
  434.                         } else {
  435.                             AV_WN16(out->data[p] + (j + start) * out->linesize[p] + i * 2, 255 * mult);
  436.                         }
  437.                     }
  438.                     for (j = h->level_height + h->scale_height - 1; j >= h->level_height; j--)
  439.                         AV_WN16(out->data[p] + (j + start) * out->linesize[p] + i * 2, i);
  440.                 }
  441.             }
  442.  
  443.             memset(h->histogram, 0, h->histogram_size * sizeof(unsigned));
  444.         }
  445.         break;
  446.     case MODE_WAVEFORM:
  447.         for (k = 0; k < h->ncomp; k++) {
  448.             const int offset = k * 256 * h->display_mode;
  449.             gen_waveform(h, in, out, k, h->step, offset, h->waveform_mode);
  450.         }
  451.         break;
  452.     case MODE_COLOR:
  453.         for (i = 0; i < inlink->h; i++) {
  454.             const int iw1 = i * in->linesize[1];
  455.             const int iw2 = i * in->linesize[2];
  456.             for (j = 0; j < inlink->w; j++) {
  457.                 const int pos = in->data[1][iw1 + j] * out->linesize[0] + in->data[2][iw2 + j];
  458.                 if (out->data[0][pos] < 255)
  459.                     out->data[0][pos]++;
  460.             }
  461.         }
  462.         for (i = 0; i < 256; i++) {
  463.             dst = out->data[0] + i * out->linesize[0];
  464.             for (j = 0; j < 256; j++) {
  465.                 if (!dst[j]) {
  466.                     out->data[1][i * out->linesize[0] + j] = i;
  467.                     out->data[2][i * out->linesize[0] + j] = j;
  468.                 }
  469.             }
  470.         }
  471.         break;
  472.     case MODE_COLOR2:
  473.         for (i = 0; i < inlink->h; i++) {
  474.             const int iw1 = i * in->linesize[1];
  475.             const int iw2 = i * in->linesize[2];
  476.             for (j = 0; j < inlink->w; j++) {
  477.                 const int u = in->data[1][iw1 + j];
  478.                 const int v = in->data[2][iw2 + j];
  479.                 const int pos = u * out->linesize[0] + v;
  480.                 if (!out->data[0][pos])
  481.                     out->data[0][pos] = FFABS(128 - u) + FFABS(128 - v);
  482.                 out->data[1][pos] = u;
  483.                 out->data[2][pos] = v;
  484.             }
  485.         }
  486.         break;
  487.     default:
  488.         av_assert0(0);
  489.     }
  490.  
  491.     av_frame_free(&in);
  492.     return ff_filter_frame(outlink, out);
  493. }
  494.  
  495. static const AVFilterPad inputs[] = {
  496.     {
  497.         .name         = "default",
  498.         .type         = AVMEDIA_TYPE_VIDEO,
  499.         .filter_frame = filter_frame,
  500.         .config_props = config_input,
  501.     },
  502.     { NULL }
  503. };
  504.  
  505. static const AVFilterPad outputs[] = {
  506.     {
  507.         .name         = "default",
  508.         .type         = AVMEDIA_TYPE_VIDEO,
  509.         .config_props = config_output,
  510.     },
  511.     { NULL }
  512. };
  513.  
  514. AVFilter ff_vf_histogram = {
  515.     .name          = "histogram",
  516.     .description   = NULL_IF_CONFIG_SMALL("Compute and draw a histogram."),
  517.     .priv_size     = sizeof(HistogramContext),
  518.     .query_formats = query_formats,
  519.     .inputs        = inputs,
  520.     .outputs       = outputs,
  521.     .priv_class    = &histogram_class,
  522. };
  523.