Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
29a92c01
Commit
29a92c01
authored
Dec 21, 2012
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
histogram filter
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
e5212354
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
417 additions
and
2 deletions
+417
-2
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+83
-0
Makefile
libavfilter/Makefile
+1
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+2
-2
vf_histogram.c
libavfilter/vf_histogram.c
+329
-0
No files found.
Changelog
View file @
29a92c01
...
@@ -13,6 +13,7 @@ version <next>:
...
@@ -13,6 +13,7 @@ version <next>:
- allpass, bass, bandpass, bandreject, biquad, equalizer, highpass, lowpass
- allpass, bass, bandpass, bandreject, biquad, equalizer, highpass, lowpass
and treble audio filter
and treble audio filter
- improved showspectrum filter, with multichannel support and sox-like colors
- improved showspectrum filter, with multichannel support and sox-like colors
- histogram filter
version 1.1:
version 1.1:
...
...
doc/filters.texi
View file @
29a92c01
...
@@ -3098,6 +3098,89 @@ the histogram. Possible values are @code{none}, @code{weak} or
...
@@ -3098,6 +3098,89 @@ the histogram. Possible values are @code{none}, @code{weak} or
@code{strong}. It defaults to @code{none}.
@code{strong}. It defaults to @code{none}.
@end table
@end table
@section histogram
Compute and draw a color distribution histogram for the input video.
The computed histogram is a representation of distribution of color components
in an image.
The filter accepts the following named parameters:
@table @option
@item mode
Set histogram mode.
It accepts the following values:
@table @samp
@item levels
standard histogram that display color components distribution in an image.
Displays color graph for each color component. Shows distribution
of the Y, U, V, A or G, B, R components, depending on input format,
in current frame. Bellow each graph is color component scale meter.
@item color
chroma values in vectorscope, if brighter more such chroma values are
distributed in an image.
Displays chroma values (U/V color placement) in two dimensional graph
(which is called a vectorscope). It can be used to read of the hue and
saturation of the current frame. At a same time it is a histogram.
The whiter a pixel in the vectorscope, the more pixels of the input frame
correspond to that pixel (that is the more pixels have this chroma value).
The V component is displayed on the horizontal (X) axis, with the leftmost
side being V = 0 and the rightmost side being V = 255.
The U component is displayed on the vertical (Y) axis, with the top
representing U = 0 and the bottom representing U = 255.
The position of a white pixel in the graph corresponds to the chroma value
of a pixel of the input clip. So the graph can be used to read of the
hue (color flavor) and the saturation (the dominance of the hue in the color).
As the hue of a color changes, it moves around the square. At the center of
the square, the saturation is zero, which means that the corresponding pixel
has no color. If you increase the amount of a specific color, while leaving
the other colors unchanged, the saturation increases, and you move towards
the edge of the square.
@item color2
chroma values in vectorscope, similar as @code{color} but actual chroma values
are displayed.
@item waveform
per row/column luminance graph. In row mode the left side represents luma = 0
and right side represents luma = 255. In column mode top side represends
luma = 0 and bottom side represents luma = 255.
@end table
Default value is @code{levels}.
@item level_height
Set height of level in @code{levels}. Default value is @code{200}.
Allowed range is [50, 2048].
@item scale_height
Set height of color scale in @code{levels}. Default value is @code{12}.
Allowed range is [0, 40].
@item step
Set step for @code{waveform} mode. Smaller values are useful to find out how much
of same luminance values across input rows/columns are distributed.
Default value is @code{10}. Allowed range is [1, 255].
@item waveform_mode
Set mode for @code{waveform}. Can be either @code{row}, or @code{column}.
Default is @code{row}.
@subsection Examples
@itemize
@item
Calculate and draw histogram:
@example
ffplay -i input -vf histogram
@end example
@end itemize
@section hqdn3d
@section hqdn3d
High precision/quality 3d denoise filter. This filter aims to reduce
High precision/quality 3d denoise filter. This filter aims to reduce
...
...
libavfilter/Makefile
View file @
29a92c01
...
@@ -122,6 +122,7 @@ OBJS-$(CONFIG_GEQ_FILTER) += vf_geq.o
...
@@ -122,6 +122,7 @@ OBJS-$(CONFIG_GEQ_FILTER) += vf_geq.o
OBJS-$(CONFIG_GRADFUN_FILTER)
+=
vf_gradfun.o
OBJS-$(CONFIG_GRADFUN_FILTER)
+=
vf_gradfun.o
OBJS-$(CONFIG_HFLIP_FILTER)
+=
vf_hflip.o
OBJS-$(CONFIG_HFLIP_FILTER)
+=
vf_hflip.o
OBJS-$(CONFIG_HISTEQ_FILTER)
+=
vf_histeq.o
OBJS-$(CONFIG_HISTEQ_FILTER)
+=
vf_histeq.o
OBJS-$(CONFIG_HISTOGRAM_FILTER)
+=
vf_histogram.o
OBJS-$(CONFIG_HQDN3D_FILTER)
+=
vf_hqdn3d.o
OBJS-$(CONFIG_HQDN3D_FILTER)
+=
vf_hqdn3d.o
OBJS-$(CONFIG_HUE_FILTER)
+=
vf_hue.o
OBJS-$(CONFIG_HUE_FILTER)
+=
vf_hue.o
OBJS-$(CONFIG_IDET_FILTER)
+=
vf_idet.o
OBJS-$(CONFIG_IDET_FILTER)
+=
vf_idet.o
...
...
libavfilter/allfilters.c
View file @
29a92c01
...
@@ -116,6 +116,7 @@ void avfilter_register_all(void)
...
@@ -116,6 +116,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
GRADFUN
,
gradfun
,
vf
);
REGISTER_FILTER
(
GRADFUN
,
gradfun
,
vf
);
REGISTER_FILTER
(
HFLIP
,
hflip
,
vf
);
REGISTER_FILTER
(
HFLIP
,
hflip
,
vf
);
REGISTER_FILTER
(
HISTEQ
,
histeq
,
vf
);
REGISTER_FILTER
(
HISTEQ
,
histeq
,
vf
);
REGISTER_FILTER
(
HISTOGRAM
,
histogram
,
vf
);
REGISTER_FILTER
(
HQDN3D
,
hqdn3d
,
vf
);
REGISTER_FILTER
(
HQDN3D
,
hqdn3d
,
vf
);
REGISTER_FILTER
(
HUE
,
hue
,
vf
);
REGISTER_FILTER
(
HUE
,
hue
,
vf
);
REGISTER_FILTER
(
IDET
,
idet
,
vf
);
REGISTER_FILTER
(
IDET
,
idet
,
vf
);
...
...
libavfilter/version.h
View file @
29a92c01
...
@@ -29,8 +29,8 @@
...
@@ -29,8 +29,8 @@
#include "libavutil/avutil.h"
#include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 3
5
#define LIBAVFILTER_VERSION_MINOR 3
6
#define LIBAVFILTER_VERSION_MICRO 10
1
#define LIBAVFILTER_VERSION_MICRO 10
0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
LIBAVFILTER_VERSION_MINOR, \
...
...
libavfilter/vf_histogram.c
0 → 100644
View file @
29a92c01
/*
* Copyright (c) 2012-2013 Paul B Mahol
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/avassert.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"
enum
HistogramMode
{
MODE_LEVELS
,
MODE_WAVEFORM
,
MODE_COLOR
,
MODE_COLOR2
,
MODE_NB
};
typedef
struct
HistogramContext
{
const
AVClass
*
class
;
///< AVClass context for log and options purpose
enum
HistogramMode
mode
;
unsigned
histogram
[
256
];
unsigned
max_hval
;
int
ncomp
;
const
uint8_t
*
bg_color
;
const
uint8_t
*
fg_color
;
int
level_height
;
int
scale_height
;
int
step
;
int
waveform_mode
;
}
HistogramContext
;
#define OFFSET(x) offsetof(HistogramContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static
const
AVOption
histogram_options
[]
=
{
{
"mode"
,
"set histogram mode"
,
OFFSET
(
mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
MODE_LEVELS
},
0
,
MODE_NB
-
1
,
FLAGS
,
"mode"
},
{
"levels"
,
"standard histogram"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
MODE_LEVELS
},
0
,
0
,
FLAGS
,
"mode"
},
{
"waveform"
,
"per row/column luminance graph"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
MODE_WAVEFORM
},
0
,
0
,
FLAGS
,
"mode"
},
{
"color"
,
"chroma values in vectorscope"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
MODE_COLOR
},
0
,
0
,
FLAGS
,
"mode"
},
{
"color2"
,
"chroma values in vectorscope"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
MODE_COLOR2
},
0
,
0
,
FLAGS
,
"mode"
},
{
"level_height"
,
"set level height"
,
OFFSET
(
level_height
),
AV_OPT_TYPE_INT
,
{.
i64
=
200
},
50
,
2048
,
FLAGS
},
{
"scale_height"
,
"set scale height"
,
OFFSET
(
scale_height
),
AV_OPT_TYPE_INT
,
{.
i64
=
12
},
0
,
40
,
FLAGS
},
{
"step"
,
"set waveform step value"
,
OFFSET
(
step
),
AV_OPT_TYPE_INT
,
{.
i64
=
10
},
1
,
255
,
FLAGS
},
{
"waveform_mode"
,
"set waveform mode"
,
OFFSET
(
waveform_mode
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
1
,
FLAGS
,
"waveform_mode"
},
{
"row"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
0
},
0
,
0
,
FLAGS
,
"waveform_mode"
},
{
"column"
,
NULL
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
1
},
0
,
0
,
FLAGS
,
"waveform_mode"
},
{
NULL
},
};
AVFILTER_DEFINE_CLASS
(
histogram
);
static
av_cold
int
init
(
AVFilterContext
*
ctx
,
const
char
*
args
)
{
HistogramContext
*
h
=
ctx
->
priv
;
int
ret
;
h
->
class
=
&
histogram_class
;
av_opt_set_defaults
(
h
);
if
((
ret
=
(
av_set_options_string
(
h
,
args
,
"="
,
":"
)))
<
0
)
return
ret
;
return
0
;
}
static
const
enum
AVPixelFormat
color_pix_fmts
[]
=
{
AV_PIX_FMT_YUV444P
,
AV_PIX_FMT_YUVA444P
,
AV_PIX_FMT_YUVJ444P
,
AV_PIX_FMT_NONE
};
static
const
enum
AVPixelFormat
levels_pix_fmts
[]
=
{
AV_PIX_FMT_YUV444P
,
AV_PIX_FMT_YUVA444P
,
AV_PIX_FMT_YUVJ444P
,
AV_PIX_FMT_GRAY8
,
AV_PIX_FMT_GBRP
,
AV_PIX_FMT_NONE
};
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
HistogramContext
*
h
=
ctx
->
priv
;
const
enum
AVPixelFormat
*
pix_fmts
;
switch
(
h
->
mode
)
{
case
MODE_LEVELS
:
pix_fmts
=
levels_pix_fmts
;
break
;
case
MODE_WAVEFORM
:
case
MODE_COLOR
:
case
MODE_COLOR2
:
pix_fmts
=
color_pix_fmts
;
break
;
default:
av_assert0
(
0
);
}
ff_set_common_formats
(
ctx
,
ff_make_format_list
(
pix_fmts
));
return
0
;
}
static
const
uint8_t
black_yuva_color
[
4
]
=
{
0
,
127
,
127
,
255
};
static
const
uint8_t
black_gbrp_color
[
4
]
=
{
0
,
0
,
0
,
255
};
static
const
uint8_t
white_yuva_color
[
4
]
=
{
255
,
127
,
127
,
255
};
static
const
uint8_t
white_gbrp_color
[
4
]
=
{
255
,
255
,
255
,
255
};
static
int
config_input
(
AVFilterLink
*
inlink
)
{
HistogramContext
*
h
=
inlink
->
dst
->
priv
;
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
h
->
ncomp
=
desc
->
nb_components
;
switch
(
inlink
->
format
)
{
case
AV_PIX_FMT_GBRP
:
h
->
bg_color
=
black_gbrp_color
;
h
->
fg_color
=
white_gbrp_color
;
break
;
default:
h
->
bg_color
=
black_yuva_color
;
h
->
fg_color
=
white_yuva_color
;
}
return
0
;
}
static
int
config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
HistogramContext
*
h
=
ctx
->
priv
;
switch
(
h
->
mode
)
{
case
MODE_LEVELS
:
outlink
->
w
=
256
;
outlink
->
h
=
(
h
->
level_height
+
h
->
scale_height
)
*
h
->
ncomp
;
break
;
case
MODE_WAVEFORM
:
if
(
h
->
waveform_mode
)
outlink
->
h
=
256
;
else
outlink
->
w
=
256
;
break
;
case
MODE_COLOR
:
case
MODE_COLOR2
:
outlink
->
h
=
outlink
->
w
=
256
;
break
;
default:
av_assert0
(
0
);
}
outlink
->
sample_aspect_ratio
=
(
AVRational
){
1
,
1
};
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFilterBufferRef
*
in
)
{
HistogramContext
*
h
=
inlink
->
dst
->
priv
;
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AVFilterBufferRef
*
out
;
const
uint8_t
*
src
;
uint8_t
*
dst
;
int
i
,
j
,
k
,
l
,
ret
;
out
=
ff_get_video_buffer
(
outlink
,
AV_PERM_WRITE
,
outlink
->
w
,
outlink
->
h
);
if
(
!
out
)
{
avfilter_unref_bufferp
(
&
in
);
return
AVERROR
(
ENOMEM
);
}
out
->
pts
=
in
->
pts
;
out
->
pos
=
in
->
pos
;
for
(
k
=
0
;
k
<
h
->
ncomp
;
k
++
)
for
(
i
=
0
;
i
<
outlink
->
h
;
i
++
)
memset
(
out
->
data
[
k
]
+
i
*
out
->
linesize
[
k
],
h
->
bg_color
[
k
],
outlink
->
w
);
switch
(
h
->
mode
)
{
case
MODE_LEVELS
:
for
(
k
=
0
;
k
<
h
->
ncomp
;
k
++
)
{
for
(
i
=
0
;
i
<
in
->
video
->
h
;
i
++
)
{
src
=
in
->
data
[
k
]
+
i
*
in
->
linesize
[
k
];
for
(
j
=
0
;
j
<
in
->
video
->
w
;
j
++
)
h
->
histogram
[
src
[
j
]]
++
;
}
for
(
i
=
0
;
i
<
256
;
i
++
)
h
->
max_hval
=
FFMAX
(
h
->
max_hval
,
h
->
histogram
[
i
]);
int
start
=
k
*
(
h
->
level_height
+
h
->
scale_height
);
for
(
i
=
0
;
i
<
outlink
->
w
;
i
++
)
{
int
col_height
=
h
->
level_height
-
(
float
)
h
->
histogram
[
i
]
/
h
->
max_hval
*
h
->
level_height
;
for
(
j
=
h
->
level_height
-
1
;
j
>=
col_height
;
j
--
)
for
(
l
=
0
;
l
<
h
->
ncomp
;
l
++
)
out
->
data
[
l
][(
j
+
start
)
*
out
->
linesize
[
l
]
+
i
]
=
h
->
fg_color
[
l
];
for
(
j
=
h
->
level_height
+
h
->
scale_height
-
1
;
j
>=
h
->
level_height
;
j
--
)
out
->
data
[
k
][(
j
+
start
)
*
out
->
linesize
[
k
]
+
i
]
=
i
;
}
memset
(
h
->
histogram
,
0
,
256
*
sizeof
(
unsigned
));
h
->
max_hval
=
0
;
}
break
;
case
MODE_WAVEFORM
:
if
(
h
->
waveform_mode
)
{
for
(
i
=
0
;
i
<
inlink
->
w
;
i
++
)
{
for
(
j
=
0
;
j
<
inlink
->
h
;
j
++
)
{
int
pos
=
in
->
data
[
0
][
j
*
in
->
linesize
[
0
]
+
i
]
*
out
->
linesize
[
0
]
+
i
;
unsigned
value
=
out
->
data
[
0
][
pos
];
value
=
FFMIN
(
value
+
h
->
step
,
255
);
out
->
data
[
0
][
pos
]
=
value
;
}
}
}
else
{
for
(
i
=
0
;
i
<
inlink
->
h
;
i
++
)
{
src
=
in
->
data
[
0
]
+
i
*
in
->
linesize
[
0
];
dst
=
out
->
data
[
0
]
+
i
*
out
->
linesize
[
0
];
for
(
j
=
0
;
j
<
inlink
->
w
;
j
++
)
{
int
pos
=
src
[
j
];
unsigned
value
=
dst
[
pos
];
value
=
FFMIN
(
value
+
h
->
step
,
255
);
dst
[
pos
]
=
value
;
}
}
}
break
;
case
MODE_COLOR
:
for
(
i
=
0
;
i
<
inlink
->
h
;
i
++
)
{
int
iw1
=
i
*
in
->
linesize
[
1
];
int
iw2
=
i
*
in
->
linesize
[
2
];
for
(
j
=
0
;
j
<
inlink
->
w
;
j
++
)
{
int
pos
=
in
->
data
[
1
][
iw1
+
j
]
*
out
->
linesize
[
0
]
+
in
->
data
[
2
][
iw2
+
j
];
if
(
out
->
data
[
0
][
pos
]
<
255
)
out
->
data
[
0
][
pos
]
++
;
}
}
for
(
i
=
0
;
i
<
256
;
i
++
)
{
dst
=
out
->
data
[
0
]
+
i
*
out
->
linesize
[
0
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
if
(
!
dst
[
j
])
{
out
->
data
[
1
][
i
*
out
->
linesize
[
0
]
+
j
]
=
i
;
out
->
data
[
2
][
i
*
out
->
linesize
[
0
]
+
j
]
=
j
;
}
}
}
break
;
case
MODE_COLOR2
:
for
(
i
=
0
;
i
<
inlink
->
h
;
i
++
)
{
int
iw1
=
i
*
in
->
linesize
[
1
];
int
iw2
=
i
*
in
->
linesize
[
2
];
for
(
j
=
0
;
j
<
inlink
->
w
;
j
++
)
{
int
u
=
in
->
data
[
1
][
iw1
+
j
];
int
v
=
in
->
data
[
2
][
iw2
+
j
];
int
pos
=
u
*
out
->
linesize
[
0
]
+
v
;
if
(
!
out
->
data
[
0
][
pos
])
out
->
data
[
0
][
pos
]
=
FFABS
(
128
-
u
)
+
FFABS
(
128
-
v
);
out
->
data
[
1
][
pos
]
=
u
;
out
->
data
[
2
][
pos
]
=
v
;
}
}
break
;
default:
av_assert0
(
0
);
}
ret
=
ff_filter_frame
(
outlink
,
out
);
avfilter_unref_bufferp
(
&
in
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
HistogramContext
*
h
=
ctx
->
priv
;
av_opt_free
(
h
);
}
static
const
AVFilterPad
inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
filter_frame
=
filter_frame
,
.
config_props
=
config_input
,
.
min_perms
=
AV_PERM_READ
,
},
{
NULL
}
};
static
const
AVFilterPad
outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
config_props
=
config_output
,
},
{
NULL
}
};
AVFilter
avfilter_vf_histogram
=
{
.
name
=
"histogram"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Compute and draw a histogram."
),
.
priv_size
=
sizeof
(
HistogramContext
),
.
init
=
init
,
.
uninit
=
uninit
,
.
query_formats
=
query_formats
,
.
inputs
=
inputs
,
.
outputs
=
outputs
,
.
priv_class
=
&
histogram_class
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment