|
|
|
@ -5,7 +5,7 @@ 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 |
|
|
|
|
of audio samples, as stored in an AVFilterBuffer structure. |
|
|
|
|
of audio samples, as stored in an AVFrame structure. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Format negotiation |
|
|
|
@ -35,32 +35,31 @@ Format negotiation |
|
|
|
|
to set the formats supported on another. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Buffer references ownership and permissions |
|
|
|
|
=========================================== |
|
|
|
|
Frame references ownership and permissions |
|
|
|
|
========================================== |
|
|
|
|
|
|
|
|
|
Principle |
|
|
|
|
--------- |
|
|
|
|
|
|
|
|
|
Audio and video data are voluminous; the buffer and buffer reference |
|
|
|
|
Audio and video data are voluminous; the frame and frame reference |
|
|
|
|
mechanism is intended to avoid, as much as possible, expensive copies of |
|
|
|
|
that data while still allowing the filters to produce correct results. |
|
|
|
|
|
|
|
|
|
The data is stored in buffers represented by AVFilterBuffer structures. |
|
|
|
|
They must not be accessed directly, but through references stored in |
|
|
|
|
AVFilterBufferRef structures. Several references can point to the |
|
|
|
|
same buffer; the buffer is automatically deallocated once all |
|
|
|
|
corresponding references have been destroyed. |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
A reference is usually obtained as input to the start_frame or |
|
|
|
|
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 the avfilter_ref_buffer. A reference is destroyed using |
|
|
|
|
the avfilter_unref_bufferp function. |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
Reference ownership |
|
|
|
|
------------------- |
|
|
|
@ -73,17 +72,13 @@ Buffer references ownership and permissions |
|
|
|
|
|
|
|
|
|
Here are the (fairly obvious) rules for reference ownership: |
|
|
|
|
|
|
|
|
|
* A reference received by the filter_frame method (or its start_frame |
|
|
|
|
deprecated version) belongs to the corresponding filter. |
|
|
|
|
* A reference received by the filter_frame method belongs to the |
|
|
|
|
corresponding filter. |
|
|
|
|
|
|
|
|
|
Special exception: for video references: the reference may be used |
|
|
|
|
internally for automatic copying and must not be destroyed before |
|
|
|
|
end_frame; it can be given away to ff_start_frame. |
|
|
|
|
* A reference passed to ff_filter_frame is given away and must no longer |
|
|
|
|
be used. |
|
|
|
|
|
|
|
|
|
* A reference passed to ff_filter_frame (or the deprecated |
|
|
|
|
ff_start_frame) is given away and must no longer be used. |
|
|
|
|
|
|
|
|
|
* A reference created with avfilter_ref_buffer belongs to the code that |
|
|
|
|
* A reference created with av_frame_ref() belongs to the code that |
|
|
|
|
created it. |
|
|
|
|
|
|
|
|
|
* A reference obtained with ff_get_video_buffer or ff_get_audio_buffer |
|
|
|
@ -95,89 +90,32 @@ Buffer references ownership and permissions |
|
|
|
|
Link reference fields |
|
|
|
|
--------------------- |
|
|
|
|
|
|
|
|
|
The AVFilterLink structure has a few AVFilterBufferRef fields. The |
|
|
|
|
cur_buf and out_buf were used with the deprecated |
|
|
|
|
start_frame/draw_slice/end_frame API and should no longer be used. |
|
|
|
|
src_buf and partial_buf are used by libavfilter internally |
|
|
|
|
and must not be accessed by filters. |
|
|
|
|
|
|
|
|
|
Reference permissions |
|
|
|
|
--------------------- |
|
|
|
|
|
|
|
|
|
The AVFilterBufferRef structure has a perms field that describes what |
|
|
|
|
the code that owns the reference is allowed to do to the buffer data. |
|
|
|
|
Different references for the same buffer can have different permissions. |
|
|
|
|
|
|
|
|
|
For video filters that implement the deprecated |
|
|
|
|
start_frame/draw_slice/end_frame API, the permissions only apply to the |
|
|
|
|
parts of the buffer that have already been covered by the draw_slice |
|
|
|
|
method. |
|
|
|
|
|
|
|
|
|
The value is a binary OR of the following constants: |
|
|
|
|
|
|
|
|
|
* AV_PERM_READ: the owner can read the buffer data; this is essentially |
|
|
|
|
always true and is there for self-documentation. |
|
|
|
|
|
|
|
|
|
* AV_PERM_WRITE: the owner can modify the buffer data. |
|
|
|
|
|
|
|
|
|
* AV_PERM_PRESERVE: the owner can rely on the fact that the buffer data |
|
|
|
|
will not be modified by previous filters. |
|
|
|
|
|
|
|
|
|
* AV_PERM_REUSE: the owner can output the buffer several times, without |
|
|
|
|
modifying the data in between. |
|
|
|
|
|
|
|
|
|
* AV_PERM_REUSE2: the owner can output the buffer several times and |
|
|
|
|
modify the data in between (useless without the WRITE permissions). |
|
|
|
|
|
|
|
|
|
* AV_PERM_ALIGN: the owner can access the data using fast operations |
|
|
|
|
that require data alignment. |
|
|
|
|
|
|
|
|
|
The READ, WRITE and PRESERVE permissions are about sharing the same |
|
|
|
|
buffer between several filters to avoid expensive copies without them |
|
|
|
|
doing conflicting changes on the data. |
|
|
|
|
|
|
|
|
|
The REUSE and REUSE2 permissions are about special memory for direct |
|
|
|
|
rendering. For example a buffer directly allocated in video memory must |
|
|
|
|
not modified once it is displayed on screen, or it will cause tearing; |
|
|
|
|
it will therefore not have the REUSE2 permission. |
|
|
|
|
|
|
|
|
|
The ALIGN permission is about extracting part of the buffer, for |
|
|
|
|
copy-less padding or cropping for example. |
|
|
|
|
|
|
|
|
|
The AVFilterLink structure has a few AVFrame fields. |
|
|
|
|
|
|
|
|
|
References received on input pads are guaranteed to have all the |
|
|
|
|
permissions stated in the min_perms field and none of the permissions |
|
|
|
|
stated in the rej_perms. |
|
|
|
|
partial_buf is used by libavfilter internally and must not be accessed |
|
|
|
|
by filters. |
|
|
|
|
|
|
|
|
|
References obtained by ff_get_video_buffer and ff_get_audio_buffer are |
|
|
|
|
guaranteed to have at least all the permissions requested as argument. |
|
|
|
|
fifo contains frames queued in the filter's input. They belong to the |
|
|
|
|
framework until they are taken by the filter. |
|
|
|
|
|
|
|
|
|
References created by avfilter_ref_buffer have the same permissions as |
|
|
|
|
the original reference minus the ones explicitly masked; the mask is |
|
|
|
|
usually ~0 to keep the same permissions. |
|
|
|
|
|
|
|
|
|
Filters should remove permissions on reference they give to output |
|
|
|
|
whenever necessary. It can be automatically done by setting the |
|
|
|
|
rej_perms field on the output pad. |
|
|
|
|
|
|
|
|
|
Here are a few guidelines corresponding to common situations: |
|
|
|
|
Reference permissions |
|
|
|
|
--------------------- |
|
|
|
|
|
|
|
|
|
* Filters that modify and forward their frame (like drawtext) need the |
|
|
|
|
WRITE permission. |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
* Filters that read their input to produce a new frame on output (like |
|
|
|
|
scale) need the READ permission on input and must request a buffer |
|
|
|
|
with the WRITE permission. |
|
|
|
|
A filter can check if a frame is writable by using the |
|
|
|
|
av_frame_is_writable() function. |
|
|
|
|
|
|
|
|
|
* Filters that intend to keep a reference after the filtering process |
|
|
|
|
is finished (after filter_frame returns) must have the PRESERVE |
|
|
|
|
permission on it and remove the WRITE permission if they create a new |
|
|
|
|
reference to give it away. |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
* Filters that intend to modify a reference they have kept after the end |
|
|
|
|
of the filtering process need the REUSE2 permission and must remove |
|
|
|
|
the PRESERVE permission if they create a new reference to give it |
|
|
|
|
away. |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Frame scheduling |
|
|
|
@ -189,11 +127,100 @@ Frame scheduling |
|
|
|
|
Simple filters that output one frame for each input frame should not have |
|
|
|
|
to worry about it. |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
filter_frame |
|
|
|
|
------------ |
|
|
|
|
|
|
|
|
|
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. |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
If the input frame is enough to produce output, then the filter should |
|
|
|
|
push the output frames on the output link immediately. |
|
|
|
@ -222,9 +249,10 @@ Frame scheduling |
|
|
|
|
request_frame |
|
|
|
|
------------- |
|
|
|
|
|
|
|
|
|
This method is called when a frame is wanted on an output. |
|
|
|
|
For filters that do not use the activate() callback, this method is |
|
|
|
|
called when a frame is wanted on an output. |
|
|
|
|
|
|
|
|
|
For an input, it should directly call filter_frame on the corresponding |
|
|
|
|
For a source, it should directly call filter_frame on the corresponding |
|
|
|
|
output. |
|
|
|
|
|
|
|
|
|
For a filter, if there are queued frames already ready, one of these |
|
|
|
@ -254,16 +282,7 @@ Frame scheduling |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
Note that, except for filters that can have queued frames, 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. |
|
|
|
|
|
|
|
|
|
Legacy API |
|
|
|
|
========== |
|
|
|
|
|
|
|
|
|
Until libavfilter 3.23, the filter_frame method was split: |
|
|
|
|
|
|
|
|
|
- for video filters, it was made of start_frame, draw_slice (that could be |
|
|
|
|
called several times on distinct parts of the frame) and end_frame; |
|
|
|
|
|
|
|
|
|
- for audio filters, it was called filter_samples. |
|
|
|
|
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. |
|
|
|
|