]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/smacker.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / smacker.c
index d2b1c6816218ddea263b91bd8cbc57f00753163b..75ab5d71205eb69afa0f7e1c777ca7b4e806cc1d 100644 (file)
@@ -62,14 +62,17 @@ typedef struct SmackVContext {
     int mmap_last[3], mclr_last[3], full_last[3], type_last[3];
 } SmackVContext;
 
+typedef struct HuffEntry {
+    uint8_t value;
+    uint8_t length;
+} HuffEntry;
+
 /**
  * Context used for code reconstructing
  */
 typedef struct HuffContext {
     int current;
-    uint32_t bits[256];
-    uint8_t lengths[256];
-    uint8_t values[256];
+    HuffEntry entries[256];
 } HuffContext;
 
 /* common parameters used for decode_bigtree */
@@ -105,7 +108,7 @@ enum SmkBlockTypes {
  * Can read SMKTREE_DECODE_MAX_RECURSION before the first check;
  * does not overread gb on success.
  */
-static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length)
+static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, int length)
 {
     if (length > SMKTREE_DECODE_MAX_RECURSION || length > 3 * SMKTREE_BITS) {
         av_log(NULL, AV_LOG_ERROR, "Maximum tree recursion level exceeded.\n");
@@ -119,18 +122,15 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref
         }
         if (get_bits_left(gb) < 8)
             return AVERROR_INVALIDDATA;
-        hc->bits[hc->current]    = prefix;
-        hc->lengths[hc->current] = length;
-        hc->values[hc->current] = get_bits(gb, 8);
-        hc->current++;
+        hc->entries[hc->current++] = (HuffEntry){ get_bits(gb, 8), length };
         return 0;
     } else { //Node
         int r;
         length++;
-        r = smacker_decode_tree(gb, hc, prefix, length);
+        r = smacker_decode_tree(gb, hc, length);
         if(r)
             return r;
-        return smacker_decode_tree(gb, hc, prefix | (1U << (length - 1)), length);
+        return smacker_decode_tree(gb, hc, length);
     }
 }
 
@@ -216,22 +216,21 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
                    i ? "high" : "low");
             continue;
         }
-        err = smacker_decode_tree(gb, &h, 0, 0);
+        err = smacker_decode_tree(gb, &h, 0);
         if (err < 0)
             goto error;
         skip_bits1(gb);
         if (h.current > 1) {
-            err = ff_init_vlc_sparse(&vlc[i], SMKTREE_BITS, h.current,
-                                     INIT_VLC_DEFAULT_SIZES(h.lengths),
-                                     INIT_VLC_DEFAULT_SIZES(h.bits),
-                                     INIT_VLC_DEFAULT_SIZES(h.values),
-                                     INIT_VLC_LE);
+            err = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current,
+                                           &h.entries[0].length, sizeof(*h.entries),
+                                           &h.entries[0].value,  sizeof(*h.entries), 1,
+                                           0, INIT_VLC_OUTPUT_LE, smk->avctx);
             if (err < 0) {
                 av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
                 goto error;
             }
         } else
-            ctx.vals[i] = h.values[0];
+            ctx.vals[i] = h.entries[0].value;
     }
 
     escapes[0]  = get_bits(gb, 16);
@@ -448,6 +447,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         case SMK_BLK_FULL:
             mode = 0;
             if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes
+                if (get_bits_left(&gb) < 1)
+                    return AVERROR_INVALIDDATA;
                 if(get_bits1(&gb)) mode = 1;
                 else if(get_bits1(&gb)) mode = 2;
             }
@@ -648,21 +649,20 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
         HuffContext h;
         h.current = 0;
         skip_bits1(&gb);
-        if ((ret = smacker_decode_tree(&gb, &h, 0, 0)) < 0)
+        if ((ret = smacker_decode_tree(&gb, &h, 0)) < 0)
             goto error;
         skip_bits1(&gb);
         if (h.current > 1) {
-            ret = ff_init_vlc_sparse(&vlc[i], SMKTREE_BITS, h.current,
-                                     INIT_VLC_DEFAULT_SIZES(h.lengths),
-                                     INIT_VLC_DEFAULT_SIZES(h.bits),
-                                     INIT_VLC_DEFAULT_SIZES(h.values),
-                                     INIT_VLC_LE);
+            ret = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current,
+                                           &h.entries[0].length, sizeof(*h.entries),
+                                           &h.entries[0].value,  sizeof(*h.entries), 1,
+                                           0, INIT_VLC_OUTPUT_LE, avctx);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
                 goto error;
             }
         } else
-            values[i] = h.values[0];
+            values[i] = h.entries[0].value;
     }
     /* this codec relies on wraparound instead of clipping audio */
     if(bits) { //decode 16-bit data
@@ -671,37 +671,23 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
         for(i = 0; i <= stereo; i++)
             *samples++ = pred[i];
         for(; i < unp_size / 2; i++) {
+            unsigned idx = 2 * (i & stereo);
             if (get_bits_left(&gb) < 0) {
                 ret = AVERROR_INVALIDDATA;
                 goto error;
             }
-            if(i & stereo) {
-                if(vlc[2].table)
-                    res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3);
-                else
-                    res = values[2];
-                val  = res;
-                if(vlc[3].table)
-                    res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3);
-                else
-                    res = values[3];
-                val |= res << 8;
-                pred[1] += val;
-                *samples++ = pred[1];
-            } else {
-                if(vlc[0].table)
-                    res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
-                else
-                    res = values[0];
-                val  = res;
-                if(vlc[1].table)
-                    res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);
-                else
-                    res = values[1];
-                val |= res << 8;
-                pred[0] += val;
-                *samples++ = pred[0];
-            }
+            if (vlc[idx].table)
+                res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
+            else
+                res = values[idx];
+            val  = res;
+            if (vlc[++idx].table)
+                res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
+            else
+                res = values[idx];
+            val |= res << 8;
+            pred[idx / 2] += val;
+            *samples++ = pred[idx / 2];
         }
     } else { //8-bit data
         for(i = stereo; i >= 0; i--)
@@ -709,25 +695,17 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
         for(i = 0; i <= stereo; i++)
             *samples8++ = pred[i];
         for(; i < unp_size; i++) {
+            unsigned idx = i & stereo;
             if (get_bits_left(&gb) < 0) {
                 ret = AVERROR_INVALIDDATA;
                 goto error;
             }
-            if(i & stereo){
-                if(vlc[1].table)
-                    res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);
-                else
-                    res = values[1];
-                pred[1] += res;
-                *samples8++ = pred[1];
-            } else {
-                if(vlc[0].table)
-                    res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
-                else
-                    res = values[0];
-                pred[0] += res;
-                *samples8++ = pred[0];
-            }
+            if (vlc[idx].table)
+                val = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
+            else
+                val = values[idx];
+            pred[idx] += val;
+            *samples8++ = pred[idx];
         }
     }
 
@@ -742,7 +720,7 @@ error:
     return ret;
 }
 
-AVCodec ff_smacker_decoder = {
+const AVCodec ff_smacker_decoder = {
     .name           = "smackvid",
     .long_name      = NULL_IF_CONFIG_SMALL("Smacker video"),
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -752,10 +730,10 @@ AVCodec ff_smacker_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1,
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
 
-AVCodec ff_smackaud_decoder = {
+const AVCodec ff_smackaud_decoder = {
     .name           = "smackaud",
     .long_name      = NULL_IF_CONFIG_SMALL("Smacker audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -763,4 +741,5 @@ AVCodec ff_smackaud_decoder = {
     .init           = smka_decode_init,
     .decode         = smka_decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };