I'm trying to find out how to call a FFmpeg filter (freezedetect) from within FFmpeg's source code. I see the filter's file is under libavfilter/vf_freezedetect.c, but I don't know how to use that filter inside the source code. How can I do that? And what I need to pass to the function?

My FFmpeg command's high-level API is this:

ffmpeg -i freeze.mp4 -vf "freezedetect=n=-60dB:d=2" -map 0:v:0 -f null -

And what I would need to get the resulting outputs directly after calling a function given its input arguments:

lavfi.freezedetect.freeze_start: 5.005
lavfi.freezedetect.freeze_duration: 2.03537
lavfi.freezedetect.freeze_end: 7.04037
lavfi.freezedetect.freeze_start: 13.0464
lavfi.freezedetect.freeze_duration: 3.03637
lavfi.freezedetect.freeze_end: 16.0827
  • Just for some context, are you already familiar with C programming and the ffmpeg APIs? If not I suggest you start with the dranger.com tutorial on reading and parsing first. If you are comfortable with that, you can ask this question on stackoverflow and I can help with creating pads and filters.
    – SlimSCSI
    May 2, 2019 at 16:11
  • I am familiar with C, but not FFmpeg C API. Knowing how to call this filter from C API would help.
    – Tina J
    May 2, 2019 at 20:04
  • 1
    Also see doc/examples in FFmpeg source code, such as filtering_video.c.
    – llogan
    May 3, 2019 at 18:09
  • Sure. I hope the answer below can be detailed enough to implement. I'm not super C guy.
    – Tina J
    May 3, 2019 at 20:35
  • 1
    @TinaJ I'm not sure, but you can view the output of ffmpeg -filters to see which filters support slice threading.
    – llogan
    Aug 19, 2019 at 17:24

1 Answer 1


You can't just call a filter, You must instantiate a filter graph.

First you need to create a buffer and buffersink via:

AVFilterContext* source = 0;
AVFilterContext* sink = 0;
AVFilterGraph *graph = avfilter_graph_alloc()
avfilter_graph_create_filter(&source, avfilter_get_by_name("buffer"), nullptr, args, nullptr, graph);

AVBufferSinkParams* buffersink_params = av_buffersink_params_alloc();
buffersink_params->pixel_fmts = /*Your pixel format HERE*/;

avfilter_graph_create_filter(&sink, avfilter_get_by_name("buffersink"), nullptr, nullptr, buffersink_params, graph);

You can then create your filter via something like this

snprintf(args, sizeof(args), "n=-60dB:d=2");
avfilter_graph_create_filter(&freezedetect, avfilter_get_by_name("freezedetect"), nullptr, args, nullptr, graph);

Then link it all together:

avfilter_link(source, 0, freezedetect, 0);
avfilter_link(freezedetect, 0, sink, 0);
avfilter_graph_config(graph, 0);

Finally you can send frames to the filter via

av_buffersrc_write_frame(source, frame);

And get the result with

 av_buffersink_get_frame(sink, frame);

Don't forget to free it all at the end

  • umm looks very promising! And at the same time not easy though. Thanks!
    – Tina J
    May 2, 2019 at 20:24
  • 1
    Yeah, Filters are pretty complicated.
    – SlimSCSI
    May 2, 2019 at 20:25
  • Is filter API sequential, or multi-threaded? I mean, when calling filters, do they run sequential, not on a separate thread?
    – Tina J
    Aug 12, 2019 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.