Browse Source

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>
tags/n1.0
Michael Niedermayer 12 years ago
parent
commit
3f943fe681
4 changed files with 64 additions and 61 deletions
  1. +1
    -0
      configure
  2. +58
    -0
      libavcodec/huffman.c
  3. +2
    -0
      libavcodec/huffman.h
  4. +3
    -61
      libavcodec/huffyuv.c

+ 1
- 0
configure View File

@@ -1557,6 +1557,7 @@ h264_vaapi_hwaccel_select="vaapi h264_decoder"
h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
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"


+ 58
- 0
libavcodec/huffman.c View File

@@ -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;
}
}

+ 2
- 0
libavcodec/huffman.h View File

@@ -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 */

+ 3
- 61
libavcodec/huffyuv.c View File

@@ -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]);


Loading…
Cancel
Save