Commit | Line | Data |
---|---|---|
72b9787e JB |
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. |