summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-08-22 03:57:45 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-08-22 16:52:07 +0200
commit3f943fe6815b493741ff65f6c25ca856c38cdafc (patch)
tree9ba7524625f8a7e4421ee47da9fac192a552a381 /libavcodec
parent4fced11df73fb1921f60660b5b0f319bb4e723ec (diff)
huffman/huffyuv: move lorens huffman table generation code to huffman.c/h
Reviewed-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/huffman.c58
-rw-r--r--libavcodec/huffman.h2
-rw-r--r--libavcodec/huffyuv.c64
3 files changed, 63 insertions, 61 deletions
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c
index cd1d0d754e..8b336dc7ff 100644
--- a/libavcodec/huffman.c
+++ b/libavcodec/huffman.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2006 Konstantin Shishkov
+ * Copyright (c) 2007 Loren Merritt
*
* This file is part of FFmpeg.
*
@@ -111,3 +112,60 @@ int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes,
}
return 0;
}
+
+typedef struct {
+ uint64_t val;
+ int name;
+} HeapElem;
+
+static void heap_sift(HeapElem *h, int root, int size)
+{
+ while(root*2+1 < size) {
+ int child = root*2+1;
+ if(child < size-1 && h[child].val > h[child+1].val)
+ child++;
+ if(h[root].val > h[child].val) {
+ FFSWAP(HeapElem, h[root], h[child]);
+ root = child;
+ } else
+ break;
+ }
+}
+
+void ff_generate_len_table(uint8_t *dst, const uint64_t *stats){
+ HeapElem h[256];
+ int up[2*256];
+ int len[2*256];
+ int offset, i, next;
+ int size = 256;
+
+ for(offset=1; ; offset<<=1){
+ for(i=0; i<size; i++){
+ h[i].name = i;
+ h[i].val = (stats[i] << 8) + offset;
+ }
+ for(i=size/2-1; i>=0; i--)
+ heap_sift(h, i, size);
+
+ for(next=size; next<size*2-1; next++){
+ // merge the two smallest entries, and put it back in the heap
+ uint64_t min1v = h[0].val;
+ up[h[0].name] = next;
+ h[0].val = INT64_MAX;
+ heap_sift(h, 0, size);
+ up[h[0].name] = next;
+ h[0].name = next;
+ h[0].val += min1v;
+ heap_sift(h, 0, size);
+ }
+
+ len[2*size-2] = 0;
+ 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;
+ }
+ if(i==size) break;
+ }
+}
diff --git a/libavcodec/huffman.h b/libavcodec/huffman.h
index 5e0787a5e8..956ac1fbce 100644
--- a/libavcodec/huffman.h
+++ b/libavcodec/huffman.h
@@ -42,4 +42,6 @@ typedef int (*HuffCmp)(const void *va, const void *vb);
int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes,
Node *nodes, HuffCmp cmp, int flags);
+void ff_generate_len_table(uint8_t *dst, const uint64_t *stats);
+
#endif /* AVCODEC_HUFFMAN_H */
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index da242a982b..0dc5c43a71 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -34,6 +34,7 @@
#include "put_bits.h"
#include "dsputil.h"
#include "thread.h"
+#include "huffman.h"
#define VLC_BITS 11
@@ -245,65 +246,6 @@ static int generate_bits_table(uint32_t *dst, const uint8_t *len_table){
return 0;
}
-#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
-typedef struct {
- uint64_t val;
- int name;
-} HeapElem;
-
-static void heap_sift(HeapElem *h, int root, int size)
-{
- while(root*2+1 < size) {
- int child = root*2+1;
- if(child < size-1 && h[child].val > h[child+1].val)
- child++;
- if(h[root].val > h[child].val) {
- FFSWAP(HeapElem, h[root], h[child]);
- root = child;
- } else
- break;
- }
-}
-
-static void generate_len_table(uint8_t *dst, const uint64_t *stats){
- HeapElem h[256];
- int up[2*256];
- int len[2*256];
- int offset, i, next;
- int size = 256;
-
- for(offset=1; ; offset<<=1){
- for(i=0; i<size; i++){
- h[i].name = i;
- h[i].val = (stats[i] << 8) + offset;
- }
- for(i=size/2-1; i>=0; i--)
- heap_sift(h, i, size);
-
- for(next=size; next<size*2-1; next++){
- // merge the two smallest entries, and put it back in the heap
- uint64_t min1v = h[0].val;
- up[h[0].name] = next;
- h[0].val = INT64_MAX;
- heap_sift(h, 0, size);
- up[h[0].name] = next;
- h[0].name = next;
- h[0].val += min1v;
- heap_sift(h, 0, size);
- }
-
- len[2*size-2] = 0;
- 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;
- }
- if(i==size) break;
- }
-}
-#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
-
static void generate_joint_tables(HYuvContext *s){
uint16_t symbols[1<<VLC_BITS];
uint16_t bits[1<<VLC_BITS];
@@ -704,7 +646,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
}
for(i=0; i<3; i++){
- generate_len_table(s->len[i], s->stats[i]);
+ ff_generate_len_table(s->len[i], s->stats[i]);
if(generate_bits_table(s->bits[i], s->len[i])<0){
return -1;
@@ -1290,7 +1232,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if(s->context){
for(i=0; i<3; i++){
- generate_len_table(s->len[i], s->stats[i]);
+ ff_generate_len_table(s->len[i], s->stats[i]);
if(generate_bits_table(s->bits[i], s->len[i])<0)
return -1;
size += store_table(s, s->len[i], &pkt->data[size]);