Coverage Report

Created: 2025-08-11 06:35

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