Merge commit '6d93307f8df81808f0dcdbc064b848054a6e83b3'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 26 Jan 2014 01:33:27 +0000 (02:33 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 26 Jan 2014 01:52:21 +0000 (02:52 +0100)
* commit '6d93307f8df81808f0dcdbc064b848054a6e83b3':
  mpeg12: check scantable indices in all decode_block functions

Benchmarks

Before:
1878 decicycles in mpeg2_decode_block_non_intra, 8388487 runs, 121 skips
1700 decicycles in mpeg2_decode_block_intra, 4194239 runs, 65 skips
1808 decicycles in mpeg2_fast_decode_block_non_intra, 8388492 runs, 116 skips
1669 decicycles in mpeg2_fast_decode_block_intra, 4194248 runs, 56 skips
--
2056 decicycles in mpeg1_decode_block_inter, 65535 runs, 1 skips
2346 decicycles in mpeg1_decode_block_intra, 32768 runs, 0 skips
2011 decicycles in mpeg1_fast_decode_block_inter, 65533 runs, 3 skips
----------------
After:
1858 decicycles in mpeg2_decode_block_non_intra, 8388490 runs, 118 skips
1691 decicycles in mpeg2_decode_block_intra, 4194233 runs, 71 skips
1823 decicycles in mpeg2_fast_decode_block_non_intra, 8388493 runs, 115 skips
1681 decicycles in mpeg2_fast_decode_block_intra, 4194238 runs, 66 skips
--
2010 decicycles in mpeg1_decode_block_inter, 65535 runs, 1 skips
2322 decicycles in mpeg1_decode_block_intra, 32766 runs, 2 skips
1995 decicycles in mpeg1_fast_decode_block_inter, 65535 runs, 1 skips

All benchmarks are the best scores of several runs

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/mpeg12dec.c

@@@ -143,16 -150,16 +152,17 @@@ static inline int mpeg1_decode_block_in
      i = 0;
      {
          OPEN_READER(re, &s->gb);
 +        UPDATE_CACHE(re, &s->gb);
 +        if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
 +            goto end;
 +
          /* now quantify & encode AC coefficients */
          for (;;) {
 -            UPDATE_CACHE(re, &s->gb);
              GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
  
 -            if (level == 127) {
 -                break;
 -            } else if (level != 0) {
 +            if (level != 0) {
                  i += run;
+                 check_scantable_index(s, i);
                  j = scantable[i];
                  level = (level * qscale * quant_matrix[j]) >> 4;
                  level = (level - 1) | 1;
                  UPDATE_CACHE(re, &s->gb);
                  level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
                  if (level == -128) {
 -                    level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8);
 +                    level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
                  } else if (level == 0) {
 -                    level = SHOW_UBITS(re, &s->gb, 8)      ; LAST_SKIP_BITS(re, &s->gb, 8);
 +                    level = SHOW_UBITS(re, &s->gb, 8)      ; SKIP_BITS(re, &s->gb, 8);
                  }
                  i += run;
+                 check_scantable_index(s, i);
                  j = scantable[i];
                  if (level < 0) {
                      level = -level;
                      level = (level - 1) | 1;
                  }
              }
-             if (i > 63) {
-                 av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                 return -1;
-             }
  
              block[j] = level;
 +            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
 +               break;
 +
 +            UPDATE_CACHE(re, &s->gb);
          }
 +end:
 +        LAST_SKIP_BITS(re, &s->gb, 2);
          CLOSE_READER(re, &s->gb);
      }
      s->block_last_index[n] = i;
@@@ -490,9 -478,8 +497,9 @@@ static inline int mpeg2_fast_decode_blo
          }
  
          block[j] = level;
-         if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF || i >= 64)
+         if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
              break;
 +
          UPDATE_CACHE(re, &s->gb);
      }
  end:
@@@ -581,17 -566,12 +586,17 @@@ static inline int mpeg2_decode_block_in
      return 0;
  }
  
 +/**
 + * Note: this function can read out of range and crash for corrupt streams.
 + * Changing this would eat up any speed benefits it has.
 + * Do not use "fast" flag if you need the code to be robust.
 + */
  static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
  {
-     int level, dc, diff, j, run;
+     int level, dc, diff, i, j, run;
      int component;
      RLTable *rl;
-     uint8_t * scantable = s->intra_scantable.permutated;
+     uint8_t * const scantable = s->intra_scantable.permutated;
      const uint16_t *quant_matrix;
      const int qscale = s->qscale;
  
              UPDATE_CACHE(re, &s->gb);
              GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
  
 -            if (level == 127) {
 +            if (level >= 64) {
                  break;
              } else if (level != 0) {
-                 scantable += run;
-                 j = *scantable;
+                 i += run;
+                 check_scantable_index(s, i);
+                 j  = scantable[i];
                  level = (level * qscale * quant_matrix[j]) >> 4;
                  level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
                  LAST_SKIP_BITS(re, &s->gb, 1);