From 164f66b68cd8fae67a0f16bfd57f6e13b58dc21e Mon Sep 17 00:00:00 2001
From: Martin Vignali <martin.vignali@gmail.com>
Date: Sat, 23 Feb 2019 17:29:39 +0100
Subject: [PATCH 1/4] avcodec/proresenc_aw : use lut for codebook to
 switchbits, riceorder, exp order, first_exp

Improve speed encoding

Basic test (prores to prores422HQ)

test1 : 137fps -> 140fps
test2 : 49fps-> 54 fps
---
 libavcodec/proresenc_anatoliy.c | 131 ++++++++++++++++++++++++++------
 1 file changed, 109 insertions(+), 22 deletions(-)

diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c
index e287d176ad..5410bb6d76 100644
--- a/libavcodec/proresenc_anatoliy.c
+++ b/libavcodec/proresenc_anatoliy.c
@@ -195,16 +195,105 @@ typedef struct {
     char *vendor;
 } ProresContext;
 
-static void encode_codeword(PutBitContext *pb, int val, int codebook)
-{
-    unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
+#define CB_TO_SWITCH_BITS(codebook) (codebook & 3)
+#define CB_TO_RICE_ORDER(codebook) (codebook >> 5)
+#define CB_TO_EXP_ORDER(codebook) ((codebook >> 2) & 7)
+#define CB_TO_FIRST_EXP(codebook) ((CB_TO_SWITCH_BITS(codebook) + 1) << CB_TO_RICE_ORDER(codebook))
+
+#define FIRST_DC_CB 0xB8
+
+#define FIRST_DC_SWITCH_BITS CB_TO_SWITCH_BITS(FIRST_DC_CB)
+#define FIRST_DC_RICE_ORDER CB_TO_RICE_ORDER(FIRST_DC_CB)
+#define FIRST_DC_EXP_ORDER CB_TO_EXP_ORDER(FIRST_DC_CB)
+#define FIRST_DC_FIRST_EXP CB_TO_FIRST_EXP(FIRST_DC_CB)
+
+
+static const uint8_t dc_cb_switch_bits[7] = {
+    CB_TO_SWITCH_BITS(0x04), CB_TO_SWITCH_BITS(0x28), CB_TO_SWITCH_BITS(0x28),
+    CB_TO_SWITCH_BITS(0x4D), CB_TO_SWITCH_BITS(0x4D), CB_TO_SWITCH_BITS(0x70),
+    CB_TO_SWITCH_BITS(0x70),
+};
+static const uint8_t dc_cb_rice_order[7] = {
+    CB_TO_RICE_ORDER(0x04), CB_TO_RICE_ORDER(0x28), CB_TO_RICE_ORDER(0x28),
+    CB_TO_RICE_ORDER(0x4D), CB_TO_RICE_ORDER(0x4D), CB_TO_RICE_ORDER(0x70),
+    CB_TO_RICE_ORDER(0x70),
+};
+static const uint8_t dc_cb_exp_order[7] = {
+    CB_TO_EXP_ORDER(0x04), CB_TO_EXP_ORDER(0x28), CB_TO_EXP_ORDER(0x28),
+    CB_TO_EXP_ORDER(0x4D), CB_TO_EXP_ORDER(0x4D), CB_TO_EXP_ORDER(0x70),
+    CB_TO_EXP_ORDER(0x70),
+};
+static const uint8_t dc_cb_first_exp[7] = {
+    CB_TO_FIRST_EXP(0x04), CB_TO_FIRST_EXP(0x28), CB_TO_FIRST_EXP(0x28),
+    CB_TO_FIRST_EXP(0x4D), CB_TO_FIRST_EXP(0x4D), CB_TO_FIRST_EXP(0x70),
+    CB_TO_FIRST_EXP(0x70),
+};
 
-    /* number of bits to switch between rice and exp golomb */
-    switch_bits = codebook & 3;
-    rice_order  = codebook >> 5;
-    exp_order   = (codebook >> 2) & 7;
 
-    first_exp = ((switch_bits + 1) << rice_order);
+static const uint8_t run_to_cb_switch_bits[16] = {
+    CB_TO_SWITCH_BITS(0x06), CB_TO_SWITCH_BITS(0x06), CB_TO_SWITCH_BITS(0x05),
+    CB_TO_SWITCH_BITS(0x05), CB_TO_SWITCH_BITS(0x04), CB_TO_SWITCH_BITS(0x29),
+    CB_TO_SWITCH_BITS(0x29), CB_TO_SWITCH_BITS(0x29), CB_TO_SWITCH_BITS(0x29),
+    CB_TO_SWITCH_BITS(0x28), CB_TO_SWITCH_BITS(0x28), CB_TO_SWITCH_BITS(0x28),
+    CB_TO_SWITCH_BITS(0x28), CB_TO_SWITCH_BITS(0x28), CB_TO_SWITCH_BITS(0x28),
+    CB_TO_SWITCH_BITS(0x4C),
+};
+static const uint8_t run_to_cb_rice_order[16] = {
+    CB_TO_RICE_ORDER(0x06), CB_TO_RICE_ORDER(0x06), CB_TO_RICE_ORDER(0x05),
+    CB_TO_RICE_ORDER(0x05), CB_TO_RICE_ORDER(0x04), CB_TO_RICE_ORDER(0x29),
+    CB_TO_RICE_ORDER(0x29), CB_TO_RICE_ORDER(0x29), CB_TO_RICE_ORDER(0x29),
+    CB_TO_RICE_ORDER(0x28), CB_TO_RICE_ORDER(0x28), CB_TO_RICE_ORDER(0x28),
+    CB_TO_RICE_ORDER(0x28), CB_TO_RICE_ORDER(0x28), CB_TO_RICE_ORDER(0x28),
+    CB_TO_RICE_ORDER(0x4C),
+};
+static const uint8_t run_to_cb_exp_order[16] = {
+    CB_TO_EXP_ORDER(0x06), CB_TO_EXP_ORDER(0x06), CB_TO_EXP_ORDER(0x05),
+    CB_TO_EXP_ORDER(0x05), CB_TO_EXP_ORDER(0x04), CB_TO_EXP_ORDER(0x29),
+    CB_TO_EXP_ORDER(0x29), CB_TO_EXP_ORDER(0x29), CB_TO_EXP_ORDER(0x29),
+    CB_TO_EXP_ORDER(0x28), CB_TO_EXP_ORDER(0x28), CB_TO_EXP_ORDER(0x28),
+    CB_TO_EXP_ORDER(0x28), CB_TO_EXP_ORDER(0x28), CB_TO_EXP_ORDER(0x28),
+    CB_TO_EXP_ORDER(0x4C),
+};
+static const uint8_t run_to_cb_first_exp[16] = {
+    CB_TO_FIRST_EXP(0x06), CB_TO_FIRST_EXP(0x06), CB_TO_FIRST_EXP(0x05),
+    CB_TO_FIRST_EXP(0x05), CB_TO_FIRST_EXP(0x04), CB_TO_FIRST_EXP(0x29),
+    CB_TO_FIRST_EXP(0x29), CB_TO_FIRST_EXP(0x29), CB_TO_FIRST_EXP(0x29),
+    CB_TO_FIRST_EXP(0x28), CB_TO_FIRST_EXP(0x28), CB_TO_FIRST_EXP(0x28),
+    CB_TO_FIRST_EXP(0x28), CB_TO_FIRST_EXP(0x28), CB_TO_FIRST_EXP(0x28),
+    CB_TO_FIRST_EXP(0x4C),
+};
+
+
+static const uint8_t lev_to_cb_switch_bits[10] = {
+    CB_TO_SWITCH_BITS(0x04), CB_TO_SWITCH_BITS(0x0A), CB_TO_SWITCH_BITS(0x05),
+    CB_TO_SWITCH_BITS(0x06), CB_TO_SWITCH_BITS(0x04), CB_TO_SWITCH_BITS(0x28),
+    CB_TO_SWITCH_BITS(0x28), CB_TO_SWITCH_BITS(0x28), CB_TO_SWITCH_BITS(0x28),
+    CB_TO_SWITCH_BITS(0x4C)
+};
+static const uint8_t lev_to_cb_rice_order[10] = {
+    CB_TO_RICE_ORDER(0x04), CB_TO_RICE_ORDER(0x0A), CB_TO_RICE_ORDER(0x05),
+    CB_TO_RICE_ORDER(0x06), CB_TO_RICE_ORDER(0x04), CB_TO_RICE_ORDER(0x28),
+    CB_TO_RICE_ORDER(0x28), CB_TO_RICE_ORDER(0x28), CB_TO_RICE_ORDER(0x28),
+    CB_TO_RICE_ORDER(0x4C)
+};
+static const uint8_t lev_to_cb_exp_order[10] = {
+    CB_TO_EXP_ORDER(0x04), CB_TO_EXP_ORDER(0x0A), CB_TO_EXP_ORDER(0x05),
+    CB_TO_EXP_ORDER(0x06), CB_TO_EXP_ORDER(0x04), CB_TO_EXP_ORDER(0x28),
+    CB_TO_EXP_ORDER(0x28), CB_TO_EXP_ORDER(0x28), CB_TO_EXP_ORDER(0x28),
+    CB_TO_EXP_ORDER(0x4C)
+};
+static const uint8_t lev_to_cb_first_exp[10] = {
+    CB_TO_FIRST_EXP(0x04), CB_TO_FIRST_EXP(0x0A), CB_TO_FIRST_EXP(0x05),
+    CB_TO_FIRST_EXP(0x06), CB_TO_FIRST_EXP(0x04), CB_TO_FIRST_EXP(0x28),
+    CB_TO_FIRST_EXP(0x28), CB_TO_FIRST_EXP(0x28), CB_TO_FIRST_EXP(0x28),
+    CB_TO_FIRST_EXP(0x4C)
+};
+
+
+static void encode_codeword(PutBitContext *pb, int val, unsigned int switch_bits, unsigned int rice_order,
+                            unsigned int exp_order, unsigned int first_exp)
+{
+    unsigned int exp, zeros;
 
     if (val >= first_exp) { /* exp golomb */
         val -= first_exp;
@@ -235,20 +324,16 @@ static av_always_inline int get_level(int val)
     return (val ^ sign) - sign;
 }
 
-#define FIRST_DC_CB 0xB8
-
-static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
-
 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
         int blocks_per_slice, int *qmat)
 {
-    int prev_dc, code;
+    int prev_dc, code, code_clamp;
     int i, sign, idx;
     int new_dc, delta, diff_sign, new_code;
 
     prev_dc = QSCALE(qmat, 0, in[0] - 16384);
     code = TO_GOLOMB(prev_dc);
-    encode_codeword(pb, code, FIRST_DC_CB);
+    encode_codeword(pb, code, FIRST_DC_SWITCH_BITS, FIRST_DC_RICE_ORDER, FIRST_DC_EXP_ORDER, FIRST_DC_FIRST_EXP);
 
     code = 5; sign = 0; idx = 64;
     for (i = 1; i < blocks_per_slice; i++, idx += 64) {
@@ -257,7 +342,9 @@ static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
         diff_sign = DIFF_SIGN(delta, sign);
         new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
 
-        encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
+        code_clamp = FFMIN(code, 6);
+        encode_codeword(pb, new_code, dc_cb_switch_bits[code_clamp], dc_cb_rice_order[code_clamp],
+                        dc_cb_exp_order[code_clamp], dc_cb_first_exp[code_clamp]);
 
         code      = new_code;
         sign      = delta >> 31;
@@ -265,16 +352,12 @@ static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
     }
 }
 
-static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
-        0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
-static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
-        0x28, 0x28, 0x28, 0x4C };
-
 static void encode_ac_coeffs(PutBitContext *pb,
         int16_t *in, int blocks_per_slice, int *qmat, const uint8_t ff_prores_scan[64])
 {
     int prev_run = 4;
     int prev_level = 2;
+    int prev_run_clamp, prev_level_clamp;
 
     int run = 0, level, code, i, j;
     for (i = 1; i < 64; i++) {
@@ -282,14 +365,18 @@ static void encode_ac_coeffs(PutBitContext *pb,
         for (j = 0; j < blocks_per_slice; j++) {
             int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
             if (val) {
-                encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
+                prev_run_clamp = FFMIN(prev_run, 15);
+                encode_codeword(pb, run, run_to_cb_switch_bits[prev_run_clamp], run_to_cb_rice_order[prev_run_clamp],
+                                run_to_cb_exp_order[prev_run_clamp], run_to_cb_first_exp[prev_run_clamp]);
 
                 prev_run   = run;
                 run        = 0;
                 level      = get_level(val);
                 code       = level - 1;
 
-                encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
+                prev_level_clamp = FFMIN(prev_level, 9);
+                encode_codeword(pb, code, lev_to_cb_switch_bits[prev_level_clamp], lev_to_cb_rice_order[prev_level_clamp],
+                                lev_to_cb_exp_order[prev_level_clamp], lev_to_cb_first_exp[prev_level_clamp]);
 
                 prev_level = level;
 
-- 
2.17.2 (Apple Git-113)

