71#define OFFSET(x) offsetof(SignalstatsContext, x)
72#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
96 s->filters |= 1 <<
s->outfilter;
100 b =
s->rgba_color[2];
101 s->yuv_color[0] = (( 66*
r + 129*
g + 25*
b + (1<<7)) >> 8) + 16;
102 s->yuv_color[1] = ((-38*
r + -74*
g + 112*
b + (1<<7)) >> 8) + 128;
103 s->yuv_color[2] = ((112*
r + -94*
g + -18*
b + (1<<7)) >> 8) + 128;
160 s->hsub =
desc->log2_chroma_w;
161 s->vsub =
desc->log2_chroma_h;
162 s->depth =
desc->comp[0].depth;
163 s->maxsize = 1 <<
s->depth;
169 if (!
s->histy || !
s->histu || !
s->histv || !
s->histsat)
172 outlink->
w = inlink->
w;
173 outlink->
h = inlink->
h;
178 s->fs = inlink->
w * inlink->
h;
179 s->cfs =
s->chromaw *
s->chromah;
188 if (!
s->frame_sat || !
s->frame_hue)
196 const int chromax = x >>
s->hsub;
197 const int chromay = y >>
s->vsub;
198 f->data[0][y *
f->linesize[0] + x] =
s->yuv_color[0];
199 f->data[1][chromay *
f->linesize[1] + chromax] =
s->yuv_color[1];
200 f->data[2][chromay *
f->linesize[2] + chromax] =
s->yuv_color[2];
205 const int chromax = x >>
s->hsub;
206 const int chromay = y >>
s->vsub;
207 const int mult = 1 << (
s->depth - 8);
208 AV_WN16(
f->data[0] + y *
f->linesize[0] + x * 2,
s->yuv_color[0] *
mult);
209 AV_WN16(
f->data[1] + chromay *
f->linesize[1] + chromax * 2,
s->yuv_color[1] *
mult);
210 AV_WN16(
f->data[2] + chromay *
f->linesize[2] + chromax * 2,
s->yuv_color[2] *
mult);
226 const int yc = y >>
s->vsub;
227 const uint8_t *pluma = &in->
data[0][y * in->
linesize[0]];
228 const uint8_t *pchromau = &in->
data[1][yc * in->
linesize[1]];
229 const uint8_t *pchromav = &in->
data[2][yc * in->
linesize[2]];
231 for (x = 0; x <
w; x++) {
232 const int xc = x >>
s->hsub;
233 const int luma = pluma[x];
234 const int chromau = pchromau[xc];
235 const int chromav = pchromav[xc];
236 const int filt = luma < 16 || luma > 235 ||
237 chromau < 16 || chromau > 240 ||
238 chromav < 16 || chromav > 240;
253 const int mult = 1 << (
s->depth - 8);
261 const int yc = y >>
s->vsub;
262 const uint16_t *pluma = (uint16_t *)&in->
data[0][y * in->
linesize[0]];
263 const uint16_t *pchromau = (uint16_t *)&in->
data[1][yc * in->
linesize[1]];
264 const uint16_t *pchromav = (uint16_t *)&in->
data[2][yc * in->
linesize[2]];
266 for (x = 0; x <
w; x++) {
267 const int xc = x >>
s->hsub;
268 const int luma = pluma[x];
269 const int chromau = pchromau[xc];
270 const int chromav = pchromav[xc];
271 const int filt = luma < 16 * mult || luma > 235 *
mult ||
272 chromau < 16 * mult || chromau > 240 *
mult ||
273 chromav < 16 * mult || chromav > 240 *
mult;
284 return ((
abs(x - y) +
abs (z - y)) / 2) -
abs(z - x) > 4;
297 const uint8_t *p = in->
data[0];
299 int x, y, score = 0,
filt;
303 if (y - 1 < 0 || y + 1 >=
h)
309#define FILTER(i, j) \
310 filter_tout_outlier(p[(y-j) * lw + x + i], \
311 p[ y * lw + x + i], \
312 p[(y+j) * lw + x + i])
314#define FILTER3(j) (FILTER(-1, j) && FILTER(0, j) && FILTER(1, j))
316 if (y - 2 >= 0 && y + 2 <
h) {
317 for (x = 1; x <
w - 1; x++) {
324 for (x = 1; x <
w - 1; x++) {
345 const uint16_t *p = (uint16_t *)in->
data[0];
347 int x, y, score = 0,
filt;
351 if (y - 1 < 0 || y + 1 >=
h)
357 if (y - 2 >= 0 && y + 2 <
h) {
358 for (x = 1; x <
w - 1; x++) {
365 for (x = 1; x <
w - 1; x++) {
388 const uint8_t *p = in->
data[0];
394 const int ylw = y * lw;
395 int filt, totdiff = 0;
400 for (x = 0; x <
w; x++)
401 totdiff +=
abs(p[y2lw + x] - p[ylw + x]);
406 for (x = 0; x <
w; x++)
422 const uint16_t *p = (uint16_t *)in->
data[0];
428 const int ylw = y * lw;
435 for (x = 0; x <
w; x++)
436 totdiff +=
abs(p[y2lw + x] - p[ylw + x]);
441 for (x = 0; x <
w; x++)
470 const int lsz_u =
src->linesize[1];
471 const int lsz_v =
src->linesize[2];
475 const int lsz_sat = dst_sat->
linesize[0];
476 const int lsz_hue = dst_hue->
linesize[0];
481 for (
i = 0;
i <
s->chromaw;
i++) {
482 const int yuvu = p_u[
i];
483 const int yuvv = p_v[
i];
484 p_sat[
i] = hypotf(yuvu - 128, yuvv - 128);
485 ((int16_t*)p_hue)[
i] = fmodf(
floorf((180.f /
M_PI) *
atan2f(yuvu-128, yuvv-128) + 180.f), 360.f);
504 const int mid = 1 << (
s->depth - 1);
509 const int lsz_u =
src->linesize[1] / 2;
510 const int lsz_v =
src->linesize[2] / 2;
511 const uint16_t *p_u = (uint16_t*)
src->data[1] +
slice_start * lsz_u;
512 const uint16_t *p_v = (uint16_t*)
src->data[2] +
slice_start * lsz_v;
514 const int lsz_sat = dst_sat->
linesize[0] / 2;
515 const int lsz_hue = dst_hue->
linesize[0] / 2;
520 for (
i = 0;
i <
s->chromaw;
i++) {
521 const int yuvu = p_u[
i];
522 const int yuvv = p_v[
i];
523 p_sat[
i] = hypotf(yuvu - mid, yuvv - mid);
524 ((int16_t*)p_hue)[
i] = fmodf(
floorf((180.f /
M_PI) *
atan2f(yuvu-mid, yuvv-mid) + 180.f), 360.f);
550 unsigned int *histy =
s->histy,
554 *histsat =
s->histsat;
555 int miny = -1, minu = -1, minv = -1;
556 int maxy = -1, maxu = -1, maxv = -1;
557 int lowy = -1, lowu = -1, lowv = -1;
558 int highy = -1, highu = -1, highv = -1;
559 int minsat = -1, maxsat = -1, lowsat = -1, highsat = -1;
560 int lowp, highp, clowp, chighp;
561 int accy, accu, accv;
562 int accsat, acchue = 0;
564 int64_t toty = 0, totu = 0, totv = 0, totsat=0;
566 int64_t dify = 0, difu = 0, difv = 0;
567 uint16_t masky = 0, masku = 0, maskv = 0;
574 const int hbd =
s->depth > 8;
584 prev =
s->frame_prev;
604 memset(
s->histy, 0,
s->maxsize *
sizeof(*
s->histy));
605 memset(
s->histu, 0,
s->maxsize *
sizeof(*
s->histu));
606 memset(
s->histv, 0,
s->maxsize *
sizeof(*
s->histv));
607 memset(
s->histsat, 0,
s->maxsize *
sizeof(*
s->histsat));
610 const uint16_t *p_sat = (uint16_t *)sat->
data[0];
611 const uint16_t *p_hue = (uint16_t *)hue->
data[0];
612 const int lsz_sat = sat->
linesize[0] / 2;
613 const int lsz_hue = hue->
linesize[0] / 2;
615 for (
int j = 0; j < link->
h; j++) {
616 for (
int i = 0;
i < link->
w;
i++) {
628 for (
int j = 0; j <
s->chromah; j++) {
629 for (
int i = 0;
i <
s->chromaw;
i++) {
641 histhue[((int16_t*)p_hue)[
i]]++;
649 const uint8_t *p_sat = sat->
data[0];
650 const uint8_t *p_hue = hue->
data[0];
651 const int lsz_sat = sat->
linesize[0];
652 const int lsz_hue = hue->
linesize[0];
654 for (
int j = 0; j < link->
h; j++) {
655 for (
int i = 0;
i < link->
w;
i++) {
656 const int yuv = in->
data[0][
w +
i];
660 dify +=
abs(yuv - prev->
data[0][pw +
i]);
667 for (
int j = 0; j <
s->chromah; j++) {
668 for (
int i = 0;
i <
s->chromaw;
i++) {
669 const int yuvu = in->
data[1][cw+
i];
670 const int yuvv = in->
data[2][cw+
i];
675 difu +=
abs(yuvu - prev->
data[1][cpw+
i]);
677 difv +=
abs(yuvv - prev->
data[2][cpw+
i]);
680 histhue[((int16_t*)p_hue)[
i]]++;
690 if (
s->filters & 1<<fil) {
693 .out =
out != in &&
s->outfilter == fil ?
out :
NULL,
695 memset(
s->jobs_rets, 0,
s->nb_jobs *
sizeof(*
s->jobs_rets));
697 &td,
s->jobs_rets,
s->nb_jobs);
698 for (
int i = 0;
i <
s->nb_jobs;
i++)
699 filtot[fil] +=
s->jobs_rets[
i];
706 lowp =
lrint(
s->fs * 10 / 100.);
707 highp =
lrint(
s->fs * 90 / 100.);
708 clowp =
lrint(
s->cfs * 10 / 100.);
709 chighp =
lrint(
s->cfs * 90 / 100.);
711 accy = accu = accv = accsat = 0;
712 for (fil = 0; fil <
s->maxsize; fil++) {
713 if (miny < 0 && histy[fil]) miny = fil;
714 if (minu < 0 && histu[fil]) minu = fil;
715 if (minv < 0 && histv[fil]) minv = fil;
716 if (minsat < 0 && histsat[fil]) minsat = fil;
718 if (histy[fil]) maxy = fil;
719 if (histu[fil]) maxu = fil;
720 if (histv[fil]) maxv = fil;
721 if (histsat[fil]) maxsat = fil;
723 toty += (uint64_t)histy[fil] * fil;
724 totu += (uint64_t)histu[fil] * fil;
725 totv += (uint64_t)histv[fil] * fil;
726 totsat += (uint64_t)histsat[fil] * fil;
731 accsat += histsat[fil];
733 if (lowy == -1 && accy >= lowp) lowy = fil;
734 if (lowu == -1 && accu >= clowp) lowu = fil;
735 if (lowv == -1 && accv >= clowp) lowv = fil;
736 if (lowsat == -1 && accsat >= clowp) lowsat = fil;
738 if (highy == -1 && accy >= highp) highy = fil;
739 if (highu == -1 && accu >= chighp) highu = fil;
740 if (highv == -1 && accv >= chighp) highv = fil;
741 if (highsat == -1 && accsat >= chighp) highsat = fil;
746 for (fil = 0; fil < 360; fil++) {
747 tothue += (uint64_t)histhue[fil] * fil;
748 acchue += histhue[fil];
750 if (medhue == -1 && acchue >
s->cfs / 2)
752 if (histhue[fil] > maxhue) {
753 maxhue = histhue[fil];
760#define SET_META(key, fmt, val) do { \
761 snprintf(metabuf, sizeof(metabuf), fmt, val); \
762 av_dict_set(&out->metadata, "lavfi.signalstats." key, metabuf, 0); \
767 SET_META(
"YAVG",
"%g", 1.0 * toty /
s->fs);
773 SET_META(
"UAVG",
"%g", 1.0 * totu /
s->cfs);
779 SET_META(
"VAVG",
"%g", 1.0 * totv /
s->cfs);
785 SET_META(
"SATAVG",
"%g", 1.0 * totsat /
s->cfs);
790 SET_META(
"HUEAVG",
"%g", 1.0 * tothue /
s->cfs);
792 SET_META(
"YDIF",
"%g", 1.0 * dify /
s->fs);
793 SET_META(
"UDIF",
"%g", 1.0 * difu /
s->cfs);
794 SET_META(
"VDIF",
"%g", 1.0 * difv /
s->cfs);
801 if (
s->filters & 1<<fil) {
803 snprintf(metabuf,
sizeof(metabuf),
"%g", 1.0 * filtot[fil] /
s->fs);
831 .p.name =
"signalstats",
832 .p.description =
"Generate statistics from video analysis.",
833 .p.priv_class = &signalstats_class,
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed)
static const int8_t filt[NUMTAPS *2]
const FFFilter ff_vf_signalstats
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
Make sure a frame is writable.
#define i(width, name, range_min, range_max)
#define AV_CEIL_RSHIFT(a, b)
static __device__ float floorf(float a)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
int(* init)(AVBSFContext *ctx)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_COLOR
Underlying C type is uint8_t[4].
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
enum AVPixelFormat pixfmt
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)
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
#define FILTER_PIXFMTS_ARRAY(array)
#define AVFILTER_DEFINE_CLASS(fname)
static enum AVPixelFormat pix_fmts[]
static const uint16_t mask[17]
Memory handling functions.
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_YUV420P16
#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_YUV420P12
#define AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P14
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_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
@ 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_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
@ 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_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_YUV422P14
#define AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV440P10
#define AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P10
Describe the class of an AVClass context structure.
AVFilterLink ** inputs
array of pointers to input links
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
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...
Used for passing data between threads.
#define av_malloc_array(a, b)
static AVFormatContext * ctx
#define SET_META(key, fmt, val)
static const AVFilterPad signalstats_outputs[]
static AVFrame * alloc_frame(enum AVPixelFormat pixfmt, int w, int h)
static int filter8_tout(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static void burn_frame8(const SignalstatsContext *s, AVFrame *f, int x, int y)
int(* process16)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static const AVFilterPad signalstats_inputs[]
static int compute_sat_hue_metrics8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_frame(AVFilterLink *link, AVFrame *in)
static int compute_sat_hue_metrics16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter8_vrep(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static unsigned compute_bit_depth(uint16_t mask)
static int filter16_vrep(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter16_tout(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter8_brng(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static const struct @017302175103271015024365147256334144304120275223 filters_def[]
static av_cold void uninit(AVFilterContext *ctx)
int(* process8)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int config_output(AVFilterLink *outlink)
static void burn_frame16(const SignalstatsContext *s, AVFrame *f, int x, int y)
static const AVOption signalstats_options[]
static int filter_tout_outlier(uint8_t x, uint8_t y, uint8_t z)
static int filter16_brng(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)