Post-processing filters are applied after decoding a low-quality video, usually to make blocking and ringing artifacts less visually annoying. They operate by blurring the video in a way that reduces blocking and ringing with as little impact as possible on the sharpness of the image. There is always a tradeoff, though, and once a lossy codec has thrown away information, it can never be recovered without access to the original source. Some things are more visually annoying than others, and postprocessing can make low-quality videos nicer to watch.
Postprocessing is usually only useful with older codecs. Newer ones (including h.264, h.265, and VP8/9) all include deblocking filters as part of the codec. For example, in h.264, the deblocking filter is applied before a decoded frame is used as a reference for future frames, and the deblocking strength is selected by the encoder. This is why it's called an "in-loop" deblocker, because it's inside the decode / reference loop, and why -skip_loop_filter all
causes errors to accumulate. (Every h.264 decoder must decode a valid h.264 stream to the same bit-identical output, so all of this filtering is specified exactly. The encoder knows what the decoder is going to do, and thus knows what it's getting when choosing reference frames and sending the difference (residual).)
The end result is that low-bit-rate h.264 video usually already has as good a balance of blurring vs. blocking and ringing as possible. If you really hate blocking/ringing, and don't mind blurring as much, then you might still want to postprocess. Or maybe you have a h.264 video where the encoder turned off deblocking (maybe targetting playback on slow CPUs since deblocking costs decoder CPU time), or the user set deblock=-5:-5
so the output ended up with more blocking and less blurring than would be ideal.
Anyway, most of the time it won't help to postprocess h.264, HEVC, VP8, or VP9 video.
Postprocessing IS certainly useful for artifacty MPEG2 and MPEG4-ASP (divx, xvid), and even older codecs, as their output is often full of blocking and ringing when the encoder didn't have enough bitrate to make the output look good.
FFmpeg includes the following post-processing filters:
- spp - Simple Postprocessing
- uspp - Ultra Simple or Slow Postprocessing
- fspp - Fast Simple Postprocessing
- pp7 - Postprocessing 7
- pp - libpostproc wrapper
These filters basically smooth away blocking and other artifacts from low quality sources. By default, they use information from the decoder to adapt the filter strength to the quality of each block. (QP = quantization parameter. Lower number = less rounding off = higher quality. Every block has its own QP, and ffmpeg's video decoders export this information along with the decoded video so filters can refer to it.) Higher QP blocks get stronger PP applied, because more of their "detail" is probably actually blocking and ringing that we want to get rid of.
This adaptive filtering is very similar to what h.264 does, but don't try to use x264 as a deblocker. There isn't an option to tell x264 that you WANT it to try to deblock, so it will still be trying to preserve all the blocking and ringing in the frames you feed it. It will see the filtered frames from its deblocking filter as worse matches for the input frames, because of the loss of all that "detail" (actually artifacts from the previous encoder, but it takes a human (or AI) to tell the difference).
Transcoding from one lossy codec to another lossy codec will never increase quality. In fact, it will always lose quality, by definition for lossy codecs. If you have other reasons for transcoding old artifacty video into something else (e.g. player compatibility, using a clip as part of a longer video, or going to an even lower bitrate), then it can be a good idea to apply some PP before feeding it to the new encoder.
uspp
uses an encoder, hence, should be used only when one has a powerful CPU. Also, uspp
is very slow as compared to other filters. Therefore, for processing large amount of data, fspp
is a good option (It gives good results if parameters are chosen wisely).
Postprocessing filters can be used on the ffmpeg
commandline like this:
ffmpeg -i INPUT ... -vf PP OUTPUT
or can be used to playback the input with ffplay
like this:
ffplay INPUT -vf PP
where PP is the postprocessing filter with its parameters.
Let's consider the example of
- Test sequence from the movie "Matrix" (187 seconds) compressed with ffmpeg's MPEG2 encoder, at 200kbps to introduce lots of blocking and ringing. The following table shows the filter options used, and frame number "123" corresponding to the output video.
Original Image | Query Image | |
---|---|---|
spp=4:10 | spp=6:20 | spp=6:44:1 |
fspp=4:10 | fspp=4:10:5 | fspp=5:44:10 |
pp7=10:0 | pp7=20:1 | pp7=42 |
uspp=5:10 | uspp=5:20 | uspp=5:40 |
pp=hb/vb/dr/fq|8 | pp=hb/vb/dr/fq|16 | pp=hb/vb/dr/fq|32 |
- Test sequence from the movie "Hannibal" (139 seconds) compressed to 200kbps. The following table shows the filter options used, and frame number "121" corresponding to the output video.
Benchmarking sample videos
- Test sequence from the movie "Matrix" (187 seconds) compressed to 200kbps. The following table shows the filter options used, and the corresponding time taken to process the video.
spp=4:10 | spp=6:20 | spp=6:44:1 |
---|---|---|
Time taken:198.784s | Time taken:686.319s | Time taken:678.862s |
fspp=4:10 | fspp=4:10:5 | fspp=5:44:10 |
Time taken:107.847s | Time taken:107.551s | Time taken:191.128s |
pp7=10:0 | pp7=20:1 | pp7=42 |
Time taken:195.468s | Time taken:192.840s | Time taken:197.956s |
uspp=5:10 | uspp=5:20 | uspp=5:40 |
Time taken:6853.268s | Time taken:6738.385s | Time taken:6641.159s |
pp=hb/vb/dr/fq|8 | pp=hb/vb/dr/fq|16 | pp=hb/vb/dr/fq|32 |
Time taken:39.978s | Time taken:45.595s | Time taken:44.119s |
- Test sequence from the movie "Hannibal" (139 seconds) compressed to 200kbps. The following table shows the filter options used, and the corresponding time taken to process the video.
spp=5:10:0:1 | spp=5:20 | spp=5:40:0:1 |
---|---|---|
Time taken:85.465s | Time taken:83.173s | Time taken:82.045s |
fspp=4:10 | fspp=4:10:10 | fspp=5:20 |
Time taken:27.182s | Time taken:27.146s | Time taken:44.639s |
pp7=10:0 | pp7=10:1 | pp7=20 |
Time taken:46.091s | Time taken:47.187s | Time taken:46.791s |
uspp=4:10 | uspp=6:20 | uspp=6:44 |
Time taken:782.629s | Time taken:3053.199s | Time taken:2936.984s |
pp=hb/vb/dr/fq|8 | pp=hb/vb/dr/fq|16 | pp=hb/vb/dr/fq|32 |
Time taken:14.137s | Time taken:14.277s | Time taken:14.053s |
Attachments (60)
-
spp.jpg
(47.9 KB
) - added by 10 years ago.
SPP - Simple Postprocessing
-
fspp.jpg
(47.7 KB
) - added by 10 years ago.
FSPP - Fast Simple Postprocessing
-
pp7.jpg
(49.8 KB
) - added by 10 years ago.
PP7 - Postprocessing 7
-
0.jpg
(48.9 KB
) - added by 10 years ago.
benchmark1 for comparing the post-processing filters
-
13.jpg
(10.1 KB
) - added by 10 years ago.
spp=4:10
-
14.jpg
(9.8 KB
) - added by 10 years ago.
spp=6:20
-
11.jpg
(8.7 KB
) - added by 10 years ago.
spp=6:44:1
-
33.jpg
(9.6 KB
) - added by 10 years ago.
fspp=4:10:5
-
41.jpg
(9.5 KB
) - added by 10 years ago.
fspp=5:44:10
-
31.jpg
(9.6 KB
) - added by 10 years ago.
fspp=5:44:10
-
34.jpg
(9.5 KB
) - added by 10 years ago.
fspp=4:10
-
43.jpg
(10.2 KB
) - added by 10 years ago.
PP7=10:0
-
41.2.jpg
(9.5 KB
) - added by 10 years ago.
PP7=42
-
44.jpg
(9.5 KB
) - added by 10 years ago.
PP7=20:1
-
lena.jpg
(5.7 KB
) - added by 10 years ago.
benchmark2 for comparing the post-processing filters
-
lena_11.jpg
(7.2 KB
) - added by 10 years ago.
spp=5:10:0:1
-
lena_12.jpg
(7.3 KB
) - added by 10 years ago.
spp=5:20
-
lena_12.2.jpg
(7.3 KB
) - added by 10 years ago.
spp=5:20
-
lena_13.jpg
(6.6 KB
) - added by 10 years ago.
spp=5:40:0:1
-
lena_31.jpg
(7.1 KB
) - added by 10 years ago.
fspp=4:10:10
-
lena_32.jpg
(6.9 KB
) - added by 10 years ago.
fspp=4:10
-
lena_33.jpg
(6.9 KB
) - added by 10 years ago.
fspp=5:20
-
lena_41.jpg
(6.9 KB
) - added by 10 years ago.
PP7=10:0
-
lena_42.jpg
(6.8 KB
) - added by 10 years ago.
PP7=10:1
-
lena_43.jpg
(7.6 KB
) - added by 10 years ago.
PP7=20
-
lena_43.2.jpg
(7.6 KB
) - added by 10 years ago.
PP7=20
- hannibal_blocky.png (78.2 KB ) - added by 10 years ago.
- hannibal_fspp0.png (179.7 KB ) - added by 10 years ago.
- hannibal_fspp1.png (176.9 KB ) - added by 10 years ago.
- hannibal_fspp2.png (174.5 KB ) - added by 10 years ago.
- hannibal_orig.png (165.4 KB ) - added by 10 years ago.
- hannibal_pp70.png (169.6 KB ) - added by 10 years ago.
- hannibal_pp71.png (165.7 KB ) - added by 10 years ago.
- hannibal_pp72.png (166.4 KB ) - added by 10 years ago.
- hannibal_spp0.png (145.2 KB ) - added by 10 years ago.
- hannibal_spp1.png (142.7 KB ) - added by 10 years ago.
- hannibal_spp2.png (141.4 KB ) - added by 10 years ago.
- hannibal_uspp0.png (150.8 KB ) - added by 10 years ago.
- hannibal_uspp1.png (142.8 KB ) - added by 10 years ago.
- hannibal_uspp2.png (137.9 KB ) - added by 10 years ago.
- hannibal_pp0.png (130.4 KB ) - added by 10 years ago.
- hannibal_pp1.png (133.6 KB ) - added by 10 years ago.
- hannibal_pp2.png (134.5 KB ) - added by 10 years ago.
- matrix_blocky.png (24.8 KB ) - added by 10 years ago.
- matrix_fspp0.png (136.0 KB ) - added by 10 years ago.
- matrix_fspp1.png (135.6 KB ) - added by 10 years ago.
- matrix_fspp2.png (129.7 KB ) - added by 10 years ago.
- matrix_orig.png (175.8 KB ) - added by 10 years ago.
- matrix_pp0.png (78.4 KB ) - added by 10 years ago.
- matrix_pp1.png (85.3 KB ) - added by 10 years ago.
- matrix_pp2.png (86.4 KB ) - added by 10 years ago.
- matrix_pp70.png (124.7 KB ) - added by 10 years ago.
- matrix_pp71.png (123.0 KB ) - added by 10 years ago.
- matrix_pp72.png (123.1 KB ) - added by 10 years ago.
- matrix_spp0.png (129.8 KB ) - added by 10 years ago.
- matrix_spp1.png (126.8 KB ) - added by 10 years ago.
- matrix_spp2.png (125.7 KB ) - added by 10 years ago.
- matrix_uspp0.png (130.9 KB ) - added by 10 years ago.
- matrix_uspp1.png (124.5 KB ) - added by 10 years ago.
- matrix_uspp2.png (119.7 KB ) - added by 10 years ago.