Coverage Report

Created: 2025-12-14 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_intra_pred_mode_prediction.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at:
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*
17
******************************************************************************/
18
/**
19
 *******************************************************************************
20
 * @file
21
 *  ihevcd_intra_pred_mode_prediction.c.c
22
 *
23
 * @brief
24
 *  Contains functions for intra pred mode prediction
25
 *
26
 * @author
27
 *  Ittiam
28
 *
29
 * @par List of Functions:
30
 * - ihevcd_intra_pred_mode_prediction()
31
 *
32
 * @remarks
33
 *  None
34
 *
35
 *******************************************************************************
36
 */
37
/*****************************************************************************/
38
/* File Includes                                                             */
39
/*****************************************************************************/
40
#include <stdio.h>
41
#include <stddef.h>
42
#include <stdlib.h>
43
#include <string.h>
44
45
#include "ihevc_typedefs.h"
46
#include "iv.h"
47
#include "ivd.h"
48
#include "ihevcd_cxa.h"
49
50
#include "ihevc_defs.h"
51
#include "ihevc_debug.h"
52
#include "ihevc_structs.h"
53
#include "ihevc_macros.h"
54
#include "ihevc_mem_fns.h"
55
#include "ihevc_platform_macros.h"
56
57
#include "ihevcd_defs.h"
58
#include "ihevc_cabac_tables.h"
59
#include "ihevcd_function_selector.h"
60
#include "ihevcd_structs.h"
61
#include "ihevcd_error.h"
62
63
#include "ihevcd_bitstream.h"
64
65
66
/*****************************************************************************/
67
/* Function Prototypes                                                       */
68
/*****************************************************************************/
69
70
/*****************************************************************************/
71
/* Availability check is not done inside the function                        */
72
/* Whenever the top and left are not available, it is assumed that Intra DC  */
73
/*                  mode will initialized in place of non available          */
74
/*                  neighbors                                                */
75
/*****************************************************************************/
76
77
/**
78
*******************************************************************************
79
*
80
* @brief Computes intra prediction mode for a CU
81
*
82
* @par   Description
83
* Computes intra prediction mode for a CU
84
*
85
* @param[in,out] ps_cu
86
* Codic unit context
87
*
88
* @param[in] ps_parse
89
* parse context
90
*
91
* @param[in] ps_codec
92
* codec context
93
*
94
* @param[in] log2_cb_size
95
* log of cb size base 2
96
*
97
* @returns none
98
*
99
* @remarks
100
* Availability check is moved to CTB level. If the neighbors are
101
*  not available or if the pred mode of neighbor is not MODE_INTRA,
102
*  INTRA_DC mode will be updated in top and left buffers.
103
*******************************************************************************
104
*/
105
void ihevcd_intra_pred_mode_prediction(codec_t *ps_codec,
106
                                       WORD32 log2_cb_size,
107
                                       WORD32 x0,
108
                                       WORD32 y0)
109
3.40M
{
110
3.40M
    WORD32 i, j, num_pred_blocks;
111
3.40M
    WORD32 available_l, available_t;
112
3.40M
    WORD32 cand_intra_pred_mode_l, cand_intra_pred_mode_t;
113
3.40M
    WORD32 cand_mode_list[3];
114
3.40M
    WORD32 cb_size, block_offset_in_min_pu;
115
3.40M
    UWORD8 *pu1_luma_intra_pred_mode_top;
116
3.40M
    UWORD8 *pu1_luma_intra_pred_mode_left;
117
118
3.40M
    parse_ctxt_t *ps_parse = &ps_codec->s_parse;
119
3.40M
    parse_cu_t *ps_cu = &ps_codec->s_parse.s_cu;
120
3.40M
    sps_t *ps_sps = ps_parse->ps_sps;
121
122
123
3.40M
    available_t = 1;
124
3.40M
    available_l = 1;
125
    /* i4_pos_x and i4_pos_y are in minCu units (8x8), convert them to 4x4 units by multiplying by 2 */
126
3.40M
    pu1_luma_intra_pred_mode_top = ps_parse->pu1_luma_intra_pred_mode_top
127
3.40M
                    + (ps_cu->i4_pos_x * 2);
128
129
3.40M
    pu1_luma_intra_pred_mode_left = ps_parse->pu1_luma_intra_pred_mode_left
130
3.40M
                    + (ps_cu->i4_pos_y * 2);
131
132
/*
133
    if(0 == ps_cu->i4_pos_y)
134
    {
135
        memset(pu1_luma_intra_pred_mode_top, INTRA_DC, 16);
136
    }
137
138
    if(0 == ps_cu->i4_pos_x)
139
    {
140
        memset(pu1_luma_intra_pred_mode_left, INTRA_DC, 16);
141
    }
142
*/
143
3.40M
    if(ps_cu->i4_pos_y)
144
2.23M
    {
145
2.23M
        UWORD8 *pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
146
2.23M
        WORD32 top_intra_flag;
147
148
2.23M
        WORD32 numbytes_row =  (ps_sps->i2_pic_width_in_luma_samples + 63) / 64;
149
2.23M
        pu1_pic_intra_flag += ((y0 - 8) / 8) * numbytes_row;
150
2.23M
        pu1_pic_intra_flag += (x0 / 64);
151
2.23M
        top_intra_flag = *pu1_pic_intra_flag;
152
2.23M
        top_intra_flag &= (1 << ((x0 / 8) % 8));
153
154
2.23M
        if(0 == top_intra_flag)
155
57.7k
        {
156
57.7k
            available_t = 0;
157
57.7k
        }
158
2.23M
    }
159
1.16M
    else
160
1.16M
        available_t = 0;
161
162
163
3.40M
    if((0 == ps_cu->i4_pos_x) && (((0 == ps_codec->s_parse.i4_ctb_slice_x) && (0 == ps_codec->s_parse.i4_ctb_slice_y)) ||
164
1.17M
                                  (0 == ps_codec->s_parse.i4_ctb_tile_x)))
165
46.0k
    {
166
46.0k
        available_l = 0;
167
46.0k
    }
168
169
3.40M
    if(available_l)
170
3.35M
    {
171
3.35M
        UWORD8 *pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
172
3.35M
        WORD32 left_intra_flag;
173
3.35M
        WORD32 numbytes_row =  (ps_sps->i2_pic_width_in_luma_samples + 63) / 64;
174
3.35M
        pu1_pic_intra_flag += (y0 / 8) * numbytes_row;
175
3.35M
        pu1_pic_intra_flag += ((x0 - 8) / 64);
176
3.35M
        left_intra_flag = *pu1_pic_intra_flag;
177
3.35M
        left_intra_flag &= (1 << (((x0 - 8) / 8) % 8));
178
179
3.35M
        if(0 == left_intra_flag)
180
64.4k
        {
181
64.4k
            available_l = 0;
182
64.4k
        }
183
3.35M
    }
184
185
3.40M
    cb_size = (1 << log2_cb_size);
186
187
3.40M
    block_offset_in_min_pu = (cb_size / 2) / MIN_PU_SIZE;
188
189
3.40M
    num_pred_blocks = (ps_cu->i4_part_mode == PART_NxN) ? 2 : 1;
190
191
7.21M
    for(i = 0; i < num_pred_blocks; i++)
192
3.81M
    {
193
3.81M
        WORD32 available_l_tmp;
194
3.81M
        available_l_tmp = available_l;
195
8.44M
        for(j = 0; j < num_pred_blocks; j++)
196
4.63M
        {
197
            /* Computing Candidate intra pred mode left */
198
4.63M
            {
199
4.63M
                WORD32 block_offset;
200
201
4.63M
                block_offset = i * block_offset_in_min_pu;
202
4.63M
                cand_intra_pred_mode_l = INTRA_DC;
203
4.63M
                if(available_l_tmp)
204
4.48M
                {
205
4.48M
                    cand_intra_pred_mode_l =
206
4.48M
                                    pu1_luma_intra_pred_mode_left[block_offset];
207
4.48M
                }
208
209
4.63M
            }
210
211
4.63M
            {
212
4.63M
                WORD32 block_offset;
213
4.63M
                block_offset = j * block_offset_in_min_pu;
214
4.63M
                cand_intra_pred_mode_t = INTRA_DC;
215
4.63M
                if(available_t)
216
3.30M
                {
217
3.30M
                    cand_intra_pred_mode_t =
218
3.30M
                                    pu1_luma_intra_pred_mode_top[block_offset];
219
3.30M
                }
220
4.63M
            }
221
222
            /* Computing Candidate mode list */
223
4.63M
            if(cand_intra_pred_mode_l == cand_intra_pred_mode_t)
224
990k
            {
225
990k
                if(cand_intra_pred_mode_l < 2)
226
686k
                {
227
686k
                    cand_mode_list[0] = INTRA_PLANAR;
228
686k
                    cand_mode_list[1] = INTRA_DC;
229
686k
                    cand_mode_list[2] = INTRA_ANGULAR(26); /* angular 26 = Vertical */
230
686k
                }
231
303k
                else
232
303k
                {
233
303k
                    cand_mode_list[0] = cand_intra_pred_mode_l;
234
303k
                    cand_mode_list[1] = 2
235
303k
                                    + ((cand_intra_pred_mode_l + 29) % 32);
236
303k
                    cand_mode_list[2] = 2
237
303k
                                    + ((cand_intra_pred_mode_l - 2 + 1) % 32);
238
303k
                }
239
990k
            }
240
3.64M
            else
241
3.64M
            {
242
3.64M
                cand_mode_list[0] = cand_intra_pred_mode_l;
243
3.64M
                cand_mode_list[1] = cand_intra_pred_mode_t;
244
245
3.64M
                if((cand_intra_pred_mode_l != INTRA_PLANAR)
246
2.74M
                                && (cand_intra_pred_mode_t != INTRA_PLANAR))
247
2.19M
                {
248
2.19M
                    cand_mode_list[2] = INTRA_PLANAR;
249
2.19M
                }
250
1.44M
                else if((cand_intra_pred_mode_l != INTRA_DC)
251
1.25M
                                && (cand_intra_pred_mode_t != INTRA_DC))
252
639k
                {
253
639k
                    cand_mode_list[2] = INTRA_DC;
254
639k
                }
255
809k
                else
256
809k
                {
257
809k
                    cand_mode_list[2] = INTRA_ANGULAR(26);
258
809k
                }
259
3.64M
            }
260
261
            /* Computing Intra pred mode */
262
4.63M
            if(ps_cu->ai4_prev_intra_luma_pred_flag[2 * i + j] == 1)
263
3.21M
            {
264
3.21M
                ps_cu->ai4_intra_luma_pred_mode[2 * i + j] =
265
3.21M
                                cand_mode_list[ps_cu->ai4_mpm_idx[2 * i + j]];
266
3.21M
            }
267
1.41M
            else
268
1.41M
            {
269
1.41M
                WORD32 intra_pred_mode;
270
                /* Arranging cand_mode_list in increasing order */
271
1.41M
                if(cand_mode_list[0] > cand_mode_list[1])
272
776k
                {
273
776k
                    SWAP(cand_mode_list[0], cand_mode_list[1]);
274
776k
                }
275
1.41M
                if(cand_mode_list[0] > cand_mode_list[2])
276
1.07M
                {
277
1.07M
                    SWAP(cand_mode_list[0], cand_mode_list[2]);
278
1.07M
                }
279
1.41M
                if(cand_mode_list[1] > cand_mode_list[2])
280
1.21M
                {
281
1.21M
                    SWAP(cand_mode_list[1], cand_mode_list[2]);
282
1.21M
                }
283
284
1.41M
                intra_pred_mode = ps_cu->ai4_rem_intra_luma_pred_mode[2 * i + j];
285
286
1.41M
                if(intra_pred_mode >= cand_mode_list[0])
287
1.35M
                    intra_pred_mode++;
288
289
1.41M
                if(intra_pred_mode >= cand_mode_list[1])
290
1.10M
                    intra_pred_mode++;
291
292
1.41M
                if(intra_pred_mode >= cand_mode_list[2])
293
497k
                    intra_pred_mode++;
294
295
1.41M
                ps_cu->ai4_intra_luma_pred_mode[2 * i + j] = intra_pred_mode;
296
1.41M
            }
297
            /* Update Top and Left intra pred mode */
298
4.63M
            {
299
4.63M
                WORD32 intra_pred_mode;
300
301
4.63M
                intra_pred_mode = ps_cu->ai4_intra_luma_pred_mode[2 * i + j];
302
303
4.63M
                ps_codec->s_func_selector.ihevc_memset_fptr(pu1_luma_intra_pred_mode_left + i * block_offset_in_min_pu, intra_pred_mode, (cb_size / num_pred_blocks) / MIN_PU_SIZE);
304
4.63M
                ps_codec->s_func_selector.ihevc_memset_fptr(pu1_luma_intra_pred_mode_top + j * block_offset_in_min_pu, intra_pred_mode, (cb_size / num_pred_blocks) / MIN_PU_SIZE);
305
306
4.63M
            }
307
            /* If partition is PART_NxN, then left is available for second column always */
308
4.63M
            available_l_tmp = 1;
309
310
4.63M
        }
311
        /* If partition is PART_NxN, then top is available for bottom row always */
312
3.81M
        available_t = 1;
313
3.81M
    }
314
315
    /* In case it is PART_2Nx2N partition, replicate intra pred mode in other three entries */
316
3.40M
    if(ps_cu->i4_part_mode == PART_2Nx2N)
317
2.99M
    {
318
2.99M
        ps_cu->ai4_intra_luma_pred_mode[1] = ps_cu->ai4_intra_luma_pred_mode[0];
319
2.99M
        ps_cu->ai4_intra_luma_pred_mode[2] = ps_cu->ai4_intra_luma_pred_mode[0];
320
2.99M
        ps_cu->ai4_intra_luma_pred_mode[3] = ps_cu->ai4_intra_luma_pred_mode[0];
321
2.99M
    }
322
3.40M
}
323