=====================================================
The simplest of ffmpeg-based Avfilter Example series articles:
Simplest FFmpeg-based Avfilter example (watermark overlay)
Simplest example of a ffmpeg-based Avfilter-Pure edition
=====================================================
The Avfilter of FFmpeg has written a watermark overlay example of the simplest ffmpeg-based Avfilter example (watermark overlay), this article as an example of supplementing and recording a pure version of Avfilter. Previously Libavfilter has been used in conjunction with the interface functions of LIBAVCODEC and other class libraries, So I always thought that libraries such as libavfilter and libavcodec are highly coupled (that is, if you want to use Libavfilter's visual and audio effects function, you must use the functions of class libraries such as Libavcodec). The two days of free time to study the Libavfilter code after the discovery of the actual situation is not the case: Libavfilter can be independent of the LIBAVCODEC and other class library interface functions as a "pure" audio-visual effect class library for use. The avfilter example of "Pure Edition" documented in this article implements a purely video effect added feature. This example input as a YUV file, the output is also a YUV file, through the function of Avfilter can handle the YUV file to achieve de-tonal, fuzzy, horizontal flip, crop, add box, overlay text and other functions.
Flow chart
The flowchart for the program is shown below. The initialization of the avfilter is more complex and simpler to use. You need to call Avfilter_register_all () to Avfilter_graph_config () a series of functions when initializing. When used, there are only two functions: Av_buffersrc_add_frame () is used to add a avframe to the filtergraph, while the Av_buffersink_get_frame () Used to remove a avframe from the filtergraph.
The key functions in the process are as follows:
Avfilter_register_all (): Register all Avfilter.
Avfilter_graph_alloc (): Allocates memory for Filtergraph.
Avfilter_graph_create_filter (): Creates and adds a filter to the filtergraph.
Avfilter_graph_parse_ptr (): Adds a string of graph descriptions to the filtergraph.
Avfilter_graph_config (): Check the configuration of the filtergraph.
Av_buffersrc_add_frame (): Add a avframe to the filtergraph.
Av_buffersink_get_frame (): Remove a avframe from the filtergraph.
Code
/** * Simplest FFmpeg-based Avfilter example-pure version * simplest FFmpeg avfilter example-pure * * Lei hua Lei xiaohua * [email protected ] * Communication University/Digital TV Technology * Communication University of China/digital TV Technology * http://blog.csdn.net/leixiaohua1020 * * this The program uses FFmpeg's avfilter to realize the filter processing function of YUV pixel data. * Can add various special effects functions to YUV data. * is the simplest ffmpeg avfilter aspect of the tutorial. * Suitable for beginners of ffmpeg. * * This software uses FFmpeg ' s avfilter to process YUV raw data. * It can add many excellent effect to YUV data. * It ' s The simplest example based on FFmpeg ' s avfilter. * Suitable for beginner of FFmpeg * */#include <stdio.h> #define __STDC_CONSTANT_MACROS#IFDEF _win32#define snprintf _snprintf//windowsextern "C" {#include "libavfilter/avfiltergraph.h" #include "libavfilter/buffersink.h" #include " Libavfilter/buffersrc.h "#include" libavutil/avutil.h "#include" libavutil/imgutils.h "} #else//linux ... #ifdef __ Cplusplusextern "C" {#endif # include <libavfilter/avfiltergraph.h> #include <libavfilter/buffersink.h># Include <libavfilter/buffersrc.h> #include <libavutil/avutil.h> #include <libavutil/imgutils.h> #ifdef __cplusplus}; #endif # Endifint Main (int argc, char* argv[]) {int ret; Avframe *frame_in; Avframe *frame_out;unsigned Char *frame_buffer_in;unsigned char *frame_buffer_out; Avfiltercontext *buffersink_ctx; Avfiltercontext *buffersrc_ctx; avfiltergraph *filter_graph;static int video_stream_index = -1;//input yuvfile *fp_in=fopen ("sintel_480x272_ Yuv420p.yuv "," rb+ "); if (fp_in==null) {printf (" Error open input file.\n "); return-1;} int In_width=480;int in_height=272;//output yuvfile *fp_out=fopen ("Output.yuv", "wb+"), if (fp_out==null) {printf (" Error open Output file.\n "); return-1;} const char *FILTER_DESCR = "lutyuv= ' u=128:v=128 '"; const char *FILTER_DESCR = "Boxblur";//const char *filter_descr = "HFL IP ";//const char *filter_descr =" hue= ' h=60:s=-3 ' ";//const char *filter_descr =" Crop=2/3*in_w:2/3*in_h ";//const char * FILTER_DESCR = "drawbox=x=100:y=100:w=100:h=100:[email protected]";//const Char *filTER_DESCR = "drawtext=fontfile=arial.ttf:fontcolor=green:fontsize=30:text= ' Lei Xiaohua '"; Avfilter_register_all (); Char args[512]; Avfilter *buffersrc = avfilter_get_by_name ("buffer"); Avfilter *buffersink = Avfilter_get_by_name ("Ffbuffersink"); Avfilterinout *outputs = Avfilter_inout_alloc (); Avfilterinout *inputs = Avfilter_inout_alloc (); enum PixelFormat pix_fmts[] = {pix_fmt_yuv420p, PIX_FMT_NONE}; Avbuffersinkparams *buffersink_params;filter_graph = Avfilter_graph_alloc ();/* Buffer video Source:the decoded frames From the decoder would be is inserted here. */snprintf (args, sizeof (args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", In_width,in_ height,pix_fmt_yuv420p,1, 25,1,1); ret = Avfilter_graph_create_filter (&buffersrc_ctx, Buffersrc, "in", Args, NULL, Filter_graph); if (Ret < 0) {printf ("Cannot create buffer source\n"); return ret;} /* Buffer Video sink:to terminate the filter chain. */buffersink_params = Av_buffersink_params_alloc (); buffersink_params->pixel_FMTS = Pix_fmts;ret = Avfilter_graph_create_filter (&buffersink_ctx, Buffersink, "out", NULL, Buffersink_params, Filter_graph); Av_free (buffersink_params); if (Ret < 0) {printf ("Cannot create buffer sink\n"); return ret;} /* Endpoints for the filter graph. */outputs->name = Av_strdup ("in"); outputs->filter_ctx = Buffersrc_ctx;outputs->pad_idx = 0;outputs->n ext = Null;inputs->name = Av_strdup ("Out"); inputs->filter_ctx = Buffersink_ctx;inputs->pad_idx = 0 ; inputs->next = null;if (ret = avfilter_graph_parse_ptr (filter_graph, Filter_descr,&inputs, &outputs, NU LL)) < 0) return ret;if (ret = Avfilter_graph_config (filter_graph, NULL)) < 0) return Ret;frame_in=av_frame_alloc () ; frame_buffer_in= (unsigned char *) av_malloc (av_image_get_buffer_size (pix_fmt_yuv420p, in_width,in_height,1)); av_ Image_fill_arrays (Frame_in->data, Frame_in->linesize,frame_buffer_in,pix_fmt_yuv420p,in_width, in_height,1 ); Frame_out=av_frame_alloc (); FRAme_buffer_out= (unsigned char *) av_malloc (av_image_get_buffer_size (pix_fmt_yuv420p, in_width,in_height,1)); av_ Image_fill_arrays (Frame_out->data, Frame_out->linesize,frame_buffer_out,pix_fmt_yuv420p,in_width, In_ height,1);frame_in->width=in_width;frame_in->height=in_height;frame_in->format=pix_fmt_yuv420p; while (1) {if (Fread (frame_buffer_in, 1, IN_WIDTH*IN_HEIGHT*3/2, fp_in)! = IN_WIDTH*IN_HEIGHT*3/2) {break;} Input Y,u,vframe_in->data[0]=frame_buffer_in;frame_in->data[1]=frame_buffer_in+in_width*in_height;frame _in->data[2]=frame_buffer_in+in_width*in_height*5/4; if (Av_buffersrc_add_frame (Buffersrc_ctx, frame_in) < 0) {printf ("Error while add frame.\n"); Break }/* Pull filtered pictures from the filtergraph */ret = Av_buffersink_get_frame (Buffersink_ctx, frame_out); if (Ret < 0) break;//output y,u,vif (frame_out->format==pix_fmt_yuv420p) {for (int i=0;i<frame_out-> height;i++) {fwrite (fRame_out->data[0]+frame_out->linesize[0]*i,1,frame_out->width,fp_out);} for (int i=0;i<frame_out->height/2;i++) {fwrite (frame_out->data[1]+frame_out->linesize[1]*i,1,frame_ Out->width/2,fp_out);} for (int i=0;i<frame_out->height/2;i++) {fwrite (frame_out->data[2]+frame_out->linesize[2]*i,1,frame_ out->width/2,fp_out);}} printf ("Process 1 frame!\n"); }fclose (fp_in); fclose (fp_out); Av_frame_free (&frame_in); Av_frame_free (&frame_out); Avfilter_graph_free (&filter_graph); return 0;}
Results
The program is entered as a yuv420p video data called "SINTEL_480X272_YUV420P.YUV", and the output is a yuv420p video data named "Output.yuv". The contents of the input video data are as follows.
Several effects are available in the program:
- lutyuv= ' u=128:v=128 '
- Boxblur
- Hflip
- Hue= ' h=60:s=-3 '
- Crop=2/3*in_w:2/3*in_h
- Drawbox=x=100:y=100:w=100:h=100:[email protected]
- drawtext=fontfile=arial.ttf:fontcolor=green:fontsize=30:text= ' Lei Xiaohua '
These effects can be achieved by modifying the FILTER_DESCR string in the program. Several special effects are shown below.
lutyuv= ' u=128:v=128 '
Boxblur
Hflip
hue= ' h=60:s=-3 '
Crop=2/3*in_w:2/3*in_h
Drawbox=x=100:y=100:w=100:h=100:[email protected]
drawtext=fontfile=arial.ttf:fontcolor=green:fontsize=30:text= ' Lei Xiaohua '
Download
simplest ffmpeg video filter
Project Home
sourceforge:https://sourceforge.net/projects/simplestffmpegvideofilter/
Github:https://github.com/leixiaohua1020/simplest_ffmpeg_video_filter
Open source China: Http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_video_filter
csdn:http://download.csdn.net/detail/leixiaohua1020/9424521
This program consists of the following two items:
Simplest_ffmpeg_video_filter: A PNG image can be overlaid onto the video as a watermark, combined with a class library such as Libavfilter,libavcodec.
Simplest_ffmpeg_video_filter_pure: You can add special effects to YUV pixel data, using only the Libavfilter library.
Simplest example of a ffmpeg-based Avfilter-Pure edition