diff mbox series

[FFmpeg-devel,3/8] avcodec/vlc: Add macro for ff_init_vlc_sparse()

Message ID 20200731112241.8948-3-andreas.rheinhardt@gmail.com
State Accepted
Commit 61669b7c40b8dc3a0841768fb39c7567513b7cfc
Headers show
Series [FFmpeg-devel,1/8] avcodec/smacker: Remove write-only and unused variables
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Andreas Rheinhardt July 31, 2020, 11:22 a.m. UTC
ff_init_vlc_sparse() supports arrays of uint8_t, uint16_t and uint32_t
as input (and it also supports padding/other elements in between the
elements). This makes the typical case in which the input is a simple
array more cumbersome. E.g. for an array of uint8_t one would either
need to call the function with arguments like "array, sizeof(array[0]),
sizeof(array[0])" or with "array, 1, 1". The former is nicer, but
longer, so that the latter is mostly used. Therefore this commit adds a
macro that expands to the sizeof() construct.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/vlc.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Michael Niedermayer Aug. 1, 2020, 6:58 p.m. UTC | #1
On Fri, Jul 31, 2020 at 01:22:36PM +0200, Andreas Rheinhardt wrote:
> ff_init_vlc_sparse() supports arrays of uint8_t, uint16_t and uint32_t
> as input (and it also supports padding/other elements in between the
> elements). This makes the typical case in which the input is a simple
> array more cumbersome. E.g. for an array of uint8_t one would either
> need to call the function with arguments like "array, sizeof(array[0]),
> sizeof(array[0])" or with "array, 1, 1". The former is nicer, but
> longer, so that the latter is mostly used. Therefore this commit adds a
> macro that expands to the sizeof() construct.
> 
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> ---
>  libavcodec/vlc.h | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/libavcodec/vlc.h b/libavcodec/vlc.h
> index 42ccddf3fc..7cb323b62c 100644
> --- a/libavcodec/vlc.h
> +++ b/libavcodec/vlc.h
> @@ -35,7 +35,12 @@ typedef struct RL_VLC_ELEM {
>      uint8_t run;
>  } RL_VLC_ELEM;
>  
> -#define init_vlc(vlc, nb_bits, nb_codes,                \
> +#define INIT_VLC_DEFAULT_SIZES(ptr) \
> +    (ptr), sizeof((ptr)[0]), sizeof((ptr)[0])

LGTM, maybe add some documentation

thx

[...]
Andreas Rheinhardt Sept. 18, 2020, 5:36 a.m. UTC | #2
Andreas Rheinhardt:
> ff_init_vlc_sparse() supports arrays of uint8_t, uint16_t and uint32_t
> as input (and it also supports padding/other elements in between the
> elements). This makes the typical case in which the input is a simple
> array more cumbersome. E.g. for an array of uint8_t one would either
> need to call the function with arguments like "array, sizeof(array[0]),
> sizeof(array[0])" or with "array, 1, 1". The former is nicer, but
> longer, so that the latter is mostly used. Therefore this commit adds a
> macro that expands to the sizeof() construct.
> 
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> ---
>  libavcodec/vlc.h | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/libavcodec/vlc.h b/libavcodec/vlc.h
> index 42ccddf3fc..7cb323b62c 100644
> --- a/libavcodec/vlc.h
> +++ b/libavcodec/vlc.h
> @@ -35,7 +35,12 @@ typedef struct RL_VLC_ELEM {
>      uint8_t run;
>  } RL_VLC_ELEM;
>  
> -#define init_vlc(vlc, nb_bits, nb_codes,                \
> +#define INIT_VLC_DEFAULT_SIZES(ptr) \
> +    (ptr), sizeof((ptr)[0]), sizeof((ptr)[0])
> +
> +#define init_vlc(...) init_vlc2(__VA_ARGS__)
> +
> +#define init_vlc2(vlc, nb_bits, nb_codes,               \
>                   bits, bits_wrap, bits_size,            \
>                   codes, codes_wrap, codes_size,         \
>                   flags)                                 \
> 

This change apparently broke building with MSVC, see [1]. The reason is
that MSVC's behaviour wrt ',' included in the __VA_ARGS__ is
spec-incompliant: These ',' are not treated as argument separators for
further macros (in our case init_vlc2), so that MSVC thinks that the
init_vlc2() macro has only one argument. See [2] for a confirmation that
this is indeed a bug in MSVC; see [3] for a minimal code snippet. There
is a workaround for this by adding an additional intermediate macro as
in [4].
Yet I don't think that this is desirable (I was actually unsure whether
this patch is worth it (after all "INIT_VLC_DEFAULT_SIZES" is quite long
in itself)) and there is the problem that it might not fix everything:
[2] indicates that until recently clang did not support said workaround
when in ms-compatibility mode (admittedly, I don't know whether there is
any reason at all to use clang in ms-compatibility mode to compile
FFmpeg, but whatever...). So my suggestion is to basically revert said
commit; adapting the smacker decoder (its only user) is trivial of
course. I will send a patch that implements this soon.

(Btw: How about macros like this:
#define INIT_VLC(vlc, nb_bits, nb_codes, bits, codes, flags)  \
    ff_init_vlc_sparse(vlc, nb_bits, nb_codes,                \
                       bits, sizeof(*bits), sizeof(*bits),    \
                       codes, sizeof(*codes), sizeof(*codes), \
                       NULL, 0, 0, flags)
and a similar one with symbols?)

- Andreas

[1]:
http://fate.ffmpeg.org/log.cgi?log=compile&time=20200918012551&slot=x86_64-msvc16-windows-native
[2]: https://reviews.llvm.org/D69626
[3]: https://godbolt.org/z/eTE3Gh
[4]: https://godbolt.org/z/obrz4h
diff mbox series

Patch

diff --git a/libavcodec/vlc.h b/libavcodec/vlc.h
index 42ccddf3fc..7cb323b62c 100644
--- a/libavcodec/vlc.h
+++ b/libavcodec/vlc.h
@@ -35,7 +35,12 @@  typedef struct RL_VLC_ELEM {
     uint8_t run;
 } RL_VLC_ELEM;
 
-#define init_vlc(vlc, nb_bits, nb_codes,                \
+#define INIT_VLC_DEFAULT_SIZES(ptr) \
+    (ptr), sizeof((ptr)[0]), sizeof((ptr)[0])
+
+#define init_vlc(...) init_vlc2(__VA_ARGS__)
+
+#define init_vlc2(vlc, nb_bits, nb_codes,               \
                  bits, bits_wrap, bits_size,            \
                  codes, codes_wrap, codes_size,         \
                  flags)                                 \