[FFmpeg-devel] [PATCH 1/2] avcodec/rv34: Don't needlessly copy VLC length and symbol arrays
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Sun Oct 25 11:30:41 EET 2020
Andreas Rheinhardt:
> Most of the VLCs used by RealVideo 3 and 4 obey three simple rules:
> Shorter codes are on the left of the tree, for each length, the symbols
> are ascending from left to right and the symbols either form a
> permutation of 1..size or 0..(size - 1). For the latter case, one just
> needs to store the length of each symbol and create the codes according
> to the other rules; no explicit code or symbol array must be stored.
> The former case is also treated in much the same way by artificially
> assigning a length of zero to the symbol 0; when a length of zero was
> encountered, the element was ignored except that the symbol counter was
> still incremented. If the length was nonzero, the symbol would be
> assigned via the symbol counter and the length copied over into a new
> array.
>
> Yet this is unnecessary, as ff_init_vlc_sparse() follows exactly the
> same pattern: If a length of zero is encountered, the element is ignored
> and only the symbol counter incremented. So one can directly forward the
> length array and also need not create a symbol table oneself, because
> ff_init_vlc_sparse() will infer the same symbol table in this case.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
> libavcodec/rv34.c | 40 ++++++++++++++++++----------------------
> 1 file changed, 18 insertions(+), 22 deletions(-)
>
> diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
> index ec0cd27916..d251c6817c 100644
> --- a/libavcodec/rv34.c
> +++ b/libavcodec/rv34.c
> @@ -106,37 +106,33 @@ static VLC_TYPE table_data[117592][2];
> * @param insyms symbols for input codes (NULL for default ones)
> * @param num VLC table number (for static initialization)
> */
> -static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms,
> +static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *syms,
> const int num)
> {
> - int i;
> int counts[17] = {0}, codes[17];
> - uint16_t cw[MAX_VLC_SIZE], syms[MAX_VLC_SIZE];
> - uint8_t bits2[MAX_VLC_SIZE];
> - int maxbits = 0, realsize = 0;
> -
> - for(i = 0; i < size; i++){
> - if(bits[i]){
> - bits2[realsize] = bits[i];
> - syms[realsize] = insyms ? insyms[i] : i;
> - realsize++;
> - maxbits = FFMAX(maxbits, bits[i]);
> - counts[bits[i]]++;
> - }
> - }
> + uint16_t cw[MAX_VLC_SIZE];
> + int maxbits;
>
> - codes[0] = 0;
> - for(i = 0; i < 16; i++)
> + for (int i = 0; i < size; i++)
> + counts[bits[i]]++;
> +
> + /* bits[0] is zero for some tables, i.e. syms actually starts at 1.
> + * So we reset it here. The code assigned to this element is 0x00. */
> + codes[0] = counts[0] = 0;
> + for (int i = 0; i < 16; i++) {
> codes[i+1] = (codes[i] + counts[i]) << 1;
> - for(i = 0; i < realsize; i++)
> - cw[i] = codes[bits2[i]]++;
> + if (counts[i])
> + maxbits = i;
> + }
> + for (int i = 0; i < size; i++)
> + cw[i] = codes[bits[i]]++;
>
> vlc->table = &table_data[table_offs[num]];
> vlc->table_allocated = table_offs[num + 1] - table_offs[num];
> - ff_init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize,
> - bits2, 1, 1,
> + ff_init_vlc_sparse(vlc, FFMIN(maxbits, 9), size,
> + bits, 1, 1,
> cw, 2, 2,
> - syms, 2, 2, INIT_VLC_USE_NEW_STATIC);
> + syms, !!syms, !!syms, INIT_VLC_USE_NEW_STATIC);
> }
>
> /**
>
Will apply this patchset tomorrow unless there are objections.
- Andreas
More information about the ffmpeg-devel
mailing list