mpeg1: Make intra-block decoding independent of MpegEncContext
authorVittorio Giovara <vittorio.giovara@gmail.com>
Mon, 25 Jan 2016 17:56:11 +0000 (12:56 -0500)
committerDiego Biurrun <diego@biurrun.de>
Tue, 9 Feb 2016 19:04:59 +0000 (20:04 +0100)
This allows untangling the eatqi decoder from the MPEG-1 decoder.

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: Diego Biurrun <diego@biurrun.de>
libavcodec/eatqi.c
libavcodec/mpeg12.c
libavcodec/mpeg12.h
libavcodec/mpeg12dec.c

index f5dcb53..59bba97 100644 (file)
@@ -66,9 +66,14 @@ static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64])
 {
     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);
+        if (ret < 0)
             return -1;
+    }
 
     return 0;
 }
index 69c6d0a..c0c680d 100644 (file)
@@ -236,3 +236,91 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size,
     pc->state = state;
     return END_NOT_FOUND;
 }
+
+#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],
+                                int16_t *block, int index, int qscale)
+{
+    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);
+        /* now quantify & encode AC coefficients */
+        while (1) {
+            int level, run, j;
+
+            UPDATE_CACHE(re, gb);
+            GET_RL_VLC(level, run, re, gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+            if (level == 127) {
+                break;
+            } else 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, 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);
+                } else if (level == 0) {
+                    level = SHOW_UBITS(re, gb, 8);
+                    LAST_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;
+        }
+        CLOSE_READER(re, gb);
+    }
+
+    if (i > MAX_INDEX)
+        i = AVERROR_INVALIDDATA;
+
+    return i;
+}
index fda1a53..c0a86b6 100644 (file)
@@ -50,7 +50,11 @@ static inline int decode_dc(GetBitContext *gb, int component)
     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);
+
 void ff_mpeg1_clean_buffers(MpegEncContext *s);
 int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s);
 
index 2a88756..c1f3527 100644 (file)
@@ -138,99 +138,6 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
         }                                                                     \
     } while (0)
 
-static inline int mpeg1_decode_block_intra(MpegEncContext *s,
-                                           int16_t *block, int index)
-{
-    int dc, diff, i = 0, component;
-    RLTable *rl = &ff_rl_mpeg1;
-    uint8_t *const scantable     = s->intra_scantable.permutated;
-    const uint16_t *quant_matrix = s->intra_matrix;
-    const int qscale             = s->qscale;
-
-    /* DC coefficient */
-    component = index <= 3 ? 0 : index - 4 + 1;
-
-    diff = decode_dc(&s->gb, component);
-    if (diff >= 0xffff)
-        return AVERROR_INVALIDDATA;
-
-    dc  = s->last_dc[component];
-    dc += diff;
-    s->last_dc[component] = dc;
-
-    block[0] = dc * quant_matrix[0];
-
-    {
-        OPEN_READER(re, &s->gb);
-        /* now quantify & encode AC coefficients */
-        while (1) {
-            int level, run, j;
-
-            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) {
-                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, &s->gb, 1)) -
-                        SHOW_SBITS(re, &s->gb, 1);
-                LAST_SKIP_BITS(re, &s->gb, 1);
-            } else {
-                /* escape */
-                run = SHOW_UBITS(re, &s->gb, 6) + 1;
-                LAST_SKIP_BITS(re, &s->gb, 6);
-                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);
-                } else if (level == 0) {
-                    level = SHOW_UBITS(re, &s->gb, 8);
-                    LAST_SKIP_BITS(re, &s->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;
-        }
-        CLOSE_READER(re, &s->gb);
-    }
-
-    check_scantable_index(s, i);
-
-    s->block_last_index[index] = i;
-    return 0;
-}
-
-int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int index)
-{
-    return mpeg1_decode_block_intra(s, block, index);
-}
-
 static inline int mpeg1_decode_block_inter(MpegEncContext *s,
                                            int16_t *block, int n)
 {
@@ -874,9 +781,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
                         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);
+                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) {