diff mbox

[FFmpeg-devel,1/2] docs/filters: add documentation to all existing OpenCL filters

Message ID 1534334426-17256-1-git-send-email-danyaschenko@gmail.com
State New
Headers show

Commit Message

Danil Iashchenko Aug. 15, 2018, noon UTC
docs/filters: add documentation to all existing OpenCL filters
---

Hi! Sorry for delay.

Added general instruction for format conversion in the start of overall section and separatly for overlay_opencl.

As far as I understand, different format conversion depends on which formats are supported by hwupload/hwdownload.  
So maybe it is better to clarify what formats are supported by them in hwupload/hwdownload section, since it is used not only by OpenCL and show set of possible input formats which do not need the conversion. All other unexpected formats should be converted by format filter.

Also added docs for erosion_opencl and dilation_opencl filters.

Thanks! 

Danil.

 doc/filters.texi | 498 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 498 insertions(+)

Comments

Gyan Aug. 18, 2018, 8:36 a.m. UTC | #1
Hi Danil,

Except overlay and the topic of format requirements, rest LGTM.

On 15-08-2018 05:30 PM, Danil Iashchenko wrote:
> docs/filters: add documentation to all existing OpenCL filters

> Added general instruction for format conversion in the start of overall section and separatly for overlay_opencl.
> 
> As far as I understand, different format conversion depends on which formats are supported by hwupload/hwdownload.
> So maybe it is better to clarify what formats are supported by them in hwupload/hwdownload section, since it is used not only by OpenCL and show set of possible input formats which do not need the conversion. All other unexpected formats should be converted by format filter.


> +Format conversion depends on format of the INPUT, on which logo is overlaying on.
> +
> +These are examples of different format conversions:
> +@example
> +if the formats of INPUT and LOGO are the same, no conversion is required. For example yuv420p is overlaying on yuv420p.
> +@end example
> +@example
> +if initial planes match, but the overlay has additional alpha plane, this case requires conversion to matching format. For example if the INPUT is yuv420p, LOGO should be yuva420p.
> +@end example
> +@example
> +if INPUT and LOGO has same-plane alpha, same layout and different but mathing format. For example RGBA is overlaying on RGB0.
> +@end example

> +Insert a JPG logo in the top-left corner of the mp4 INPUT. No conversion needed.
> +@example
> +-i INPUT -i LOGO -filter_complex "[0:v]hwupload[a], [1:v]hwupload[b], [a][b]overlay_opencl, hwdownload" OUTPUT

I tried to overlay a 4:4:4 JPG on a 4:2:0 video, using

     ffmpeg -i video.mp4 -i image.jpg
            -init_hw_device opencl=gpu:0.0 -filter_hw_device gpu
            -filter_complex "[0]hwupload@m[m];[1]hwupload@o[o];
                             [m][o]overlay_opencl=100:100,hwdownload"
            -t 1 -an -y test.mp4

This "succeeded", but the colors are, obviously, wrong. It works 
correctly with format=yuv420p before hwupload for the JPG. It also 
"works" with format=rgba, but the colors are again wrong.

Shouldn't there be validation of the matching of pixel formats within 
the filter?

> +Insert a PNG logo in the top-left corner of the mp4 INPUT. Explicit format conversion is a must.
> +@example
> +-i INPUT -i LOGO -filter_complex "[0:v]hwupload[a], [1:v]format=yuva420p, hwupload[b], [a][b]overlay_opencl, hwdownload" OUTPUT

I tried to overlay a RGBA input on a 4:2:0 video, using

     ffmpeg -i video.mp4 -i image.png
            -init_hw_device opencl=gpu:0.0 -filter_hw_device gpu
            -filter_complex "[0]hwupload@m[m];
                             [1]format=yuva420p,hwupload@o[o];
                             [m][o]overlay_opencl=100:100,hwdownload"
            -t 1 -an -y test.mp4

This failed with

     [hwupload @ 0000000006ee5e80] Failed to allocate frame to upload to.
     Error while filtering: Cannot allocate memory
     Failed to inject frame into filter network: Cannot allocate memory
     Error while processing the decoded data for stream #1:0

If I skip format, I get

     [AVHWDeviceContext @ 0000000002983700] OpenCL error: Invalid memory 
object.
     [Parsed_overlay_opencl_3 @ 0000000007125f00] Failed to set kernel 
argument 3: error -38.

If I use instead format=rgb24, it "works" but with a weird result. 
Again, validation?

If I insert format with arg yuva420p before both video and image, I get

     [hwdownload @ 0000000006ce14c0] Invalid output format yuv420p for 
hwframe download.
     [Parsed_hwdownload_5 @ 0000000006efb040] Failed to configure output 
pad on Parsed_hwdownload_5


Adding format=yuv420p after hwdownload, I get

[hwdownload @ 0000000006f2b440] Invalid output format yuv420p for 
hwframe download.
[Parsed_hwdownload_5 @ 00000000070148c0] Failed to configure output pad 
on Parsed_hwdownload_5


Adding instead format=yuva420p after hwdownload, I get

[hwupload @ 0000000006aaf2c0] Failed to allocate frame to upload to.


If I change both input formats to rgba *and* output format to rgba, it 
works but the image's alpha is ignored, with the result being a straight 
overlay of the image RGB components.

In overlay_opencl, I see

     if (main_planes == overlay_planes) {
         if (main_desc->nb_components == overlay_desc->nb_components)
             kernel = "overlay_no_alpha";
         else
             kernel = "overlay_internal_alpha";
         ctx->alpha_separate = 0;
     } else {
         kernel = "overlay_external_alpha";
         ctx->alpha_separate = 1;
     }

This looks wrong to me. For the purposes of overlay, only the presence 
of alpha on the 2nd input matters and should be handled when present.

All tests performed with on-die Intel HD / OpenCL runtime 1.2 on Win 7 
x64. My driver looks to be 3 years old.

Regards,
Gyan
Gyan Sept. 5, 2018, 7 a.m. UTC | #2
Hi Danil,

On 18-08-2018 02:06 PM, Gyan Doshi wrote:
> 
> Hi Danil,
> 
> Except overlay and the topic of format requirements, rest LGTM.
> 

This patch appears to be abandoned.

These filters need to be documented, but the format constraints should 
be clarified first, as asked in the parent post. Also, the filter's 
kernel selection and/or implementation involving alpha channel should be 
corrected.

Thanks,
Gyan
diff mbox

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index 267bd04..12b6c9f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10190,6 +10190,7 @@  A floating point number which specifies chroma temporal strength. It defaults to
 @var{luma_tmp}*@var{chroma_spatial}/@var{luma_spatial}.
 @end table
 
+@anchor{hwdownload}
 @section hwdownload
 
 Download hardware frames to system memory.
@@ -10280,6 +10281,7 @@  ways if there are any additional constraints on that filter's output.
 Do not use it without fully understanding the implications of its use.
 @end table
 
+@anchor{hwupload}
 @section hwupload
 
 Upload system memory frames to hardware surfaces.
@@ -17595,6 +17597,502 @@  pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 
 @c man end VIDEO FILTERS
 
+@chapter OpenCL Video Filters
+@c man begin OPENCL VIDEO FILTERS
+
+Below is a description of the currently available OpenCL video filters.
+
+To enable compilation of these filters you need to configure FFmpeg with
+@code{--enable-opencl}.
+
+Running OpenCL filters requires you to initialize a hardware device and to pass that device to all filters in any filter graph.
+@table @option
+
+@item -init_hw_device opencl[=@var{name}][:@var{device}[,@var{key=value}...]]
+Initialise a new hardware device of type @var{opencl} called @var{name}, using the
+given device parameters.
+
+@item -filter_hw_device @var{name}
+Pass the hardware device called @var{name} to all filters in any filter graph.
+
+@end table
+
+For more detailed information see @url{https://www.ffmpeg.org/ffmpeg.html#Advanced-Video-options}
+
+@itemize
+@item
+Example of choosing the first device on the second platform and running avgblur_opencl filter with default parameters on it.
+@example
+-init_hw_device opencl=gpu:1.0 -filter_hw_device gpu -i INPUT -vf "hwupload, avgblur_opencl, hwdownload" OUTPUT
+@end example
+@end itemize
+
+Since OpenCL filters are not able to access frame data in normal memory, all frame data needs to be uploaded(@ref{hwupload}) to hardware surfaces connected to the appropriate device before being used and then downloaded(@ref{hwdownload}) back to normal memory. Note that @ref{hwupload} will upload to a surface with the same layout as the software frame, so it may be necessary to add a @ref{format} filter immediately before to get the input into the right format and @ref{hwdownload} does not support all formats on the output - it may be necessary to insert an additional @ref{format} filter immediately following in the graph to get the output in a supported format.
+
+@section avgblur_opencl
+
+Apply average blur filter.
+
+The filter accepts the following options:
+
+@table @option
+@item sizeX
+Set horizontal radius size.
+Range is @code{[1, 1024]} and default value is @code{1}.
+
+@item planes
+Set which planes to filter. Default value is @code{0xf}, by which all planes are processed.
+
+@item sizeY
+Set vertical radius size. Range is @code{[1, 1024]} and default value is @code{0}. If zero, @code{sizeX} value will be used.
+@end table
+
+@subsection Example
+
+@itemize
+@item
+Apply average blur filter with horizontal and vertical size of 3, setting each pixel of the output to the average value of the 7x7 region centered on it in the input. For pixels on the edges of the image, the region does not extend beyond the image boundaries, and so out-of-range coordinates are not used in the calculations.
+@example
+-i INPUT -vf "hwupload, avgblur_opencl=3, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section boxblur_opencl
+
+Apply a boxblur algorithm to the input video.
+
+It accepts the following parameters:
+
+@table @option
+
+@item luma_radius, lr
+@item luma_power, lp
+@item chroma_radius, cr
+@item chroma_power, cp
+@item alpha_radius, ar
+@item alpha_power, ap
+
+@end table
+
+A description of the accepted options follows.
+
+@table @option
+@item luma_radius, lr
+@item chroma_radius, cr
+@item alpha_radius, ar
+Set an expression for the box radius in pixels used for blurring the
+corresponding input plane.
+
+The radius value must be a non-negative number, and must not be
+greater than the value of the expression @code{min(w,h)/2} for the
+luma and alpha planes, and of @code{min(cw,ch)/2} for the chroma
+planes.
+
+Default value for @option{luma_radius} is "2". If not specified,
+@option{chroma_radius} and @option{alpha_radius} default to the
+corresponding value set for @option{luma_radius}.
+
+The expressions can contain the following constants:
+@table @option
+@item w
+@item h
+The input width and height in pixels.
+
+@item cw
+@item ch
+The input chroma image width and height in pixels.
+
+@item hsub
+@item vsub
+The horizontal and vertical chroma subsample values. For example, for the
+pixel format "yuv422p", @var{hsub} is 2 and @var{vsub} is 1.
+@end table
+
+@item luma_power, lp
+@item chroma_power, cp
+@item alpha_power, ap
+Specify how many times the boxblur filter is applied to the
+corresponding plane.
+
+Default value for @option{luma_power} is 2. If not specified,
+@option{chroma_power} and @option{alpha_power} default to the
+corresponding value set for @option{luma_power}.
+
+A value of 0 will disable the effect.
+@end table
+
+@subsection Examples
+
+Apply boxblur filter, setting each pixel of the output to the average value of box-radiuses @var{luma_radius}, @var{chroma_radius}, @var{alpha_radius} for each plane respectively. The filter will apply @var{luma_power}, @var{chroma_power}, @var{alpha_power} times onto the corresponding plane. For pixels on the edges of the image, the radius does not extend beyond the image boundaries, and so out-of-range coordinates are not used in the calculations.
+
+@itemize
+@item
+Apply a boxblur filter with the luma, chroma, and alpha radius
+set to 2 and luma, chroma, and alpha power set to 3. The filter will run 3 times with box-radius set to 2 for every plane of the image.
+@example
+-i INPUT -vf "hwupload, boxblur_opencl=luma_radius=2:luma_power=3, hwdownload" OUTPUT
+-i INPUT -vf "hwupload, boxblur_opencl=2:3, hwdownload" OUTPUT
+@end example
+
+@item
+Apply a boxblur filter with luma radius set to 2, luma_power to 1, chroma_radius to 4, chroma_power to 5, alpha_radius to 3 and alpha_power to 7.
+
+For the luma plane, a 2x2 box radius will be run once.
+
+For the chroma plane, a 4x4 box radius will be run 5 times.
+
+For the alpha plane, a 3x3 box radius will be run 7 times.
+@example
+-i INPUT -vf "hwupload, boxblur_opencl=2:1:4:5:3:7, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section convolution_opencl
+
+Apply convolution of 3x3, 5x5, 7x7 matrix.
+
+The filter accepts the following options:
+
+@table @option
+@item 0m
+@item 1m
+@item 2m
+@item 3m
+Set matrix for each plane.
+Matrix is sequence of 9, 25 or 49 signed numbers.
+Default value for each plane is @code{0 0 0 0 1 0 0 0 0}.
+
+@item 0rdiv
+@item 1rdiv
+@item 2rdiv
+@item 3rdiv
+Set multiplier for calculated value for each plane.
+If unset or 0, it will be sum of all matrix elements.
+The option value must be an float number greater or equal to @code{0.0}. Default value is @code{1.0}.
+
+@item 0bias
+@item 1bias
+@item 2bias
+@item 3bias
+Set bias for each plane. This value is added to the result of the multiplication.
+Useful for making the overall image brighter or darker.
+The option value must be an float number greater or equal to @code{0.0}. Default value is @code{0.0}.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Apply sharpen:
+@example
+-i INPUT -vf "hwupload, convolution_opencl=0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 0 -1 0, hwdownload" OUTPUT
+@end example
+
+@item
+Apply blur:
+@example
+-i INPUT -vf "hwupload, convolution_opencl=1 1 1 1 1 1 1 1 1:1 1 1 1 1 1 1 1 1:1 1 1 1 1 1 1 1 1:1 1 1 1 1 1 1 1 1:1/9:1/9:1/9:1/9, hwdownload" OUTPUT
+@end example
+
+@item
+Apply edge enhance:
+@example
+-i INPUT -vf "hwupload, convolution_opencl=0 0 0 -1 1 0 0 0 0:0 0 0 -1 1 0 0 0 0:0 0 0 -1 1 0 0 0 0:0 0 0 -1 1 0 0 0 0:5:1:1:1:0:128:128:128, hwdownload" OUTPUT
+@end example
+
+@item
+Apply edge detect:
+@example
+-i INPUT -vf "hwupload, convolution_opencl=0 1 0 1 -4 1 0 1 0:0 1 0 1 -4 1 0 1 0:0 1 0 1 -4 1 0 1 0:0 1 0 1 -4 1 0 1 0:5:5:5:1:0:128:128:128, hwdownload" OUTPUT
+@end example
+
+@item
+Apply laplacian edge detector which includes diagonals:
+@example
+-i INPUT -vf "hwupload, convolution_opencl=1 1 1 1 -8 1 1 1 1:1 1 1 1 -8 1 1 1 1:1 1 1 1 -8 1 1 1 1:1 1 1 1 -8 1 1 1 1:5:5:5:1:0:128:128:0, hwdownload" OUTPUT
+@end example
+
+@item
+Apply emboss:
+@example
+-i INPUT -vf "hwupload, convolution_opencl=-2 -1 0 -1 1 1 0 1 2:-2 -1 0 -1 1 1 0 1 2:-2 -1 0 -1 1 1 0 1 2:-2 -1 0 -1 1 1 0 1 2, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section dilation_opencl
+
+Apply dilation effect to the video.
+
+This filter replaces the pixel by the local(3x3) maximum.
+
+It accepts the following options:
+
+@table @option
+@item threshold0
+@item threshold1
+@item threshold2
+@item threshold3
+Limit the maximum change for each plane. Range is @code{[0, 65535]} and default value is @code{65535}.
+If @code{0}, plane will remain unchanged.
+
+@item coordinates
+Flag which specifies the pixel to refer to.
+Range is @code{[0, 255]} and default value is @code{255}, i.e. all eight pixels are used.
+
+Flags to local 3x3 coordinates region centered on @code{x}:
+
+    1 2 3
+
+    4 x 5
+
+    6 7 8
+@end table
+
+@subsection Example
+
+@itemize
+@item
+Apply dilation filter with threshold0 set to 30, threshold1 set 40, threshold2 set to 50 and coordinates set to 231, setting each pixel of the output to the local maximum between pixels: 1, 2, 3, 6, 7, 8 of the 3x3 region centered on it in the input. If the difference between input pixel and local maximum is more then threshold of the corresponding plane, output pixel will be set to input pixel + threshold of corresponding plane.
+@example
+-i INPUT -vf "hwupload, dilation_opencl=30:40:50:coordinates=231, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section erosion_opencl
+
+Apply erosion effect to the video.
+
+This filter replaces the pixel by the local(3x3) minimum.
+
+It accepts the following options:
+
+@table @option
+@item threshold0
+@item threshold1
+@item threshold2
+@item threshold3
+Limit the maximum change for each plane. Range is @code{[0, 65535]} and default value is @code{65535}.
+If @code{0}, plane will remain unchanged.
+
+@item coordinates
+Flag which specifies the pixel to refer to.
+Range is @code{[0, 255]} and default value is @code{255}, i.e. all eight pixels are used.
+
+Flags to local 3x3 coordinates region centered on @code{x}:
+
+    1 2 3
+
+    4 x 5
+
+    6 7 8
+@end table
+
+@subsection Example
+
+@itemize
+@item
+Apply erosion filter with threshold0 set to 30, threshold1 set 40, threshold2 set to 50 and coordinates set to 231, setting each pixel of the output to the local minimum between pixels: 1, 2, 3, 6, 7, 8 of the 3x3 region centered on it in the input. If the difference between input pixel and local minimum is more then threshold of the corresponding plane, output pixel will be set to input pixel - threshold of corresponding plane.
+@example
+-i INPUT -vf "hwupload, erosion_opencl=30:40:50:coordinates=231, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section overlay_opencl
+
+Overlay one video on top of another.
+
+It takes two inputs and has one output. The first input is the "main"
+video on which the second input is overlaid.
+
+The filter accepts the following options:
+
+@table @option
+
+@item x
+Set the x coordinate of the overlaid video on the main video.
+Default value is @code{0}.
+
+@item y
+Set the x coordinate of the overlaid video on the main video.
+Default value is @code{0}.
+
+@end table
+
+Format conversion depends on format of the INPUT, on which logo is overlaying on.
+
+These are examples of different format conversions:
+@example
+if the formats of INPUT and LOGO are the same, no conversion is required. For example yuv420p is overlaying on yuv420p.
+@end example
+@example
+if initial planes match, but the overlay has additional alpha plane, this case requires conversion to matching format. For example if the INPUT is yuv420p, LOGO should be yuva420p.
+@end example
+@example
+if INPUT and LOGO has same-plane alpha, same layout and different but mathing format. For example RGBA is overlaying on RGB0.
+@end example
+
+@subsection Example
+
+@itemize
+@item
+Insert a JPG logo in the top-left corner of the mp4 INPUT. No conversion needed.
+@example
+-i INPUT -i LOGO -filter_complex "[0:v]hwupload[a], [1:v]hwupload[b], [a][b]overlay_opencl, hwdownload" OUTPUT
+@end example
+@item
+Insert a PNG logo in the top-left corner of the mp4 INPUT. Explicit format conversion is a must.
+@example
+-i INPUT -i LOGO -filter_complex "[0:v]hwupload[a], [1:v]format=yuva420p, hwupload[b], [a][b]overlay_opencl, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section prewitt_opencl
+
+Apply the Prewitt operator (@url{https://en.wikipedia.org/wiki/Prewitt_operator}) to input video stream.
+
+The filter accepts the following option:
+
+@table @option
+@item planes
+Set which planes to filter. Default value is @code{0xf}, by which all planes are processed.
+
+@item scale
+Set value which will be multiplied with filtered result.
+Range is @code{[0.0, 65535]} and default value is @code{1.0}.
+
+@item delta
+Set value which will be added to filtered result.
+Range is @code{[-65535, 65535]} and default value is @code{0.0}.
+@end table
+
+@subsection Example
+
+@itemize
+@item
+Apply the Prewitt operator with scale set to 2 and delta set to 10.
+@example
+-i INPUT -vf "hwupload, prewitt_opencl=scale=2:delta=10, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section roberts_opencl
+Apply the Roberts cross operator (@url{https://en.wikipedia.org/wiki/Roberts_cross}) to input video stream.
+
+The filter accepts the following option:
+
+@table @option
+@item planes
+Set which planes to filter. Default value is @code{0xf}, by which all planes are processed.
+
+@item scale
+Set value which will be multiplied with filtered result.
+Range is @code{[0.0, 65535]} and default value is @code{1.0}.
+
+@item delta
+Set value which will be added to filtered result.
+Range is @code{[-65535, 65535]} and default value is @code{0.0}.
+@end table
+
+@subsection Example
+
+@itemize
+@item
+Apply the Roberts cross operator with scale set to 2 and delta set to 10
+@example
+-i INPUT -vf "hwupload, roberts_opencl=scale=2:delta=10, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section sobel_opencl
+
+Apply the Sobel operator (@url{https://en.wikipedia.org/wiki/Sobel_operator}) to input video stream.
+
+The filter accepts the following option:
+
+@table @option
+@item planes
+Set which planes to filter. Default value is @code{0xf}, by which all planes are processed.
+
+@item scale
+Set value which will be multiplied with filtered result.
+Range is @code{[0.0, 65535]} and default value is @code{1.0}.
+
+@item delta
+Set value which will be added to filtered result.
+Range is @code{[-65535, 65535]} and default value is @code{0.0}.
+@end table
+
+@subsection Example
+
+@itemize
+@item
+Apply sobel operator with scale set to 2 and delta set to 10
+@example
+-i INPUT -vf "hwupload, sobel_opencl=scale=2:delta=10, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@section unsharp_opencl
+
+Sharpen or blur the input video.
+
+It accepts the following parameters:
+
+@table @option
+@item luma_msize_x, lx
+Set the luma matrix horizontal size.
+Range is @code{[1, 23]} and default value is @code{5}.
+
+@item luma_msize_y, ly
+Set the luma matrix vertical size.
+Range is @code{[1, 23]} and default value is @code{5}.
+
+@item luma_amount, la
+Set the luma effect strength.
+Range is @code{[-10, 10]} and default value is @code{1.0}.
+
+Negative values will blur the input video, while positive values will
+sharpen it, a value of zero will disable the effect.
+
+@item chroma_msize_x, cx
+Set the chroma matrix horizontal size.
+Range is @code{[1, 23]} and default value is @code{5}.
+
+@item chroma_msize_y, cy
+Set the chroma matrix vertical size.
+Range is @code{[1, 23]} and default value is @code{5}.
+
+@item chroma_amount, ca
+Set the chroma effect strength.
+Range is @code{[-10, 10]} and default value is @code{0.0}.
+
+Negative values will blur the input video, while positive values will
+sharpen it, a value of zero will disable the effect.
+
+@end table
+
+All parameters are optional and default to the equivalent of the
+string '5:5:1.0:5:5:0.0'.
+
+@subsection Examples
+
+@itemize
+@item
+Apply strong luma sharpen effect:
+@example
+-i INPUT -vf "hwupload, unsharp_opencl=luma_msize_x=7:luma_msize_y=7:luma_amount=2.5, hwdownload" OUTPUT
+@end example
+
+@item
+Apply a strong blur of both luma and chroma parameters:
+@example
+-i INPUT -vf "hwupload, unsharp_opencl=7:7:-2:7:7:-2, hwdownload" OUTPUT
+@end example
+@end itemize
+
+@c man end OPENCL VIDEO FILTERS
+
 @chapter Video Sources
 @c man begin VIDEO SOURCES