55#define OFFSET(x) offsetof(PhotosensitivityContext, x)
56#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
61 {
"threshold",
"set detection threshold factor (lower is stricter)",
OFFSET(threshold_multiplier),
AV_OPT_TYPE_FLOAT, {.dbl=1}, 0.1, FLT_MAX,
FLAGS },
62 {
"t",
"set detection threshold factor (lower is stricter)",
OFFSET(threshold_multiplier),
AV_OPT_TYPE_FLOAT, {.dbl=1}, 0.1, FLT_MAX,
FLAGS },
78#define NUM_CELLS (GRID_SIZE * GRID_SIZE)
82 int cell, gx, gy, x0, x1, y0, y1, x, y,
c, area;
106 for (y = y0; y < y1; y +=
skip) {
108 for (x = x0; x < x1; x +=
skip) {
151 const uint16_t s_mul = td->
s_mul;
152 const uint16_t t_mul = 0x100 - s_mul;
160 for (x = 0; x < linesize; x++) {
161 *t = (*t * t_mul + *
s * s_mul) >> 8;
180 int badness, x, y,
c;
185 badness +=
abs((
int)
a->grid[y][x][
c] - (
int)
b->grid[y][x][
c]);
207 int this_badness, current_badness, fixed_badness, new_badness, badness_threshold,
i, res, start;
220 if (
s->history_size) {
221 start =
s->nb_frames +
s->history_pos -
s->history_size;
222 for (
i = 1;
i <
s->history_size;
i++)
223 current_badness +=
i *
s->history[(start +
i) %
s->nb_frames];
224 current_badness /=
s->history_size;
225 badness_threshold =
s->badness_threshold *
s->history_size;
227 badness_threshold = INT_MAX;
232 new_badness = current_badness + this_badness;
234 current_badness, new_badness, badness_threshold,
235 100 * new_badness / badness_threshold, new_badness < badness_threshold ?
"OK" :
"EXCEEDED");
237 if (new_badness < badness_threshold || !s->last_frame_av ||
s->bypass) {
240 s->last_frame_av =
src = in;
241 s->last_frame_e = ef;
242 fixed_badness = new_badness;
244 factor = (
float)(badness_threshold - current_badness) / (new_badness - current_badness) *
s->blend_factor;
248 fixed_badness = current_badness;
259 fixed_badness = current_badness + this_badness;
261 current_badness, fixed_badness, badness_threshold,
262 100 * new_badness / badness_threshold,
factor);
263 s->last_frame_e = ef;
265 src =
s->last_frame_av;
268 s->history[
s->history_pos] = this_badness;
269 s->history_pos = (
s->history_pos + 1) %
s->nb_frames;
270 if (
s->history_size <
s->nb_frames)
319 .p.name =
"photosensitivity",
320 .p.description =
NULL_IF_CONFIG_SMALL(
"Filter out photosensitive epilepsy seizure-inducing flashes."),
321 .p.priv_class = &photosensitivity_class,
static const AVFilterPad inputs[]
static int config_input(AVFilterLink *inlink)
const FFFilter ff_vf_photosensitivity
static AVFormatContext * ctx
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.
Main libavfilter public API header.
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define i(width, name, range_min, range_max)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
#define AV_LOG_VERBOSE
Detailed information.
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#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(...)
#define AVFILTER_DEFINE_CLASS(fname)
static const int factor[16]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Describe the class of an AVClass context structure.
A link between two filters.
AVFilterContext * dst
dest filter
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...
float threshold_multiplier
PhotosensitivityFrame last_frame_e
uint8_t grid[GRID_SIZE][GRID_SIZE][4]
PhotosensitivityFrame * out
In the ELBG jargon, a cell is the set of points that are closest to a codebook entry.
static const AVOption photosensitivity_options[]
static int convert_frame_partial(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static void blend_frame(AVFilterContext *ctx, AVFrame *target, AVFrame *source, float factor)
static int config_input(AVFilterLink *inlink)
static int blend_frame_partial(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int get_badness(PhotosensitivityFrame *a, PhotosensitivityFrame *b)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static void convert_frame(AVFilterContext *ctx, AVFrame *in, PhotosensitivityFrame *out, int skip)
static av_cold void uninit(AVFilterContext *ctx)
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)