X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmagicyuvenc.c;h=7edaf1b45ef308ee85d73a82415f9d807b856b3b;hb=a247ac640df3da573cd661065bf53f37863e2b46;hp=16e9a1c28d4cc867a853e6e70164725e6ef48265;hpb=762c2b5dcd99a08452299cd1f83070f88115f1f3;p=ffmpeg diff --git a/libavcodec/magicyuvenc.c b/libavcodec/magicyuvenc.c index 16e9a1c28d4..7edaf1b45ef 100644 --- a/libavcodec/magicyuvenc.c +++ b/libavcodec/magicyuvenc.c @@ -40,7 +40,6 @@ typedef enum Prediction { } Prediction; typedef struct HuffEntry { - uint8_t sym; uint8_t len; uint32_t code; } HuffEntry; @@ -245,32 +244,18 @@ static av_cold int magy_encode_init(AVCodecContext *avctx) 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; - return (aa->len - bb->len) * 256 + aa->sym - bb->sym; -} - -static int huff_cmp_sym(const void *a, const void *b) -{ - const HuffEntry *aa = a, *bb = b; - 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); + for (unsigned i = 32, nb_codes = 0; i > 0; i--) { + 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 } - AV_QSORT(he, 256, HuffEntry, huff_cmp_sym); + for (unsigned i = 0; i < 256; i++) { + he[i].code = codes_count[he[i].len]; + codes_count[he[i].len]++; + } } static void count_usage(uint8_t *src, int width, @@ -295,12 +280,13 @@ typedef struct PackageMergerList { static int compare_by_prob(const void *a, const void *b) { - PTable a_val = *(PTable *)a; - PTable b_val = *(PTable *)b; - return a_val.prob - b_val.prob; + const PTable *a2 = a; + const PTable *b2 = b; + return a2->prob - b2->prob; } static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts, + uint16_t codes_counts[33], int size, int max_length) { 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++) { - distincts[i].sym = 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) { PTable counts[256] = { {0} }; + uint16_t codes_counts[33] = { 0 }; int i; count_usage(dst, width, height, counts); for (i = 0; i < 256; i++) { 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++) { put_bits(pb, 1, 0); @@ -413,11 +400,9 @@ static int encode_slice(uint8_t *src, uint8_t *dst, int dst_size, if (count) put_bits(&pb, 32 - count, 0); - count = put_bits_count(&pb); - flush_put_bits(&pb); - return count >> 3; + return put_bytes_output(&pb); } static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt, @@ -512,7 +497,7 @@ static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt, AV_CEIL_RSHIFT(frame->height, s->vshift[i]), &s->pb, s->he[i]); } - s->tables_size = (put_bits_count(&s->pb) + 7) >> 3; + s->tables_size = put_bytes_count(&s->pb, 1); bytestream2_skip_p(&pb, s->tables_size); for (i = 0; i < s->planes; i++) { @@ -571,7 +556,7 @@ static const AVClass magicyuv_class = { .version = LIBAVUTIL_VERSION_INT, }; -AVCodec ff_magicyuv_encoder = { +const AVCodec ff_magicyuv_encoder = { .name = "magicyuv", .long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"), .type = AVMEDIA_TYPE_VIDEO, @@ -581,10 +566,11 @@ AVCodec ff_magicyuv_encoder = { .init = magy_encode_init, .close = magy_encode_close, .encode2 = magy_encode_frame, - .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY, + .capabilities = AV_CODEC_CAP_FRAME_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, };