aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/magicyuv.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-11-08 05:15:56 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-12-08 17:51:47 +0100
commitc638d1d126fa1462bdcd30883061be9dd6f29dcd (patch)
treed6f53d4b61094856b0a5768b8e7bc229b34b86f1 /libavcodec/magicyuv.c
parent5d503c91f306585c3cd2188c239cfe247dd9a33e (diff)
downloadffmpeg-c638d1d126fa1462bdcd30883061be9dd6f29dcd.tar.gz
avcodec/utvideodec: Avoid implicit qsort when creating Huffman tables
The Huffman trees used by Ut Video have two important characteristics: (i) Longer codes are on the left of the tree and (ii) for codes of the same length, the symbol is descending from left to right in the tree. Therefore all the information that needs to be transmitted is how long the code corresponding to a given symbol is; and this is also all that is transmitted. Before 341914495e5c2f60bc920b0c6f660e5948a47f5a, the decoder used qsort to sort the (length, symbol) pairs by ascending length and for equal lengths by ascending symbol. Since said commit, the decoder uses a first pass over the lengths table to count how many symbols of each length there are; with (i) one can then easily calculate the code of the left-most code with a given length in the tree and from there one can calculate the codes for all entries, using one running counter for each possible length. This eliminated the explicit qsort in build_huff(). Yet ff_init_vlc_sparse() sorts the table itself as it has to ensure that all the entries that will be placed in the same subtable are contiguous. The tables created now are non-contiguous (they are ordered by symbol and codes of different length aren't ordered at all; only codes of the same length are ordered according to (ii)). This commit therefore modifies the algorithm used to automatically create tables whose codes are sorted from left to right in the tree. The key to do so is the observation that the counts obtained in the first pass can be used to contain the range of the codes of each length in the second pass: If counts[i] is the count of codes with length i, then the first counts[32] codes are of length 32, the next counts[31] codes are of length 31 etc. So one knows the index of the lowest symbol whose code has length 32 (if any): It is counts[32] - 1 due to (ii), whereas the index of the lowest symbol whose code has length 31 (if any) is counts[32] + counts[31] - 1; the index of the second-to-lowest symbol of length 32 (if existing) is counts[32] - 2 etc. If one follows the algorithm outlined above, one can switch to ff_init_vlc_from_lengths() which has no implicit qsort; it also means that one can offload the computation of the codes. This turned out to be beneficial for performance: For the sample from ticket #4044 it decreased the decicycles spent on one call to build_huff() from 508480 to 340688 (GCC 9.3, looping 10 times over the file to get enough runs and then repeating this ten times); for another sample (YUV420p, natural content, 5500 frames, also ten iterations) the time went down from 382346 to 275533 decicycles. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavcodec/magicyuv.c')
0 files changed, 0 insertions, 0 deletions