Changes between Version 4 and Version 5 of colorspace
- Timestamp:
- May 12, 2019, 4:19:24 PM (7 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
colorspace
v4 v5 1 1 = Colorspace support in FFmpeg = 2 2 3 == What is colorspace? Why should we care? == 4 Colorspace describes how an array of pixel values should be displayed on the screen. 5 6 For example, it tells the format of the array of pixels (eg. RGB or YUV), and how the values of each color component should be translated, to be properly displayed by the photons of the screen. (ie. 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 12 - RGB distinguishes color pixel values into 3 components: Red, Green, Blue. (hence the name) 13 - YUV is an orthogonal representation that represents color pixel values in: Luminance (Y, or brightness), Chroma (UV, or color differences). ^(Note: YUV represents color in 3 components)^ 14 [[BR]] 15 [[BR]] 3 == What is colorspace? == 4 5 Colorspace describes how pixel values are stored within a file or displayed on the screen, and what the range and meaning of those values are. 6 7 For example, it describes how the values of pixels store color information (e.g. RGB or YUV), and how the values of each color component (e.g., R, G, or B) should be translated in order to be properly displayed by the screen. 8 9 The difference between RGB and YUV is, in simple terms: 10 11 - RGB distinguishes color in three components: Red, Green, Blue 12 - YUV represents color in brightness (Y) and color differences (UV). 13 14 {{{ 15 #!div style="border: 1px solid #e5e5c7; margin: 1em; background-color: #ffd;" 16 '''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. 17 }}} 18 16 19 The 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. 17 20 … … 21 24 - [https://en.wikipedia.org/wiki/Rec._2020 BT.2020] ("Ultra-High-Definition" or UHD) 22 25 23 These standards describe not just things like how to converta YUV signal to RGB, but also how a RGB signal should be represented in terms of photon emission, in a device-independent way.26 These standards describe not just converions from a YUV signal to RGB, but also how a RGB signal should be represented in terms of photon emission, in a device-independent way. 24 27 25 28 == How does FFmpeg identify colorspaces? == 26 29 27 In practical terms, the things you care are: 28 29 1. Whether the pixel buffer contains RGB, YUV or some other type of signals, and the bit-depth. 30 In FFmpeg, colorspace is represented in [http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavutil/pixfmt.h;hb=HEAD pixel formats]. 31 32 In practical terms, the things you care about are: 33 34 1. Whether the pixel buffer contains RGB, YUV or some other type of pixel format, and the bit-depth. 30 35 2. Whether the signals are full range or restricted range. (YUV only, unlikely a problem for other type of signals...) 31 36 3. The transformation matrix between YUV and RGB. 32 37 4. The linearization function from RGB to a linear RGB signal. 33 38 5. The conversion matrix between the linearized RGB and the device-independent XYZ colorspace. 34 [[BR]] 39 40 "Full range" refers to the YUV component values being in the range 0–255, whereas "restricted range" has values between 16–235. 41 35 42 FFmpeg stores all these properties in the [https://ffmpeg.org/doxygen/trunk/structAVFrame.html AVFrame] struct: 36 43 … … 44 51 45 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)^ 46 [[BR]] 47 [[BR]] 48 [[BR]] 53 49 54 Video filter `colorspace`, `colormatrix` have the following relationship: 50 55 … … 53 58 - `colormatrix` does not apply gamma (primaries) 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`). ^(Note: With `fast=0` (default) it seems to produce significantly worse quality (discoloration)... gamma miscorrection?..)^ 54 59 - `colormatrix` is C only, whereas `colorspace` uses x86 SIMD (ie. it's faster). 55 [[BR]] 56 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]] 57 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])^ 58 [[BR]] 59 [[BR]] 60 [[BR]] 61 [[BR]] 62 [[BR]] 60 61 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]] 62 63 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])^ 64 63 65 Read the filters' respective documentation to read up exactly on how to use them. 64 66 65 67 The easiest way to use these filters is to ensure that the input AVFrames have all relevant struct members set to the appropriate value. (or got to specify them manually as the filter arguments...)[[BR]] 66 68 Then, set the target color properties on the video filter, and it will output the converted frames. 67 [[BR]] 68 [[BR]] 69 [[BR]] 69 70 70 To convert RGB/YUV or scale using swscale, use swscale and set the appropriate color properties using [https://ffmpeg.org/doxygen/trunk/group__lsws.html#ga541bdffa8149f5f9203664f955faa040 sws_setColorspaceDetails](). 71 71 72 == Examples ^(Build from: https://zeranoe.com/builds/win64/static/ffmpeg-20190416-e2f766e-win64-static.zip)^==73 74 Caveat: For all these images to be properly displayed... some decent browser shall be a requisite.75 [[BR]] 76 [[BR]] 77 [[BR]] 72 == Examples == 73 74 These use a [https://zeranoe.com/builds/win64/static/ffmpeg-20190416-e2f766e-win64-static.zip build from Zeranoe]. 75 76 Caveat: For all these images to be properly displayed, a decent browser is a requisite. 77 78 78 ==== The input source (rgb24): ==== 79 79 80 80 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/origin(rgb24).png, 720px)]] 81 [[BR]] 82 [[BR]] 83 [[BR]] 84 [[BR]] 85 [[BR]] 86 [[BR]] 87 [[BR]] 81 88 82 ==== `colormatrix` (yuv444p10le): ==== 83 89 84 {{{ 90 85 ffmpeg -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 "colormatrix=bt470bg:bt709" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colormatrix_yuv444p10le.avi" 91 86 ffmpeg -i "colormatrix_yuv444p10le.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colormatrix_yuv444p10le.png" 92 87 }}} 88 93 89 Output bit-identical as [#colormatrixyuv444p: `colormatrix` (yuv444p)]. 94 [[BR]] 95 [[BR]] 90 96 91 ==== `colorspace` (yuv444p10le): ^(Note: SSIM > 99.98% with [#Theinputsourcergb24: The input source (rgb24)]. Should be 100% if the conversion algorithms are improved though...)^ ==== 92 97 93 {{{ 98 94 ffmpeg -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" 99 95 ffmpeg -i "colorspace_yuv444p10le.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_yuv444p10le.png" 100 96 }}} 97 101 98 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_yuv444p10le.png, 720px)]] 102 [[BR]] 103 [[BR]] 104 [[BR]] 105 [[BR]] 106 [[BR]] 99 107 100 ==== Reference (yuv444p): ==== 101 108 102 {{{ 109 103 ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p -sws_flags spline+accurate_rnd+full_chroma_int -color_range 1 -colorspace 5 -color_primaries 5 -color_trc 6 "yuv444p.avi" 110 104 ffmpeg -i "yuv444p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "yuv444p.png" 111 105 }}} 106 112 107 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/yuv444p.png, 720px)]] 113 [[BR]] 114 [[BR]] 108 115 109 ==== `colormatrix` (yuv444p): ==== 110 116 111 {{{ 117 112 ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p -sws_flags spline+accurate_rnd+full_chroma_int -vf "colormatrix=bt470bg:bt709" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colormatrix_yuv444p.avi" 118 113 ffmpeg -i "colormatrix_yuv444p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colormatrix_yuv444p.png" 119 114 }}} 115 120 116 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colormatrix_yuv444p.png, 720px)]] 121 [[BR]] 122 [[BR]] 117 123 118 ==== `colorspace` (yuv444p): ==== 119 124 120 {{{ 125 121 ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p -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_yuv444p.avi" 126 122 ffmpeg -i "colorspace_yuv444p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_yuv444p.png" 127 123 }}} 124 128 125 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_yuv444p.png, 720px)]] 129 [[BR]] 130 [[BR]] 126 131 127 ==== `colorspace` (yuv444p10le -> yuv444p): ==== 128 132 129 {{{ 133 130 ffmpeg -i "colorspace_yuv444p10le.avi" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p -sws_flags spline+accurate_rnd+full_chroma_int -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colorspace_yuv444p10le-yuv444p.avi" 134 131 ffmpeg -i "colorspace_yuv444p10le-yuv444p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_yuv444p10le-yuv444p.png" 135 132 }}} 133 136 134 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_yuv444p10le-yuv444p.png, 720px)]] 137 [[BR]] 138 [[BR]] 139 [[BR]] 140 [[BR]] 141 [[BR]] 142 [[BR]] 143 [[BR]] 135 144 136 ==== `colorspace` with `fast=0` `iall=bt601-6-625`: ==== 137 145 138 {{{ 146 139 ffmpeg -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" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colorspace_fast=0_iall=bt601-6-625.avi" 147 140 ffmpeg -i "colorspace_fast=0_iall=bt601-6-625.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_fast=0_iall=bt601-6-625.png" 148 141 }}} 142 149 143 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_fast%3D0_iall%3Dbt601-6-625.png, 720px)]] 150 [[BR]] 151 [[BR]] 144 152 145 ==== `colorspace` with `fast=0` `iall=bt601-6-525`: ==== 146 153 147 {{{ 154 148 ffmpeg -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-525" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colorspace_fast=0_iall=bt601-6-525.avi" 155 149 ffmpeg -i "colorspace_fast=0_iall=bt601-6-525.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_fast=0_iall=bt601-6-525.png" 156 150 }}} 151 157 152 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_fast%3D0_iall%3Dbt601-6-525.png, 720px)]] 158 [[BR]] 159 [[BR]] 153 160 154 ==== `colorspace` with `fast=1` `iall=bt601-6-525`: ==== 155 161 156 {{{ 162 157 ffmpeg -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-525:fast=1" -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colorspace_fast=1_iall=bt601-6-525.avi" 163 158 ffmpeg -i "colorspace_fast=1_iall=bt601-6-525.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_fast=1_iall=bt601-6-525.png" 164 159 }}} 160 165 161 Output bit-identical as [#colorspaceyuv444p10le:Note:SSIM99.98withTheinputsourcergb24.Shouldbe100iftheconversionalgorithmsareimprovedthough... `colorspace` (yuv444p10le)]. 166 [[BR]] 167 [[BR]] 168 [[BR]] 169 [[BR]] 170 [[BR]] 171 [[BR]] 172 [[BR]] 162 173 163 ==== Reference (yuv420p10le): ==== 164 174 165 {{{ 175 166 ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv420p10le -sws_flags spline+accurate_rnd+full_chroma_int -color_range 1 -colorspace 5 -color_primaries 5 -color_trc 6 "yuv420p10le.avi" 176 167 ffmpeg -i "yuv420p10le.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "yuv420p10le.png" 177 168 }}} 169 178 170 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/yuv420p10le.png, 720px)]] 179 [[BR]] 180 [[BR]] 171 181 172 ==== `colorspace` (yuv420p10le): ==== 173 182 174 {{{ 183 175 ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv420p10le -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_yuv420p10le.avi" 184 176 ffmpeg -i "colorspace_yuv420p10le.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_yuv420p10le.png" 185 177 }}} 178 186 179 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_yuv420p10le.png, 720px)]] 187 [[BR]] 188 [[BR]] 189 [[BR]] 190 [[BR]] 191 [[BR]] 180 192 181 ==== Reference (yuv420p): ==== 182 193 183 {{{ 194 184 ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv420p -sws_flags spline+accurate_rnd+full_chroma_int -color_range 1 -colorspace 5 -color_primaries 5 -color_trc 6 "yuv420p.avi" 195 185 ffmpeg -i "yuv420p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "yuv420p.png" 196 186 }}} 187 197 188 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/yuv420p.png, 720px)]] 198 [[BR]] 199 [[BR]] 189 190 200 191 ==== `colorspace` (yuv420p): ==== 192 201 193 {{{ 202 194 ffmpeg -i "origin(rgb24).png" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv420p -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_yuv420p.avi" 203 195 ffmpeg -i "colorspace_yuv420p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_yuv420p.png" 204 196 }}} 197 205 198 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_yuv420p.png, 720px)]] 206 [[BR]] 207 [[BR]] 199 208 200 ==== `colorspace` (yuv420p10le -> yuv420p): ==== 201 209 202 {{{ 210 203 ffmpeg -i "colorspace_yuv420p10le.avi" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv420p -sws_flags spline+accurate_rnd+full_chroma_int -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colorspace_yuv420p10le-yuv420p.avi" 211 204 ffmpeg -i "colorspace_yuv420p10le-yuv420p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_yuv420p10le-yuv420p.png" 212 205 }}} 206 213 207 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_yuv420p10le-yuv420p.png, 720px)]] 214 [[BR]] 215 [[BR]] 208 216 209 ==== `colorspace` (yuv444p10le -> yuv420p): ==== 210 217 211 {{{ 218 212 ffmpeg -i "colorspace_yuv444p10le.avi" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv420p -sws_flags spline+accurate_rnd+full_chroma_int -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 1 "colorspace_yuv444p10le-yuv420p.avi" 219 213 ffmpeg -i "colorspace_yuv444p10le-yuv420p.avi" -compression_level 10 -pred mixed -pix_fmt rgb24 -sws_flags +accurate_rnd+full_chroma_int "colorspace_yuv444p10le-yuv420p.png" 220 214 }}} 215 221 216 [[Image(https://trac.ffmpeg.org/raw-attachment/wiki/colorspace/colorspace_yuv444p10le-yuv420p.png, 720px)]]
