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*  ihevc_deblk_edge_filter.c
22*
23* @brief
24*  Contains function definitions for deblocking filters
25*
26* @author
27*  Srinivas T
28*
29* @par List of Functions:
30*   - ihevc_deblk_luma_vert()
31*   - ihevc_deblk_luma_horz()
32*   - ihevc_deblk_chroma_vert()
33*   - ihevc_deblk_chroma_horz()
34* @remarks
35*  None
36*
37*******************************************************************************
38*/
39#include <stdlib.h>
40#include <stdio.h>
41#include <assert.h>
42#include "ihevc_typedefs.h"
43#include "ihevc_macros.h"
44#include "ihevc_platform_macros.h"
45#include "ihevc_func_selector.h"
46#include "ihevc_deblk.h"
47#include "ihevc_deblk_tables.h"
48#include "ihevc_debug.h"
49
50
51/**
52*******************************************************************************
53*
54* @brief
55*       Decision process and filtering for the luma block vertical edge.
56*
57* @par Description:
58*     The decision process for the luma block vertical edge is  carried out and
59*     an appropriate filter is applied. The  boundary filter strength, bs should
60*     be greater than 0.  The pcm flags and the transquant bypass flags should
61*     be  taken care of by the calling function.
62*
63* @param[in] pu1_src
64*  Pointer to the src sample q(0,0)
65*
66* @param[in] src_strd
67*  Source stride
68*
69* @param[in] bs
70*  Boundary filter strength of q(0,0)
71*
72* @param[in] quant_param_p
73*  quantization parameter of p block
74*
75* @param[in] quant_param_q
76*  quantization parameter of p block
77*
78* @param[in] beta_offset_div2
79*
80*
81* @param[in] tc_offset_div2
82*
83*
84* @param[in] filter_flag_p
85*  flag whether to filter the p block
86*
87* @param[in] filter_flag_q
88*  flag whether to filter the q block
89*
90* @returns
91*
92* @remarks
93*  None
94*
95*******************************************************************************
96*/
97
98void ihevc_deblk_luma_vert(UWORD8 *pu1_src,
99                           WORD32 src_strd,
100                           WORD32 bs,
101                           WORD32 quant_param_p,
102                           WORD32 quant_param_q,
103                           WORD32 beta_offset_div2,
104                           WORD32 tc_offset_div2,
105                           WORD32 filter_flag_p,
106                           WORD32 filter_flag_q)
107{
108    WORD32 qp_luma, beta_indx, tc_indx;
109    WORD32 beta, tc;
110    WORD32 dp0, dp3, dq0, dq3, d0, d3, dp, dq, d;
111    WORD32 d_sam0, d_sam3;
112    WORD32 de, dep, deq;
113    WORD32 row;
114    WORD32 tmp_p0, tmp_p1, tmp_p2, tmp_q0, tmp_q1, tmp_q2;
115    WORD32 delta, delta_p, delta_q;
116
117    ASSERT((bs > 0) && (bs <= 3));
118    ASSERT(filter_flag_p || filter_flag_q);
119
120    qp_luma = (quant_param_p + quant_param_q + 1) >> 1;
121    beta_indx = CLIP3(qp_luma + (beta_offset_div2 << 1), 0, 51);
122
123    /* BS based on implementation can take value 3 if it is intra/inter egde          */
124    /* based on BS, tc index is calcuated by adding 2 * ( bs - 1) to QP and tc_offset */
125    /* for BS = 1 adding factor is (0*2), BS = 2 or 3 adding factor is (1*2)          */
126    /* the above desired functionallity is achieved by doing (2*(bs>>1))              */
127
128    tc_indx = CLIP3(qp_luma + (2 * (bs >> 1)) + (tc_offset_div2 << 1), 0, 53);
129
130    beta = gai4_ihevc_beta_table[beta_indx];
131    tc = gai4_ihevc_tc_table[tc_indx];
132    if(0 == tc)
133    {
134        return;
135    }
136
137    dq0 = ABS(pu1_src[2] - 2 * pu1_src[1] + pu1_src[0]);
138    dq3 = ABS(pu1_src[3 * src_strd + 2] - 2 * pu1_src[3 * src_strd + 1]
139                    + pu1_src[3 * src_strd + 0]);
140    dp0 = ABS(pu1_src[-3] - 2 * pu1_src[-2] + pu1_src[-1]);
141    dp3 = ABS(pu1_src[3 * src_strd - 3] - 2 * pu1_src[3 * src_strd - 2]
142                    + pu1_src[3 * src_strd - 1]);
143
144    d0 = dp0 + dq0;
145    d3 = dp3 + dq3;
146
147    dp = dp0 + dp3;
148    dq = dq0 + dq3;
149
150    d = d0 + d3;
151
152    de = 0;
153    dep = 0;
154    deq = 0;
155
156    if(d < beta)
157    {
158        d_sam0 = 0;
159        if((2 * d0 < (beta >> 2))
160                        && (ABS(pu1_src[3] - pu1_src[0]) + ABS(pu1_src[-1] - pu1_src[-4])
161                                        < (beta >> 3))
162                        && ABS(pu1_src[0] - pu1_src[-1]) < ((5 * tc + 1) >> 1))
163        {
164            d_sam0 = 1;
165        }
166
167        pu1_src += 3 * src_strd;
168        d_sam3 = 0;
169        if((2 * d3 < (beta >> 2))
170                        && (ABS(pu1_src[3] - pu1_src[0]) + ABS(pu1_src[-1] - pu1_src[-4])
171                                        < (beta >> 3))
172                        && ABS(pu1_src[0] - pu1_src[-1]) < ((5 * tc + 1) >> 1))
173        {
174            d_sam3 = 1;
175        }
176        pu1_src -= 3 * src_strd;
177
178        de = (d_sam0 == 1 && d_sam3 == 1) ? 2 : 1;
179        dep = (dp < (beta + (beta >> 1)) >> 3) ? 1 : 0;
180        deq = (dq < (beta + (beta >> 1)) >> 3) ? 1 : 0;
181        if(tc <= 1)
182        {
183            dep = 0;
184            deq = 0;
185        }
186    }
187
188    if(de != 0)
189    {
190        for(row = 0; row < 4; row++)
191        {
192            tmp_p0 = pu1_src[-1];
193            tmp_p1 = pu1_src[-2];
194            tmp_p2 = pu1_src[-3];
195
196            tmp_q0 = pu1_src[0];
197            tmp_q1 = pu1_src[1];
198            tmp_q2 = pu1_src[2];
199
200            if(de == 2)
201            {
202                tmp_q0 = CLIP3((pu1_src[2] + 2 * pu1_src[1] +
203                                2 * pu1_src[0] + 2 * pu1_src[-1] +
204                                pu1_src[-2] + 4) >> 3,
205                                pu1_src[0] - 2 * tc,
206                                pu1_src[0] + 2 * tc);
207
208                tmp_q1 = CLIP3((pu1_src[2] + pu1_src[1] + pu1_src[0] +
209                                pu1_src[-1] + 2) >> 2,
210                                pu1_src[1] - 2 * tc,
211                                pu1_src[1] + 2 * tc);
212
213                tmp_q2 = CLIP3((2 * pu1_src[3] + 3 * pu1_src[2] +
214                                pu1_src[1] + pu1_src[0] +
215                                pu1_src[-1] + 4) >> 3,
216                                pu1_src[2] - 2 * tc,
217                                pu1_src[2] + 2 * tc);
218
219                tmp_p0 = CLIP3((pu1_src[1] + 2 * pu1_src[0] +
220                                2 * pu1_src[-1] + 2 * pu1_src[-2] +
221                                pu1_src[-3] + 4) >> 3,
222                                pu1_src[-1] - 2 * tc,
223                                pu1_src[-1] + 2 * tc);
224
225                tmp_p1 = CLIP3((pu1_src[0] + pu1_src[-1] +
226                                pu1_src[-2] + pu1_src[-3] + 2) >> 2,
227                                pu1_src[-2] - 2 * tc,
228                                pu1_src[-2] + 2 * tc);
229
230                tmp_p2 = CLIP3((pu1_src[0] + pu1_src[-1] +
231                                pu1_src[-2] + 3 * pu1_src[-3] +
232                                2 * pu1_src[-4] + 4) >> 3,
233                                pu1_src[-3] - 2 * tc,
234                                pu1_src[-3] + 2 * tc);
235            }
236            else
237            {
238                delta = (9 * (pu1_src[0] - pu1_src[-1]) -
239                                3 * (pu1_src[1] - pu1_src[-2]) + 8) >> 4;
240                if(ABS(delta) < 10 * tc)
241                {
242                    delta = CLIP3(delta, -tc, tc);
243
244                    tmp_p0 = CLIP_U8(pu1_src[-1] + delta);
245                    tmp_q0 = CLIP_U8(pu1_src[0] - delta);
246
247                    if(dep == 1)
248                    {
249                        delta_p = CLIP3((((pu1_src[-3] + pu1_src[-1] + 1) >> 1)
250                                        - pu1_src[-2] + delta) >> 1,
251                                        -(tc >> 1),
252                                        (tc >> 1));
253                        tmp_p1 = CLIP_U8(pu1_src[-2] + delta_p);
254                    }
255
256                    if(deq == 1)
257                    {
258                        delta_q = CLIP3((((pu1_src[2] + pu1_src[0] + 1) >> 1)
259                                        - pu1_src[1] - delta) >> 1,
260                                        -(tc >> 1),
261                                        (tc >> 1));
262                        tmp_q1 = CLIP_U8(pu1_src[1] + delta_q);
263                    }
264                }
265            }
266
267            if(filter_flag_p != 0)
268            {
269                pu1_src[-3] = tmp_p2;
270                pu1_src[-2] = tmp_p1;
271                pu1_src[-1] = tmp_p0;
272            }
273
274            if(filter_flag_q != 0)
275            {
276                pu1_src[0] = tmp_q0;
277                pu1_src[1] = tmp_q1;
278                pu1_src[2] = tmp_q2;
279            }
280
281            pu1_src += src_strd;
282        }
283    }
284
285}
286
287/**
288*******************************************************************************
289*
290* @brief
291*
292*     Decision process and filtering for the luma block horizontal edge
293*
294* @par Description:
295*     The decision process for the luma block horizontal edge  is carried out
296*    and an appropriate filter is applied. The  boundary filter strength, bs
297*    should be greater than 0.  The pcm flags and the transquant bypass flags
298*    should be  taken care of by the calling function.
299*
300* @param[in] pu1_src
301*  Pointer to the src sample q(0,0)
302*
303* @param[in] src_strd
304*  Source stride
305*
306* @param[in] bs
307*  Boundary filter strength of q(0,0)
308*
309* @param[in] quant_param_p
310*  quantization parameter of p block
311*
312* @param[in] quant_param_q
313*  quantization parameter of p block
314*
315* @param[in] beta_offset_div2
316*
317*
318* @param[in] tc_offset_div2
319*
320*
321* @param[in] filter_flag_p
322*  flag whether to filter the p block
323*
324* @param[in] filter_flag_q
325*  flag whether to filter the q block
326*
327* @returns
328*
329* @remarks
330*  None
331*
332*******************************************************************************
333*/
334
335void ihevc_deblk_luma_horz(UWORD8 *pu1_src,
336                           WORD32 src_strd,
337                           WORD32 bs,
338                           WORD32 quant_param_p,
339                           WORD32 quant_param_q,
340                           WORD32 beta_offset_div2,
341                           WORD32 tc_offset_div2,
342                           WORD32 filter_flag_p,
343                           WORD32 filter_flag_q)
344{
345    WORD32 qp_luma, beta_indx, tc_indx;
346    WORD32 beta, tc;
347    WORD32 dp0, dp3, dq0, dq3, d0, d3, dp, dq, d;
348    WORD32 d_sam0, d_sam3;
349    WORD32 de, dep, deq;
350    WORD32 col;
351    WORD32 tmp_p0, tmp_p1, tmp_p2, tmp_q0, tmp_q1, tmp_q2;
352    WORD32 delta, delta_p, delta_q;
353
354    ASSERT((bs > 0));
355    ASSERT(filter_flag_p || filter_flag_q);
356
357    qp_luma = (quant_param_p + quant_param_q + 1) >> 1;
358    beta_indx = CLIP3(qp_luma + (beta_offset_div2 << 1), 0, 51);
359
360    /* BS based on implementation can take value 3 if it is intra/inter egde          */
361    /* based on BS, tc index is calcuated by adding 2 * ( bs - 1) to QP and tc_offset */
362    /* for BS = 1 adding factor is (0*2), BS = 2 or 3 adding factor is (1*2)          */
363    /* the above desired functionallity is achieved by doing (2*(bs>>1))              */
364
365    tc_indx = CLIP3(qp_luma + 2 * (bs >> 1) + (tc_offset_div2 << 1), 0, 53);
366
367    beta = gai4_ihevc_beta_table[beta_indx];
368    tc = gai4_ihevc_tc_table[tc_indx];
369    if(0 == tc)
370    {
371        return;
372    }
373
374    dq0 = ABS(pu1_src[2 * src_strd] - 2 * pu1_src[1 * src_strd] +
375                    pu1_src[0 * src_strd]);
376
377    dq3 = ABS(pu1_src[3 + 2 * src_strd] - 2 * pu1_src[3 + 1 * src_strd] +
378                    pu1_src[3 + 0 * src_strd]);
379
380    dp0 = ABS(pu1_src[-3 * src_strd] - 2 * pu1_src[-2 * src_strd] +
381                    pu1_src[-1 * src_strd]);
382
383    dp3 = ABS(pu1_src[3 - 3 * src_strd] - 2 * pu1_src[3 - 2 * src_strd] +
384                    pu1_src[3 - 1 * src_strd]);
385
386    d0 = dp0 + dq0;
387    d3 = dp3 + dq3;
388
389    dp = dp0 + dp3;
390    dq = dq0 + dq3;
391
392    d = d0 + d3;
393
394    de = 0;
395    dep = 0;
396    deq = 0;
397
398    if(d < beta)
399    {
400        d_sam0 = 0;
401        if((2 * d0 < (beta >> 2))
402                        && (ABS(pu1_src[3 * src_strd] - pu1_src[0 * src_strd]) +
403                                        ABS(pu1_src[-1 * src_strd] - pu1_src[-4 * src_strd])
404                                        < (beta >> 3))
405                        && ABS(pu1_src[0 * src_strd] - pu1_src[-1 * src_strd])
406                        < ((5 * tc + 1) >> 1))
407        {
408            d_sam0 = 1;
409        }
410
411        pu1_src += 3;
412        d_sam3 = 0;
413        if((2 * d3 < (beta >> 2))
414                        && (ABS(pu1_src[3 * src_strd] - pu1_src[0 * src_strd]) +
415                                        ABS(pu1_src[-1 * src_strd] - pu1_src[-4 * src_strd])
416                                        < (beta >> 3))
417                        && ABS(pu1_src[0 * src_strd] - pu1_src[-1 * src_strd])
418                        < ((5 * tc + 1) >> 1))
419        {
420            d_sam3 = 1;
421        }
422        pu1_src -= 3;
423
424        de = (d_sam0 == 1 && d_sam3 == 1) ? 2 : 1;
425        dep = (dp < ((beta + (beta >> 1)) >> 3)) ? 1 : 0;
426        deq = (dq < ((beta + (beta >> 1)) >> 3)) ? 1 : 0;
427        if(tc <= 1)
428        {
429            dep = 0;
430            deq = 0;
431        }
432    }
433
434    if(de != 0)
435    {
436        for(col = 0; col < 4; col++)
437        {
438            tmp_p0 = pu1_src[-1 * src_strd];
439            tmp_p1 = pu1_src[-2 * src_strd];
440            tmp_p2 = pu1_src[-3 * src_strd];
441
442            tmp_q0 = pu1_src[0 * src_strd];
443            tmp_q1 = pu1_src[1 * src_strd];
444            tmp_q2 = pu1_src[2 * src_strd];
445            if(de == 2)
446            {
447                tmp_q0 = CLIP3((pu1_src[2 * src_strd] +
448                                2 * pu1_src[1 * src_strd] +
449                                2 * pu1_src[0 * src_strd] +
450                                2 * pu1_src[-1 * src_strd] +
451                                pu1_src[-2 * src_strd] + 4) >> 3,
452                                pu1_src[0 * src_strd] - 2 * tc,
453                                pu1_src[0 * src_strd] + 2 * tc);
454
455                tmp_q1 = CLIP3((pu1_src[2 * src_strd] +
456                                pu1_src[1 * src_strd] +
457                                pu1_src[0 * src_strd] +
458                                pu1_src[-1 * src_strd] + 2) >> 2,
459                                pu1_src[1 * src_strd] - 2 * tc,
460                                pu1_src[1 * src_strd] + 2 * tc);
461
462                tmp_q2 = CLIP3((2 * pu1_src[3 * src_strd] +
463                                3 * pu1_src[2 * src_strd] +
464                                pu1_src[1 * src_strd] +
465                                pu1_src[0 * src_strd] +
466                                pu1_src[-1 * src_strd] + 4) >> 3,
467                                pu1_src[2 * src_strd] - 2 * tc,
468                                pu1_src[2 * src_strd] + 2 * tc);
469
470                tmp_p0 = CLIP3((pu1_src[1 * src_strd] +
471                                2 * pu1_src[0 * src_strd] +
472                                2 * pu1_src[-1 * src_strd] +
473                                2 * pu1_src[-2 * src_strd] +
474                                pu1_src[-3 * src_strd] + 4) >> 3,
475                                pu1_src[-1 * src_strd] - 2 * tc,
476                                pu1_src[-1 * src_strd] + 2 * tc);
477
478                tmp_p1 = CLIP3((pu1_src[0 * src_strd] +
479                                pu1_src[-1 * src_strd] +
480                                pu1_src[-2 * src_strd] +
481                                pu1_src[-3 * src_strd] + 2) >> 2,
482                                pu1_src[-2 * src_strd] - 2 * tc,
483                                pu1_src[-2 * src_strd] + 2 * tc);
484
485                tmp_p2 = CLIP3((pu1_src[0 * src_strd] +
486                                pu1_src[-1 * src_strd] +
487                                pu1_src[-2 * src_strd] +
488                                3 * pu1_src[-3 * src_strd] +
489                                2 * pu1_src[-4 * src_strd] + 4) >> 3,
490                                pu1_src[-3 * src_strd] - 2 * tc,
491                                pu1_src[-3 * src_strd] + 2 * tc);
492            }
493            else
494            {
495                delta = (9 * (pu1_src[0 * src_strd] - pu1_src[-1 * src_strd]) -
496                                3 * (pu1_src[1 * src_strd] - pu1_src[-2 * src_strd]) +
497                                8) >> 4;
498                if(ABS(delta) < 10 * tc)
499                {
500                    delta = CLIP3(delta, -tc, tc);
501
502                    tmp_p0 = CLIP_U8(pu1_src[-1 * src_strd] + delta);
503                    tmp_q0 = CLIP_U8(pu1_src[0 * src_strd] - delta);
504
505                    if(dep == 1)
506                    {
507                        delta_p = CLIP3((((pu1_src[-3 * src_strd] +
508                                        pu1_src[-1 * src_strd] + 1) >> 1) -
509                                        pu1_src[-2 * src_strd] + delta) >> 1,
510                                        -(tc >> 1),
511                                        (tc >> 1));
512                        tmp_p1 = CLIP_U8(pu1_src[-2 * src_strd] + delta_p);
513                    }
514
515                    if(deq == 1)
516                    {
517                        delta_q = CLIP3((((pu1_src[2 * src_strd] +
518                                        pu1_src[0 * src_strd] + 1) >> 1) -
519                                        pu1_src[1 * src_strd] - delta) >> 1,
520                                        -(tc >> 1),
521                                        (tc >> 1));
522                        tmp_q1 = CLIP_U8(pu1_src[1 * src_strd] + delta_q);
523                    }
524                }
525            }
526
527            if(filter_flag_p != 0)
528            {
529                pu1_src[-3 * src_strd] = tmp_p2;
530                pu1_src[-2 * src_strd] = tmp_p1;
531                pu1_src[-1 * src_strd] = tmp_p0;
532            }
533
534            if(filter_flag_q != 0)
535            {
536                pu1_src[0 * src_strd] = tmp_q0;
537                pu1_src[1 * src_strd] = tmp_q1;
538                pu1_src[2 * src_strd] = tmp_q2;
539            }
540
541            pu1_src += 1;
542        }
543    }
544
545}
546
547/**
548*******************************************************************************
549*
550* @brief
551*     Filtering for the chroma block vertical edge.
552*
553* @par Description:
554*     Filter for chroma vertical edge. The  boundary filter strength, bs
555*    should be greater than 1.  The pcm flags and the transquant bypass flags
556*    should be  taken care of by the calling function.
557*
558* @param[in] pu1_src
559*  Pointer to the src sample q(0,0)
560*
561* @param[in] src_strd
562*  Source stride
563*
564* @param[in] bs
565*  Boundary filter strength of q(0,0)
566*
567* @param[in] quant_param_p
568*  quantization parameter of p block
569*
570* @param[in] quant_param_q
571*  quantization parameter of p block
572*
573* @param[in] beta_offset_div2
574*
575*
576* @param[in] tc_offset_div2
577*
578*
579* @param[in] filter_flag_p
580*  flag whether to filter the p block
581*
582* @param[in] filter_flag_q
583*  flag whether to filter the q block
584*
585* @returns
586*
587* @remarks
588*  None
589*
590*******************************************************************************
591*/
592
593void ihevc_deblk_chroma_vert(UWORD8 *pu1_src,
594                             WORD32 src_strd,
595                             WORD32 quant_param_p,
596                             WORD32 quant_param_q,
597                             WORD32 qp_offset_u,
598                             WORD32 qp_offset_v,
599                             WORD32 tc_offset_div2,
600                             WORD32 filter_flag_p,
601                             WORD32 filter_flag_q)
602{
603    WORD32 qp_indx_u, qp_chroma_u;
604    WORD32 qp_indx_v, qp_chroma_v;
605    WORD32 tc_indx_u, tc_u;
606    WORD32 tc_indx_v, tc_v;
607    WORD32 delta_u, tmp_p0_u, tmp_q0_u;
608    WORD32 delta_v, tmp_p0_v, tmp_q0_v;
609    WORD32 row;
610
611    ASSERT(filter_flag_p || filter_flag_q);
612
613    /* chroma processing is done only if BS is 2             */
614    /* this function is assumed to be called only if BS is 2 */
615    qp_indx_u = qp_offset_u + ((quant_param_p + quant_param_q + 1) >> 1);
616    qp_chroma_u = qp_indx_u < 0 ? qp_indx_u : (qp_indx_u > 57 ? qp_indx_u - 6 : gai4_ihevc_qp_table[qp_indx_u]);
617
618    qp_indx_v = qp_offset_v + ((quant_param_p + quant_param_q + 1) >> 1);
619    qp_chroma_v = qp_indx_v < 0 ? qp_indx_v : (qp_indx_v > 57 ? qp_indx_v - 6 : gai4_ihevc_qp_table[qp_indx_v]);
620
621    tc_indx_u = CLIP3(qp_chroma_u + 2 + (tc_offset_div2 << 1), 0, 53);
622    tc_u = gai4_ihevc_tc_table[tc_indx_u];
623
624    tc_indx_v = CLIP3(qp_chroma_v + 2 + (tc_offset_div2 << 1), 0, 53);
625    tc_v = gai4_ihevc_tc_table[tc_indx_v];
626
627    if(0 == tc_u && 0 == tc_v)
628    {
629        return;
630    }
631
632    for(row = 0; row < 4; row++)
633    {
634        delta_u = CLIP3((((pu1_src[0] - pu1_src[-2]) << 2) +
635                        pu1_src[-4] - pu1_src[2] + 4) >> 3,
636                        -tc_u, tc_u);
637
638        tmp_p0_u = CLIP_U8(pu1_src[-2] + delta_u);
639        tmp_q0_u = CLIP_U8(pu1_src[0] - delta_u);
640
641        delta_v = CLIP3((((pu1_src[1] - pu1_src[-1]) << 2) +
642                        pu1_src[-3] - pu1_src[3] + 4) >> 3,
643                        -tc_v, tc_v);
644
645        tmp_p0_v = CLIP_U8(pu1_src[-1] + delta_v);
646        tmp_q0_v = CLIP_U8(pu1_src[1] - delta_v);
647
648        if(filter_flag_p != 0)
649        {
650            pu1_src[-2] = tmp_p0_u;
651            pu1_src[-1] = tmp_p0_v;
652        }
653
654        if(filter_flag_q != 0)
655        {
656            pu1_src[0] = tmp_q0_u;
657            pu1_src[1] = tmp_q0_v;
658        }
659
660        pu1_src += src_strd;
661    }
662
663}
664
665
666
667/**
668*******************************************************************************
669*
670* @brief
671*   Filtering for the chroma block horizontal edge.
672*
673* @par Description:
674*     Filter for chroma horizontal edge. The  boundary filter strength, bs
675*    should be greater than 1.  The pcm flags and the transquant bypass flags
676*    should be  taken care of by the calling function.
677*
678* @param[in] pu1_src
679*  Pointer to the src sample q(0,0)
680*
681* @param[in] src_strd
682*  Source stride
683*
684* @param[in] bs
685*  Boundary filter strength of q(0,0)
686*
687* @param[in] quant_param_p
688*  quantization parameter of p block
689*
690* @param[in] quant_param_q
691*  quantization parameter of p block
692*
693* @param[in] beta_offset_div2
694*
695*
696* @param[in] tc_offset_div2
697*
698*
699* @param[in] filter_flag_p
700*  flag whether to filter the p block
701*
702* @param[in] filter_flag_q
703*  flag whether to filter the q block
704*
705* @returns
706*
707* @remarks
708*  None
709*
710*******************************************************************************
711*/
712
713void ihevc_deblk_chroma_horz(UWORD8 *pu1_src,
714                             WORD32 src_strd,
715                             WORD32 quant_param_p,
716                             WORD32 quant_param_q,
717                             WORD32 qp_offset_u,
718                             WORD32 qp_offset_v,
719                             WORD32 tc_offset_div2,
720                             WORD32 filter_flag_p,
721                             WORD32 filter_flag_q)
722{
723    WORD32 qp_indx_u, qp_chroma_u;
724    WORD32 qp_indx_v, qp_chroma_v;
725    WORD32 tc_indx_u, tc_u;
726    WORD32 tc_indx_v, tc_v;
727    WORD32 tc;
728
729    WORD32 delta, tmp_p0, tmp_q0;
730    WORD32 col;
731
732    ASSERT(filter_flag_p || filter_flag_q);
733
734    /* chroma processing is done only if BS is 2             */
735    /* this function is assumed to be called only if BS is 2 */
736    qp_indx_u = qp_offset_u + ((quant_param_p + quant_param_q + 1) >> 1);
737    qp_chroma_u = qp_indx_u < 0 ? qp_indx_u : (qp_indx_u > 57 ? qp_indx_u - 6 : gai4_ihevc_qp_table[qp_indx_u]);
738
739    qp_indx_v = qp_offset_v + ((quant_param_p + quant_param_q + 1) >> 1);
740    qp_chroma_v = qp_indx_v < 0 ? qp_indx_v : (qp_indx_v > 57 ? qp_indx_v - 6 : gai4_ihevc_qp_table[qp_indx_v]);
741
742    tc_indx_u = CLIP3(qp_chroma_u + 2 + (tc_offset_div2 << 1), 0, 53);
743    tc_u = gai4_ihevc_tc_table[tc_indx_u];
744
745    tc_indx_v = CLIP3(qp_chroma_v + 2 + (tc_offset_div2 << 1), 0, 53);
746    tc_v = gai4_ihevc_tc_table[tc_indx_v];
747
748    if(0 == tc_u && 0 == tc_v)
749    {
750        return;
751    }
752
753    for(col = 0; col < 8; col++)
754    {
755        tc = (col & 1) ? tc_v : tc_u;
756        delta = CLIP3((((pu1_src[0 * src_strd] -
757                      pu1_src[-1 * src_strd]) << 2) +
758                      pu1_src[-2 * src_strd] -
759                      pu1_src[1 * src_strd] + 4) >> 3,
760                      -tc, tc);
761
762        tmp_p0 = CLIP_U8(pu1_src[-1 * src_strd] + delta);
763        tmp_q0 = CLIP_U8(pu1_src[0 * src_strd] - delta);
764
765        if(filter_flag_p != 0)
766        {
767            pu1_src[-1 * src_strd] = tmp_p0;
768        }
769
770        if(filter_flag_q != 0)
771        {
772            pu1_src[0 * src_strd] = tmp_q0;
773        }
774
775        pu1_src += 1;
776    }
777
778}
779
780