Coverage Report

Created: 2026-07-16 06:32

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
5.93k
void svt_aom_largest_coding_unit_dctor(EbPtr p) {
20
    // av1xd / final_blk_arr / ptree are borrowed from per-PCS pools (freed in the PCS dctor).
21
5.93k
    (void)p;
22
5.93k
}
23
24
504k
static void setup_ptree(PARTITION_TREE* pc_tree, int index, BlockSize bsize, const int min_sq_size) {
25
504k
    pc_tree->bsize = bsize;
26
504k
    pc_tree->index = index;
27
28
    // If applicable, add split depths
29
504k
    const int sq_size = block_size_wide[bsize];
30
504k
    if (sq_size > min_sq_size) {
31
124k
        const BlockSize subsize             = get_partition_subsize(bsize, PARTITION_SPLIT);
32
124k
        const int       sq_subsize          = block_size_wide[subsize];
33
124k
        int             blocks_per_subdepth = (sq_subsize / min_sq_size) * (sq_subsize / min_sq_size);
34
124k
        int             blocks_to_skip      = 0;
35
36
285k
        for (int i = min_sq_size; i <= sq_subsize; i <<= 1, blocks_per_subdepth >>= 2) {
37
160k
            blocks_to_skip += blocks_per_subdepth;
38
160k
        }
39
40
623k
        for (int i = 0; i < SUB_PARTITIONS_SPLIT; ++i) {
41
498k
            pc_tree->sub_tree[i] = pc_tree + i * blocks_to_skip + 1;
42
498k
            setup_ptree(pc_tree->sub_tree[i], i, subsize, min_sq_size);
43
498k
        }
44
124k
    }
45
504k
}
46
47
/*
48
Tasks & Questions
49
    -Need a GetEmptyChain function for testing sub partitions.  Tie it to an Itr?
50
    -How many empty CUs do we need?  We need to have enough for the max CU count AND
51
       enough for temp storage when calculating a subdivision.
52
    -Where do we store temp reconstructed picture data while deciding to subdivide or not?
53
    -Need a ReconPicture for each candidate.
54
    -I don't see a way around doing the copies in temp memory and then copying it in...
55
*/
56
EbErrorType svt_aom_largest_coding_unit_ctor(SuperBlock* larget_coding_unit_ptr, uint8_t sb_size_pix,
57
                                             uint16_t sb_origin_x, uint16_t sb_origin_y, uint16_t sb_index,
58
5.93k
                                             EncMode enc_mode, bool rtc, bool allintra, PictureControlSet* pcs) {
59
5.93k
    larget_coding_unit_ptr->dctor = svt_aom_largest_coding_unit_dctor;
60
61
    // ************ SB ***************
62
    // Which borderLargestCuSize is not a power of two
63
64
    // Which borderLargestCuSize is not a power of two
65
5.93k
    larget_coding_unit_ptr->pcs = pcs;
66
67
5.93k
    larget_coding_unit_ptr->org_x = sb_origin_x;
68
5.93k
    larget_coding_unit_ptr->org_y = sb_origin_y;
69
70
5.93k
    larget_coding_unit_ptr->index = sb_index;
71
5.93k
    bool disallow_sub_8x8_nsq     = true;
72
5.93k
    bool disallow_sub_16x16_nsq   = true;
73
35.6k
    for (uint8_t coeff_lvl = 0; coeff_lvl <= HIGH_LVL + 1; coeff_lvl++) {
74
29.6k
        uint8_t nsq_geom_lvl = allintra ? svt_aom_get_nsq_geom_level_allintra(enc_mode)
75
29.6k
            : rtc                       ? svt_aom_get_nsq_geom_level_rtc()
76
0
                                        : svt_aom_get_nsq_geom_level_default(enc_mode, coeff_lvl);
77
        // nsq_geom_lvl level 0 means NSQ shapes are disallowed so don't adjust based on the level
78
29.6k
        if (nsq_geom_lvl) {
79
0
            uint8_t allow_HVA_HVB, allow_HV4, min_nsq_bsize;
80
0
            svt_aom_set_nsq_geom_ctrls(NULL, nsq_geom_lvl, &allow_HVA_HVB, &allow_HV4, &min_nsq_bsize);
81
0
            if (min_nsq_bsize < 8) {
82
0
                disallow_sub_8x8_nsq = false;
83
0
            }
84
0
            if (min_nsq_bsize < 16) {
85
0
                disallow_sub_16x16_nsq = false;
86
0
            }
87
0
        }
88
29.6k
    }
89
5.93k
    bool     disallow_4x4 = allintra ? svt_aom_get_disallow_4x4_allintra(enc_mode)
90
5.93k
            : rtc                    ? svt_aom_get_disallow_4x4_rtc()
91
0
                                     : svt_aom_get_disallow_4x4_default(enc_mode);
92
5.93k
    bool     disallow_8x8 = allintra ? svt_aom_get_disallow_8x8_allintra()
93
5.93k
            : rtc                    ? svt_aom_get_disallow_8x8_rtc(enc_mode, pcs->frame_width, pcs->frame_height)
94
0
                                     : svt_aom_get_disallow_8x8_default();
95
5.93k
    uint32_t tot_blk_num;
96
5.93k
    if (sb_size_pix == 128) {
97
0
        if (disallow_8x8 && disallow_sub_16x16_nsq) {
98
0
            tot_blk_num = 64;
99
0
        } else if (disallow_8x8 || (disallow_4x4 && disallow_sub_8x8_nsq)) {
100
0
            tot_blk_num = 256;
101
0
        } else if (disallow_4x4) {
102
0
            tot_blk_num = 512;
103
0
        } else {
104
0
            tot_blk_num = 1024;
105
0
        }
106
5.93k
    } else if (disallow_8x8 && disallow_sub_16x16_nsq) {
107
0
        tot_blk_num = 16;
108
5.93k
    } else if (disallow_8x8 || (disallow_4x4 && disallow_sub_8x8_nsq)) {
109
5.93k
        tot_blk_num = 64;
110
5.93k
    } else if (disallow_4x4) {
111
0
        tot_blk_num = 128;
112
0
    } else {
113
0
        tot_blk_num = 256;
114
0
    }
115
    // Do NOT initialize the final_blk_arr here
116
    // Malloc maximum but only initialize it only when actually used.
117
    // This will help to same actually memory usage
118
    // Alloc ptree, which is used to store final block data/mode info for the SB that is passed
119
    // from encdec to EC
120
5.93k
    uint8_t min_bsize        = disallow_8x8 ? 16 : disallow_4x4 ? 8 : 4;
121
5.93k
    int     blocks_per_depth = (sb_size_pix / min_bsize) * (sb_size_pix / min_bsize);
122
5.93k
    int     blocks_to_alloc  = 0;
123
124
29.6k
    for (int i = min_bsize; i <= sb_size_pix; i <<= 1, blocks_per_depth >>= 2) {
125
23.7k
        blocks_to_alloc += blocks_per_depth;
126
23.7k
    }
127
    // All SBs in a PCS resolve to identical tot_blk_num / blocks_to_alloc, so back the whole
128
    // sb_ptr_array with one allocation each (created on the first SB) and hand each SB a slice,
129
    // instead of 3 allocations per SB.
130
5.93k
    const uint16_t all_sb = pcs->sb_total_count;
131
5.93k
    if (sb_index == 0) {
132
        // This ctor is re-run per frame on the resize/superres path (superres_setup_child_pcs),
133
        // so free any pool from a prior setup before reallocating (NULL-safe on first use).
134
448
        EB_FREE_ARRAY(pcs->sb_final_blk_arr_pool);
135
448
        EB_FREE_ARRAY(pcs->sb_av1xd_pool);
136
448
        EB_FREE_ARRAY(pcs->sb_ptree_pool);
137
448
        EB_MALLOC_ARRAY(pcs->sb_final_blk_arr_pool, (size_t)all_sb * tot_blk_num);
138
448
        EB_MALLOC_ARRAY(pcs->sb_av1xd_pool, all_sb);
139
448
        EB_CALLOC_ARRAY(pcs->sb_ptree_pool, (size_t)all_sb * blocks_to_alloc);
140
448
    }
141
5.93k
    larget_coding_unit_ptr->final_blk_arr = pcs->sb_final_blk_arr_pool + (size_t)sb_index * tot_blk_num;
142
5.93k
    larget_coding_unit_ptr->av1xd         = pcs->sb_av1xd_pool + sb_index;
143
5.93k
    larget_coding_unit_ptr->ptree         = pcs->sb_ptree_pool + (size_t)sb_index * blocks_to_alloc;
144
5.93k
    setup_ptree(larget_coding_unit_ptr->ptree, 0, sb_size_pix == 128 ? BLOCK_128X128 : BLOCK_64X64, min_bsize);
145
146
5.93k
    return EB_ErrorNone;
147
5.93k
}