1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

doc/filters: Document OpenCL program filters

Include some example programs.
This commit is contained in:
Mark Thompson 2018-01-03 22:43:53 +00:00
parent dfdc146161
commit 03c08d59fb

View File

@ -12524,6 +12524,136 @@ Set value which will be multiplied with filtered result.
Set value which will be added to filtered result.
@end table
@anchor{program_opencl}
@section program_opencl
Filter video using an OpenCL program.
@table @option
@item source
OpenCL program source file.
@item kernel
Kernel name in program.
@item inputs
Number of inputs to the filter. Defaults to 1.
@item size, s
Size of output frames. Defaults to the same as the first input.
@end table
The program source file must contain a kernel function with the given name,
which will be run once for each plane of the output. Each run on a plane
gets enqueued as a separate 2D global NDRange with one work-item for each
pixel to be generated. The global ID offset for each work-item is therefore
the coordinates of a pixel in the destination image.
The kernel function needs to take the following arguments:
@itemize
@item
Destination image, @var{__write_only image2d_t}.
This image will become the output; the kernel should write all of it.
@item
Frame index, @var{unsigned int}.
This is a counter starting from zero and increasing by one for each frame.
@item
Source images, @var{__read_only image2d_t}.
These are the most recent images on each input. The kernel may read from
them to generate the output, but they can't be written to.
@end itemize
Example programs:
@itemize
@item
Copy the input to the output (output must be the same size as the input).
@verbatim
__kernel void copy(__write_only image2d_t destination,
unsigned int index,
__read_only image2d_t source)
{
const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE;
int2 location = (int2)(get_global_id(0), get_global_id(1));
float4 value = read_imagef(source, sampler, location);
write_imagef(destination, location, value);
}
@end verbatim
@item
Apply a simple transformation, rotating the input by an amount increasing
with the index counter. Pixel values are linearly interpolated by the
sampler, and the output need not have the same dimensions as the input.
@verbatim
__kernel void rotate_image(__write_only image2d_t dst,
unsigned int index,
__read_only image2d_t src)
{
const sampler_t sampler = (CLK_NORMALIZED_COORDS_FALSE |
CLK_FILTER_LINEAR);
float angle = (float)index / 100.0f;
float2 dst_dim = convert_float2(get_image_dim(dst));
float2 src_dim = convert_float2(get_image_dim(src));
float2 dst_cen = dst_dim / 2.0f;
float2 src_cen = src_dim / 2.0f;
int2 dst_loc = (int2)(get_global_id(0), get_global_id(1));
float2 dst_pos = convert_float2(dst_loc) - dst_cen;
float2 src_pos = {
cos(angle) * dst_pos.x - sin(angle) * dst_pos.y,
sin(angle) * dst_pos.x + cos(angle) * dst_pos.y
};
src_pos = src_pos * src_dim / dst_dim;
float2 src_loc = src_pos + src_cen;
if (src_loc.x < 0.0f || src_loc.y < 0.0f ||
src_loc.x > src_dim.x || src_loc.y > src_dim.y)
write_imagef(dst, dst_loc, 0.5f);
else
write_imagef(dst, dst_loc, read_imagef(src, sampler, src_loc));
}
@end verbatim
@item
Blend two inputs together, with the amount of each input used varying
with the index counter.
@verbatim
__kernel void blend_images(__write_only image2d_t dst,
unsigned int index,
__read_only image2d_t src1,
__read_only image2d_t src2)
{
const sampler_t sampler = (CLK_NORMALIZED_COORDS_FALSE |
CLK_FILTER_LINEAR);
float blend = (cos((float)index / 50.0f) + 1.0f) / 2.0f;
int2 dst_loc = (int2)(get_global_id(0), get_global_id(1));
int2 src1_loc = dst_loc * get_image_dim(src1) / get_image_dim(dst);
int2 src2_loc = dst_loc * get_image_dim(src2) / get_image_dim(dst);
float4 val1 = read_imagef(src1, sampler, src1_loc);
float4 val2 = read_imagef(src2, sampler, src2_loc);
write_imagef(dst, dst_loc, val1 * blend + val2 * (1.0f - blend));
}
@end verbatim
@end itemize
@section pseudocolor
Alter frame colors in video with pseudocolors.
@ -17498,6 +17628,78 @@ Set the color of the created image. Accepts the same syntax of the
corresponding @option{color} option.
@end table
@section openclsrc
Generate video using an OpenCL program.
@table @option
@item source
OpenCL program source file.
@item kernel
Kernel name in program.
@item size, s
Size of frames to generate. This must be set.
@item format
Pixel format to use for the generated frames. This must be set.
@item rate, r
Number of frames generated every second. Default value is '25'.
@end table
For details of how the program loading works, see the @ref{program_opencl}
filter.
Example programs:
@itemize
@item
Generate a colour ramp by setting pixel values from the position of the pixel
in the output image. (Note that this will work with all pixel formats, but
the generated output will not be the same.)
@verbatim
__kernel void ramp(__write_only image2d_t dst,
unsigned int index)
{
int2 loc = (int2)(get_global_id(0), get_global_id(1));
float4 val;
val.xy = val.zw = convert_float2(loc) / convert_float2(get_image_dim(dst));
write_imagef(dst, loc, val);
}
@end verbatim
@item
Generate a Sierpinski carpet pattern, panning by a single pixel each frame.
@verbatim
__kernel void sierpinski_carpet(__write_only image2d_t dst,
unsigned int index)
{
int2 loc = (int2)(get_global_id(0), get_global_id(1));
float4 value = 0.0f;
int x = loc.x + index;
int y = loc.y + index;
while (x > 0 || y > 0) {
if (x % 3 == 1 && y % 3 == 1) {
value = 1.0f;
break;
}
x /= 3;
y /= 3;
}
write_imagef(dst, loc, value);
}
@end verbatim
@end itemize
@c man end VIDEO SOURCES
@chapter Video Sinks