]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/bitstream.c
fftools/ffmpeg: make specifying thread_queue_size turn on threaded input
[ffmpeg] / libavcodec / bitstream.c
index ed528fe4af7d1d75eafe537467fd3ee881bc3796..d379dbc0e8c041ca490b8ecfbf53956e072d00a2 100644 (file)
@@ -162,9 +162,9 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
     uint32_t code;
     volatile VLC_TYPE (* volatile table)[2]; // the double volatile is needed to prevent an internal compiler error in gcc 4.2
 
-    table_size = 1 << table_nb_bits;
     if (table_nb_bits > 30)
-       return -1;
+       return AVERROR(EINVAL);
+    table_size = 1 << table_nb_bits;
     table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
     ff_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
     if (table_index < 0)
@@ -188,8 +188,9 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
             }
             for (k = 0; k < nb; k++) {
                 int bits = table[j][1];
+                int oldsym  = table[j][0];
                 ff_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
-                if (bits != 0 && bits != n) {
+                if ((bits || oldsym) && (bits != n || oldsym != symbol)) {
                     av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
                     return AVERROR_INVALIDDATA;
                 }
@@ -226,6 +227,10 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
             /* note: realloc has been done, so reload tables */
             table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
             table[j][0] = index; //code
+            if (table[j][0] != index) {
+                avpriv_request_sample(NULL, "strange codes");
+                return AVERROR_PATCHWELCOME;
+            }
             i = k-1;
         }
     }
@@ -280,7 +285,6 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
     vlc->bits = nb_bits;
     if (flags & INIT_VLC_USE_NEW_STATIC) {
         av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
-        buf = localbuf;
         localvlc = *vlc_arg;
         vlc = &localvlc;
         vlc->table_size = 0;
@@ -288,11 +292,13 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
         vlc->table           = NULL;
         vlc->table_allocated = 0;
         vlc->table_size      = 0;
-
+    }
+    if (nb_codes + 1 > FF_ARRAY_ELEMS(localbuf)) {
         buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode));
         if (!buf)
             return AVERROR(ENOMEM);
-    }
+    } else
+        buf = localbuf;
 
 
     av_assert0(symbols_size <= 2 || !symbols);
@@ -304,17 +310,17 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
             continue;                                                       \
         if (buf[j].bits > 3*nb_bits || buf[j].bits>32) {                    \
             av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\
-            if (!(flags & INIT_VLC_USE_NEW_STATIC))                         \
+            if (buf != localbuf)                                            \
                 av_free(buf);                                               \
-            return -1;                                                      \
+            return AVERROR(EINVAL);                                         \
         }                                                                   \
         GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);            \
         if (buf[j].code >= (1LL<<buf[j].bits)) {                            \
             av_log(NULL, AV_LOG_ERROR, "Invalid code %"PRIx32" for %d in "  \
                    "init_vlc\n", buf[j].code, i);                           \
-            if (!(flags & INIT_VLC_USE_NEW_STATIC))                         \
+            if (buf != localbuf)                                            \
                 av_free(buf);                                               \
-            return -1;                                                      \
+            return AVERROR(EINVAL);                                         \
         }                                                                   \
         if (flags & INIT_VLC_LE)                                            \
             buf[j].code = bitswap_32(buf[j].code);                          \
@@ -341,7 +347,8 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
         av_assert0(ret >= 0);
         *vlc_arg = *vlc;
     } else {
-        av_free(buf);
+        if (buf != localbuf)
+            av_free(buf);
         if (ret < 0) {
             av_freep(&vlc->table);
             return ret;