Coverage Report

Created: 2025-12-14 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmpeg2/common/ideint_cac.c
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Copyright (C) 2015 The Android Open Source Project
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
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19
*/
20
/**
21
*******************************************************************************
22
* @file
23
*  ideint_cac.c
24
*
25
* @brief
26
*  This file include the definitions of the combing  artifact check function
27
* of the de-interlacer and some  variant of that.
28
*
29
* @author
30
*  Ittiam
31
*
32
* @par List of Functions:
33
*  cac_4x8()
34
*  ideint_cac()
35
*
36
* @remarks
37
*  In the de-interlacer workspace, cac is not a seperate  assembly module as
38
* it comes along with the  de_int_decision() function. But in C-Model, to
39
* keep  the things cleaner, it was made to be a separate  function during
40
* cac experiments long after the  assembly was written by Mudit.
41
*
42
*******************************************************************************
43
*/
44
/*****************************************************************************/
45
/* File Includes                                                             */
46
/*****************************************************************************/
47
/* System include files */
48
#include <stdio.h>
49
#include <stdint.h>
50
#include <string.h>
51
#include <stdlib.h>
52
53
/* User include files */
54
#include "icv_datatypes.h"
55
#include "icv_macros.h"
56
#include "icv.h"
57
#include "icv_variance.h"
58
#include "icv_sad.h"
59
#include "ideint.h"
60
#include "ideint_defs.h"
61
#include "ideint_structs.h"
62
#include "ideint_cac.h"
63
64
/**
65
*******************************************************************************
66
*
67
* @brief
68
* Combing artifact check function for 8x4 block
69
*
70
* @par   Description
71
*  Adjacent and alternate SADs are calculated by row based and column-based
72
*  collapsing. The adjacent and alternate SADs are then compared with some
73
*  biasing to get CAC
74
*
75
* @param[in] pu1_top
76
*  Top field
77
*
78
* @param[in] pu1_bot
79
*  Bottom field
80
*
81
* @param[in] top_strd
82
*  Top field Stride
83
*
84
* @param[in] bot_strd
85
*  Bottom field stride
86
*
87
* @param[in] pi4_adj_sad
88
*  Pointer to return adjacent SAD
89
*
90
* @param[in] pi4_alt_sad
91
*  Pointer to return alternate SAD
92
*
93
* @returns
94
* combing artifact flag (1 = detected, 0 = not detected)
95
*
96
* @remarks
97
*
98
*******************************************************************************
99
*/
100
static WORD32 cac_4x8(UWORD8 *pu1_top,
101
                      UWORD8 *pu1_bot,
102
                      WORD32 top_strd,
103
                      WORD32 bot_strd)
104
9.50M
{
105
9.50M
    WORD32 ca;
106
9.50M
    WORD32 adj;
107
9.50M
    WORD32 alt;
108
9.50M
    UWORD8 *pu1_tmp_top;
109
9.50M
    UWORD8 *pu1_tmp_bot;
110
9.50M
    WORD32 i;
111
9.50M
    WORD32 j;
112
9.50M
    UWORD8 *pu1_top_0;
113
9.50M
    UWORD8 *pu1_top_1;
114
9.50M
    UWORD8 *pu1_top_2;
115
9.50M
    UWORD8 *pu1_top_3;
116
9.50M
    UWORD8 *pu1_bot_0;
117
9.50M
    UWORD8 *pu1_bot_1;
118
9.50M
    UWORD8 *pu1_bot_2;
119
9.50M
    UWORD8 *pu1_bot_3;
120
9.50M
    WORD32 rsum_csum_thresh;
121
9.50M
    WORD32 sad_bias_mult_shift;
122
9.50M
    WORD32 sad_bias_additive;
123
124
9.50M
    WORD32 diff_sum;
125
9.50M
    WORD32 top_row_end_incr;
126
9.50M
    WORD32 bot_row_end_incr;
127
128
9.50M
    ca = 0;
129
130
9.50M
    adj = 0;
131
9.50M
    alt = 0;
132
133
9.50M
    rsum_csum_thresh    = RSUM_CSUM_THRESH;
134
9.50M
    sad_bias_additive   = SAD_BIAS_ADDITIVE;
135
9.50M
    sad_bias_mult_shift = SAD_BIAS_MULT_SHIFT;
136
137
    /*************************************************************************/
138
    /* In the adjacent sad calculation by row-method, the absolute           */
139
    /* difference is taken between the adjacent rows. The pixels of the diff */
140
    /* row, thus obtained, are then summed up. If this sum of absolute       */
141
    /* differace (sad) is greater than a threshold value, it is added to the */
142
    /* adjcacent SAD value.                                                  */
143
    /*************************************************************************/
144
145
    /*************************************************************************/
146
    /* Adj dif: Row based                                                    */
147
    /*************************************************************************/
148
149
9.50M
    pu1_tmp_top = pu1_top;
150
9.50M
    pu1_tmp_bot = pu1_bot;
151
152
9.50M
    top_row_end_incr = top_strd - SUB_BLK_WD;
153
9.50M
    bot_row_end_incr = bot_strd - SUB_BLK_WD;
154
155
    /*************************************************************************/
156
    /* The outer-loop runs for BLK_HT/2 times, because one pixel   */
157
    /* is touched only once.                                                 */
158
    /*************************************************************************/
159
28.2M
    for(j = 0; j < BLK_HT; j += 4)
160
18.7M
    {
161
18.7M
        WORD32 sum_1, sum_2, sum_3, sum_4;
162
18.7M
        WORD32 sum_diff;
163
164
        /*********************************************************************/
165
        /* Because the 8x4 is split into two halves of 4x4, the width of the */
166
        /* block is now 4.                                                   */
167
        /*********************************************************************/
168
18.7M
        sum_1 = 0;
169
18.7M
        sum_2 = 0;
170
171
93.8M
        for(i = 0; i < SUB_BLK_WD; i ++)
172
75.1M
        {
173
75.1M
            sum_1 += *pu1_tmp_top++;
174
75.1M
            sum_2 += *pu1_tmp_bot++;
175
75.1M
        }
176
177
18.7M
        sum_diff = ABS_DIF(sum_1, sum_2);
178
179
        /*********************************************************************/
180
        /* Thresholding.                                                     */
181
        /*********************************************************************/
182
18.7M
        if(sum_diff >= rsum_csum_thresh)
183
152k
            adj += sum_diff;
184
185
18.7M
        pu1_tmp_top += top_row_end_incr;
186
18.7M
        pu1_tmp_bot += bot_row_end_incr;
187
188
189
18.7M
        sum_3 = 0;
190
18.7M
        sum_4 = 0;
191
192
93.4M
        for(i = 0; i < SUB_BLK_WD; i ++)
193
74.6M
        {
194
74.6M
            sum_3 += *pu1_tmp_top++;
195
74.6M
            sum_4 += *pu1_tmp_bot++;
196
74.6M
        }
197
198
18.7M
        sum_diff = ABS_DIF(sum_3, sum_4);
199
200
        /*********************************************************************/
201
        /* Thresholding.                                                     */
202
        /*********************************************************************/
203
18.7M
        if(sum_diff >= rsum_csum_thresh)
204
152k
            adj += sum_diff;
205
206
18.7M
        pu1_tmp_top += top_row_end_incr;
207
18.7M
        pu1_tmp_bot += bot_row_end_incr;
208
209
        /*************************************************************************/
210
        /* Alt diff : Row based                                                  */
211
        /*************************************************************************/
212
18.7M
        alt += ABS_DIF(sum_1, sum_3);
213
18.7M
        alt += ABS_DIF(sum_2, sum_4);
214
215
18.7M
    }
216
217
    /*************************************************************************/
218
    /* In the adjacent sad calculation by column-method, the rows of both    */
219
    /* the fields are averaged separately and then summed across the column. */
220
    /* The difference of the two values, thus obtained, is added to the      */
221
    /* adjacent sad value, if it is beyond the threshold.                    */
222
    /*************************************************************************/
223
224
9.50M
    pu1_top_0 = pu1_top;
225
9.50M
    pu1_top_1 = pu1_top_0 + top_strd;
226
9.50M
    pu1_top_2 = pu1_top_1 + top_strd;
227
9.50M
    pu1_top_3 = pu1_top_2 + top_strd;
228
229
9.50M
    pu1_bot_0 = pu1_bot;
230
9.50M
    pu1_bot_1 = pu1_bot_0 + bot_strd;
231
9.50M
    pu1_bot_2 = pu1_bot_1 + bot_strd;
232
9.50M
    pu1_bot_3 = pu1_bot_2 + bot_strd;
233
234
    /*************************************************************************/
235
    /* Adj dif: Col based                                                    */
236
    /*************************************************************************/
237
9.50M
    diff_sum = 0;
238
239
    /*************************************************************************/
240
    /* As the DSP implementation of this modules is anyway going to assume   */
241
    /* the size of the block to the fixed (8x4 or two 4x4's), the height of  */
242
    /* block is also kept to be 8, to have a clean implementation.           */
243
    /*************************************************************************/
244
46.5M
    for(i = 0; i < SUB_BLK_WD; i ++)
245
37.0M
    {
246
37.0M
        WORD32 val_1;
247
37.0M
        WORD32 val_2;
248
37.0M
        WORD32 tmp_1, tmp_2;
249
37.0M
        WORD32 tmp_diff;
250
251
37.0M
        tmp_1 = AVG(pu1_top_0[i], pu1_top_1[i]);
252
37.0M
        tmp_2 = AVG(pu1_top_2[i], pu1_top_3[i]);
253
37.0M
        val_1 = AVG(tmp_1,        tmp_2);
254
255
37.0M
        tmp_1 = AVG(pu1_bot_0[i], pu1_bot_1[i]);
256
37.0M
        tmp_2 = AVG(pu1_bot_2[i], pu1_bot_3[i]);
257
37.0M
        val_2 = AVG(tmp_1,        tmp_2);
258
259
37.0M
        tmp_diff = ABS_DIF(val_1, val_2);
260
261
37.0M
        if(tmp_diff >= (rsum_csum_thresh >> 2))
262
369k
            diff_sum += tmp_diff;
263
37.0M
    }
264
265
266
9.50M
    adj += diff_sum << 2;
267
268
    /*************************************************************************/
269
    /* Alt diff : Col based                                                  */
270
    /*************************************************************************/
271
9.50M
    diff_sum = 0;
272
273
46.3M
    for(i = 0; i < SUB_BLK_WD; i ++)
274
36.8M
    {
275
36.8M
        WORD32 val_1;
276
36.8M
        WORD32 val_2;
277
36.8M
        WORD32 tmp_1, tmp_2;
278
36.8M
        WORD32 tmp_diff;
279
280
36.8M
        tmp_1 = AVG(pu1_top_0[i], pu1_bot_0[i]);
281
36.8M
        tmp_2 = AVG(pu1_top_2[i], pu1_bot_2[i]);
282
36.8M
        val_1 = AVG(tmp_1,        tmp_2);
283
284
36.8M
        tmp_1 = AVG(pu1_top_1[i], pu1_bot_1[i]);
285
36.8M
        tmp_2 = AVG(pu1_top_3[i], pu1_bot_3[i]);
286
36.8M
        val_2 = AVG(tmp_1, tmp_2);
287
288
36.8M
        tmp_diff = ABS_DIF(val_1, val_2);
289
290
36.8M
        diff_sum += tmp_diff;
291
36.8M
    }
292
293
    /*************************************************************************/
294
    /* because of the averaging used in place of summation, a factor of 4 is */
295
    /* needed while adding the the diff_sum to the sad.                      */
296
    /*************************************************************************/
297
298
9.50M
    alt += diff_sum << 2;
299
300
9.50M
    pu1_top += SUB_BLK_WD;
301
9.50M
    pu1_bot += SUB_BLK_WD;
302
303
9.50M
    alt += (alt >> sad_bias_mult_shift) + (sad_bias_additive >> 1);
304
9.50M
    ca   = (alt < adj);
305
306
9.50M
    return ca;
307
9.50M
}
308
309
/**
310
*******************************************************************************
311
*
312
* @brief
313
* Combing artifact check function for 8x8 block
314
*
315
* @par   Description
316
* Determines CAC for 8x8 block by calling 8x4 CAC function
317
*
318
* @param[in] pu1_top
319
*  Top field
320
*
321
* @param[in] pu1_bot
322
*  Bottom field
323
*
324
* @param[in] top_strd
325
*  Top field Stride
326
*
327
* @param[in] bot_strd
328
*  Bottom field stride
329
*
330
* @returns
331
* combing artifact flag (1 = detected, 0 = not detected)
332
*
333
* @remarks
334
*
335
*******************************************************************************
336
*/
337
WORD32 ideint_cac_8x8(UWORD8 *pu1_top,
338
                      UWORD8 *pu1_bot,
339
                      WORD32 top_strd,
340
                      WORD32 bot_strd)
341
6.92M
{
342
6.92M
    WORD32 ca;        /* combing artifact result                          */
343
6.92M
    WORD32 k;
344
345
6.92M
    ca = 0;
346
    /*************************************************************************/
347
    /* This loop runs for the two halves of the 4x8 block.                   */
348
    /*************************************************************************/
349
16.4M
    for(k = 0; k < 2; k ++)
350
9.50M
    {
351
9.50M
        ca |= cac_4x8(pu1_top, pu1_bot, top_strd, bot_strd);
352
353
9.50M
        pu1_top += SUB_BLK_WD;
354
9.50M
        pu1_bot += SUB_BLK_WD;
355
356
        /* If Combing Artifact is detected, then return. Else continue to
357
         * check the next half
358
         */
359
9.50M
        if(ca)
360
22.8k
            return ca;
361
9.50M
    }
362
363
6.90M
    return ca;
364
6.92M
}
365