[2/7] huffman/huffyuv: Move huffman length gen to common huffman.c/h

Message ID 1345934081-10636-2-git-send-email-jeebjp@gmail.com
State New
Headers show

Commit Message

Jan Ekström Aug. 25, 2012, 10:34 p.m.
From: Michael Niedermayer <michaelni@gmx.at>

Loren had already created an optimized algorithm, and it is
now also needed by Ut Video. This enables its usage generally.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
---
 configure            |    2 +
 libavcodec/Makefile  |    4 +-
 libavcodec/huffman.c |   58 +++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/huffman.h |    2 +
 libavcodec/huffyuv.c |   64 ++-----------------------------------------------
 5 files changed, 67 insertions(+), 63 deletions(-)

Comments

Diego Biurrun Aug. 25, 2012, 11:17 p.m. | #1
On Sun, Aug 26, 2012 at 01:34:36AM +0300, Jan Ekström wrote:
> 
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -160,7 +160,7 @@ OBJS-$(CONFIG_ESCAPE124_DECODER)       += escape124.o
>  OBJS-$(CONFIG_FFVHUFF_DECODER)         += huffyuv.o
> -OBJS-$(CONFIG_FFVHUFF_ENCODER)         += huffyuv.o
> +OBJS-$(CONFIG_FFVHUFF_ENCODER)         += huffyuv.o huffman.o
>  OBJS-$(CONFIG_FLAC_DECODER)            += flacdec.o flacdata.o flac.o flacdsp.o
> @@ -192,7 +192,7 @@ OBJS-$(CONFIG_H264_DXVA2_HWACCEL)      += dxva2_h264.o
>  OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o
> -OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o
> +OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o huffman.o
>  OBJS-$(CONFIG_IAC_DECODER)             += imc.o

wrong

Diego
Luca Barbato Aug. 25, 2012, 11:36 p.m. | #2
On 8/26/12 12:34 AM, Jan Ekström wrote:
> --- a/libavcodec/huffman.c
> +++ b/libavcodec/huffman.c
> @@ -1,5 +1,6 @@
>   /*
>    * Copyright (c) 2006 Konstantin Shishkov
> + * Copyright (c) 2007 Loren Merritt

2007? Where is this code come from?
Derek Buitenhuis Aug. 25, 2012, 11:48 p.m. | #3
On 25/08/2012 7:17 PM, Diego Biurrun wrote:
> wrong

You could be a little more helpful.

- Derek
Derek Buitenhuis Aug. 25, 2012, 11:52 p.m. | #4
On 25/08/2012 7:36 PM, Luca Barbato wrote:
> 2007? Where is this code come from?

98ef8c324cbab46521fc08fc0483de91e156093e

$ git blame libavcodec/huffyuv.c

- Derek
Kostya Shishkov Aug. 26, 2012, 6:03 a.m. | #5
On Sat, Aug 25, 2012 at 07:48:58PM -0400, Derek Buitenhuis wrote:
> On 25/08/2012 7:17 PM, Diego Biurrun wrote:
> > wrong
> 
> You could be a little more helpful.

Probably that stands for "since you have a dependency on it in configure,
there's no need to add object file explicitly".
Diego Biurrun Aug. 26, 2012, 6:47 a.m. | #6
On Sat, Aug 25, 2012 at 07:48:58PM -0400, Derek Buitenhuis wrote:
> On 25/08/2012 7:17 PM, Diego Biurrun wrote:
> > wrong
> 
> You could be a little more helpful.

The change on the lines I quoted, the addition of huffman.o, was wrong.
There is no need for that change.

Diego
Derek Buitenhuis Aug. 26, 2012, 5:22 p.m. | #7
On 26/08/2012 2:47 AM, Diego Biurrun wrote:
> The change on the lines I quoted, the addition of huffman.o, was wrong.
> There is no need for that change.

I gathered that.. it's the "why" that was missing. Kostya seems to have
cleared that up, in any case.

- Derek

Patch

diff --git a/configure b/configure
index 12052c0..78857da 100755
--- a/configure
+++ b/configure
@@ -1364,6 +1364,7 @@  eatgq_decoder_select="aandcttables"
 eatqi_decoder_select="aandcttables error_resilience mpegvideo"
 ffv1_decoder_select="golomb rangecoder"
 ffv1_encoder_select="rangecoder"
+ffvhuff_encoder_select="huffman"
 flac_decoder_select="golomb"
 flac_encoder_select="golomb lpc"
 flashsv_decoder_select="zlib"
@@ -1385,6 +1386,7 @@  h264_dxva2_hwaccel_select="dxva2 h264_decoder"
 h264_vaapi_hwaccel_select="vaapi h264_decoder"
 h264_vda_hwaccel_select="vda h264_decoder"
 h264_vdpau_decoder_select="vdpau h264_decoder"
+huffyuv_encoder_select="huffman"
 iac_decoder_select="fft mdct sinewin"
 imc_decoder_select="fft mdct sinewin"
 jpegls_decoder_select="golomb"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 5219a00..a5cbe88 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -160,7 +160,7 @@  OBJS-$(CONFIG_ESCAPE124_DECODER)       += escape124.o
 OBJS-$(CONFIG_FFV1_DECODER)            += ffv1.o
 OBJS-$(CONFIG_FFV1_ENCODER)            += ffv1.o
 OBJS-$(CONFIG_FFVHUFF_DECODER)         += huffyuv.o
-OBJS-$(CONFIG_FFVHUFF_ENCODER)         += huffyuv.o
+OBJS-$(CONFIG_FFVHUFF_ENCODER)         += huffyuv.o huffman.o
 OBJS-$(CONFIG_FLAC_DECODER)            += flacdec.o flacdata.o flac.o flacdsp.o
 OBJS-$(CONFIG_FLAC_ENCODER)            += flacenc.o flacdata.o flac.o
 OBJS-$(CONFIG_FLASHSV_DECODER)         += flashsv.o
@@ -192,7 +192,7 @@  OBJS-$(CONFIG_H264_DXVA2_HWACCEL)      += dxva2_h264.o
 OBJS-$(CONFIG_H264_VAAPI_HWACCEL)      += vaapi_h264.o
 OBJS-$(CONFIG_H264_VDA_HWACCEL)        += vda_h264.o
 OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o
-OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o
+OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o huffman.o
 OBJS-$(CONFIG_IAC_DECODER)             += imc.o
 OBJS-$(CONFIG_IDCIN_DECODER)           += idcinvideo.o
 OBJS-$(CONFIG_IFF_BYTERUN1_DECODER)    += iff.o
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c
index 9446332..f33679a 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 Libav.
  *
@@ -110,3 +111,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 5625313..0ddfb73 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 8e428ac..a29a1a2 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -33,6 +33,7 @@ 
 #include "put_bits.h"
 #include "dsputil.h"
 #include "thread.h"
+#include "huffman.h"
 
 #define VLC_BITS 11
 
@@ -214,65 +215,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];
@@ -667,7 +609,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;
@@ -1253,7 +1195,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]);