Coverage Report

Created: 2026-05-30 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/coding_unit.c
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
*
4
* This source code is subject to the terms of the BSD 2 Clause License and
5
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
* was not distributed with this source code in the LICENSE file, you can
7
* obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8
* Media Patent License 1.0 was not distributed with this source code in the
9
* PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10
*/
11
12
#include <stdlib.h>
13
#include <stdint.h>
14
15
#include "pcs.h"
16
#include "utility.h"
17
#include "enc_mode_config.h"
18
19
6.90k
void svt_aom_largest_coding_unit_dctor(EbPtr p) {
20
6.90k
    SuperBlock* obj = (SuperBlock*)p;
21
6.90k
    EB_FREE_ARRAY(obj->av1xd);
22
6.90k
    EB_FREE_ARRAY(obj->final_blk_arr);
23
6.90k
    EB_FREE_ARRAY(obj->ptree);
24
6.90k
}
25
26
587k
static void setup_ptree(PARTITION_TREE* pc_tree, int index, BlockSize bsize, const int min_sq_size) {
27
587k
    pc_tree->bsize = bsize;
28
587k
    pc_tree->index = index;
29
30
    // If applicable, add split depths
31
587k
    const int sq_size = block_size_wide[bsize];
32
587k
    if (sq_size > min_sq_size) {
33
145k
        const BlockSize subsize             = get_partition_subsize(bsize, PARTITION_SPLIT);
34
145k
        const int       sq_subsize          = block_size_wide[subsize];
35
145k
        int             blocks_per_subdepth = (sq_subsize / min_sq_size) * (sq_subsize / min_sq_size);
36
145k
        int             blocks_to_skip      = 0;
37
38
331k
        for (int i = min_sq_size; i <= sq_subsize; i <<= 1, blocks_per_subdepth >>= 2) {
39
186k
            blocks_to_skip += blocks_per_subdepth;
40
186k
        }
41
42
725k
        for (int i = 0; i < SUB_PARTITIONS_SPLIT; ++i) {
43
580k
            pc_tree->sub_tree[i] = pc_tree + i * blocks_to_skip + 1;
44
580k
            setup_ptree(pc_tree->sub_tree[i], i, subsize, min_sq_size);
45
580k
        }
46
145k
    }
47
587k
}
48
49
/*
50
Tasks & Questions
51
    -Need a GetEmptyChain function for testing sub partitions.  Tie it to an Itr?
52
    -How many empty CUs do we need?  We need to have enough for the max CU count AND
53
       enough for temp storage when calculating a subdivision.
54
    -Where do we store temp reconstructed picture data while deciding to subdivide or not?
55
    -Need a ReconPicture for each candidate.
56
    -I don't see a way around doing the copies in temp memory and then copying it in...
57
*/
58
EbErrorType svt_aom_largest_coding_unit_ctor(SuperBlock* larget_coding_unit_ptr, uint8_t sb_size_pix,
59
                                             uint16_t sb_origin_x, uint16_t sb_origin_y, uint16_t sb_index,
60
6.90k
                                             EncMode enc_mode, bool rtc, bool allintra, PictureControlSet* pcs) {
61
6.90k
    larget_coding_unit_ptr->dctor = svt_aom_largest_coding_unit_dctor;
62
63
    // ************ SB ***************
64
    // Which borderLargestCuSize is not a power of two
65
66
    // Which borderLargestCuSize is not a power of two
67
6.90k
    larget_coding_unit_ptr->pcs = pcs;
68
69
6.90k
    larget_coding_unit_ptr->org_x = sb_origin_x;
70
6.90k
    larget_coding_unit_ptr->org_y = sb_origin_y;
71
72
6.90k
    larget_coding_unit_ptr->index = sb_index;
73
6.90k
    bool disallow_sub_8x8_nsq     = true;
74
6.90k
    bool disallow_sub_16x16_nsq   = true;
75
41.4k
    for (uint8_t coeff_lvl = 0; coeff_lvl <= HIGH_LVL + 1; coeff_lvl++) {
76
34.5k
        uint8_t nsq_geom_lvl = allintra ? svt_aom_get_nsq_geom_level_allintra(enc_mode)
77
34.5k
#if TUNE_SIMPLIFY_SETTINGS
78
34.5k
            : rtc ? svt_aom_get_nsq_geom_level_rtc()
79
#else
80
            : rtc ? svt_aom_get_nsq_geom_level_rtc(enc_mode)
81
#endif
82
0
                  : svt_aom_get_nsq_geom_level_default(enc_mode, coeff_lvl);
83
        // nsq_geom_lvl level 0 means NSQ shapes are disallowed so don't adjust based on the level
84
34.5k
        if (nsq_geom_lvl) {
85
0
            uint8_t allow_HVA_HVB, allow_HV4, min_nsq_bsize;
86
0
            svt_aom_set_nsq_geom_ctrls(NULL, nsq_geom_lvl, &allow_HVA_HVB, &allow_HV4, &min_nsq_bsize);
87
0
            if (min_nsq_bsize < 8) {
88
0
                disallow_sub_8x8_nsq = false;
89
0
            }
90
0
            if (min_nsq_bsize < 16) {
91
0
                disallow_sub_16x16_nsq = false;
92
0
            }
93
0
        }
94
34.5k
    }
95
6.90k
    bool disallow_4x4 = allintra ? svt_aom_get_disallow_4x4_allintra(enc_mode)
96
6.90k
#if TUNE_SIMPLIFY_SETTINGS
97
6.90k
        : rtc ? svt_aom_get_disallow_4x4_rtc()
98
#else
99
        : rtc ? svt_aom_get_disallow_4x4_rtc(enc_mode)
100
#endif
101
0
              : svt_aom_get_disallow_4x4_default(enc_mode);
102
6.90k
    bool     disallow_8x8 = allintra ? svt_aom_get_disallow_8x8_allintra()
103
6.90k
            : rtc                    ? svt_aom_get_disallow_8x8_rtc(enc_mode, pcs->frame_width, pcs->frame_height)
104
0
                                     : svt_aom_get_disallow_8x8_default();
105
6.90k
    uint32_t tot_blk_num;
106
6.90k
    if (sb_size_pix == 128) {
107
0
        if (disallow_8x8 && disallow_sub_16x16_nsq) {
108
0
            tot_blk_num = 64;
109
0
        } else if (disallow_8x8 || (disallow_4x4 && disallow_sub_8x8_nsq)) {
110
0
            tot_blk_num = 256;
111
0
        } else if (disallow_4x4) {
112
0
            tot_blk_num = 512;
113
0
        } else {
114
0
            tot_blk_num = 1024;
115
0
        }
116
6.90k
    } else if (disallow_8x8 && disallow_sub_16x16_nsq) {
117
0
        tot_blk_num = 16;
118
6.90k
    } else if (disallow_8x8 || (disallow_4x4 && disallow_sub_8x8_nsq)) {
119
6.90k
        tot_blk_num = 64;
120
6.90k
    } else if (disallow_4x4) {
121
0
        tot_blk_num = 128;
122
0
    } else {
123
0
        tot_blk_num = 256;
124
0
    }
125
    // Do NOT initialize the final_blk_arr here
126
    // Malloc maximum but only initialize it only when actually used.
127
    // This will help to same actually memory usage
128
6.90k
    EB_MALLOC_ARRAY(larget_coding_unit_ptr->final_blk_arr, tot_blk_num);
129
6.90k
    EB_MALLOC_ARRAY(larget_coding_unit_ptr->av1xd, 1);
130
131
    // Alloc ptree, which is used to store final block data/mode info for the SB that is passed
132
    // from encdec to EC
133
6.90k
    uint8_t min_bsize        = disallow_8x8 ? 16 : disallow_4x4 ? 8 : 4;
134
6.90k
    int     blocks_per_depth = (sb_size_pix / min_bsize) * (sb_size_pix / min_bsize);
135
6.90k
    int     blocks_to_alloc  = 0;
136
137
34.5k
    for (int i = min_bsize; i <= sb_size_pix; i <<= 1, blocks_per_depth >>= 2) {
138
27.6k
        blocks_to_alloc += blocks_per_depth;
139
27.6k
    }
140
6.90k
    EB_CALLOC_ARRAY(larget_coding_unit_ptr->ptree, blocks_to_alloc);
141
6.90k
    setup_ptree(larget_coding_unit_ptr->ptree, 0, sb_size_pix == 128 ? BLOCK_128X128 : BLOCK_64X64, min_bsize);
142
143
6.90k
    return EB_ErrorNone;
144
6.90k
}