doc/filter_design.txt
7a442233
 Filter design
 =============
 
 This document explains guidelines that should be observed (or ignored with
 good reason) when writing filters for libavfilter.
 
 In this document, the word “frame” indicates either a video frame or a group
064c9d45
 of audio samples, as stored in an AVFrame structure.
7a442233
 
 
a28aa76a
 Format negotiation
7a442233
 ==================
 
   The query_formats method should set, for each input and each output links,
8c2ce16f
   the list of supported formats.
7a442233
 
   For video links, that means pixel format. For audio links, that means
23686c72
   channel layout, sample format (the sample packing is implied by the sample
   format) and sample rate.
7a442233
 
   The lists are not just lists, they are references to shared objects. When
a28aa76a
   the negotiation mechanism computes the intersection of the formats
23686c72
   supported at each end of a link, all references to both lists are replaced
   with a reference to the intersection. And when a single format is
7a442233
   eventually chosen for a link amongst the remaining list, again, all
   references to the list are updated.
 
   That means that if a filter requires that its input and output have the
8c2ce16f
   same format amongst a supported list, all it has to do is use a reference
7a442233
   to the same list of formats.
 
125acd21
   query_formats can leave some formats unset and return AVERROR(EAGAIN) to
   cause the negotiation mechanism to try again later. That can be used by
   filters with complex requirements to use the format negotiated on one link
   to set the formats supported on another.
 
7a442233
 
064c9d45
 Frame references ownership and permissions
 ==========================================
7a442233
 
082b745d
   Principle
   ---------
 
064c9d45
     Audio and video data are voluminous; the frame and frame reference
082b745d
     mechanism is intended to avoid, as much as possible, expensive copies of
     that data while still allowing the filters to produce correct results.
 
064c9d45
     The data is stored in buffers represented by AVFrame structures.
     Several references can point to the same frame buffer; the buffer is
     automatically deallocated once all corresponding references have been
     destroyed.
082b745d
 
     The characteristics of the data (resolution, sample rate, etc.) are
     stored in the reference; different references for the same buffer can
     show different characteristics. In particular, a video reference can
     point to only a part of a video buffer.
 
064c9d45
     A reference is usually obtained as input to the filter_frame method or
     requested using the ff_get_video_buffer or ff_get_audio_buffer
     functions. A new reference on an existing buffer can be created with
     av_frame_ref(). A reference is destroyed using
     the av_frame_free() function.
082b745d
 
   Reference ownership
   -------------------
 
     At any time, a reference “belongs” to a particular piece of code,
     usually a filter. With a few caveats that will be explained below, only
     that piece of code is allowed to access it. It is also responsible for
     destroying it, although this is sometimes done automatically (see the
     section on link reference fields).
 
     Here are the (fairly obvious) rules for reference ownership:
 
064c9d45
     * A reference received by the filter_frame method belongs to the
       corresponding filter.
082b745d
 
064c9d45
     * A reference passed to ff_filter_frame is given away and must no longer
       be used.
082b745d
 
064c9d45
     * A reference created with av_frame_ref() belongs to the code that
082b745d
       created it.
 
6e03da7f
     * A reference obtained with ff_get_video_buffer or ff_get_audio_buffer
082b745d
       belongs to the code that requested it.
 
     * A reference given as return value by the get_video_buffer or
       get_audio_buffer method is given away and must no longer be used.
 
   Link reference fields
   ---------------------
 
064c9d45
     The AVFilterLink structure has a few AVFrame fields.
082b745d
 
064c9d45
     partial_buf is used by libavfilter internally and must not be accessed
     by filters.
082b745d
 
064c9d45
     fifo contains frames queued in the filter's input. They belong to the
     framework until they are taken by the filter.
082b745d
 
064c9d45
   Reference permissions
   ---------------------
082b745d
 
064c9d45
     Since the same frame data can be shared by several frames, modifying may
     have unintended consequences. A frame is considered writable if only one
     reference to it exists. The code owning that reference it then allowed
     to modify the data.
082b745d
 
064c9d45
     A filter can check if a frame is writable by using the
     av_frame_is_writable() function.
082b745d
 
064c9d45
     A filter can ensure that a frame is writable at some point of the code
     by using the ff_inlink_make_frame_writable() function. It will duplicate
     the frame if needed.
082b745d
 
064c9d45
     A filter can ensure that the frame passed to the filter_frame() callback
     is writable by setting the needs_writable flag on the corresponding
     input pad. It does not apply to the activate() callback.
7a442233
 
 
 Frame scheduling
 ================
 
   The purpose of these rules is to ensure that frames flow in the filter
   graph without getting stuck and accumulating somewhere.
 
   Simple filters that output one frame for each input frame should not have
   to worry about it.
 
064c9d45
   There are two design for filters: one using the filter_frame() and
   request_frame() callbacks and the other using the activate() callback.
 
   The design using filter_frame() and request_frame() is legacy, but it is
   suitable for filters that have a single input and process one frame at a
   time. New filters with several inputs, that treat several frames at a time
   or that require a special treatment at EOF should probably use the design
   using activate().
 
   activate
   --------
 
     This method is called when something must be done in a filter; the
     definition of that "something" depends on the semantic of the filter.
 
     The callback must examine the status of the filter's links and proceed
     accordingly.
 
     The status of output links is stored in the frame_wanted_out, status_in
     and status_out fields and tested by the ff_outlink_frame_wanted()
     function. If this function returns true, then the processing requires a
     frame on this link and the filter is expected to make efforts in that
     direction.
 
     The status of input links is stored by the status_in, fifo and
     status_out fields; they must not be accessed directly. The fifo field
     contains the frames that are queued in the input for processing by the
     filter. The status_in and status_out fields contains the queued status
     (EOF or error) of the link; status_in is a status change that must be
     taken into account after all frames in fifo have been processed;
     status_out is the status that have been taken into account, it is final
     when it is not 0.
 
     The typical task of an activate callback is to first check the backward
     status of output links, and if relevant forward it to the corresponding
     input. Then, if relevant, for each input link: test the availability of
     frames in fifo and process them;  if no frame is available, test and
     acknowledge a change of status using ff_inlink_acknowledge_status(); and
     forward the result (frame or status change) to the corresponding input.
     If nothing is possible, test the status of outputs and forward it to the
     corresponding input(s). If still not possible, return FFERROR_NOT_READY.
 
     If the filters stores internally one or a few frame for some input, it
     can consider them to be part of the FIFO and delay acknowledging a
     status change accordingly.
 
     Example code:
 
     ret = ff_outlink_get_status(outlink);
     if (ret) {
         ff_inlink_set_status(inlink, ret);
         return 0;
     }
     if (priv->next_frame) {
         /* use it */
         return 0;
     }
     ret = ff_inlink_consume_frame(inlink, &frame);
     if (ret < 0)
         return ret;
     if (ret) {
         /* use it */
         return 0;
     }
     ret = ff_inlink_acknowledge_status(inlink, &status, &pts);
     if (ret) {
         /* flush */
         ff_outlink_set_status(outlink, status, pts);
         return 0;
     }
     if (ff_outlink_frame_wanted(outlink)) {
         ff_inlink_request_frame(inlink);
         return 0;
     }
     return FFERROR_NOT_READY;
 
     The exact code depends on how similar the /* use it */ blocks are and
     how related they are to the /* flush */ block, and needs to apply these
     operations to the correct inlink or outlink if there are several.
 
     Macros are available to factor that when no extra processing is needed:
 
     FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
     FF_FILTER_FORWARD_STATUS_ALL(outlink, filter);
     FF_FILTER_FORWARD_STATUS(inlink, outlink);
     FF_FILTER_FORWARD_STATUS_ALL(inlink, filter);
     FF_FILTER_FORWARD_WANTED(outlink, inlink);
 
23686c72
   filter_frame
   ------------
7a442233
 
064c9d45
     For filters that do not use the activate() callback, this method is
     called when a frame is pushed to the filter's input. It can be called at
     any time except in a reentrant way.
7a442233
 
     If the input frame is enough to produce output, then the filter should
     push the output frames on the output link immediately.
 
     As an exception to the previous rule, if the input frame is enough to
     produce several output frames, then the filter needs output only at
     least one per link. The additional frames can be left buffered in the
     filter; these buffered frames must be flushed immediately if a new input
     produces new output.
 
fe64b889
     (Example: frame rate-doubling filter: filter_frame must (1) flush the
a48abf5e
     second copy of the previous frame, if it is still there, (2) push the
     first copy of the incoming frame, (3) keep the second copy for later.)
7a442233
 
     If the input frame is not enough to produce output, the filter must not
     call request_frame to get more. It must just process the frame or queue
     it. The task of requesting more frames is left to the filter's
     request_frame method or the application.
 
     If a filter has several inputs, the filter must be ready for frames
8c2ce16f
     arriving randomly on any input. Therefore, any filter with several inputs
7a442233
     will most likely require some kind of queuing mechanism. It is perfectly
     acceptable to have a limited queue and to drop frames when the inputs
     are too unbalanced.
 
   request_frame
   -------------
 
064c9d45
     For filters that do not use the activate() callback, this method is
     called when a frame is wanted on an output.
7a442233
 
064c9d45
     For a source, it should directly call filter_frame on the corresponding
23686c72
     output.
7a442233
 
     For a filter, if there are queued frames already ready, one of these
     frames should be pushed. If not, the filter should request a frame on
8c2ce16f
     one of its inputs, repeatedly until at least one frame has been pushed.
7a442233
 
     Return values:
2a351f6c
     if request_frame could produce a frame, or at least make progress
     towards producing a frame, it should return 0;
7a442233
     if it could not for temporary reasons, it should return AVERROR(EAGAIN);
a48abf5e
     if it could not because there are no more frames, it should return
7a442233
     AVERROR_EOF.
 
     The typical implementation of request_frame for a filter with several
     inputs will look like that:
 
         if (frames_queued) {
             push_one_frame();
             return 0;
         }
2a351f6c
         input = input_where_a_frame_is_most_needed();
         ret = ff_request_frame(input);
         if (ret == AVERROR_EOF) {
             process_eof_on_input();
         } else if (ret < 0) {
             return ret;
7a442233
         }
         return 0;
 
064c9d45
     Note that, except for filters that can have queued frames and sources,
     request_frame does not push frames: it requests them to its input, and
     as a reaction, the filter_frame method possibly will be called and do
     the work.