21#include "config_components.h"
66#define OFFSET(x) offsetof(HistogramContext, x)
67#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
69#define COMMON_OPTIONS \
70 { "display_mode", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS, .unit = "display_mode"}, \
71 { "d", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS, .unit = "display_mode"}, \
72 { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "display_mode" }, \
73 { "parade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "display_mode" }, \
74 { "stack", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, .unit = "display_mode" }, \
75 { "levels_mode", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "levels_mode"}, \
76 { "m", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "levels_mode"}, \
77 { "linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "levels_mode" }, \
78 { "logarithmic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "levels_mode" }, \
79 { "components", "set color components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 1, 15, FLAGS}, \
80 { "c", "set color components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 1, 15, FLAGS},
174 if (!
ctx->inputs[0]->incfg.formats ||
175 !
ctx->inputs[0]->incfg.formats->nb_formats) {
179 if (!
ctx->inputs[0]->outcfg.formats)
182 avff =
ctx->inputs[0]->incfg.formats;
236 s->ncomp =
s->desc->nb_components;
237 s->histogram_size = 1 <<
s->desc->comp[0].depth;
238 s->mult =
s->histogram_size / 256;
250 s->start[0] =
s->start[1] =
s->start[2] =
s->start[3] = 0;
251 memcpy(
s->envelope_color,
s->envelope_rgba, 4);
258 s->start[0] =
s->start[3] = 0;
259 s->start[1] =
s->start[2] =
s->histogram_size / 2;
260 s->envelope_color[0] =
RGB_TO_Y_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2]);
261 s->envelope_color[1] =
RGB_TO_U_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2], 0);
262 s->envelope_color[2] =
RGB_TO_V_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2], 0);
263 s->envelope_color[3] =
s->envelope_rgba[3];
266 for (
int i = 1;
i < 4;
i++) {
267 memcpy(
s->fg_color[
i],
s->fg_color[0], 4);
268 memcpy(
s->bg_color[
i],
s->bg_color[0], 4);
271 if (
s->display_mode) {
272 if (
s->colors_mode == 1) {
273 for (
int i = 0;
i < 4;
i++)
274 for (
int j = 0; j < 4; j++)
275 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
276 }
else if (
s->colors_mode == 2) {
277 for (
int i = 0;
i < 4;
i++)
279 }
else if (
s->colors_mode == 3) {
280 for (
int i = 0;
i < 4;
i++)
281 for (
int j = 0; j < 4; j++)
282 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
283 for (
int i = 0;
i < 4;
i++)
285 }
else if (
s->colors_mode == 4) {
295 }
else if (
s->colors_mode == 5) {
296 for (
int i = 0;
i < 4;
i++)
297 for (
int j = 0; j < 4; j++)
298 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
308 }
else if (
s->colors_mode == 6) {
309 for (
int i = 0;
i < 4;
i++)
320 }
else if (
s->colors_mode == 7) {
321 for (
int i = 0;
i < 4;
i++)
322 for (
int j = 0; j < 4; j++)
323 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
333 }
else if (
s->colors_mode == 8) {
343 }
else if (
s->colors_mode == 9) {
344 for (
int i = 0;
i < 4;
i++)
358 for (
int i = 0;
i < 4;
i++) {
359 s->fg_color[
i][3] =
s->fgopacity * 255;
360 s->bg_color[
i][3] =
s->bgopacity * 255;
363 s->planeheight[1] =
s->planeheight[2] =
AV_CEIL_RSHIFT(inlink->
h,
s->desc->log2_chroma_h);
364 s->planeheight[0] =
s->planeheight[3] = inlink->
h;
365 s->planewidth[1] =
s->planewidth[2] =
AV_CEIL_RSHIFT(inlink->
w,
s->desc->log2_chroma_w);
366 s->planewidth[0] =
s->planewidth[3] = inlink->
w;
377 if (!strcmp(
ctx->filter->name,
"thistogram"))
380 for (
i = 0;
i <
s->ncomp;
i++) {
381 if ((1 <<
i) &
s->components)
387 s->width =
ctx->inputs[0]->w;
388 outlink->
w =
s->width *
FFMAX(ncomp * (
s->display_mode == 1), 1);
389 outlink->
h =
s->histogram_size *
FFMAX(ncomp * (
s->display_mode == 2), 1);
391 outlink->
w =
s->histogram_size *
FFMAX(ncomp * (
s->display_mode == 1), 1);
392 outlink->
h = (
s->level_height +
s->scale_height) *
FFMAX(ncomp * (
s->display_mode == 2), 1);
396 s->dncomp =
s->odesc->nb_components;
410 if (!
s->thistogram || !
out) {
418 for (k = 0; k < 4 &&
out->data[k]; k++) {
419 const int is_chroma = (k == 1 || k == 2);
420 const int dst_h =
AV_CEIL_RSHIFT(outlink->
h, (is_chroma ?
s->odesc->log2_chroma_h : 0));
421 const int dst_w =
AV_CEIL_RSHIFT(outlink->
w, (is_chroma ?
s->odesc->log2_chroma_w : 0));
423 if (
s->histogram_size <= 256) {
424 for (
i = 0;
i < dst_h ;
i++)
425 memset(
out->data[
s->odesc->comp[k].plane] +
426 i *
out->linesize[
s->odesc->comp[k].plane],
427 s->bg_color[0][k], dst_w);
429 const int mult =
s->mult;
431 for (
i = 0;
i < dst_h ;
i++)
432 for (j = 0; j < dst_w; j++)
434 i *
out->linesize[
s->odesc->comp[k].plane] + j * 2,
435 s->bg_color[0][k] *
mult);
440 for (m = 0, k = 0; k <
s->ncomp; k++) {
441 const int p =
s->desc->comp[k].plane;
442 const int max_value =
s->histogram_size - 1 -
s->start[p];
443 const int height =
s->planeheight[p];
444 const int width =
s->planewidth[p];
445 const int mid =
s->mid;
447 unsigned max_hval = 0;
450 if (!((1 << k) &
s->components))
453 starty = m *
s->histogram_size * (
s->display_mode == 2);
454 startx = m++ *
s->width * (
s->display_mode == 1);
456 startx = m *
s->histogram_size * (
s->display_mode == 1);
457 starty = m++ * (
s->level_height +
s->scale_height) * (
s->display_mode == 2);
460 if (
s->histogram_size <= 256) {
463 for (j = 0; j <
width; j++)
464 s->histogram[
src[j]]++;
468 const uint16_t *
src = (
const uint16_t *)(in->
data[p] +
i * in->
linesize[p]);
469 for (j = 0; j <
width; j++)
470 s->histogram[
src[j]]++;
474 for (
i = 0;
i <
s->histogram_size;
i++)
475 max_hval =
FFMAX(max_hval,
s->histogram[
i]);
476 max_hval_log =
log2(max_hval + 1);
479 const int bpp = 1 + (
s->histogram_size > 256);
480 int minh =
s->histogram_size - 1, maxh = 0;
483 s->x_pos =
out->width - 1;
484 for (j = 0; j < outlink->
h; j++) {
485 memmove(
out->data[p] + j *
out->linesize[p] ,
486 out->data[p] + j *
out->linesize[p] + bpp,
487 (outlink->
w - 1) * bpp);
489 }
else if (
s->slide == 3) {
491 for (j = 0; j < outlink->
h; j++) {
492 memmove(
out->data[p] + j *
out->linesize[p] + bpp,
493 out->data[p] + j *
out->linesize[p],
494 (outlink->
w - 1) * bpp);
498 for (
int i = 0;
i <
s->histogram_size;
i++) {
499 int idx =
s->histogram_size -
i - 1;
502 if (
s->envelope &&
s->histogram[idx]) {
508 value +=
lrint(max_value * (
log2(
s->histogram[idx] + 1) / max_hval_log));
510 value +=
lrint(max_value *
s->histogram[idx] / (
float)max_hval);
512 if (
s->histogram_size <= 256) {
513 s->out->data[p][(
i + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
value;
515 AV_WN16(
s->out->data[p] + (
i + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
value);
520 if (
s->histogram_size <= 256) {
521 s->out->data[0][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[0];
522 s->out->data[0][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[0];
523 if (
s->dncomp >= 3) {
524 s->out->data[1][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[1];
525 s->out->data[2][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[2];
526 s->out->data[1][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[1];
527 s->out->data[2][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[2];
530 const int mult =
s->mult;
532 AV_WN16(
s->out->data[0] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[0] *
mult);
533 AV_WN16(
s->out->data[0] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[0] *
mult);
534 if (
s->dncomp >= 3) {
535 AV_WN16(
s->out->data[1] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[1] *
mult);
536 AV_WN16(
s->out->data[2] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[2] *
mult);
537 AV_WN16(
s->out->data[1] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[1] *
mult);
538 AV_WN16(
s->out->data[2] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[2] *
mult);
543 for (
i = 0;
i <
s->histogram_size;
i++) {
547 col_height =
lrint(
s->level_height * (1. - (
log2(
s->histogram[
i] + 1) / max_hval_log)));
549 col_height =
s->level_height - (
s->histogram[
i] * (
int64_t)
s->level_height + max_hval - 1) / max_hval;
551 if (
s->histogram_size <= 256) {
552 for (j =
s->level_height - 1; j >= col_height; j--) {
553 if (
s->display_mode) {
554 for (l = 0; l <
s->dncomp; l++)
555 out->data[l][(j + starty) *
out->linesize[l] + startx +
i] =
s->fg_color[p][l];
557 out->data[p][(j + starty) *
out->linesize[p] + startx +
i] = 255;
560 if (
s->display_mode) {
561 for (j = col_height - 1; j >= 0; j--) {
562 for (l = 0; l <
s->dncomp; l++)
563 out->data[l][(j + starty) *
out->linesize[l] + startx +
i] =
s->bg_color[p][l];
566 for (j =
s->level_height +
s->scale_height - 1; j >=
s->level_height; j--)
567 for (l = 0; l <
s->dncomp; l++)
568 out->data[l][(j + starty) *
out->linesize[l] + startx +
i] = p == l ?
i : mid;
570 const int mult =
s->mult;
572 for (j =
s->level_height - 1; j >= col_height; j--) {
573 if (
s->display_mode) {
574 for (l = 0; l <
s->dncomp; l++)
575 AV_WN16(
out->data[l] + (j + starty) *
out->linesize[l] + startx * 2 +
i * 2,
s->fg_color[p][l] *
mult);
577 AV_WN16(
out->data[p] + (j + starty) *
out->linesize[p] + startx * 2 +
i * 2, 255 *
mult);
580 if (
s->display_mode) {
581 for (j = col_height - 1; j >= 0; j--) {
582 for (l = 0; l <
s->dncomp; l++)
583 AV_WN16(
out->data[l] + (j + starty) *
out->linesize[l] + startx * 2 +
i * 2,
s->bg_color[p][l] *
mult);
586 for (j =
s->level_height +
s->scale_height - 1; j >=
s->level_height; j--)
587 for (l = 0; l <
s->dncomp; l++)
588 AV_WN16(
out->data[l] + (j + starty) *
out->linesize[l] + startx * 2 +
i * 2, p == l ?
i : mid *
mult);
593 memset(
s->histogram, 0,
s->histogram_size *
sizeof(
unsigned));
600 if (
s->x_pos >=
s->width) {
602 if (
s->thistogram && (
s->slide == 4 ||
s->slide == 0)) {
606 }
else if (
s->thistogram &&
s->slide == 4) {
638#if CONFIG_HISTOGRAM_FILTER
641 .p.name =
"histogram",
643 .p.priv_class = &histogram_class,
652#if CONFIG_THISTOGRAM_FILTER
661static const AVOption thistogram_options[] = {
683 .p.name =
"thistogram",
685 .p.priv_class = &thistogram_class,
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
static int config_input(AVFilterLink *inlink)
const FFFilter ff_vf_thistogram
const FFFilter ff_vf_histogram
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
#define AV_CEIL_RSHIFT(a, b)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
static const uint8_t bits[8]
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
@ AV_OPT_TYPE_COLOR
Underlying C type is uint8_t[4].
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
static int16_t mult(Float11 *f1, Float11 *f2)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FILTER_QUERY_FUNC(func)
#define AVFILTER_DEFINE_CLASS(fname)
Various defines for YUV<->RGB conversion.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#define FFSWAP(type, a, b)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
#define AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA422P10
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
#define AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUV444P10
Describe the class of an AVClass context structure.
void * priv
private data for use by the filter
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Rational number (pair of numerator and denominator).
const AVPixFmtDescriptor * odesc
const AVPixFmtDescriptor * desc
unsigned histogram[256 *256]
uint8_t envelope_color[4]
static AVFormatContext * ctx
static enum AVPixelFormat out_pix_fmts[]
static const uint8_t black_yuva_color[4]
static const uint8_t green_yuva_color[4]
static const AVOption histogram_options[]
static enum AVPixelFormat levels_in_pix_fmts[]
static enum AVPixelFormat levels_out_rgb10_pix_fmts[]
static const uint8_t blue_yuva_color[4]
static int query_formats(AVFilterContext *ctx)
static const uint8_t white_yuva_color[4]
static int config_input(AVFilterLink *inlink)
static enum AVPixelFormat levels_out_rgb8_pix_fmts[]
static const uint8_t blue_gbrp_color[4]
static const uint8_t gray_color[4]
static enum AVPixelFormat levels_out_rgb12_pix_fmts[]
static enum AVPixelFormat levels_out_rgb9_pix_fmts[]
static const uint8_t red_gbrp_color[4]
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static const uint8_t white_gbrp_color[4]
static enum AVPixelFormat levels_out_yuv10_pix_fmts[]
static enum AVPixelFormat levels_out_yuv12_pix_fmts[]
static int config_output(AVFilterLink *outlink)
static const uint8_t green_gbrp_color[4]
static const uint8_t black_gbrp_color[4]
static const uint8_t red_yuva_color[4]
static enum AVPixelFormat levels_out_yuv9_pix_fmts[]
static enum AVPixelFormat levels_out_yuv8_pix_fmts[]
static const uint8_t igreen_yuva_color[4]
static float envelope(const float x)
#define RGB_TO_Y_BT709(r, g, b)
#define RGB_TO_U_BT709(r1, g1, b1, max)
#define RGB_TO_V_BT709(r1, g1, b1, max)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.