diff mbox series

[FFmpeg-devel,v2,004/162] avcodec/bitstream: Allow static VLC tables to be bigger than needed

Message ID 20201120072116.818090-5-andreas.rheinhardt@gmail.com
State Accepted
Commit b629deab3d42e6db5216d6c6ee054d2d70a4071e
Headers show
Series VLC, esp. init_vlc patches
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished

Commit Message

Andreas Rheinhardt Nov. 20, 2020, 7:18 a.m. UTC
Right now the allocated size of the VLC table of a static VLC has to
exactly match the size actually used for the VLC: If it is not enough,
abort is called; if it is more than enough, an error message is
emitted. This is no problem when one wants to initialize an individual
VLC via one of the INIT_VLC macros as one just hardcodes the needed
size. Yet it is an obstacle when one wants to initialize several VLCs
in a loop as one then needs to add an array for the sizes/offsets of
the VLC tables (unless max_depth of all arrays is one in which case
the sizes are derivable from the number of bits used).

Yet said size array is not necessary if one disables the warning for too
big buffers. The reason is that the amount of entries needed for the
table is of course generated as a byproduct of initializing the VLC.
To this end a flag that disables the warning has been added.
So one can proceed as follows:

static VLC vlcs[NUM];
static VLC_TYPE vlc_table[BUF_SIZE][2];

for (int i = 0, offset = 0; i < NUM; i++) {
    vlcs[i].table           = &vlc_table[offset];
    vlcs[i].table_allocated = BUF_SIZE - offset;
    init_vlc(); /* With INIT_VLC_STATIC_OVERLONG flag */
    offset += vlcs[i].table_size;
}

Of course, BUF_SIZE should be equal to the number of entries actually
needed.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
Default behaviour is unchanged as Paul wished. The reason I opted for
the flag (and not AV_LOG_DEBUG) is that initialization of all
static VLCs should be done via ff_thread_once() in the future (this
patchset already does this for several of them), so that no logcontext
will be available anyway. And therefore it should be completely quiet
in normal mode.

 libavcodec/bitstream.c | 4 ++--
 libavcodec/vlc.h       | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index 4ce49fd51c..7570fb2204 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -281,9 +281,9 @@  static int vlc_common_end(VLC *vlc, int nb_bits, int nb_codes, VLCcode *codes,
     int ret = build_table(vlc, nb_bits, nb_codes, codes, flags);
 
     if (flags & INIT_VLC_USE_NEW_STATIC) {
-        if(vlc->table_size != vlc->table_allocated)
+        if (vlc->table_size != vlc->table_allocated &&
+            !(flags & (INIT_VLC_STATIC_OVERLONG & ~INIT_VLC_USE_NEW_STATIC)))
             av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
-
         av_assert0(ret >= 0);
         *vlc_arg = *vlc;
     } else {
diff --git a/libavcodec/vlc.h b/libavcodec/vlc.h
index 50a1834b84..6879c3ca6a 100644
--- a/libavcodec/vlc.h
+++ b/libavcodec/vlc.h
@@ -93,6 +93,7 @@  void ff_free_vlc(VLC *vlc);
 #define INIT_VLC_OUTPUT_LE      8
 #define INIT_VLC_LE             (INIT_VLC_INPUT_LE | INIT_VLC_OUTPUT_LE)
 #define INIT_VLC_USE_NEW_STATIC 4
+#define INIT_VLC_STATIC_OVERLONG (1 | INIT_VLC_USE_NEW_STATIC)
 
 #define INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g,      \
                                       h, i, j, flags, static_size)         \