From 54399431210348c98ca0a13d963c63d9cf985e77 Mon Sep 17 00:00:00 2001 From: Henrik Gramner Date: Fri, 12 May 2023 13:16:26 +0200 Subject: [PATCH] Eliminate duplicate and constant intra_edge table entries Reduces the table size by around 3 kB. --- src/decode.c | 52 +++++++++++++++++------------------- src/intra_edge.c | 69 ++++++++++++++---------------------------------- src/intra_edge.h | 20 +++++++++----- 3 files changed, 58 insertions(+), 83 deletions(-) diff --git a/src/decode.c b/src/decode.c index 4d1ad555f..db06ed6e5 100644 --- a/src/decode.c +++ b/src/decode.c @@ -2390,19 +2390,19 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl, if (bl == BL_8X8) { const EdgeTip *const tip = (const EdgeTip *) node; assert(hsz == 1); - if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[0])) + if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, EDGE_ALL_TR_AND_BL)) return -1; const enum Filter2d tl_filter = t->tl_4x4_filter; t->bx++; - if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[1])) + if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[0])) return -1; t->bx--; t->by++; - if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[2])) + if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[1])) return -1; t->bx++; t->tl_4x4_filter = tl_filter; - if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[3])) + if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[2])) return -1; t->bx--; t->by--; @@ -2435,56 +2435,52 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl, } break; case PARTITION_T_TOP_SPLIT: { - const EdgeBranch *const branch = (const EdgeBranch *) node; - if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, branch->tts[0])) + if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, EDGE_ALL_TR_AND_BL)) return -1; t->bx += hsz; - if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, branch->tts[1])) + if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, node->v[1])) return -1; t->bx -= hsz; t->by += hsz; - if (decode_b(t, bl, b[1], PARTITION_T_TOP_SPLIT, branch->tts[2])) + if (decode_b(t, bl, b[1], PARTITION_T_TOP_SPLIT, node->h[1])) return -1; t->by -= hsz; break; } case PARTITION_T_BOTTOM_SPLIT: { - const EdgeBranch *const branch = (const EdgeBranch *) node; - if (decode_b(t, bl, b[0], PARTITION_T_BOTTOM_SPLIT, branch->tbs[0])) + if (decode_b(t, bl, b[0], PARTITION_T_BOTTOM_SPLIT, node->h[0])) return -1; t->by += hsz; - if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, branch->tbs[1])) + if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, node->v[0])) return -1; t->bx += hsz; - if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, branch->tbs[2])) + if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, 0)) return -1; t->bx -= hsz; t->by -= hsz; break; } case PARTITION_T_LEFT_SPLIT: { - const EdgeBranch *const branch = (const EdgeBranch *) node; - if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, branch->tls[0])) + if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, EDGE_ALL_TR_AND_BL)) return -1; t->by += hsz; - if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, branch->tls[1])) + if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, node->h[1])) return -1; t->by -= hsz; t->bx += hsz; - if (decode_b(t, bl, b[1], PARTITION_T_LEFT_SPLIT, branch->tls[2])) + if (decode_b(t, bl, b[1], PARTITION_T_LEFT_SPLIT, node->v[1])) return -1; t->bx -= hsz; break; } case PARTITION_T_RIGHT_SPLIT: { - const EdgeBranch *const branch = (const EdgeBranch *) node; - if (decode_b(t, bl, b[0], PARTITION_T_RIGHT_SPLIT, branch->trs[0])) + if (decode_b(t, bl, b[0], PARTITION_T_RIGHT_SPLIT, node->v[0])) return -1; t->bx += hsz; - if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, branch->trs[1])) + if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, node->h[0])) return -1; t->by += hsz; - if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, branch->trs[2])) + if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, 0)) return -1; t->by -= hsz; t->bx -= hsz; @@ -2492,34 +2488,34 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl, } case PARTITION_H4: { const EdgeBranch *const branch = (const EdgeBranch *) node; - if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[0])) + if (decode_b(t, bl, b[0], PARTITION_H4, node->h[0])) return -1; t->by += hsz >> 1; - if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[1])) + if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4)) return -1; t->by += hsz >> 1; - if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[2])) + if (decode_b(t, bl, b[0], PARTITION_H4, EDGE_ALL_LEFT_HAS_BOTTOM)) return -1; t->by += hsz >> 1; if (t->by < f->bh) - if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[3])) + if (decode_b(t, bl, b[0], PARTITION_H4, node->h[1])) return -1; t->by -= hsz * 3 >> 1; break; } case PARTITION_V4: { const EdgeBranch *const branch = (const EdgeBranch *) node; - if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[0])) + if (decode_b(t, bl, b[0], PARTITION_V4, node->v[0])) return -1; t->bx += hsz >> 1; - if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[1])) + if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4)) return -1; t->bx += hsz >> 1; - if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[2])) + if (decode_b(t, bl, b[0], PARTITION_V4, EDGE_ALL_TOP_HAS_RIGHT)) return -1; t->bx += hsz >> 1; if (t->bx < f->bw) - if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[3])) + if (decode_b(t, bl, b[0], PARTITION_V4, node->v[1])) return -1; t->bx -= hsz * 3 >> 1; break; diff --git a/src/intra_edge.c b/src/intra_edge.c index 684d113fa..2e4e68d53 100644 --- a/src/intra_edge.c +++ b/src/intra_edge.c @@ -44,66 +44,37 @@ static void init_edges(EdgeNode *const node, const enum EdgeFlags edge_flags) { node->o = edge_flags; + node->h[0] = edge_flags | EDGE_ALL_LEFT_HAS_BOTTOM; + node->v[0] = edge_flags | EDGE_ALL_TOP_HAS_RIGHT; -#define ALL_FL(t) (EDGE_I444_##t | EDGE_I422_##t | EDGE_I420_##t) if (bl == BL_8X8) { EdgeTip *const nt = (EdgeTip *) node; - node->h[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM); - node->h[1] = edge_flags & (ALL_FL(LEFT_HAS_BOTTOM) | + node->h[1] = edge_flags & (EDGE_ALL_LEFT_HAS_BOTTOM | EDGE_I420_TOP_HAS_RIGHT); - - node->v[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT); - node->v[1] = edge_flags & (ALL_FL(TOP_HAS_RIGHT) | + node->v[1] = edge_flags & (EDGE_ALL_TOP_HAS_RIGHT | EDGE_I420_LEFT_HAS_BOTTOM | EDGE_I422_LEFT_HAS_BOTTOM); - nt->split[0] = ALL_FL(TOP_HAS_RIGHT) | ALL_FL(LEFT_HAS_BOTTOM); - nt->split[1] = (edge_flags & ALL_FL(TOP_HAS_RIGHT)) | + nt->split[0] = (edge_flags & EDGE_ALL_TOP_HAS_RIGHT) | EDGE_I422_LEFT_HAS_BOTTOM; - nt->split[2] = edge_flags | EDGE_I444_TOP_HAS_RIGHT; - nt->split[3] = edge_flags & (EDGE_I420_TOP_HAS_RIGHT | + nt->split[1] = edge_flags | EDGE_I444_TOP_HAS_RIGHT; + nt->split[2] = edge_flags & (EDGE_I420_TOP_HAS_RIGHT | EDGE_I420_LEFT_HAS_BOTTOM | EDGE_I422_LEFT_HAS_BOTTOM); } else { EdgeBranch *const nwc = (EdgeBranch *) node; - node->h[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM); - node->h[1] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM); - - node->v[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT); - node->v[1] = edge_flags & ALL_FL(TOP_HAS_RIGHT); - - nwc->h4[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM); - nwc->h4[1] = - nwc->h4[2] = ALL_FL(LEFT_HAS_BOTTOM); - nwc->h4[3] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM); - if (bl == BL_16X16) - nwc->h4[1] |= edge_flags & EDGE_I420_TOP_HAS_RIGHT; - - nwc->v4[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT); - nwc->v4[1] = - nwc->v4[2] = ALL_FL(TOP_HAS_RIGHT); - nwc->v4[3] = edge_flags & ALL_FL(TOP_HAS_RIGHT); - if (bl == BL_16X16) - nwc->v4[1] |= edge_flags & (EDGE_I420_LEFT_HAS_BOTTOM | - EDGE_I422_LEFT_HAS_BOTTOM); - - nwc->tls[0] = ALL_FL(TOP_HAS_RIGHT) | ALL_FL(LEFT_HAS_BOTTOM); - nwc->tls[1] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM); - nwc->tls[2] = edge_flags & ALL_FL(TOP_HAS_RIGHT); + node->h[1] = edge_flags & EDGE_ALL_LEFT_HAS_BOTTOM; + node->v[1] = edge_flags & EDGE_ALL_TOP_HAS_RIGHT; - nwc->trs[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT); - nwc->trs[1] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM); - nwc->trs[2] = 0; - - nwc->tts[0] = ALL_FL(TOP_HAS_RIGHT) | ALL_FL(LEFT_HAS_BOTTOM); - nwc->tts[1] = edge_flags & ALL_FL(TOP_HAS_RIGHT); - nwc->tts[2] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM); - - nwc->tbs[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM); - nwc->tbs[1] = edge_flags | ALL_FL(TOP_HAS_RIGHT); - nwc->tbs[2] = 0; + nwc->h4 = EDGE_ALL_LEFT_HAS_BOTTOM; + nwc->v4 = EDGE_ALL_TOP_HAS_RIGHT; + if (bl == BL_16X16) { + nwc->h4 |= edge_flags & EDGE_I420_TOP_HAS_RIGHT; + nwc->v4 |= edge_flags & (EDGE_I420_LEFT_HAS_BOTTOM | + EDGE_I422_LEFT_HAS_BOTTOM); + } } } @@ -114,17 +85,17 @@ static void init_mode_node(EdgeBranch *const nwc, const int left_has_bottom) { init_edges(&nwc->node, bl, - (top_has_right ? ALL_FL(TOP_HAS_RIGHT) : 0) | - (left_has_bottom ? ALL_FL(LEFT_HAS_BOTTOM) : 0)); + (top_has_right ? EDGE_ALL_TOP_HAS_RIGHT : 0) | + (left_has_bottom ? EDGE_ALL_LEFT_HAS_BOTTOM : 0)); if (bl == BL_16X16) { for (int n = 0; n < 4; n++) { EdgeTip *const nt = mem->nt++; nwc->split[n] = &nt->node; init_edges(&nt->node, bl + 1, ((n == 3 || (n == 1 && !top_has_right)) ? 0 : - ALL_FL(TOP_HAS_RIGHT)) | + EDGE_ALL_TOP_HAS_RIGHT) | (!(n == 0 || (n == 2 && left_has_bottom)) ? 0 : - ALL_FL(LEFT_HAS_BOTTOM))); + EDGE_ALL_LEFT_HAS_BOTTOM)); } } else { for (int n = 0; n < 4; n++) { diff --git a/src/intra_edge.h b/src/intra_edge.h index 8759095e1..720f12ab2 100644 --- a/src/intra_edge.h +++ b/src/intra_edge.h @@ -31,12 +31,20 @@ #include enum EdgeFlags { - EDGE_I444_TOP_HAS_RIGHT = 1 << 0, - EDGE_I422_TOP_HAS_RIGHT = 1 << 1, - EDGE_I420_TOP_HAS_RIGHT = 1 << 2, + EDGE_I444_TOP_HAS_RIGHT = 1 << 0, + EDGE_I422_TOP_HAS_RIGHT = 1 << 1, + EDGE_I420_TOP_HAS_RIGHT = 1 << 2, EDGE_I444_LEFT_HAS_BOTTOM = 1 << 3, EDGE_I422_LEFT_HAS_BOTTOM = 1 << 4, EDGE_I420_LEFT_HAS_BOTTOM = 1 << 5, + EDGE_ALL_TOP_HAS_RIGHT = EDGE_I444_TOP_HAS_RIGHT | + EDGE_I422_TOP_HAS_RIGHT | + EDGE_I420_TOP_HAS_RIGHT, + EDGE_ALL_LEFT_HAS_BOTTOM = EDGE_I444_LEFT_HAS_BOTTOM | + EDGE_I422_LEFT_HAS_BOTTOM | + EDGE_I420_LEFT_HAS_BOTTOM, + EDGE_ALL_TR_AND_BL = EDGE_ALL_TOP_HAS_RIGHT | + EDGE_ALL_LEFT_HAS_BOTTOM, }; typedef struct EdgeNode { @@ -45,13 +53,13 @@ typedef struct EdgeNode { typedef struct EdgeTip { EdgeNode node; - uint8_t /* enum EdgeFlags */ split[4]; + uint8_t /* enum EdgeFlags */ split[3]; } EdgeTip; typedef struct EdgeBranch { EdgeNode node; - uint8_t /* enum EdgeFlags */ tts[3], tbs[3], tls[3], trs[3], h4[4], v4[4]; - EdgeNode *split[4]; + uint8_t /* enum EdgeFlags */ h4, v4; + const EdgeNode *split[4]; } EdgeBranch; void dav1d_init_mode_tree(EdgeNode *const root, EdgeTip *const nt,