You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
avcodec/magicyuvenc: Avoid sorting Huffman table unnecessarily
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
@@ -40,7 +40,6 @@ typedef enum Prediction {
|
|||||||
} Prediction;
|
} Prediction;
|
||||||
|
|
||||||
typedef struct HuffEntry {
|
typedef struct HuffEntry {
|
||||||
uint8_t sym;
|
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
uint32_t code;
|
uint32_t code;
|
||||||
} HuffEntry;
|
} HuffEntry;
|
||||||
@@ -245,32 +244,18 @@ static av_cold int magy_encode_init(AVCodecContext *avctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int magy_huff_cmp_len(const void *a, const void *b)
|
static void calculate_codes(HuffEntry *he, uint16_t codes_count[33])
|
||||||
{
|
{
|
||||||
const HuffEntry *aa = a, *bb = b;
|
for (unsigned i = 32, nb_codes = 0; i > 0; i--) {
|
||||||
return (aa->len - bb->len) * 256 + aa->sym - bb->sym;
|
uint16_t curr = codes_count[i]; // # of leafs of length i
|
||||||
|
codes_count[i] = nb_codes / 2; // # of non-leaf nodes on level i
|
||||||
|
nb_codes = codes_count[i] + curr; // # of nodes on level i
|
||||||
}
|
}
|
||||||
|
|
||||||
static int huff_cmp_sym(const void *a, const void *b)
|
for (unsigned i = 0; i < 256; i++) {
|
||||||
{
|
he[i].code = codes_count[he[i].len];
|
||||||
const HuffEntry *aa = a, *bb = b;
|
codes_count[he[i].len]++;
|
||||||
return bb->sym - aa->sym;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calculate_codes(HuffEntry *he)
|
|
||||||
{
|
|
||||||
uint32_t code;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
AV_QSORT(he, 256, HuffEntry, magy_huff_cmp_len);
|
|
||||||
|
|
||||||
code = 1;
|
|
||||||
for (i = 255; i >= 0; i--) {
|
|
||||||
he[i].code = code >> (32 - he[i].len);
|
|
||||||
code += 0x80000000u >> (he[i].len - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
AV_QSORT(he, 256, HuffEntry, huff_cmp_sym);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void count_usage(uint8_t *src, int width,
|
static void count_usage(uint8_t *src, int width,
|
||||||
@@ -301,6 +286,7 @@ static int compare_by_prob(const void *a, const void *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts,
|
static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts,
|
||||||
|
uint16_t codes_counts[33],
|
||||||
int size, int max_length)
|
int size, int max_length)
|
||||||
{
|
{
|
||||||
PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp;
|
PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp;
|
||||||
@@ -356,8 +342,8 @@ static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
distincts[i].sym = i;
|
|
||||||
distincts[i].len = nbits[i];
|
distincts[i].len = nbits[i];
|
||||||
|
codes_counts[nbits[i]]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,18 +352,19 @@ static int encode_table(AVCodecContext *avctx, uint8_t *dst,
|
|||||||
PutBitContext *pb, HuffEntry *he)
|
PutBitContext *pb, HuffEntry *he)
|
||||||
{
|
{
|
||||||
PTable counts[256] = { {0} };
|
PTable counts[256] = { {0} };
|
||||||
|
uint16_t codes_counts[33] = { 0 };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
count_usage(dst, width, height, counts);
|
count_usage(dst, width, height, counts);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
counts[i].prob++;
|
counts[i].prob++;
|
||||||
counts[i].value = 255 - i;
|
counts[i].value = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
magy_huffman_compute_bits(counts, he, 256, 12);
|
magy_huffman_compute_bits(counts, he, codes_counts, 256, 12);
|
||||||
|
|
||||||
calculate_codes(he);
|
calculate_codes(he, codes_counts);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
put_bits(pb, 1, 0);
|
put_bits(pb, 1, 0);
|
||||||
|
Reference in New Issue
Block a user