FFmpeg  4.3
vf_freezedetect.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file
21  * video freeze detection filter
22  */
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/imgutils.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
28 #include "libavutil/timestamp.h"
29 
30 #include "avfilter.h"
31 #include "filters.h"
32 #include "scene_sad.h"
33 
34 typedef struct FreezeDetectContext {
35  const AVClass *class;
36 
37  ptrdiff_t width[4];
38  ptrdiff_t height[4];
40  int bitdepth;
42  int64_t n;
43  int64_t reference_n;
44  int frozen;
45 
46  double noise;
47  int64_t duration; ///< minimum duration of frozen frame until notification
49 
50 #define OFFSET(x) offsetof(FreezeDetectContext, x)
51 #define V AV_OPT_FLAG_VIDEO_PARAM
52 #define F AV_OPT_FLAG_FILTERING_PARAM
53 
54 static const AVOption freezedetect_options[] = {
55  { "n", "set noise tolerance", OFFSET(noise), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0, 1.0, V|F },
56  { "noise", "set noise tolerance", OFFSET(noise), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0, 1.0, V|F },
57  { "d", "set minimum duration in seconds", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=2000000}, 0, INT64_MAX, V|F },
58  { "duration", "set minimum duration in seconds", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=2000000}, 0, INT64_MAX, V|F },
59 
60  {NULL}
61 };
62 
63 AVFILTER_DEFINE_CLASS(freezedetect);
64 
66 {
67  static const enum AVPixelFormat pix_fmts[] = {
92  };
93 
94  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
95  if (!fmts_list)
96  return AVERROR(ENOMEM);
97  return ff_set_common_formats(ctx, fmts_list);
98 }
99 
100 static int config_input(AVFilterLink *inlink)
101 {
102  AVFilterContext *ctx = inlink->dst;
103  FreezeDetectContext *s = ctx->priv;
104  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
105 
106  s->bitdepth = pix_desc->comp[0].depth;
107 
108  for (int plane = 0; plane < 4; plane++) {
109  ptrdiff_t line_size = av_image_get_linesize(inlink->format, inlink->w, plane);
110  s->width[plane] = line_size >> (s->bitdepth > 8);
111  s->height[plane] = inlink->h >> ((plane == 1 || plane == 2) ? pix_desc->log2_chroma_h : 0);
112  }
113 
114  s->sad = ff_scene_sad_get_fn(s->bitdepth == 8 ? 8 : 16);
115  if (!s->sad)
116  return AVERROR(EINVAL);
117 
118  return 0;
119 }
120 
122 {
123  FreezeDetectContext *s = ctx->priv;
125 }
126 
128 {
129  uint64_t sad = 0;
130  uint64_t count = 0;
131  double mafd;
132  for (int plane = 0; plane < 4; plane++) {
133  if (s->width[plane]) {
134  uint64_t plane_sad;
135  s->sad(frame->data[plane], frame->linesize[plane],
136  reference->data[plane], reference->linesize[plane],
137  s->width[plane], s->height[plane], &plane_sad);
138  sad += plane_sad;
139  count += s->width[plane] * s->height[plane];
140  }
141  }
142  emms_c();
143  mafd = (double)sad / count / (1ULL << s->bitdepth);
144  return (mafd <= s->noise);
145 }
146 
147 static int set_meta(FreezeDetectContext *s, AVFrame *frame, const char *key, const char *value)
148 {
149  av_log(s, AV_LOG_INFO, "%s: %s\n", key, value);
150  return av_dict_set(&frame->metadata, key, value, 0);
151 }
152 
154 {
155  int ret;
156  AVFilterLink *inlink = ctx->inputs[0];
157  AVFilterLink *outlink = ctx->outputs[0];
158  FreezeDetectContext *s = ctx->priv;
159  AVFrame *frame;
160 
161  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
162 
163  ret = ff_inlink_consume_frame(inlink, &frame);
164  if (ret < 0)
165  return ret;
166 
167  if (frame) {
168  int frozen = 0;
169  s->n++;
170 
171  if (s->reference_frame) {
172  int64_t duration;
173  if (s->reference_frame->pts == AV_NOPTS_VALUE || frame->pts == AV_NOPTS_VALUE || frame->pts < s->reference_frame->pts) // Discontinuity?
174  duration = inlink->frame_rate.num > 0 ? av_rescale_q(s->n - s->reference_n, av_inv_q(inlink->frame_rate), AV_TIME_BASE_Q) : 0;
175  else
176  duration = av_rescale_q(frame->pts - s->reference_frame->pts, inlink->time_base, AV_TIME_BASE_Q);
177 
178  frozen = is_frozen(s, s->reference_frame, frame);
179  if (duration >= s->duration) {
180  if (!s->frozen)
181  set_meta(s, frame, "lavfi.freezedetect.freeze_start", av_ts2timestr(s->reference_frame->pts, &inlink->time_base));
182  if (!frozen) {
183  set_meta(s, frame, "lavfi.freezedetect.freeze_duration", av_ts2timestr(duration, &AV_TIME_BASE_Q));
184  set_meta(s, frame, "lavfi.freezedetect.freeze_end", av_ts2timestr(frame->pts, &inlink->time_base));
185  }
186  s->frozen = frozen;
187  }
188  }
189 
190  if (!frozen) {
192  s->reference_frame = av_frame_clone(frame);
193  s->reference_n = s->n;
194  if (!s->reference_frame) {
195  av_frame_free(&frame);
196  return AVERROR(ENOMEM);
197  }
198  }
199  return ff_filter_frame(outlink, frame);
200  }
201 
202  FF_FILTER_FORWARD_STATUS(inlink, outlink);
203  FF_FILTER_FORWARD_WANTED(outlink, inlink);
204 
205  return FFERROR_NOT_READY;
206 }
207 
209  {
210  .name = "default",
211  .type = AVMEDIA_TYPE_VIDEO,
212  .config_props = config_input,
213  },
214  { NULL }
215 };
216 
218  {
219  .name = "default",
220  .type = AVMEDIA_TYPE_VIDEO,
221  },
222  { NULL }
223 };
224 
226  .name = "freezedetect",
227  .description = NULL_IF_CONFIG_SMALL("Detects frozen video input."),
228  .priv_size = sizeof(FreezeDetectContext),
229  .priv_class = &freezedetect_class,
230  .uninit = uninit,
232  .inputs = freezedetect_inputs,
233  .outputs = freezedetect_outputs,
234  .activate = activate,
235 };
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:81
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link&#39;s FIFO and update the link&#39;s stats.
Definition: avfilter.c:1476
#define NULL
Definition: coverity.c:32
void(* ff_scene_sad_fn)(SCENE_SAD_PARAMS)
Definition: scene_sad.h:34
int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
Compute the size of an image line with format pix_fmt and width width for the plane plane...
Definition: imgutils.c:76
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:440
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:399
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:432
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2549
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
AVOption.
Definition: opt.h:246
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:434
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:407
8 bits gray, 8 bits alpha
Definition: pixfmt.h:143
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:417
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:435
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
ff_scene_sad_fn ff_scene_sad_get_fn(int depth)
Definition: scene_sad.c:59
#define OFFSET(x)
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
int num
Numerator.
Definition: rational.h:59
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:413
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:377
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:401
const char * key
static const AVFilterPad freezedetect_outputs[]
#define F
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:378
static int set_meta(FreezeDetectContext *s, AVFrame *frame, const char *key, const char *value)
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:379
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
#define av_cold
Definition: attributes.h:88
AVOptions.
timestamp utils, mostly useful for debugging/logging purposes
#define emms_c()
Definition: internal.h:55
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:393
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:431
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:412
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
static AVFrame * frame
static const AVOption freezedetect_options[]
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
AVFILTER_DEFINE_CLASS(freezedetect)
AVDictionary * metadata
metadata.
Definition: frame.h:586
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:410
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:402
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:439
#define av_log(a,...)
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
A filter pad used for either input or output.
Definition: internal.h:54
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
Scene SAD functions.
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
static int query_formats(AVFilterContext *ctx)
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:600
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
#define AVERROR(e)
Definition: error.h:43
static int activate(AVFilterContext *ctx)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:76
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static int config_input(AVFilterLink *inlink)
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:441
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:418
simple assert() macros that are a bit more flexible than ISO C assert().
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:400
int64_t duration
minimum duration of frozen frame until notification
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:419
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:395
as above, but U and V bytes are swapped
Definition: pixfmt.h:90
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
Definition: filters.h:254
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:416
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:381
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
AVFormatContext * ctx
Definition: movenc.c:48
packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb
Definition: pixfmt.h:210
#define s(width, name)
Definition: cbs_vp9.c:257
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:436
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:396
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:415
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:541
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:408
static av_cold void uninit(AVFilterContext *ctx)
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:405
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
static const AVFilterPad freezedetect_inputs[]
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:380
ff_scene_sad_fn sad
#define V
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:67
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:397
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
double value
Definition: eval.c:98
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
const char * name
Filter name.
Definition: avfilter.h:148
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:403
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:394
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
#define FF_FILTER_FORWARD_STATUS(inlink, outlink)
Acknowledge the status on an input link and forward it to an output link.
Definition: filters.h:226
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:406
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:414
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:398
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:404
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
static int is_frozen(FreezeDetectContext *s, AVFrame *reference, AVFrame *frame)
Y , 8bpp.
Definition: pixfmt.h:74
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:433
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:201
A list of supported formats for one end of a filter link.
Definition: formats.h:64
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
An instance of a filter.
Definition: avfilter.h:338
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
int depth
Number of bits in the component.
Definition: pixdesc.h:58
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:409
AVFilter ff_vf_freezedetect
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248