| 1 | Lossless |
| 2 | -------- |
| 3 | |
| 4 | Lossless Encoding |
| 5 | ================= |
| 6 | |
| 7 | x265 can encode HEVC bitstreams that are entirely lossless (the |
| 8 | reconstructed images are bit-exact to the source images) by using the |
| 9 | :option:`--lossless` option. Lossless operation is theoretically |
| 10 | simple. Rate control, by definition, is disabled and the encoder |
| 11 | disables all quality metrics since they would only waste CPU cycles. |
| 12 | Instead, x265 reports only a compression factor at the end of the |
| 13 | encode. |
| 14 | |
| 15 | In HEVC, lossless coding means bypassing both the DCT transforms and |
| 16 | bypassing quantization (often referred to as transquant bypass). Normal |
| 17 | predictions are still allowed, so the encoder will find optimal inter or |
| 18 | intra predictions and then losslessly code the residual (with transquant |
| 19 | bypass). |
| 20 | |
| 21 | All :option:`--preset` options are capable of generating lossless video |
| 22 | streams, but in general the slower the preset the better the compression |
| 23 | ratio (and the slower the encode). Here are some examples:: |
| 24 | |
| 25 | ./x265 ../test-720p.y4m o.bin --preset ultrafast --lossless |
| 26 | ... <snip> ... |
| 27 | encoded 721 frames in 238.38s (3.02 fps), 57457.94 kb/s |
| 28 | |
| 29 | ./x265 ../test-720p.y4m o.bin --preset faster --lossless |
| 30 | ... <snip> ... |
| 31 | x265 [info]: lossless compression ratio 3.11::1 |
| 32 | encoded 721 frames in 258.46s (2.79 fps), 56787.65 kb/s |
| 33 | |
| 34 | ./x265 ../test-720p.y4m o.bin --preset slow --lossless |
| 35 | ... <snip> ... |
| 36 | x265 [info]: lossless compression ratio 3.36::1 |
| 37 | encoded 721 frames in 576.73s (1.25 fps), 52668.25 kb/s |
| 38 | |
| 39 | ./x265 ../test-720p.y4m o.bin --preset veryslow --lossless |
| 40 | x265 [info]: lossless compression ratio 3.76::1 |
| 41 | encoded 721 frames in 6298.22s (0.11 fps), 47008.65 kb/s |
| 42 | |
| 43 | .. Note:: |
| 44 | In HEVC, only QP=4 is truly lossless quantization, and thus when |
| 45 | encoding losslesly x265 uses QP=4 internally in its RDO decisions. |
| 46 | |
| 47 | Near-lossless Encoding |
| 48 | ====================== |
| 49 | |
| 50 | Near-lossless conditions are a quite a bit more interesting. Normal ABR |
| 51 | rate control will allow one to scale the bitrate up to the point where |
| 52 | quantization is entirely bypassed (QP <= 4), but even at this point |
| 53 | there is a lot of SSIM left on the table because of the DCT transforms, |
| 54 | which are not lossless:: |
| 55 | |
| 56 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 40000 --ssim |
| 57 | encoded 721 frames in 326.62s (2.21 fps), 39750.56 kb/s, SSIM Mean Y: 0.9990703 (30.317 dB) |
| 58 | |
| 59 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 50000 --ssim |
| 60 | encoded 721 frames in 349.27s (2.06 fps), 44326.84 kb/s, SSIM Mean Y: 0.9994134 (32.316 dB) |
| 61 | |
| 62 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 60000 --ssim |
| 63 | encoded 721 frames in 360.04s (2.00 fps), 45394.50 kb/s, SSIM Mean Y: 0.9994823 (32.859 dB) |
| 64 | |
| 65 | For the encoder to get over this quality plateau, one must enable |
| 66 | lossless coding at the CU level with :option:`--cu-lossless`. It tells |
| 67 | the encoder to evaluate trans-quant bypass as a coding option for each |
| 68 | CU, and to pick the option with the best rate-distortion |
| 69 | characteristics. |
| 70 | |
| 71 | The :option:`--cu-lossless` option is very expensive, computationally, |
| 72 | and it only has a positive effect when the QP is extremely low, allowing |
| 73 | RDO to spend a large amount of bits to make small improvements to |
| 74 | quality. So this option should only be enabled when you are encoding |
| 75 | near-lossless bitstreams:: |
| 76 | |
| 77 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 40000 --ssim --cu-lossless |
| 78 | encoded 721 frames in 500.51s (1.44 fps), 40017.10 kb/s, SSIM Mean Y: 0.9997790 (36.557 dB) |
| 79 | |
| 80 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 50000 --ssim --cu-lossless |
| 81 | encoded 721 frames in 524.60s (1.37 fps), 46083.37 kb/s, SSIM Mean Y: 0.9999432 (42.456 dB) |
| 82 | |
| 83 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 60000 --ssim --cu-lossless |
| 84 | encoded 721 frames in 523.63s (1.38 fps), 46552.92 kb/s, SSIM Mean Y: 0.9999489 (42.917 dB) |
| 85 | |
| 86 | .. Note:: |
| 87 | It is not unusual for bitrate to drop as you increase lossless coding. |
| 88 | Having "perfectly coded" reference blocks reduces residual in later |
| 89 | frames. It is quite possible for a near-lossless encode to spend |
| 90 | more bits than a lossless encode. |
| 91 | |
| 92 | Enabling psycho-visual rate distortion will improve lossless coding. |
| 93 | :option:`--psy-rd` influences the RDO decisions in favor of energy |
| 94 | (detail) preservation over bit cost and results in more blocks being |
| 95 | losslessly coded. Our psy-rd feature is not yet assembly optimized, so |
| 96 | this makes the encodes run even slower:: |
| 97 | |
| 98 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 40000 --ssim --cu-lossless --psy-rd 1.0 |
| 99 | encoded 721 frames in 581.83s (1.24 fps), 40112.15 kb/s, SSIM Mean Y: 0.9998632 (38.638 dB) |
| 100 | |
| 101 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 50000 --ssim --cu-lossless --psy-rd 1.0 |
| 102 | encoded 721 frames in 587.54s (1.23 fps), 46284.55 kb/s, SSIM Mean Y: 0.9999663 (44.721 dB) |
| 103 | |
| 104 | ./x265 ../test-720p.y4m o.bin --preset medium --bitrate 60000 --ssim --cu-lossless --psy-rd 1.0 |
| 105 | encoded 721 frames in 592.93s (1.22 fps), 46839.51 kb/s, SSIM Mean Y: 0.9999707 (45.334 dB) |
| 106 | |
| 107 | :option:`--cu-lossless` will also be more effective at slower |
| 108 | presets which perform RDO at more levels and thus may find smaller |
| 109 | blocks that would benefit from lossless coding:: |
| 110 | |
| 111 | ./x265 ../test-720p.y4m o.bin --preset veryslow --bitrate 40000 --ssim --cu-lossless |
| 112 | encoded 721 frames in 12969.25s (0.06 fps), 37331.96 kb/s, SSIM Mean Y: 0.9998108 (37.231 dB) |
| 113 | |
| 114 | ./x265 ../test-720p.y4m o.bin --preset veryslow --bitrate 50000 --ssim --cu-lossless |
| 115 | encoded 721 frames in 46217.84s (0.05 fps), 42976.28 kb/s, SSIM Mean Y: 0.9999482 (42.856 dB) |
| 116 | |
| 117 | ./x265 ../test-720p.y4m o.bin --preset veryslow --bitrate 60000 --ssim --cu-lossless |
| 118 | encoded 721 frames in 13738.17s (0.05 fps), 43864.21 kb/s, SSIM Mean Y: 0.9999633 (44.348 dB) |
| 119 | |
| 120 | And with psy-rd and a slow preset together, very high SSIMs are |
| 121 | possible:: |
| 122 | |
| 123 | ./x265 ../test-720p.y4m o.bin --preset veryslow --bitrate 40000 --ssim --cu-lossless --psy-rd 1.0 |
| 124 | encoded 721 frames in 11675.81s (0.06 fps), 37819.45 kb/s, SSIM Mean Y: 0.9999181 (40.867 dB) |
| 125 | |
| 126 | ./x265 ../test-720p.y4m o.bin --preset veryslow --bitrate 50000 --ssim --cu-lossless --psy-rd 1.0 |
| 127 | encoded 721 frames in 12414.56s (0.06 fps), 42815.75 kb/s, SSIM Mean Y: 0.9999758 (46.168 dB) |
| 128 | |
| 129 | ./x265 ../test-720p.y4m o.bin --preset veryslow --bitrate 60000 --ssim --cu-lossless --psy-rd 1.0 |
| 130 | encoded 721 frames in 11684.89s (0.06 fps), 43324.48 kb/s, SSIM Mean Y: 0.9999793 (46.835 dB) |
| 131 | |
| 132 | |
| 133 | It's important to note in the end that it is easier (less work) for the |
| 134 | encoder to encode the video losslessly than it is to encode it |
| 135 | near-losslessly. If the encoder knows up front the encode must be |
| 136 | lossless, it does not need to evaluate any lossy coding methods. The |
| 137 | encoder only needs to find the most efficient prediction for each block |
| 138 | and then entropy code the residual. |
| 139 | |
| 140 | It is not feasible for :option:`--cu-lossless` to turn itself on when |
| 141 | the encoder determines it is encoding a near-lossless bitstream (ie: |
| 142 | when rate control nearly disables all quantization) because the feature |
| 143 | requires a flag to be enabled in the stream headers. At the time the |
| 144 | stream headers are being coded we do not know whether |
| 145 | :option:`--cu-lossless` would be a help or a hinder. If very few or no |
| 146 | blocks end up being coded as lossless, then having the feature enabled |
| 147 | is a net loss in compression efficiency because it adds a flag that must |
| 148 | be coded for every CU. So ignoring even the performance aspects of the |
| 149 | feature, it can be a compression loss if enabled without being used. So |
| 150 | it is up to the user to only enable this feature when they are coding at |
| 151 | near-lossless quality. |
| 152 | |
| 153 | Transform Skip |
| 154 | ============== |
| 155 | |
| 156 | A somewhat related feature, :option:`--tskip` tells the encoder to |
| 157 | evaluate transform-skip (bypass DCT but with quantization still enabled) |
| 158 | when coding small 4x4 transform blocks. This feature is intended to |
| 159 | improve the coding efficiency of screen content (aka: text on a screen) |
| 160 | and is not really intended for lossless coding. This feature should |
| 161 | only be enabled if the content has a lot of very sharp edges in it, and |
| 162 | is mostly unrelated to lossless coding. |