0

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 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 at 20:04
  • 1
    Also see doc/examples in FFmpeg source code, such as filtering_video.c. – llogan May 3 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 at 20:35
2

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 at 20:24
  • 1
    Yeah, Filters are pretty complicated. – SlimSCSI May 2 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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