FFmpeg AVfilter application example
Header file
Extern "C" {
# include "libavutil/mem.h"
# include "libavfilter/avfiltergraph.h"
# include "libavfilter/buffersink.h"
# include "libavfilter/buffersrc.h"
# include "libavutil/avutil.h"
# include "libavutil/imgutils.h"
# include "libavdevice/avdevice.h"
}
Registration filter
Avfilter_register_all ()
/ *
For pSrcFrame frame, the final image data is saved in pDestFrame
, /
Void VideoDecodec::DrawRectangleToFrame (AVFrame* pSrcFrame, AVFrame* pDestFrame, int x, int y, int w, int h)
{
AVFilterGraph* pFilterGraph = avfilter_graph_alloc ()
Char szErrMsg [128] = {0}
Char szArgs [512] = {0}
Char szFilterDescr [256] = {0}
Sprintf (szFilterDescr, "drawbox=x=%d:y=%d:w=%d:h=%d:color=yellow@1", x, y, w, h)
AVFilter* pBufferSrc = avfilter_get_by_name ("buffer")
AVFilter* pBufferSink = avfilter_get_by_name ("buffersink")
AVFilterInOut* pFilterOut = avfilter_inout_alloc ()
AVFilterInOut* pFilterIn = avfilter_inout_alloc ()
Enum AVPixelFormat pix_fmts [] = {AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE}
AVBufferSinkParams* pBufferSinkParams
/ / the last few parameters do not use real video format parameters
Snprintf (szArgs, sizeof (szArgs), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d"
PSrcFrame- > width, pSrcFrame- > height, pSrcFrame- > format, 1,1,1,1)
Int ret = 0
AVFilterContext* pBufferSinkContext = NULL
AVFilterContext* pBufferSrcContext = NULL
If ((ret = avfilter_graph_create_filter (& pBufferSrcContext, pBufferSrc, "in", szArgs, NULL, pFilterGraph))
< 0) { sprintf(szErrMsg, "Cannot graph create filter, error:%s\n", av_err2str(ret)); return; } pBufferSinkParams = av_buffersink_params_alloc(); pBufferSinkParams->Pixel_fmts = pix_fmts
If ((ret = avfilter_graph_create_filter (& pBufferSinkContext, pBufferSink, "out", NULL, pBufferSinkParams, pFilterGraph))
< 0) { sprintf(szErrMsg, "Cannot graph create filter, error:%s\n", av_err2str(ret)); return; } pFilterOut->Name = av_strdup ("in")
PFilterOut- > filter_ctx = pBufferSrcContext
PFilterOut- > pad_idx = 0
PFilterOut- > next = NULL
PFilterIn- > name = av_strdup ("out")
PFilterIn- > filter_ctx = pBufferSinkContext
PFilterIn- > pad_idx = 0
PFilterIn- > next = NULL
Do
{
If ((ret = avfilter_graph_parse_ptr (pFilterGraph, szFilterDescr, & pFilterIn, & pFilterOut, NULL) < 0)
{
Sprintf (szErrMsg, "Cannot graph parse ptr, error:%s\ n", av_err2str (ret))
Break
}
If ((ret = avfilter_graph_config (pFilterGraph, NULL)) < 0)
{
Sprintf (szErrMsg, "Cannot graph config filter, error:%s\ n", av_err2str (ret))
Break
}
If ((ret = av_buffersrc_add_frame (pBufferSrcContext, pSrcFrame)) < 0)
{
Sprintf (szErrMsg, "Cannot add frame from buffersrc, error:%s\ n", av_err2str (ret))
Break
}
/ / the length and width of pDestFrame frames must be specified.
/ / after the image format conversion, the data data in pSrcFrame is set to NULL,pSrcFrame structure is not available
If ((ret = av_buffersink_get_frame (pBufferSinkContext, pDestFrame)) < 0)
{
Sprintf (szErrMsg, "Cannot get frame frome buffersink, error:%s\ n", av_err2str (ret))
Break
}
} while (0)
Avfilter_inout_free & pFilterIn)
Avfilter_inout_free & pFilterOut)
Av_free (pBufferSinkParams)
Avfilter_graph_free & pFilterGraph)
}
Be careful
1. When calling avfilter_get_by_name ("ffbuffersink"), the ffmpeg in the new version 3.4 should be changed to avfilter_get_by_name ("buffersink"); otherwise, the return pointer is empty, and the call avfilter_graph_create_filter returns-12.