From Avisynth wiki
Jump to: navigation, search
Author Kassandro
Version v0.3
Category Deblocker
License GPLv2
Discussion VideoProcessing Thread



MDeblock is an AviSynth plugin for removing block artifacts.


  • AviSynth 2.5.8 or greater
  • Supported color formats: YV12

Syntax and Parameters

MDeblock (clip, string "mode", int "width", int "height", int "cwidth", int "cheight", int "leftcrop", int "topcrop")

clip   =
Input clip.

string  mode = "222222"
Currently MDeblock has five modes 0 (do nothing),1 (MDeblock 0.1), 2 (MDeblock 0.2.1), and the new modes 3,4. These modes can be specified for all planes separately with the "mode" string. The "mode" string (default = "222222") consists of 6 digits (currently only 0-4 are allowed). The first digit is for horizontal deblocking of the luma, the second digit is for vertical deblocking of the luma, the third (resp. the fourth) digit is for horizontal (resp. vertical) deblocking of the U plane and finally the fifth (resp. the sixth) digit is for horizontal (resp. vertical) deblocking of the V plane. Note that horizontal deblocking deals with vertical edges and vertical deblocking deals with horizontal edges (I have taken over this idiotic notation from MPEG2DEC3 postprocessing). The mode string is particularly useful for interlaced content, because one should never apply vertical deblocking to interlaced content. Thus one should use MDeblock with mode="101010" for field based footage. However, vertical deblocking can be used for interlaced material as well if SeparateFields is applied before. For instance, SeparateFields().MDeblock(cheight= 4).Weave() is the right choice for handling interlaced MPEG2. However, in general it is more reasonable to deinterlace or inverse telecine the video before deblocking. A blur deinterlacer usually takes care of horizontal block edges, because blockiness normally only occurs in the presence of motion. Thus only horizontal deblocking (handling vertical edges) is necessary. Actually the deinterlacer RGDeinterlace derived from my RemoveGrain package usually deblocks also vertical edges. Thus deblocking is primarily useful for progressive content. If image quality should be maximized, then one should deblock as early as possible. If compression is an issue one should deblock as late as possible and one won't loose much image quality either. Especially if the clip originates from a DCT codec and is processed by block based filters like PixieDust or RemoveDirt, which share a similar block grid with the codec, deblocking should occur after these filters but before cropping. RemoveDirt has 8x8 blocks for the luma and 4x4 blocks for the YV12 chroma, while DCT codecs 8x8 for both the luma and the chroma in the progressive case and 8x4 chroma blocks in the interlaced case.

int  width = 8
int  height = 8
int  cwidth = 8
int  cheight = 8
"width" (default=8) is the luma block width, "height" (default=8) is the luma block height, "cwidth" (default=8) is the chroma block width, "cheight" (default= 8) is the chroma block height.
The default value 8 for "width", "height", "cwidth", "cheight" are the right values for progressive clips which are generated by a codec based on the DCT (discrete cosine transformation), like MPEG2 or MPEG4. RemoveDirt has its own deblocking routines (driven by the variables pthreshold, cthreshold), but if you want even more deblocking, you can use MDeblock(cwidth=4, cheight=4).

int  leftcrop = 0
int  topcrop = 0
If the clip has been cropped before MDeblock and after the block structure has been imposed on the clip by a filter, then you have to specify the sum of all left crop values in the variable "leftcrop" (default=0) and the sum of all top crop values in "topcrop" (default=0). If the user does not crop before MDeblock, he doesn't need to care about "leftcrop" and "topcrop". Under certain circumstances MDeblock is unable to deblock the blocks near the margins if the clip has been cropped before and "leftcrop" , "topcrop" are used. It is very good rule for any AviSynth script to crop as late as possible and there are only very few exceptions from this rule.

How MDeblock works

Let x1 be a pixel on the left edge of a block, x2 a pixel on the right side of this edge. The pixel x2 already belongs to the neighbour block. Let further x0 be the left neighbour of the pixel x1 and x3 be the right neighbour of the pixel x2. Blockiness becomes visible for the human eye if the (luma) difference | x1 - x2| is fairly large compared with the differences |x0 - x1|, |x2 - x3|. A deblocking filter then must change at least the edge pixels x1, x2 such that this imbalance disappears. MDeblock with mode=1 changes only the edge pixels. Only the edge pixels should be changed by a deblocking filter. The interior pixels of a block should not be changed. With MDeblock we persue the following strategy. If x1 < x2, then we put a = x1 - |x0 - x1|, b = x2 + |x3 - x2|, y1 = (2*a + b)/3 and y2 = (a + 2*b)/3. Now MDeblock replaces x1 by y1 if x1 < y1, otherwise x1 remains unchanged, it also replaces x2 by y2, if y2 < x2, otherwise x2 remains unchanged. Similarly, if x1 > x2, then we put a = x1 + |x0 - x1|, b = x2 - |x3 - x2|, y1 = (2*a + b)/3, y2 = (a + 2*b)/3 and MDeblock replaces x1 by y1 if x1 > y1, x2 by y2, if y2 > x2, Thus in any case the difference of the edge pixels is shrinking. In the extreme cases x0 < x1 < x2 < x3 and x0 > x1 > x2 > x3 we even have |x0 - y1| = |y1 - y2| = |y2 - x3| if |x0 - x1| <= |x1 - x2| and |x2 - x3| <= |x1 - x2|. The above description is only the basic idea, the actual implementation is more sophisticated and considerably more conservative. For instance, the changes made by MDeblock are limited by |x0 - x3|. In particular, if x0=x3, then x1 and x2 remain unchanged. It also operates more conservatively if only one edge pixel is changed.

MDeblock distinguishes itself from most other deblockers by being based on clear mathematical principles.

Currently MDeblock is a pure C implementation. It can be SSE optimized, though. However, SSE optimization will only yield a performance gain of 100-200% with SSE and 150-300% with SSE2, because it involves a lot of branching, which degrades the advantages of SIMD programming. With SIMD programming unlike standard programming always all branches have to be executed. In the horizontal case data arrangement is also quite hostile to SSE programming. Thus I will only do SSE optimization if MDeblock proves to be really useful.


MDeblock with default settings:

MDeblock(mode="222222", width=8, height=8, cwidth=8, cheight=8, leftcrop=0, topcrop=0)

Archived Downloads

Version Download Mirror

External Links

Back to External Filters

Personal tools