63 #define OFFSET(x) offsetof(HistogramContext, x)
64 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
66 #define COMMON_OPTIONS \
67 { "display_mode", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS, "display_mode"}, \
68 { "d", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS, "display_mode"}, \
69 { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "display_mode" }, \
70 { "parade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "display_mode" }, \
71 { "stack", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "display_mode" }, \
72 { "levels_mode", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "levels_mode"}, \
73 { "m", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "levels_mode"}, \
74 { "linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "levels_mode" }, \
75 { "logarithmic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "levels_mode" }, \
76 { "components", "set color components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 1, 15, FLAGS}, \
77 { "c", "set color components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 1, 15, FLAGS},
159 if (!
ctx->inputs[0]->incfg.formats ||
160 !
ctx->inputs[0]->incfg.formats->nb_formats) {
164 if (!
ctx->inputs[0]->outcfg.formats)
167 avff =
ctx->inputs[0]->incfg.formats;
212 s->ncomp =
s->desc->nb_components;
213 s->histogram_size = 1 <<
s->desc->comp[0].depth;
214 s->mult =
s->histogram_size / 256;
226 s->start[0] =
s->start[1] =
s->start[2] =
s->start[3] = 0;
227 memcpy(
s->envelope_color,
s->envelope_rgba, 4);
232 s->start[0] =
s->start[3] = 0;
233 s->start[1] =
s->start[2] =
s->histogram_size / 2;
234 s->envelope_color[0] =
RGB_TO_Y_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2]);
235 s->envelope_color[1] =
RGB_TO_U_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2], 0);
236 s->envelope_color[2] =
RGB_TO_V_BT709(
s->envelope_rgba[0],
s->envelope_rgba[1],
s->envelope_rgba[2], 0);
237 s->envelope_color[3] =
s->envelope_rgba[3];
240 s->fg_color[3] =
s->fgopacity * 255;
241 s->bg_color[3] =
s->bgopacity * 255;
243 s->planeheight[1] =
s->planeheight[2] =
AV_CEIL_RSHIFT(inlink->
h,
s->desc->log2_chroma_h);
244 s->planeheight[0] =
s->planeheight[3] = inlink->
h;
245 s->planewidth[1] =
s->planewidth[2] =
AV_CEIL_RSHIFT(inlink->
w,
s->desc->log2_chroma_w);
246 s->planewidth[0] =
s->planewidth[3] = inlink->
w;
257 if (!strcmp(
ctx->filter->name,
"thistogram"))
260 for (
i = 0;
i <
s->ncomp;
i++) {
261 if ((1 <<
i) &
s->components)
267 s->width =
ctx->inputs[0]->w;
268 outlink->
w =
s->width *
FFMAX(ncomp * (
s->display_mode == 1), 1);
269 outlink->
h =
s->histogram_size *
FFMAX(ncomp * (
s->display_mode == 2), 1);
271 outlink->
w =
s->histogram_size *
FFMAX(ncomp * (
s->display_mode == 1), 1);
272 outlink->
h = (
s->level_height +
s->scale_height) *
FFMAX(ncomp * (
s->display_mode == 2), 1);
276 s->dncomp =
s->odesc->nb_components;
290 if (!
s->thistogram || !
out) {
298 for (k = 0; k < 4 &&
out->data[k]; k++) {
299 const int is_chroma = (k == 1 || k == 2);
300 const int dst_h =
AV_CEIL_RSHIFT(outlink->
h, (is_chroma ?
s->odesc->log2_chroma_h : 0));
301 const int dst_w =
AV_CEIL_RSHIFT(outlink->
w, (is_chroma ?
s->odesc->log2_chroma_w : 0));
303 if (
s->histogram_size <= 256) {
304 for (
i = 0;
i < dst_h ;
i++)
305 memset(
out->data[
s->odesc->comp[k].plane] +
306 i *
out->linesize[
s->odesc->comp[k].plane],
307 s->bg_color[k], dst_w);
309 const int mult =
s->mult;
311 for (
i = 0;
i < dst_h ;
i++)
312 for (j = 0; j < dst_w; j++)
314 i *
out->linesize[
s->odesc->comp[k].plane] + j * 2,
315 s->bg_color[k] *
mult);
320 for (m = 0, k = 0; k <
s->ncomp; k++) {
321 const int p =
s->desc->comp[k].plane;
322 const int max_value =
s->histogram_size - 1 -
s->start[p];
323 const int height =
s->planeheight[p];
324 const int width =
s->planewidth[p];
326 unsigned max_hval = 0;
329 if (!((1 << k) &
s->components))
332 starty = m *
s->histogram_size * (
s->display_mode == 2);
333 startx = m++ *
s->width * (
s->display_mode == 1);
335 startx = m *
s->histogram_size * (
s->display_mode == 1);
336 starty = m++ * (
s->level_height +
s->scale_height) * (
s->display_mode == 2);
339 if (
s->histogram_size <= 256) {
342 for (j = 0; j <
width; j++)
343 s->histogram[
src[j]]++;
347 const uint16_t *
src = (
const uint16_t *)(
in->data[p] +
i *
in->linesize[p]);
348 for (j = 0; j <
width; j++)
349 s->histogram[
src[j]]++;
353 for (
i = 0;
i <
s->histogram_size;
i++)
354 max_hval =
FFMAX(max_hval,
s->histogram[
i]);
355 max_hval_log =
log2(max_hval + 1);
358 const int bpp = 1 + (
s->histogram_size > 256);
359 int minh =
s->histogram_size - 1, maxh = 0;
362 s->x_pos =
out->width - 1;
363 for (j = 0; j < outlink->
h; j++) {
364 memmove(
out->data[p] + j *
out->linesize[p] ,
365 out->data[p] + j *
out->linesize[p] + bpp,
366 (outlink->
w - 1) * bpp);
368 }
else if (
s->slide == 3) {
370 for (j = 0; j < outlink->
h; j++) {
371 memmove(
out->data[p] + j *
out->linesize[p] + bpp,
372 out->data[p] + j *
out->linesize[p],
373 (outlink->
w - 1) * bpp);
377 for (
int i = 0;
i <
s->histogram_size;
i++) {
378 int idx =
s->histogram_size -
i - 1;
381 if (
s->envelope &&
s->histogram[idx]) {
387 value +=
lrint(max_value * (
log2(
s->histogram[idx] + 1) / max_hval_log));
389 value +=
lrint(max_value *
s->histogram[idx] / (
float)max_hval);
391 if (
s->histogram_size <= 256) {
392 s->out->data[p][(
i + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
value;
394 AV_WN16(
s->out->data[p] + (
i + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
value);
399 if (
s->histogram_size <= 256) {
400 s->out->data[0][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[0];
401 s->out->data[0][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[0];
402 if (
s->dncomp >= 3) {
403 s->out->data[1][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[1];
404 s->out->data[2][(minh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[2];
405 s->out->data[1][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[1];
406 s->out->data[2][(maxh + starty) *
s->out->linesize[p] + startx +
s->x_pos] =
s->envelope_color[2];
409 const int mult =
s->mult;
411 AV_WN16(
s->out->data[0] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[0] *
mult);
412 AV_WN16(
s->out->data[0] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[0] *
mult);
413 if (
s->dncomp >= 3) {
414 AV_WN16(
s->out->data[1] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[1] *
mult);
415 AV_WN16(
s->out->data[2] + (minh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[2] *
mult);
416 AV_WN16(
s->out->data[1] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[1] *
mult);
417 AV_WN16(
s->out->data[2] + (maxh + starty) *
s->out->linesize[p] + startx * 2 +
s->x_pos * 2,
s->envelope_color[2] *
mult);
422 for (
i = 0;
i <
s->histogram_size;
i++) {
426 col_height =
lrint(
s->level_height * (1. - (
log2(
s->histogram[
i] + 1) / max_hval_log)));
428 col_height =
s->level_height - (
s->histogram[
i] * (int64_t)
s->level_height + max_hval - 1) / max_hval;
430 if (
s->histogram_size <= 256) {
431 for (j =
s->level_height - 1; j >= col_height; j--) {
432 if (
s->display_mode) {
433 for (l = 0; l <
s->dncomp; l++)
434 out->data[l][(j + starty) *
out->linesize[l] + startx +
i] =
s->fg_color[l];
436 out->data[p][(j + starty) *
out->linesize[p] + startx +
i] = 255;
439 for (j =
s->level_height +
s->scale_height - 1; j >=
s->level_height; j--)
440 out->data[p][(j + starty) *
out->linesize[p] + startx +
i] =
i;
442 const int mult =
s->mult;
444 for (j =
s->level_height - 1; j >= col_height; j--) {
445 if (
s->display_mode) {
446 for (l = 0; l <
s->dncomp; l++)
447 AV_WN16(
out->data[l] + (j + starty) *
out->linesize[l] + startx * 2 +
i * 2,
s->fg_color[l] *
mult);
449 AV_WN16(
out->data[p] + (j + starty) *
out->linesize[p] + startx * 2 +
i * 2, 255 *
mult);
452 for (j =
s->level_height +
s->scale_height - 1; j >=
s->level_height; j--)
453 AV_WN16(
out->data[p] + (j + starty) *
out->linesize[p] + startx * 2 +
i * 2,
i);
458 memset(
s->histogram, 0,
s->histogram_size *
sizeof(
unsigned));
464 if (
s->x_pos >=
s->width) {
466 if (
s->thistogram && (
s->slide == 4 ||
s->slide == 0)) {
470 }
else if (
s->thistogram &&
s->slide == 4) {
504 #if CONFIG_HISTOGRAM_FILTER
513 .priv_class = &histogram_class,
518 #if CONFIG_THISTOGRAM_FILTER
527 static const AVOption thistogram_options[] = {
549 .
name =
"thistogram",
556 .priv_class = &thistogram_class,
AVFilter ff_vf_thistogram
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Main libavfilter public API header.
#define AV_CEIL_RSHIFT(a, b)
static av_cold int uninit(AVCodecContext *avctx)
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static int16_t mult(Float11 *f1, Float11 *f2)
Various defines for YUV<->RGB conversion.
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
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
static const SheerTable rgb[2]
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.
const char * name
Pad name.
const char * name
Filter name.
This structure describes decoded (raw) audio or video data.
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 enum AVPixelFormat out_pix_fmts[]
static const uint8_t black_yuva_color[4]
static const AVOption histogram_options[]
static enum AVPixelFormat levels_in_pix_fmts[]
static enum AVPixelFormat levels_out_rgb10_pix_fmts[]
static int query_formats(AVFilterContext *ctx)
static const uint8_t white_yuva_color[4]
static int config_input(AVFilterLink *inlink)
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
static enum AVPixelFormat levels_out_rgb8_pix_fmts[]
static enum AVPixelFormat levels_out_rgb12_pix_fmts[]
static enum AVPixelFormat levels_out_rgb9_pix_fmts[]
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)
AVFILTER_DEFINE_CLASS(histogram)
static const uint8_t black_gbrp_color[4]
static enum AVPixelFormat levels_out_yuv9_pix_fmts[]
static enum AVPixelFormat levels_out_yuv8_pix_fmts[]
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.