165 lines · 6.5 KB · C
RawDownload
/* * Copyright © 2018, VideoLAN and dav1d authors * Copyright © 2018, Two Orioles, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this *    list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include <stdlib.h> #include "common/attributes.h" #include "src/intra_edge.h"#include "src/levels.h" struct ModeSelMem {    EdgeBranch *nwc[3 /* 64x64, 32x32, 16x16 */];    EdgeTip *nt;}; static void init_edges(EdgeNode *const node,                       const enum BlockLevel bl,                       const enum EdgeFlags edge_flags){    node->o = edge_flags; #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) |                                   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) |                                   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)) |                       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 |                                     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);         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;    }} static void init_mode_node(EdgeBranch *const nwc,                           const enum BlockLevel bl,                           struct ModeSelMem *const mem,                           const int top_has_right,                           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));    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)) |                       (!(n == 0 || (n == 2 && left_has_bottom)) ? 0 :                        ALL_FL(LEFT_HAS_BOTTOM)));        }    } else {        for (int n = 0; n < 4; n++) {            EdgeBranch *const nwc_child = mem->nwc[bl]++;            nwc->split[n] = &nwc_child->node;            init_mode_node(nwc_child, bl + 1, mem,                           !(n == 3 || (n == 1 && !top_has_right)),                           n == 0 || (n == 2 && left_has_bottom));        }    }} void dav1d_init_mode_tree(EdgeNode *const root_node, EdgeTip *const nt,                          const int allow_sb128){    EdgeBranch *const root = (EdgeBranch *) root_node;    struct ModeSelMem mem;    mem.nt = nt;     if (allow_sb128) {        mem.nwc[BL_128X128] = &root[1];        mem.nwc[BL_64X64] = &root[1 + 4];        mem.nwc[BL_32X32] = &root[1 + 4 + 16];        init_mode_node(root, BL_128X128, &mem, 1, 0);        assert(mem.nwc[BL_128X128] == &root[1 + 4]);        assert(mem.nwc[BL_64X64] == &root[1 + 4 + 16]);        assert(mem.nwc[BL_32X32] == &root[1 + 4 + 16 + 64]);        assert(mem.nt == &nt[256]);    } else {        mem.nwc[BL_128X128] = NULL;        mem.nwc[BL_64X64] = &root[1];        mem.nwc[BL_32X32] = &root[1 + 4];        init_mode_node(root, BL_64X64, &mem, 1, 0);        assert(mem.nwc[BL_64X64] == &root[1 + 4]);        assert(mem.nwc[BL_32X32] == &root[1 + 4 + 16]);        assert(mem.nt == &nt[64]);    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t