The MPEG1/2/4 and H.261/2/3 IDCT

The 8×8 Inverse discrete cosine transform used in most video codecs converts the very sparse and thus easily compressible dct coefficient matrixes into the 8×8 blocks vissible or the 8×8 difference relative to some area from the previous frame
The IDCT in these codecs is not exactly specified, instead the MPEG and ITU commitees only require the used IDCT to be approximately equal to a idealized and very slow reference IDCT due to that, decoders and encoders use various different IDCTs, if the actually used encoder and decoder happen to use 2 different enough IDCTs and the video material, encoding parameters, moon phase and so on match then the tiny +-1 differences between the IDCTs will accumulate and turn the pale face of a corpse pink or green or add stripes or worse …
some examples of such artifacts:

LLM/IJG int simpleidct
libmpeg2 idct xvids idct
LLM/IJG int simpleidct
libmpeg2 idct xvids idct

Its also very important to keep in mind that these artifacts are caused by the difference between the encoder and decoder IDCT and not the difference to some idealized IDCT only on the decoder side, so using the reference IDCT on the decoder side will often not help at all, and sometimes might make the artifacts worse
now maybe you are curious which IDCT was used in the encoders for the 2 examples above, well iam curious too about that as theres no 100% certain way to find out, allthough i would guess the first used the idct from the msmpeg4v3 codec and the second the one from xvid
Which prameters can be tuned on the encoder side to reduce these artifacts? First use a smaller keyframe interval, then avoid qp=1, avoid qpel and use lots of b frames or use H.264 which doesnt suffer from this mess as it has a exactly specified idct approximation

3 Comments on "The MPEG1/2/4 and H.261/2/3 IDCT"

  1. This is an old problem, and much was done to address it after it was introduced in H.261 and then MPEG-1/2.
    For example, encoders supposed to use so-called “Morris test”, extra tests have been added to IDCT precision specification (ISO/IEC 23002-1), and finally there is whole new fixed-point 8×8 IDCT specification: ISO/IEC 23002-2, produced by MPEG in 2008.
    For more info, please see:
    Y.A.Reznik, A.T.Hinds, L.Yu, Z.Ni, and C-X.Zhang, “Efficient fixed-point approximations of the 8×8 inverse discrete cosine transform”, Proc. SPIE Vol. 6696, Sep. 24, 2007.
    G.Sullivan, “Analysis and encoder prevention techniques for pathological IDCT drift accumulation in static video scenes”, Proc. SPIE Vol. 6696, Sep. 24, 2007.


  2. Hi Yuriy

    Yes, its a old problem and its a old blog post too, ISO 23002-* came out after i wrote it.
    Being old though doesn’t mean its a problem of only the past. Files in the wild still have the same issues here and encoders of old 8×8 IDCT based hybrid codecs still use a wide range of IDCTs and not just one and the same.
    The problem really was fixed in H.264 and later standards by specifying a bit exact IDCT.
    It also seems the ISO specs (still) are available only behind pay-walls, especially for this here where i believe everyone wanted it to be adopted this seems a rather unskillful choice. More so as some of the standards using 8×8 IDCTs are freely available for download.
    Besides a bit exact IDCT and better precision/accuracy requirements one thing sorely needed is a way to identify what IDCT the encoder used. For example is there a way now to identify if ISO/IEC 23002-2 was used by the encoder ?
    As far as FFmpeg is concerned we support many IDCTs and i would certainly welcome it if someone would submit a patch for adding the one from 23002-2. I cant add it easily as i dont have the standard and cant just download it. And the reference software is not under a license compatible with the (L)GPL as far as i can tell as a non lawyer.
    Is there some free implementation that is GPL compatible ?


Leave a Reply

Your email address will not be published.