Coverage Report

Created: 2025-10-10 06:56

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
13.0M
{
105
13.0M
    WORD32 ca;
106
13.0M
    WORD32 adj;
107
13.0M
    WORD32 alt;
108
13.0M
    UWORD8 *pu1_tmp_top;
109
13.0M
    UWORD8 *pu1_tmp_bot;
110
13.0M
    WORD32 i;
111
13.0M
    WORD32 j;
112
13.0M
    UWORD8 *pu1_top_0;
113
13.0M
    UWORD8 *pu1_top_1;
114
13.0M
    UWORD8 *pu1_top_2;
115
13.0M
    UWORD8 *pu1_top_3;
116
13.0M
    UWORD8 *pu1_bot_0;
117
13.0M
    UWORD8 *pu1_bot_1;
118
13.0M
    UWORD8 *pu1_bot_2;
119
13.0M
    UWORD8 *pu1_bot_3;
120
13.0M
    WORD32 rsum_csum_thresh;
121
13.0M
    WORD32 sad_bias_mult_shift;
122
13.0M
    WORD32 sad_bias_additive;
123
124
13.0M
    WORD32 diff_sum;
125
13.0M
    WORD32 top_row_end_incr;
126
13.0M
    WORD32 bot_row_end_incr;
127
128
13.0M
    ca = 0;
129
130
13.0M
    adj = 0;
131
13.0M
    alt = 0;
132
133
13.0M
    rsum_csum_thresh    = RSUM_CSUM_THRESH;
134
13.0M
    sad_bias_additive   = SAD_BIAS_ADDITIVE;
135
13.0M
    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
13.0M
    pu1_tmp_top = pu1_top;
150
13.0M
    pu1_tmp_bot = pu1_bot;
151
152
13.0M
    top_row_end_incr = top_strd - SUB_BLK_WD;
153
13.0M
    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
38.7M
    for(j = 0; j < BLK_HT; j += 4)
160
25.7M
    {
161
25.7M
        WORD32 sum_1, sum_2, sum_3, sum_4;
162
25.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
25.7M
        sum_1 = 0;
169
25.7M
        sum_2 = 0;
170
171
128M
        for(i = 0; i < SUB_BLK_WD; i ++)
172
103M
        {
173
103M
            sum_1 += *pu1_tmp_top++;
174
103M
            sum_2 += *pu1_tmp_bot++;
175
103M
        }
176
177
25.7M
        sum_diff = ABS_DIF(sum_1, sum_2);
178
179
        /*********************************************************************/
180
        /* Thresholding.                                                     */
181
        /*********************************************************************/
182
25.7M
        if(sum_diff >= rsum_csum_thresh)
183
126k
            adj += sum_diff;
184
185
25.7M
        pu1_tmp_top += top_row_end_incr;
186
25.7M
        pu1_tmp_bot += bot_row_end_incr;
187
188
189
25.7M
        sum_3 = 0;
190
25.7M
        sum_4 = 0;
191
192
129M
        for(i = 0; i < SUB_BLK_WD; i ++)
193
103M
        {
194
103M
            sum_3 += *pu1_tmp_top++;
195
103M
            sum_4 += *pu1_tmp_bot++;
196
103M
        }
197
198
25.7M
        sum_diff = ABS_DIF(sum_3, sum_4);
199
200
        /*********************************************************************/
201
        /* Thresholding.                                                     */
202
        /*********************************************************************/
203
25.7M
        if(sum_diff >= rsum_csum_thresh)
204
130k
            adj += sum_diff;
205
206
25.7M
        pu1_tmp_top += top_row_end_incr;
207
25.7M
        pu1_tmp_bot += bot_row_end_incr;
208
209
        /*************************************************************************/
210
        /* Alt diff : Row based                                                  */
211
        /*************************************************************************/
212
25.7M
        alt += ABS_DIF(sum_1, sum_3);
213
25.7M
        alt += ABS_DIF(sum_2, sum_4);
214
215
25.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
13.0M
    pu1_top_0 = pu1_top;
225
13.0M
    pu1_top_1 = pu1_top_0 + top_strd;
226
13.0M
    pu1_top_2 = pu1_top_1 + top_strd;
227
13.0M
    pu1_top_3 = pu1_top_2 + top_strd;
228
229
13.0M
    pu1_bot_0 = pu1_bot;
230
13.0M
    pu1_bot_1 = pu1_bot_0 + bot_strd;
231
13.0M
    pu1_bot_2 = pu1_bot_1 + bot_strd;
232
13.0M
    pu1_bot_3 = pu1_bot_2 + bot_strd;
233
234
    /*************************************************************************/
235
    /* Adj dif: Col based                                                    */
236
    /*************************************************************************/
237
13.0M
    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
64.3M
    for(i = 0; i < SUB_BLK_WD; i ++)
245
51.3M
    {
246
51.3M
        WORD32 val_1;
247
51.3M
        WORD32 val_2;
248
51.3M
        WORD32 tmp_1, tmp_2;
249
51.3M
        WORD32 tmp_diff;
250
251
51.3M
        tmp_1 = AVG(pu1_top_0[i], pu1_top_1[i]);
252
51.3M
        tmp_2 = AVG(pu1_top_2[i], pu1_top_3[i]);
253
51.3M
        val_1 = AVG(tmp_1,        tmp_2);
254
255
51.3M
        tmp_1 = AVG(pu1_bot_0[i], pu1_bot_1[i]);
256
51.3M
        tmp_2 = AVG(pu1_bot_2[i], pu1_bot_3[i]);
257
51.3M
        val_2 = AVG(tmp_1,        tmp_2);
258
259
51.3M
        tmp_diff = ABS_DIF(val_1, val_2);
260
261
51.3M
        if(tmp_diff >= (rsum_csum_thresh >> 2))
262
382k
            diff_sum += tmp_diff;
263
51.3M
    }
264
265
266
13.0M
    adj += diff_sum << 2;
267
268
    /*************************************************************************/
269
    /* Alt diff : Col based                                                  */
270
    /*************************************************************************/
271
13.0M
    diff_sum = 0;
272
273
64.3M
    for(i = 0; i < SUB_BLK_WD; i ++)
274
51.3M
    {
275
51.3M
        WORD32 val_1;
276
51.3M
        WORD32 val_2;
277
51.3M
        WORD32 tmp_1, tmp_2;
278
51.3M
        WORD32 tmp_diff;
279
280
51.3M
        tmp_1 = AVG(pu1_top_0[i], pu1_bot_0[i]);
281
51.3M
        tmp_2 = AVG(pu1_top_2[i], pu1_bot_2[i]);
282
51.3M
        val_1 = AVG(tmp_1,        tmp_2);
283
284
51.3M
        tmp_1 = AVG(pu1_top_1[i], pu1_bot_1[i]);
285
51.3M
        tmp_2 = AVG(pu1_top_3[i], pu1_bot_3[i]);
286
51.3M
        val_2 = AVG(tmp_1, tmp_2);
287
288
51.3M
        tmp_diff = ABS_DIF(val_1, val_2);
289
290
51.3M
        diff_sum += tmp_diff;
291
51.3M
    }
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
13.0M
    alt += diff_sum << 2;
299
300
13.0M
    pu1_top += SUB_BLK_WD;
301
13.0M
    pu1_bot += SUB_BLK_WD;
302
303
13.0M
    alt += (alt >> sad_bias_mult_shift) + (sad_bias_additive >> 1);
304
13.0M
    ca   = (alt < adj);
305
306
13.0M
    return ca;
307
13.0M
}
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
9.65M
{
342
9.65M
    WORD32 ca;        /* combing artifact result                          */
343
9.65M
    WORD32 k;
344
345
9.65M
    ca = 0;
346
    /*************************************************************************/
347
    /* This loop runs for the two halves of the 4x8 block.                   */
348
    /*************************************************************************/
349
22.6M
    for(k = 0; k < 2; k ++)
350
13.0M
    {
351
13.0M
        ca |= cac_4x8(pu1_top, pu1_bot, top_strd, bot_strd);
352
353
13.0M
        pu1_top += SUB_BLK_WD;
354
13.0M
        pu1_bot += SUB_BLK_WD;
355
356
        /* If Combing Artifact is detected, then return. Else continue to
357
         * check the next half
358
         */
359
13.0M
        if(ca)
360
26.4k
            return ca;
361
13.0M
    }
362
363
9.62M
    return ca;
364
9.65M
}
365