diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-06-09 14:49:35 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-06-09 14:56:00 +0200 |
commit | 334aafe5650007dab180f12a49081ad1561f0e08 (patch) | |
tree | 0582dc291e66c2f2e03e5b6c18b03f926f0fb0db /libavcodec/huffman.c | |
parent | 673716c54b39eba9579a38ad222130e3f9549167 (diff) | |
download | ffmpeg-334aafe5650007dab180f12a49081ad1561f0e08.tar.gz |
avcodec/huffman/ff_huff_gen_len_table: support skiping stat=0 entries
This is probably not the simplest solution but as this is needed for a bugfix,
simplification is left for later.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/huffman.c')
-rw-r--r-- | libavcodec/huffman.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c index 0fc2055dbe..2866eef310 100644 --- a/libavcodec/huffman.c +++ b/libavcodec/huffman.c @@ -52,12 +52,14 @@ static void heap_sift(HeapElem *h, int root, int size) } } -int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int size) +int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int stats_size, int skip0) { - HeapElem *h = av_malloc_array(sizeof(*h), size); - int *up = av_malloc_array(sizeof(*up) * 2, size); - uint8_t *len = av_malloc_array(sizeof(*len) * 2, size); + HeapElem *h = av_malloc_array(sizeof(*h), stats_size); + int *up = av_malloc_array(sizeof(*up) * 2, stats_size); + uint8_t *len = av_malloc_array(sizeof(*len) * 2, stats_size); + uint16_t *map= av_malloc_array(sizeof(*map), stats_size); int offset, i, next; + int size = 0; int ret = 0; if (!h || !up || !len) { @@ -65,10 +67,16 @@ int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int size) goto end; } + for (i = 0; i<stats_size; i++) { + dst[i] = 255; + if (stats[i] || !skip0) + map[size++] = i; + } + for (offset = 1; ; offset <<= 1) { for (i=0; i < size; i++) { h[i].name = i; - h[i].val = (stats[i] << 14) + offset; + h[i].val = (stats[map[i]] << 14) + offset; } for (i = size / 2 - 1; i >= 0; i--) heap_sift(h, i, size); @@ -89,8 +97,8 @@ int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int size) for (i = 2 * size - 3; i >= size; i--) len[i] = len[up[i]] + 1; for (i = 0; i < size; i++) { - dst[i] = len[up[i]] + 1; - if (dst[i] >= 32) break; + dst[map[i]] = len[up[i]] + 1; + if (dst[map[i]] >= 32) break; } if (i==size) break; } @@ -98,6 +106,7 @@ end: av_free(h); av_free(up); av_free(len); + av_free(map); return ret; } |