學習如何使用ffmpeg的編程主要是熟悉API(固然能夠研究它的源碼,分析他的架構和如何實現的編碼是更有價值的)。這裏主要將程序裏的函數提出來分析。 編程
根據filter的名字獲取到AVFilter 架構
/** * Get a filter definition matching the given name. * * @param name the filter name to find * @return the filter definition, if any matching one is registered. * NULL if none found. */ #if !FF_API_NOCONST_GET_NAME const #endif AVFilter *avfilter_get_by_name(const char *name);
分配一個AVFilterInOut入口 app
/** * Allocate a single AVFilterInOut entry. * Must be freed with avfilter_inout_free(). * @return allocated AVFilterInOut on success, NULL on failure. */ AVFilterInOut *avfilter_inout_alloc(void);AVFilterInOut是什麼?
一個輸入或者輸出的過濾器鏈的鏈表節點。 ide
/** * A linked-list of the inputs/outputs of the filter chain. * * This is mainly useful for avfilter_graph_parse() / avfilter_graph_parse2(), * where it is used to communicate open (unlinked) inputs and outputs from and * to the caller. * This struct specifies, per each not connected pad contained in the graph, the * filter context and the pad index required for establishing a link. */ typedef struct AVFilterInOut { /** unique name for this input/output in the list */ char *name; /** filter context associated to this input/output */ AVFilterContext *filter_ctx; /** index of the filt_ctx pad to use for linking */ int pad_idx; /** next input/input in the list, NULL if this is the last */ struct AVFilterInOut *next; } AVFilterInOut;
分配一個AVFilterGraph的空間 函數
/** * Allocate a filter graph. */ AVFilterGraph *avfilter_graph_alloc(void);那麼AVFilterGraph是什麼?反正Filter是用FlterGraph組織管理的。
typedef struct AVFilterGraph { const AVClass *av_class; #if FF_API_FOO_COUNT attribute_deprecated unsigned filter_count_unused; #endif AVFilterContext **filters; #if !FF_API_FOO_COUNT unsigned nb_filters; #endif char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters char *resample_lavr_opts; ///< libavresample options to use for the auto-inserted resample filters #if FF_API_FOO_COUNT unsigned nb_filters; #endif /** * Type of multithreading allowed for filters in this graph. A combination * of AVFILTER_THREAD_* flags. * * May be set by the caller at any point, the setting will apply to all * filters initialized after that. The default is allowing everything. * * When a filter in this graph is initialized, this field is combined using * bit AND with AVFilterContext.thread_type to get the final mask used for * determining allowed threading types. I.e. a threading type needs to be * set in both to be allowed. */ int thread_type; /** * Maximum number of threads used by filters in this graph. May be set by * the caller before adding any filters to the filtergraph. Zero (the * default) means that the number of threads is determined automatically. */ int nb_threads; /** * Opaque object for libavfilter internal use. */ AVFilterGraphInternal *internal; /** * Opaque user data. May be set by the caller to an arbitrary value, e.g. to * be used from callbacks like @ref AVFilterGraph.execute. * Libavfilter will not touch this field in any way. */ void *opaque; /** * This callback may be set by the caller immediately after allocating the * graph and before adding any filters to it, to provide a custom * multithreading implementation. * * If set, filters with slice threading capability will call this callback * to execute multiple jobs in parallel. * * If this field is left unset, libavfilter will use its internal * implementation, which may or may not be multithreaded depending on the * platform and build options. */ avfilter_execute_func *execute; char *aresample_swr_opts; ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions /** * Private fields * * The following fields are for internal use only. * Their type, offset, number and semantic can change without notice. */ AVFilterLink **sink_links; int sink_links_count; unsigned disable_auto_convert; } AVFilterGraph;
在filtergraph裏建立一個filter實例。 學習
/** * Create a new filter instance in a filter graph. * * @param graph graph in which the new filter will be used * @param filter the filter to create an instance of * @param name Name to give to the new instance (will be copied to * AVFilterContext.name). This may be used by the caller to identify * different filters, libavfilter itself assigns no semantics to * this parameter. May be NULL. * * @return the context of the newly created filter instance (note that it is * also retrievable directly through AVFilterGraph.filters or with * avfilter_graph_get_filter()) on success or NULL on failure. */ AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph, const AVFilter *filter, const char *name);
建立並添加一個filter實例到一個已經存在的graph中。 ui
/** * Create and add a filter instance into an existing graph. * The filter instance is created from the filter filt and inited * with the parameters args and opaque. * * In case of success put in *filt_ctx the pointer to the created * filter instance, otherwise set *filt_ctx to NULL. * * @param name the instance name to give to the created filter instance * @param graph_ctx the filter graph * @return a negative AVERROR error code in case of failure, a non * negative value otherwise */ int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx);
建立一個AVBufferSinkParams結構體。必須用av_free()函數來釋放。 this
/** * Create an AVBufferSinkParams structure. * * Must be freed with av_free(). */ AVBufferSinkParams *av_buffersink_params_alloc(void);那麼什麼是AVBufferSinkParams結構體呢?用於初始化一個buffersink上下文的結構體。
/** * Struct to use for initializing a buffersink context. */ typedef struct { const enum AVPixelFormat *pixel_fmts; ///< list of allowed pixel formats, terminated by AV_PIX_FMT_NONE } AVBufferSinkParams;
添加一個用字符串描述的graph到一個graph中。 編碼
/** * Add a graph described by a string to a graph. * * @param graph the filter graph where to link the parsed graph context * @param filters string to be parsed * @param inputs pointer to a linked list to the inputs of the graph, may be NULL. * If non-NULL, *inputs is updated to contain the list of open inputs * after the parsing, should be freed with avfilter_inout_free(). * @param outputs pointer to a linked list to the outputs of the graph, may be NULL. * If non-NULL, *outputs is updated to contain the list of open outputs * after the parsing, should be freed with avfilter_inout_free(). * @return non negative on success, a negative AVERROR code on error */ int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx);
檢查有效性並配置graph中全部的links和格式。 spa
/** * Check validity and configure all the links and formats in the graph. * * @param graphctx the filter graph * @param log_ctx context used for logging * @return >= 0 in case of success, a negative AVERROR code otherwise */ int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx);
釋放一個graph,並銷燬他的links,並將指向AVFilterGraph的指針設爲NULL。若是原本就是NULL,什麼也不幹
/** * Free a graph, destroy its links, and set *graph to NULL. * If *graph is NULL, do nothing. */ void avfilter_graph_free(AVFilterGraph **graph);
將指定的AVFrame的全部字段設爲默認值。
/** * Set the fields of the given AVFrame to default values. * * @param frame The AVFrame of which the fields should be set to default values. * * @deprecated use av_frame_unref() */ attribute_deprecated void avcodec_get_frame_defaults(AVFrame *frame);
獲取AVFrame裏的timestamp字段。
int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame);
添加一幀到緩衝源
/** * Add a frame to the buffer source. * * @param ctx an instance of the buffersrc filter * @param frame frame to be added. If the frame is reference counted, this * function will take ownership of the reference(s) and reset the frame. * Otherwise the frame data will be copied. If this function returns an error, * the input frame is not touched. * * @return 0 on success, a negative AVERROR on error. * * @note the difference between this function and av_buffersrc_write_frame() is * that av_buffersrc_write_frame() creates a new reference to the input frame, * while this function takes ownership of the reference passed to it. * * This function is equivalent to av_buffersrc_add_frame_flags() without the * AV_BUFFERSRC_FLAG_KEEP_REF flag. */ int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame);
這個函數從buffer_sink參數中獲取音或者視頻緩衝數據並放到bufref參數(AVFilterBufferRef結構體指針)中去。
/** * Get an audio/video buffer data from buffer_sink and put it in bufref. * * This function works with both audio and video buffer sinks. * * @param buffer_sink pointer to a buffersink or abuffersink context * @param flags a combination of AV_BUFFERSINK_FLAG_* flags * @return >= 0 in case of success, a negative AVERROR code in case of * failure */ attribute_deprecated int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, AVFilterBufferRef **bufref, int flags);AVFilterBufferRef結構體是什麼?是一個AVFilterBuffer結構的參考。由於每個過濾器爲了避免使用memcpy而進行圖像裁剪,能夠操做buffer的原始版本,所以,緩衝區origin以及尺寸是屬於每一個引用的屬性。
/** * A reference to an AVFilterBuffer. Since filters can manipulate the origin of * a buffer to, for example, crop image without any memcpy, the buffer origin * and dimensions are per-reference properties. Linesize is also useful for * image flipping, frame to field filters, etc, and so is also per-reference. * * TODO: add anything necessary for frame reordering */ typedef struct AVFilterBufferRef { AVFilterBuffer *buf; ///< the buffer that this is a reference to uint8_t *data[8]; ///< picture/audio data for each plane /** * pointers to the data planes/channels. * * For video, this should simply point to data[]. * * For planar audio, each channel has a separate data pointer, and * linesize[0] contains the size of each channel buffer. * For packed audio, there is just one data pointer, and linesize[0] * contains the total size of the buffer for all channels. * * Note: Both data and extended_data will always be set, but for planar * audio with more channels that can fit in data, extended_data must be used * in order to access all channels. */ uint8_t **extended_data; int linesize[8]; ///< number of bytes per line AVFilterBufferRefVideoProps *video; ///< video buffer specific properties AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties /** * presentation timestamp. The time unit may change during * filtering, as it is specified in the link and the filter code * may need to rescale the PTS accordingly. */ int64_t pts; int64_t pos; ///< byte position in stream, -1 if unknown int format; ///< media format int perms; ///< permissions, see the AV_PERM_* flags enum AVMediaType type; ///< media type of buffer data AVDictionary *metadata; ///< dictionary containing metadata key=value tags } AVFilterBufferRef;AVFilterBuffer又是什麼?是一個用於濾鏡系統的參考計數的緩衝區數據類型。filter不要存儲直接指向這個結構體的指針,而要使用上面那個AVFilterBufferRef結構體。
/** * A reference-counted buffer data type used by the filter system. Filters * should not store pointers to this structure directly, but instead use the * AVFilterBufferRef structure below. */ typedef struct AVFilterBuffer { uint8_t *data[8]; ///< buffer data for each plane/channel /** * pointers to the data planes/channels. * * For video, this should simply point to data[]. * * For planar audio, each channel has a separate data pointer, and * linesize[0] contains the size of each channel buffer. * For packed audio, there is just one data pointer, and linesize[0] * contains the total size of the buffer for all channels. * * Note: Both data and extended_data will always be set, but for planar * audio with more channels that can fit in data, extended_data must be used * in order to access all channels. */ uint8_t **extended_data; int linesize[8]; ///< number of bytes per line /** private data to be used by a custom free function */ void *priv; /** * A pointer to the function to deallocate this buffer if the default * function is not sufficient. This could, for example, add the memory * back into a memory pool to be reused later without the overhead of * reallocating it from scratch. */ void (*free)(struct AVFilterBuffer *buf); int format; ///< media format int w, h; ///< width and height of the allocated buffer unsigned refcount; ///< number of references to this buffer } AVFilterBuffer;
刪除對一個AVFilterBuffer的引用,並將指針設爲NULL。若是這是最後一個引用,那麼AVFilterBuffer結構體本身會自動刪除。
/** * Remove a reference to a buffer and set the pointer to NULL. * If this is the last reference to the buffer, the buffer itself * is also automatically freed. * * @param ref pointer to the buffer reference */ attribute_deprecated void avfilter_unref_bufferp(AVFilterBufferRef **ref);
15.1 buffer的文檔
buffer是一種源filter,相似於DirectShow裏面也是那種源filter。
Buffer video frames, and make them available to the filter chain.
This source is mainly intended for a programmatic use, in particular through the interface defined in ‘libavfilter/vsrc_buffer.h’.
It accepts the following parameters:(他的主要參數以下)
‘video_size’Specify the size (width and height) of the buffered video frames. For the syntax of this option, check the "Video size" section in the ffmpeg-utils manual.
‘width’The input video width.
‘height’The input video height.
‘pix_fmt’A string representing the pixel format of the buffered video frames. It may be a number corresponding to a pixel format, or a pixel format name.
‘time_base’Specify the timebase assumed by the timestamps of the buffered frames.
‘frame_rate’Specify the frame rate expected for the video stream.
‘pixel_aspect, sar’The sample (pixel) aspect ratio of the input video.
‘sws_param’Specify the optional parameters to be used for the scale filter which is automatically inserted when an input change is detected in the input size or format.
For example:
buffer=width=320:height=240:pix_fmt=yuv410p:time_base=1/24:sar=1 |
will instruct the source to accept video frames with size 320x240 and with format "yuv410p", assuming 1/24 as the timestamps timebase and square pixels (1:1 sample aspect ratio). Since the pixel format with name "yuv410p" corresponds to the number 6 (check the enum AVPixelFormat definition in ‘libavutil/pixfmt.h’), this example corresponds to:
buffer=size=320x240:pixfmt=6:time_base=1/24:pixel_aspect=1/1 |
Alternatively, the options can be specified as a flat string, but this syntax is deprecated:
width:height:pix_fmt:time_base.num:time_base.den:pixel_aspect.num:pixel_aspect.den[:sws_param]
15.2 buffersink的文檔
buffersink是一種sink過濾器。也就是用在最後的那種過濾器。
Buffer video frames, and make them available to the end of the filter graph.
This sink is mainly intended for programmatic use, in particular through the interface defined in ‘libavfilter/buffersink.h’ or the options system.
It accepts a pointer to an AVBufferSinkContext structure, which defines the incoming buffers’ formats, to be passed as the opaque parameter toavfilter_init_filterfor initialization.