ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

FFmpeg之AVFilterLink

2026/8/4 16:27:58 拓冰建站 浏览量
FFmpeg之AVFilterLink

这个结构体主要是用来link两个filter的,它存在于每个AVFilterContext中

struct AVFilterContext {const AVClass *av_class;        ///< needed for av_log() and filters common optionsconst AVFilter *filter;         ///< the AVFilter of which this is an instancechar *name;                     ///< name of this filter instanceAVFilterPad   *input_pads;      ///< array of input padsAVFilterLink **inputs;          ///< array of pointers to input linksunsigned    nb_inputs;          ///< number of input padsAVFilterPad   *output_pads;     ///< array of output padsAVFilterLink **outputs;         ///< array of pointers to output linksunsigned    nb_outputs;         ///< number of output padsvoid *priv;                     ///< private data for use by the filterstruct AVFilterGraph *graph;    ///< filtergraph this filter belongs to...}

结构体

先看结构体定义


/*** A link between two filters. This contains pointers to the source and* destination filters between which this link exists, and the indexes of* the pads involved. In addition, this link also contains the parameters* which have been negotiated and agreed upon between the filter, such as* image dimensions, format, etc.** Applications must not normally access the link structure directly.* Use the buffersrc and buffersink API instead.* In the future, access to the header may be reserved for filters* implementation.*/
struct AVFilterLink {AVFilterContext *src;       ///< source filterAVFilterPad *srcpad;        ///< output pad on the source filterAVFilterContext *dst;       ///< dest filterAVFilterPad *dstpad;        ///< input pad on the dest filterenum AVMediaType type;      ///< filter media type/* These parameters apply only to video */int w;                      ///< agreed upon image widthint h;                      ///< agreed upon image heightAVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio/* These parameters apply only to audio */uint64_t channel_layout;    ///< channel layout of current buffer (see libavutil/channel_layout.h)int sample_rate;            ///< samples per secondint format;                 ///< agreed upon media format/*** Define the time base used by the PTS of the frames/samples* which will pass through this link.* During the configuration stage, each filter is supposed to* change only the output timebase, while the timebase of the* input link is assumed to be an unchangeable property.*/AVRational time_base;/****************************************************************** All fields below this line are not part of the public API. They* may not be used outside of libavfilter and can be changed and* removed at will.* New public fields should be added right above.******************************************************************//*** Lists of supported formats / etc. supported by the input filter.*/AVFilterFormatsConfig incfg;/*** Lists of supported formats / etc. supported by the output filter.*/AVFilterFormatsConfig outcfg;/** stage of the initialization of the link properties (dimensions, etc) */enum {AVLINK_UNINIT = 0,      ///< not startedAVLINK_STARTINIT,       ///< started, but incompleteAVLINK_INIT             ///< complete} init_state;/*** Graph the filter belongs to.*/struct AVFilterGraph *graph;/*** Current timestamp of the link, as defined by the most recent* frame(s), in link time_base units.*/int64_t current_pts;/*** Current timestamp of the link, as defined by the most recent* frame(s), in AV_TIME_BASE units.*/int64_t current_pts_us;/*** Index in the age array.*/int age_index;/*** Frame rate of the stream on the link, or 1/0 if unknown or variable;* if left to 0/0, will be automatically copied from the first input* of the source filter if it exists.** Sources should set it to the best estimation of the real frame rate.* If the source frame rate is unknown or variable, set this to 1/0.* Filters should update it if necessary depending on their function.* Sinks can use it to set a default output frame rate.* It is similar to the r_frame_rate field in AVStream.*/AVRational frame_rate;/*** Minimum number of samples to filter at once. If filter_frame() is* called with fewer samples, it will accumulate them in fifo.* This field and the related ones must not be changed after filtering* has started.* If 0, all related fields are ignored.*/int min_samples;/*** Maximum number of samples to filter at once. If filter_frame() is* called with more samples, it will split them.*/int max_samples;/*** Number of channels.*/int channels;/*** Number of past frames sent through the link.*/int64_t frame_count_in, frame_count_out;/*** Number of past samples sent through the link.*/int64_t sample_count_in, sample_count_out;/*** A pointer to a FFFramePool struct.*/void *frame_pool;/*** True if a frame is currently wanted on the output of this filter.* Set when ff_request_frame() is called by the output,* cleared when a frame is filtered.*/int frame_wanted_out;/*** For hwaccel pixel formats, this should be a reference to the* AVHWFramesContext describing the frames.*/AVBufferRef *hw_frames_ctx;#ifndef FF_INTERNAL_FIELDS/*** Internal structure members.* The fields below this limit are internal for libavfilter's use* and must in no way be accessed by applications.*/char reserved[0xF000];#else /* FF_INTERNAL_FIELDS *//*** Queue of frames waiting to be filtered.*/FFFrameQueue fifo;/*** If set, the source filter can not generate a frame as is.* The goal is to avoid repeatedly calling the request_frame() method on* the same link.*/int frame_blocked_in;/*** Link input status.* If not zero, all attempts of filter_frame will fail with the* corresponding code.*/int status_in;/*** Timestamp of the input status change.*/int64_t status_in_pts;/*** Link output status.* If not zero, all attempts of request_frame will fail with the* corresponding code.*/int status_out;#endif /* FF_INTERNAL_FIELDS */};

操作函数


/*** Link two filters together.** @param src    the source filter* @param srcpad index of the output pad on the source filter* @param dst    the destination filter* @param dstpad index of the input pad on the destination filter* @return       zero on success*/
int avfilter_link(AVFilterContext *src, unsigned srcpad,AVFilterContext *dst, unsigned dstpad);/*** Free the link in *link, and set its pointer to NULL.*/
void avfilter_link_free(AVFilterLink **link);/*** Negotiate the media format, dimensions, etc of all inputs to a filter.** @param filter the filter to negotiate the properties for its inputs* @return       zero on successful negotiation*/
int avfilter_config_links(AVFilterContext *filter);

说说什么是LINK,就是link指针的drcpad和dstpad的赋值

int avfilter_link(AVFilterContext *src, unsigned srcpad,AVFilterContext *dst, unsigned dstpad)
{AVFilterLink *link;
...link->src     = src;link->dst     = dst;link->srcpad  = &src->output_pads[srcpad];link->dstpad  = &dst->input_pads[dstpad];link->type    = src->output_pads[srcpad].type;av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);link->format  = -1;ff_framequeue_init(&link->fifo, &src->graph->internal->frame_queues);return 0;
}