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