Changes between Version 13 and Version 14 of colorspace


Ignore:
Timestamp:
Oct 14, 2023, 9:27:27 PM (3 years ago)
Author:
Hunter Hogan
Comment:

Improve formatting, fix typos, improve readability

Legend:

Unmodified
Added
Removed
Modified
  • colorspace

    v13 v14  
    44Colorspace describes how an array of pixel values should be displayed on the screen. It provides information like how pixel values are stored within a file, and what the range and meaning of those values are.
    55
    6 Basically, it tells the format of the array of pixels (e.g. RGB or YUV), and how the values of each color component should be translated, to be properly displayed by the photons of the screen. (i.e. picking a colorspace randomly seems unlikely a good choice...)
    7 [[BR]]
    8 [[BR]]
    9 [[BR]]
    10 The difference between RGB and YUV should be rather obvious:
    11 
     6Basically, it tells the format of the array of pixels (e.g. RGB or YUV), and how the values of each color component should be translated, to be properly displayed by the photons of the screen. (i.e. picking a colorspace randomly seems unlikely to be a good choice...)
     7
     8The differences between RGB and YUV:
    129- RGB distinguishes color pixel values into 3 components: Red, Green, Blue. (hence the name)
    1310- YUV uses a different representation schema that represents color pixel values in: Luma (Y, or brightness), Chroma (U and V, two color differences). This format exploits the fact that humans are able to better notice details in luminance (approximated by luma) than in chroma. ^(Note: YUV represents color in 3 components)^
     
    1613'''Note:''' The term "YUV" is ambiguous and often used wrongly, including the definition of pixel formats in FFmpeg. A more accurate term for how color is stored in digital video would be [https://en.wikipedia.org/wiki/YCbCr YCbCr]. Y'UV on other other hand specifies a colorspace consisting of luma (Y') and chrominance (UV) components. For more info read [https://en.wikipedia.org/wiki/YUV the respective Wikipedia article]. In the following, the term YUV is used as in the FFmpeg pixel formats, referring to YCbCr in digital video.
    1714}}}
    18 [[BR]]
    19 [[BR]]
     15
    2016The conversion between YUV pixel buffer representation and its visual representation depends on the type of the YUV represented in the pixel buffers, which are essentially device-dependent. The accuracy of grey vs color separation depends on how well the transformation matrix matches the underlying RGB space.
    2117
     
    3026
    3127In FFmpeg, colorspaces are represented in the form of [http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavutil/pixfmt.h;hb=HEAD pixel format].
    32 [[BR]]
    33 [[BR]]
    34 In practical terms, the things you care are:
    35 
    36 1. Whether the pixel buffer contains RGB, YUV or some other type of signals, and the bit-depth.
    37 2. Whether the signals are full range or restricted range. (YUV only, unlikely a problem for other type of signals...) ^(Note: "Full range" refers to the YUV component values being in the range 0–255, whereas "restricted range" has values between 16–235)^
     28
     29In practical terms, the properties you care about are:
     30
     311. The signal format in the pixel buffer:
     32 a. the signal type: RGB, YUV, or other type, and
     33 b. the signal bit-depth.
     342. For YUV signals, the color range: full/pc/jpeg or limited/restricted/tv/mpeg.
    38353. The transformation matrix between YUV and RGB.
    39364. The linearization function from RGB to a linear RGB signal.
    40375. The conversion matrix between the linearized RGB and the device-independent XYZ colorspace.
    41 [[BR]]
    42 FFmpeg stores all these properties in the [https://ffmpeg.org/doxygen/trunk/structAVFrame.html AVFrame] struct:
    43 
    44 - The format (type and bit-depth), in AVFrame->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#aed14fa772ce46881020fd1545c86432c format]
    45 - The signal range, in AVFrame->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#a853afbad220bbc58549b4860732a3aa5 color_range]
    46 - The YUV/RGB transformation matrix, in AVFrame->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#a9262c231f1f64869439b4fe587fe1710 colorspace]
    47 - The linearization function (a.k.a. transformation characteristics), in AVFrame->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#ab09abb126e3922bc1d010cf044087939 color_trc]
    48 - The RGB/XYZ matrix, in AVFrame->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#a59a3f830494f2ed1133103a1bc9481e7 color_primaries]
    49 
    50 == How to convert between colorspaces using FFmpeg? ==
    51 
    52 Conversion between RGB/YUV is typically done using swscale. Conversion between different color properties (bit-depth, range, matrix, transfer characteristics, primaries) can be done using the [https://ffmpeg.org/ffmpeg-filters.html#colorspace colorspace] or [https://ffmpeg.org/ffmpeg-filters.html#colormatrix colormatrix] video filter. There's also a filter using the external library [https://ffmpeg.org/ffmpeg-filters.html#zscale zscale]. (for both aforementioned purposes) ^(...and seems to be a more reliable choice for all these swscale hazards)^
    53 [[BR]]
    54 [[BR]]
    55 [[BR]]
    56 Video filter `colorspace`, `colormatrix` have the following relationship:
    57 
    58 - They both do only YUV to YUV colorspace conversion; YUV to RGB, and scaling requires swscale.
    59 - `colormatrix` supports only 8bpc (8-bit per component) pixel formats, whereas `colorspace` supports 10bpc, 12bpc also.
    60 - `colormatrix` does not apply gamma and primaries (i.e. which exact color "red", "green", and "blue" each is) correction, whereas `colorspace` does (it has an option `fast=1` to disable this if you want faster conversion, or compatible output with that produced by `colormatrix`).[[BR]]Note: the examples are significantly worse with `fast=0` than with `fast=1`. This is because screenshot sRGB is incorrectly specified as BT. 601, while it should have been `ispace=bt709:itrc=srgb`. Don't repeat this mistake!
    61 - `colormatrix` is C only, whereas `colorspace` uses x86 SIMD (i.e. it's faster).
    62 [[BR]]
    63 Anyway the major difference between them is `colormatrix` produces horrible quality for anything > 8bpc (8-bit per component)... while `colorspace` produces something decent, at least for 10bpc (for 8bpc they both produce similar bad quality... probably due to improper design in the algorithms). ^(floor instead of round on color approximation?..)^[[BR]]
    64 Anyway for 8bpc... `colorspace` still seems to produce slightly better quality than `colormatrix` (while it's pointless... as doing things in 10bpc first, then 10bpc -> 8bpc seems to be a better approach... if you don't mind dithering). ^([https://trac.ffmpeg.org/ticket/4614 dithering is enforced in swscale YUV 10bpc -> 8bpc])^
    65 
    66 Read the filters' respective documentation to read up exactly on how to use them.
    67 
    68 === `-colorspace` and friends ===
    69 The easiest way to use these filters is to ensure that the input AVFrames have all relevant struct members set to the appropriate values. On ffmpeg command-line this is what options such as `-colorspace` and `color_trc` do; you can also put them on the output side to modify what space the output is in.
    70 
    71 If everything goes well, `swscale` figures out how to do the conversion and you can avoid calling the filter manually. However, AVFrames does not cover every option needed, so advanced use will go back to `-vf colorspace` or `-vf zscale`.
     38
     39FFmpeg stores these properties in the [https://ffmpeg.org/doxygen/trunk/structAVFrame.html AVFrame] struct:
     40
     41- The format (type and bit-depth)->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#aed14fa772ce46881020fd1545c86432c format]
     42- The signal range->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#a853afbad220bbc58549b4860732a3aa5 color_range]
     43- The YUV/RGB transformation matrix->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#a9262c231f1f64869439b4fe587fe1710 colorspace]
     44- The linearization function (a.k.a. transformation characteristics)->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#ab09abb126e3922bc1d010cf044087939 color_trc]
     45- The RGB/XYZ matrix->[https://ffmpeg.org/doxygen/trunk/structAVFrame.html#a59a3f830494f2ed1133103a1bc9481e7 color_primaries]
     46
     47== How to use FFmpeg to convert the colorspace ==
     48
     49Pixel format conversion is often performed by [https://ffmpeg.org/libswscale.html libswscale], which you will most likely access through the [https://ffmpeg.org/ffmpeg-scaler.html FFmpeg Scaler] or the scale [https://ffmpeg.org/ffmpeg-filters.html#scale-1 video filter].
     50
     51Other video filters include:
     52- `colormatrix` ([https://ffmpeg.org/ffmpeg-filters.html#colormatrix native])
     53- `colorspace` ([https://ffmpeg.org/ffmpeg-filters.html#colorspace native])
     54- `zscale` ([https://ffmpeg.org/ffmpeg-filters.html#zscale z.lib library])
     55
     56=== Comparing and contrasting `colorspace`, `colormatrix`, libswscale, and `zscale` ===
     57
     58- `colorspace` and `colormatrix` can only convert YUV to YUV
     59- libswscale can convert between YUV and RGB
     60- `colormatrix` only supports 8bpc (8-bit per component) pixel formats
     61- `colorspace` supports 8bpc, 10bpc, and 12bpc
     62- `colormatrix` does not apply gamma and primaries correction (i.e. which exact color "red", "green", and "blue" each is)
     63- `colorspace` applies gamma and primaries correction by default. (Use `fast=1` to disable this for faster conversion or to make output compatible with output produced by `colormatrix`.)
     64- `colormatrix` is C only, whereas `colorspace` uses x86 SIMD so it's faster
     65- `colormatrix` produces horrible quality for 10bpc and 12bpc
     66- `colorspace` produces something decent for 10bpc
     67- For 8bpc, `colorspace` seems to produce slightly better quality than `colormatrix`
     68- `zscale` produces better results at all bit depths
     69
     70=== `colorspace` and friends ===
     71The easiest way to use these filters is to ensure that the input AVFrames have all relevant struct members set to the appropriate values. On ffmpeg command-line this is what options such as `colorspace` and `color_trc` do; you can also put them on the output side to modify what space the output is in.
     72
     73If everything goes well, libswscale figures out how to do the conversion and you can avoid calling the filter manually. However, AVFrames does not cover every option needed, so advanced use will go back to `colorspace` or `zscale`.
    7274
    7375See also [https://ffmpeg.org/doxygen/trunk/group__lsws.html#ga541bdffa8149f5f9203664f955faa040 sws_setColorspaceDetails]() and [https://stackoverflow.com/a/67885887 F.X.'s colorspace answer].
     
    7577=== sRGB ===
    7678
    77 There is no colorspace default called `srgb` in ffmpeg, because it's identical to Bt. 709 except for a different transfer function. Just use one of the following:
     79There is no colorspace default called sRGB in FFmpeg, because it's identical to BT.709 except for a different transfer function. Just use one of the following:
    7880
    7981* sRGB input, fast: `-vf "colorspace=all=bt709:fast=1"`, aka `-colorspace bt709` (on the input side!)
     
    8284See also [https://stackoverflow.com/a/69251961 F.X.'s HDR answer] and [https://stackoverflow.com/a/55411219 Gyan's sRGB output answer]. If `srgb` does not work, try the more academic name `iec61966-2-1`.
    8385
    84 == Examples ^(Build from: https://zeranoe.com/builds/win64/static/ffmpeg-20190416-e2f766e-win64-static.zip)^ ==
    85 
    86 Caveat: For all these images to be properly displayed... some decent browser shall be a requisite.
    87 [[BR]]
    88 [[BR]]
    89 [[BR]]
     86== Examples (Made using [https://zeranoe.com/builds/win64/static/ffmpeg-20190416-e2f766e-win64-static.zip zeranoe 20190416]) ==
     87
    9088==== The input source (rgb24): ====
    9189
     
    106104[[BR]]
    107105[[BR]]
    108 ==== `colorspace` (yuv444p10le): ^(Note: SSIM > 99.98% with [#Theinputsourcergb24: The input source (rgb24)]. Should be 100% if the conversion algorithms are improved though...)^ ====
     106==== `colorspace` (yuv444p10le): ====
     107Note: SSIM > 99.98% with [#Theinputsourcergb24: The input source (rgb24)]. Should be 100% if the conversion algorithms are improved, though.
    109108{{{
    110109ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p10le -sws_flags spline+accurate_rnd+full_chroma_int -vf "colorspace=bt709:iall=bt601-6-625:fast=1" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colorspace_yuv444p10le.avi"