Go to the documentation of this file.
64 #define OFFSET(x) offsetof(HistogramContext, x)
65 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
67 #define COMMON_OPTIONS \
68 { "display_mode", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS, "display_mode"}, \
69 { "d", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS, "display_mode"}, \
70 { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "display_mode" }, \
71 { "parade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "display_mode" }, \
72 { "stack", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "display_mode" }, \
73 { "levels_mode", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "levels_mode"}, \
74 { "m", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "levels_mode"}, \
75 { "linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "levels_mode" }, \
76 { "logarithmic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "levels_mode" }, \
77 { "components", "set color components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 1, 15, FLAGS}, \
78 { "c", "set color components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 1, 15, FLAGS},
172 if (!
ctx->inputs[0]->incfg.formats ||
173 !
ctx->inputs[0]->incfg.formats->nb_formats) {
177 if (!
ctx->inputs[0]->outcfg.formats)
180 avff =
ctx->inputs[0]->incfg.formats;
234 s->ncomp =
s->desc->nb_components;
235 s->histogram_size = 1 <<
s->desc->comp[0].depth;
236 s->mult =
s->histogram_size / 256;
248 s->start[0] =
s->start[1] =
s->start[2] =
s->start[3] = 0;
249 memcpy(
s->envelope_color,
s->envelope_rgba, 4);
256 s->start[0] =
s->start[3] = 0;
257 s->start[1] =
s->start[2] =
s->histogram_size / 2;
258 s->envelope_color[0] =
RGB_TO_Y_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2]);
259 s->envelope_color[1] =
RGB_TO_U_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2], 0);
260 s->envelope_color[2] =
RGB_TO_V_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2], 0);
261 s->envelope_color[3] =
s->envelope_rgba[3];
264 for (
int i = 1;
i < 4;
i++) {
265 memcpy(
s->fg_color[
i],
s->fg_color[0], 4);
266 memcpy(
s->bg_color[
i],
s->bg_color[0], 4);
269 if (
s->display_mode) {
270 if (
s->colors_mode == 1) {
271 for (
int i = 0;
i < 4;
i++)
272 for (
int j = 0; j < 4; j++)
273 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
274 }
else if (
s->colors_mode == 2) {
275 for (
int i = 0;
i < 4;
i++)
277 }
else if (
s->colors_mode == 3) {
278 for (
int i = 0;
i < 4;
i++)
279 for (
int j = 0; j < 4; j++)
280 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
281 for (
int i = 0;
i < 4;
i++)
283 }
else if (
s->colors_mode == 4) {
293 }
else if (
s->colors_mode == 5) {
294 for (
int i = 0;
i < 4;
i++)
295 for (
int j = 0; j < 4; j++)
296 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
306 }
else if (
s->colors_mode == 6) {
307 for (
int i = 0;
i < 4;
i++)
318 }
else if (
s->colors_mode == 7) {
319 for (
int i = 0;
i < 4;
i++)
320 for (
int j = 0; j < 4; j++)
321 FFSWAP(uint8_t,
s->fg_color[
i][j],
s->bg_color[
i][j]);
331 }
else if (
s->colors_mode == 8) {
341 }
else if (
s->colors_mode == 9) {
342 for (
int i = 0;
i < 4;
i++)
356 for (
int i = 0;
i < 4;
i++) {
357 s->fg_color[
i][3] =
s->fgopacity * 255;
358 s->bg_color[
i][3] =
s->bgopacity * 255;
362 s->planeheight[0] =
s->planeheight[3] =
inlink->h;
364 s->planewidth[0] =
s->planewidth[3] =
inlink->w;
375 if (!strcmp(
ctx->filter->name,
"thistogram"))
378 for (
i = 0;
i <
s->ncomp;
i++) {
379 if ((1 <<
i) &
s->components)
385 s->width =
ctx->inputs[0]->w;
386 outlink->
w =
s->width *
FFMAX(ncomp * (
s->display_mode == 1), 1);
387 outlink->
h =
s->histogram_size *
FFMAX(ncomp * (
s->display_mode == 2), 1);
389 outlink->
w =
s->histogram_size *
FFMAX(ncomp * (
s->display_mode == 1), 1);
390 outlink->
h = (
s->level_height +
s->scale_height) *
FFMAX(ncomp * (
s->display_mode == 2), 1);
394 s->dncomp =
s->odesc->nb_components;
408 if (!
s->thistogram || !
out) {
416 for (k = 0; k < 4 &&
out->data[k]; k++) {
417 const int is_chroma = (k == 1 || k == 2);
418 const int dst_h =
AV_CEIL_RSHIFT(outlink->
h, (is_chroma ?
s->odesc->log2_chroma_h : 0));
419 const int dst_w =
AV_CEIL_RSHIFT(outlink->
w, (is_chroma ?
s->odesc->log2_chroma_w : 0));
421 if (
s->histogram_size <= 256) {
422 for (
i = 0;
i < dst_h ;
i++)
423 memset(
out->data[
s->odesc->comp[k].plane] +
424 i *
out->linesize[
s->odesc->comp[k].plane],
425 s->bg_color[0][k], dst_w);
427 const int mult =
s->mult;
429 for (
i = 0;
i < dst_h ;
i++)
430 for (j = 0; j < dst_w; j++)
432 i *
out->linesize[
s->odesc->comp[k].plane] + j * 2,
433 s->bg_color[0][k] *
mult);
438 for (m = 0, k = 0; k <
s->ncomp; k++) {
439 const int p =
s->desc->comp[k].plane;
440 const int max_value =
s->histogram_size - 1 -
s->start[p];
441 const int height =
s->planeheight[p];
442 const int width =
s->planewidth[p];
443 const int mid =
s->mid;
445 unsigned max_hval = 0;
448 if (!((1 << k) &
s->components))
451 starty = m *
s->histogram_size * (
s->display_mode == 2);
452 startx = m++ *
s->width * (
s->display_mode == 1);
454 startx = m *
s->histogram_size * (
s->display_mode == 1);
455 starty = m++ * (
s->level_height +
s->scale_height) * (
s->display_mode == 2);
458 if (
s->histogram_size <= 256) {
461 for (j = 0; j <
width; j++)
462 s->histogram[
src[j]]++;
466 const uint16_t *
src = (
const uint16_t *)(in->
data[p] +
i * in->
linesize[p]);
467 for (j = 0; j <
width; j++)
468 s->histogram[
src[j]]++;
472 for (
i = 0;
i <
s->histogram_size;
i++)
473 max_hval =
FFMAX(max_hval,
s->histogram[
i]);
474 max_hval_log =
log2(max_hval + 1);
477 const int bpp = 1 + (
s->histogram_size > 256);
478 int minh =
s->histogram_size - 1, maxh = 0;
481 s->x_pos =
out->width - 1;
482 for (j = 0; j < outlink->
h; j++) {
483 memmove(
out->data[p] + j *
out->linesize[p] ,
484 out->data[p] + j *
out->linesize[p] + bpp,
485 (outlink->
w - 1) * bpp);
487 }
else if (
s->slide == 3) {
489 for (j = 0; j < outlink->
h; j++) {
490 memmove(
out->data[p] + j *
out->linesize[p] + bpp,
491 out->data[p] + j *
out->linesize[p],
492 (outlink->
w - 1) * bpp);
496 for (
int i = 0;
i <
s->histogram_size;
i++) {
497 int idx =
s->histogram_size -
i - 1;
500 if (
s->envelope &&
s->histogram[idx]) {
506 value +=
lrint(max_value * (
log2(
s->histogram[idx] + 1) / max_hval_log));
508 value +=
lrint(max_value *
s->histogram[idx] / (
float)max_hval);
510 if (
s->histogram_size <= 256) {
511 s->out->data[p][(
i + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
value;
513 AV_WN16(
s->out->data[p] + (
i + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
value);
518 if (
s->histogram_size <= 256) {
519 s->out->data[0][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[0];
520 s->out->data[0][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[0];
521 if (
s->dncomp >= 3) {
522 s->out->data[1][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[1];
523 s->out->data[2][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[2];
524 s->out->data[1][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[1];
525 s->out->data[2][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[2];
528 const int mult =
s->mult;
530 AV_WN16(
s->out->data[0] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[0] *
mult);
531 AV_WN16(
s->out->data[0] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[0] *
mult);
532 if (
s->dncomp >= 3) {
533 AV_WN16(
s->out->data[1] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[1] *
mult);
534 AV_WN16(
s->out->data[2] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[2] *
mult);
535 AV_WN16(
s->out->data[1] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[1] *
mult);
536 AV_WN16(
s->out->data[2] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[2] *
mult);
541 for (
i = 0;
i <
s->histogram_size;
i++) {
545 col_height =
lrint(
s->level_height * (1. - (
log2(
s->histogram[
i] + 1) / max_hval_log)));
547 col_height =
s->level_height - (
s->histogram[
i] * (int64_t)
s->level_height + max_hval - 1) / max_hval;
549 if (
s->histogram_size <= 256) {
550 for (j =
s->level_height - 1; j >= col_height; j--) {
551 if (
s->display_mode) {
552 for (l = 0; l <
s->dncomp; l++)
553 out->data[l][(j + starty) *
out->linesize[l] + startx +
i] =
s->fg_color[p][l];
555 out->data[p][(j + starty) *
out->linesize[p] + startx +
i] = 255;
558 if (
s->display_mode) {
559 for (j = col_height - 1; j >= 0; j--) {
560 for (l = 0; l <
s->dncomp; l++)
561 out->data[l][(j + starty) *
out->linesize[l] + startx +
i] =
s->bg_color[p][l];
564 for (j =
s->level_height +
s->scale_height - 1; j >=
s->level_height; j--)
565 for (l = 0; l <
s->dncomp; l++)
566 out->data[l][(j + starty) *
out->linesize[l] + startx +
i] = p == l ?
i : mid;
568 const int mult =
s->mult;
570 for (j =
s->level_height - 1; j >= col_height; j--) {
571 if (
s->display_mode) {
572 for (l = 0; l <
s->dncomp; l++)
573 AV_WN16(
out->data[l] + (j + starty) *
out->linesize[l] + startx * 2 +
i * 2,
s->fg_color[p][l] *
mult);
575 AV_WN16(
out->data[p] + (j + starty) *
out->linesize[p] + startx * 2 +
i * 2, 255 *
mult);
578 if (
s->display_mode) {
579 for (j = col_height - 1; j >= 0; j--) {
580 for (l = 0; l <
s->dncomp; l++)
581 AV_WN16(
out->data[l] + (j + starty) *
out->linesize[l] + startx * 2 +
i * 2,
s->bg_color[p][l] *
mult);
584 for (j =
s->level_height +
s->scale_height - 1; j >=
s->level_height; j--)
585 for (l = 0; l <
s->dncomp; l++)
586 AV_WN16(
out->data[l] + (j + starty) *
out->linesize[l] + startx * 2 +
i * 2, p == l ?
i : mid *
mult);
591 memset(
s->histogram, 0,
s->histogram_size *
sizeof(
unsigned));
597 if (
s->x_pos >=
s->width) {
599 if (
s->thistogram && (
s->slide == 4 ||
s->slide == 0)) {
603 }
else if (
s->thistogram &&
s->slide == 4) {
635 #if CONFIG_HISTOGRAM_FILTER
644 .priv_class = &histogram_class,
649 #if CONFIG_THISTOGRAM_FILTER
658 static const AVOption thistogram_options[] = {
680 .
name =
"thistogram",
687 .priv_class = &thistogram_class,
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
AVPixelFormat
Pixel format.
const AVFilter ff_vf_thistogram
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static const AVFilterPad outputs[]
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
const AVPixFmtDescriptor * odesc
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define AV_PIX_FMT_YUVA422P9
static int query_formats(AVFilterContext *ctx)
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
static const uint8_t black_yuva_color[4]
#define AV_PIX_FMT_YUVA420P10
static enum AVPixelFormat levels_out_yuv8_pix_fmts[]
#define FILTER_QUERY_FUNC(func)
#define AV_PIX_FMT_YUV420P10
static enum AVPixelFormat levels_out_yuv9_pix_fmts[]
static const uint8_t green_gbrp_color[4]
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
static int config_input(AVFilterLink *inlink)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
const char * name
Filter name.
static const uint8_t white_gbrp_color[4]
A link between two filters.
#define AV_PIX_FMT_YUVA422P10
static const uint8_t blue_yuva_color[4]
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
#define AV_PIX_FMT_YUVA420P9
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
static const uint8_t red_gbrp_color[4]
#define AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_YUV422P9
A filter pad used for either input or output.
static enum AVPixelFormat levels_out_rgb10_pix_fmts[]
#define AV_PIX_FMT_YUV444P10
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
static int16_t mult(Float11 *f1, Float11 *f2)
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
#define AV_PIX_FMT_GBRAP10
#define RGB_TO_Y_BT709(r, g, b)
static const AVOption histogram_options[]
#define AV_PIX_FMT_GBRAP12
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
#define AV_CEIL_RSHIFT(a, b)
#define RGB_TO_U_BT709(r1, g1, b1, max)
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
uint8_t envelope_color[4]
#define AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUV420P9
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
#define FILTER_INPUTS(array)
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Describe the class of an AVClass context structure.
Rational number (pair of numerator and denominator).
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
static enum AVPixelFormat levels_out_rgb12_pix_fmts[]
#define AV_PIX_FMT_YUV422P10
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
static int config_output(AVFilterLink *outlink)
const AVFilter ff_vf_histogram
static const uint8_t blue_gbrp_color[4]
#define RGB_TO_V_BT709(r1, g1, b1, max)
static const AVFilterPad inputs[]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
AVFILTER_DEFINE_CLASS(histogram)
int format
agreed upon media format
#define AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV444P12
AVFilterContext * src
source filter
static const uint8_t red_yuva_color[4]
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
#define AV_PIX_FMT_YUVA444P10
static enum AVPixelFormat levels_in_pix_fmts[]
static const uint8_t gray_color[4]
#define i(width, name, range_min, range_max)
static float envelope(const float x)
int w
agreed upon image width
#define AV_PIX_FMT_GBRP12
static enum AVPixelFormat out_pix_fmts[]
static enum AVPixelFormat levels_out_yuv10_pix_fmts[]
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
const AVPixFmtDescriptor * desc
const char * name
Pad name.
#define AV_PIX_FMT_YUV444P9
#define FFSWAP(type, a, b)
#define AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUV420P12
int h
agreed upon image height
#define AV_PIX_FMT_YUVA422P12
static const uint8_t igreen_yuva_color[4]
static enum AVPixelFormat levels_out_rgb8_pix_fmts[]
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
static enum AVPixelFormat levels_out_yuv12_pix_fmts[]
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
#define FILTER_OUTPUTS(array)
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
static const SheerTable rgb[2]
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
static enum AVPixelFormat levels_out_rgb9_pix_fmts[]
unsigned histogram[256 *256]
static av_cold int uninit(AVCodecContext *avctx)
#define AV_PIX_FMT_YUV440P12
static const uint8_t black_gbrp_color[4]
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
static const uint8_t white_yuva_color[4]
static const uint8_t green_yuva_color[4]