mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avfilter/vf_histogram: add envelope to thistogram filter
This commit is contained in:
parent
b2491566a6
commit
f651b18c19
@ -17792,7 +17792,13 @@ Set what color components to display.
|
|||||||
Default is @code{7}.
|
Default is @code{7}.
|
||||||
|
|
||||||
@item bgopacity, b
|
@item bgopacity, b
|
||||||
Set background opacity. Default is @code{0.5}.
|
Set background opacity. Default is @code{0.9}.
|
||||||
|
|
||||||
|
@item envelope, e
|
||||||
|
Show envelope. Default is disabled.
|
||||||
|
|
||||||
|
@item ecolor, ec
|
||||||
|
Set envelope color. Default is @code{gold}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@section threshold
|
@section threshold
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
|
#include "libavutil/colorspace.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/parseutils.h"
|
#include "libavutil/parseutils.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
@ -32,6 +33,7 @@
|
|||||||
typedef struct HistogramContext {
|
typedef struct HistogramContext {
|
||||||
const AVClass *class; ///< AVClass context for log and options purpose
|
const AVClass *class; ///< AVClass context for log and options purpose
|
||||||
int thistogram;
|
int thistogram;
|
||||||
|
int envelope;
|
||||||
unsigned histogram[256*256];
|
unsigned histogram[256*256];
|
||||||
int histogram_size;
|
int histogram_size;
|
||||||
int width;
|
int width;
|
||||||
@ -41,6 +43,8 @@ typedef struct HistogramContext {
|
|||||||
int dncomp;
|
int dncomp;
|
||||||
uint8_t bg_color[4];
|
uint8_t bg_color[4];
|
||||||
uint8_t fg_color[4];
|
uint8_t fg_color[4];
|
||||||
|
uint8_t envelope_rgba[4];
|
||||||
|
uint8_t envelope_color[4];
|
||||||
int level_height;
|
int level_height;
|
||||||
int scale_height;
|
int scale_height;
|
||||||
int display_mode;
|
int display_mode;
|
||||||
@ -219,12 +223,17 @@ static int config_input(AVFilterLink *inlink)
|
|||||||
memcpy(s->bg_color, black_gbrp_color, 4);
|
memcpy(s->bg_color, black_gbrp_color, 4);
|
||||||
memcpy(s->fg_color, white_gbrp_color, 4);
|
memcpy(s->fg_color, white_gbrp_color, 4);
|
||||||
s->start[0] = s->start[1] = s->start[2] = s->start[3] = 0;
|
s->start[0] = s->start[1] = s->start[2] = s->start[3] = 0;
|
||||||
|
memcpy(s->envelope_color, s->envelope_rgba, 4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
memcpy(s->bg_color, black_yuva_color, 4);
|
memcpy(s->bg_color, black_yuva_color, 4);
|
||||||
memcpy(s->fg_color, white_yuva_color, 4);
|
memcpy(s->fg_color, white_yuva_color, 4);
|
||||||
s->start[0] = s->start[3] = 0;
|
s->start[0] = s->start[3] = 0;
|
||||||
s->start[1] = s->start[2] = s->histogram_size / 2;
|
s->start[1] = s->start[2] = s->histogram_size / 2;
|
||||||
|
s->envelope_color[0] = RGB_TO_Y_BT709(s->envelope_rgba[0], s->envelope_rgba[1], s->envelope_rgba[2]);
|
||||||
|
s->envelope_color[1] = RGB_TO_U_BT709(s->envelope_rgba[0], s->envelope_rgba[1], s->envelope_rgba[2], 0);
|
||||||
|
s->envelope_color[2] = RGB_TO_V_BT709(s->envelope_rgba[0], s->envelope_rgba[1], s->envelope_rgba[2], 0);
|
||||||
|
s->envelope_color[3] = s->envelope_rgba[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
s->fg_color[3] = s->fgopacity * 255;
|
s->fg_color[3] = s->fgopacity * 255;
|
||||||
@ -345,10 +354,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
|||||||
max_hval_log = log2(max_hval + 1);
|
max_hval_log = log2(max_hval + 1);
|
||||||
|
|
||||||
if (s->thistogram) {
|
if (s->thistogram) {
|
||||||
|
int minh = s->histogram_size - 1, maxh = 0;
|
||||||
|
|
||||||
for (int i = 0; i < s->histogram_size; i++) {
|
for (int i = 0; i < s->histogram_size; i++) {
|
||||||
int idx = s->histogram_size - i - 1;
|
int idx = s->histogram_size - i - 1;
|
||||||
int value = s->start[p];
|
int value = s->start[p];
|
||||||
|
|
||||||
|
if (s->envelope && s->histogram[idx]) {
|
||||||
|
minh = FFMIN(minh, i);
|
||||||
|
maxh = FFMAX(maxh, i);
|
||||||
|
}
|
||||||
|
|
||||||
if (s->levels_mode)
|
if (s->levels_mode)
|
||||||
value += lrint(max_value * (log2(s->histogram[idx] + 1) / max_hval_log));
|
value += lrint(max_value * (log2(s->histogram[idx] + 1) / max_hval_log));
|
||||||
else
|
else
|
||||||
@ -360,6 +376,30 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
|||||||
AV_WN16(s->out->data[p] + (i + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, value);
|
AV_WN16(s->out->data[p] + (i + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->envelope) {
|
||||||
|
if (s->histogram_size <= 256) {
|
||||||
|
s->out->data[0][(minh + starty) * s->out->linesize[p] + startx + s->x_pos] = s->envelope_color[0];
|
||||||
|
s->out->data[0][(maxh + starty) * s->out->linesize[p] + startx + s->x_pos] = s->envelope_color[0];
|
||||||
|
if (s->dncomp >= 3) {
|
||||||
|
s->out->data[1][(minh + starty) * s->out->linesize[p] + startx + s->x_pos] = s->envelope_color[1];
|
||||||
|
s->out->data[2][(minh + starty) * s->out->linesize[p] + startx + s->x_pos] = s->envelope_color[2];
|
||||||
|
s->out->data[1][(maxh + starty) * s->out->linesize[p] + startx + s->x_pos] = s->envelope_color[1];
|
||||||
|
s->out->data[2][(maxh + starty) * s->out->linesize[p] + startx + s->x_pos] = s->envelope_color[2];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const int mult = s->mult;
|
||||||
|
|
||||||
|
AV_WN16(s->out->data[0] + (minh + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, s->envelope_color[0] * mult);
|
||||||
|
AV_WN16(s->out->data[0] + (maxh + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, s->envelope_color[0] * mult);
|
||||||
|
if (s->dncomp >= 3) {
|
||||||
|
AV_WN16(s->out->data[1] + (minh + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, s->envelope_color[1] * mult);
|
||||||
|
AV_WN16(s->out->data[2] + (minh + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, s->envelope_color[2] * mult);
|
||||||
|
AV_WN16(s->out->data[1] + (maxh + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, s->envelope_color[1] * mult);
|
||||||
|
AV_WN16(s->out->data[2] + (maxh + starty) * s->out->linesize[p] + startx * 2 + s->x_pos * 2, s->envelope_color[2] * mult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < s->histogram_size; i++) {
|
for (i = 0; i < s->histogram_size; i++) {
|
||||||
int col_height;
|
int col_height;
|
||||||
@ -455,8 +495,12 @@ static const AVOption thistogram_options[] = {
|
|||||||
{ "width", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
|
{ "width", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
|
||||||
{ "w", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
|
{ "w", "set width", OFFSET(width), AV_OPT_TYPE_INT, {.i64=0}, 0, 8192, FLAGS},
|
||||||
COMMON_OPTIONS
|
COMMON_OPTIONS
|
||||||
{ "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS},
|
{ "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.9}, 0, 1, FLAGS},
|
||||||
{ "b", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS},
|
{ "b", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.9}, 0, 1, FLAGS},
|
||||||
|
{ "envelope", "display envelope", OFFSET(envelope), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
|
||||||
|
{ "e", "display envelope", OFFSET(envelope), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
|
||||||
|
{ "ecolor", "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS },
|
||||||
|
{ "ec", "set envelope color", OFFSET(envelope_rgba), AV_OPT_TYPE_COLOR, {.str="gold"}, 0, 0, FLAGS },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user