Merge commit '7c25ffe070c286874a8c3513f7504b90e1626b0c'
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>
Tue, 16 Feb 2016 19:19:23 +0000 (19:19 +0000)
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>
Tue, 16 Feb 2016 19:25:17 +0000 (19:25 +0000)
* commit '7c25ffe070c286874a8c3513f7504b90e1626b0c':
  mpeg1: Make intra-block decoding independent of MpegEncContext

Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
1  2 
libavcodec/eatqi.c
libavcodec/mpeg12.c
libavcodec/mpeg12.h
libavcodec/mpeg12dec.c

@@@ -66,9 -66,14 +66,14 @@@ static int tqi_decode_mb(MpegEncContex
  {
      int n;
      s->bdsp.clear_blocks(block[0]);
-     for (n=0; n<6; n++)
-         if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0)
+     for (n = 0; n < 6; n++) {
+         int ret = ff_mpeg1_decode_block_intra(&s->gb,
+                                               s->intra_matrix,
+                                               s->intra_scantable.permutated,
 -                                              s->last_dc, block[n], n, 1);
++                                              s->last_dc, block[n], n, 1, s->block_last_index);
+         if (ret < 0)
              return -1;
+     }
  
      return 0;
  }
@@@ -243,3 -237,90 +243,100 @@@ int ff_mpeg1_find_frame_end(ParseContex
      return END_NOT_FOUND;
  }
  
 -                                int16_t *block, int index, int qscale)
+ #define MAX_INDEX (64 - 1)
+ int ff_mpeg1_decode_block_intra(GetBitContext *gb,
+                                 const uint16_t *quant_matrix,
+                                 uint8_t *const scantable, int last_dc[3],
 -            UPDATE_CACHE(re, gb);
 -            GET_RL_VLC(level, run, re, gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
++                                int16_t *block, int index, int qscale,
++                                int block_last_index[12])
+ {
+     int dc, diff, i = 0, component;
+     RLTable *rl = &ff_rl_mpeg1;
+     /* DC coefficient */
+     component = index <= 3 ? 0 : index - 4 + 1;
+     diff = decode_dc(gb, component);
+     if (diff >= 0xffff)
+         return AVERROR_INVALIDDATA;
+     dc  = last_dc[component];
+     dc += diff;
+     last_dc[component] = dc;
+     block[0] = dc * quant_matrix[0];
+     {
+         OPEN_READER(re, gb);
++        UPDATE_CACHE(re, gb);
++        if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF)
++            goto end;
++
+         /* now quantify & encode AC coefficients */
+         while (1) {
+             int level, run, j;
 -            if (level == 127) {
 -                break;
 -            } else if (level != 0) {
++            GET_RL_VLC(level, run, re, gb, rl->rl_vlc[0],
++                       TEX_VLC_BITS, 2, 0);
 -                LAST_SKIP_BITS(re, gb, 1);
++            if (level != 0) {
+                 i += run;
+                 if (i > MAX_INDEX)
+                     break;
+                 j = scantable[i];
+                 level = (level * qscale * quant_matrix[j]) >> 4;
+                 level = (level - 1) | 1;
+                 level = (level ^ SHOW_SBITS(re, gb, 1)) -
+                         SHOW_SBITS(re, gb, 1);
 -                    LAST_SKIP_BITS(re, gb, 8);
++                SKIP_BITS(re, gb, 1);
+             } else {
+                 /* escape */
+                 run = SHOW_UBITS(re, gb, 6) + 1;
+                 LAST_SKIP_BITS(re, gb, 6);
+                 UPDATE_CACHE(re, gb);
+                 level = SHOW_SBITS(re, gb, 8);
+                 SKIP_BITS(re, gb, 8);
+                 if (level == -128) {
+                     level = SHOW_UBITS(re, gb, 8) - 256;
 -                    LAST_SKIP_BITS(re, gb, 8);
++                    SKIP_BITS(re, gb, 8);
+                 } else if (level == 0) {
+                     level = SHOW_UBITS(re, gb, 8);
 -    if (i > MAX_INDEX)
++                    SKIP_BITS(re, gb, 8);
+                 }
+                 i += run;
+                 if (i > MAX_INDEX)
+                     break;
+                 j = scantable[i];
+                 if (level < 0) {
+                     level = -level;
+                     level = (level * qscale * quant_matrix[j]) >> 4;
+                     level = (level - 1) | 1;
+                     level = -level;
+                 } else {
+                     level = (level * qscale * quant_matrix[j]) >> 4;
+                     level = (level - 1) | 1;
+                 }
+             }
+             block[j] = level;
++            if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF)
++               break;
++
++            UPDATE_CACHE(re, gb);
+         }
++end:
++        LAST_SKIP_BITS(re, gb, 2);
+         CLOSE_READER(re, gb);
+     }
 -    return i;
++      if (i > MAX_INDEX)
+         i = AVERROR_INVALIDDATA;
++    block_last_index[index] = i;
++    return 0;
+ }
@@@ -50,7 -50,11 +50,12 @@@ static inline int decode_dc(GetBitConte
      return diff;
  }
  
- int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n);
+ int ff_mpeg1_decode_block_intra(GetBitContext *gb,
+                                 const uint16_t *quant_matrix,
+                                 uint8_t *const scantable, int last_dc[3],
 -                                int16_t *block, int index, int qscale);
++                                int16_t *block, int index, int qscale,
++                                int block_last_index[12]);
  void ff_mpeg1_clean_buffers(MpegEncContext *s);
  int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s);
  
@@@ -887,9 -781,20 +787,20 @@@ static int mpeg_decode_mb(MpegEncContex
                          return ret;
              }
          } else {
-             for (i = 0; i < 6; i++)
-                 if ((ret = mpeg1_decode_block_intra(s, *s->pblocks[i], i)) < 0)
+             for (i = 0; i < 6; i++) {
+                 ret = ff_mpeg1_decode_block_intra(&s->gb,
+                                                   s->intra_matrix,
+                                                   s->intra_scantable.permutated,
+                                                   s->last_dc, *s->pblocks[i],
 -                                                  i, s->qscale);
++                                                  i, s->qscale, s->block_last_index);
+                 if (ret < 0) {
+                     av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n",
+                            s->mb_x, s->mb_y);
                      return ret;
+                 }
+                 s->block_last_index[i] = ret;
+             }
          }
      } else {
          if (mb_type & MB_TYPE_ZERO_MV) {